vendor: update go-discover (#3634)
* vendor: update go-discover Pull in providers: * Aliyun (Alibaba Cloud) * Digital Ocean * OpenStack (os) * Scaleway * doc: use ... instead of xxx * doc: strip trailing whitespace * doc: add docs for aliyun, digitalocean, os and scaleway * agent: fix test
This commit is contained in:
parent
7432fd6d50
commit
56561523cf
|
@ -10,7 +10,7 @@ import (
|
|||
func TestGoDiscoverRegistration(t *testing.T) {
|
||||
d := discover.Discover{}
|
||||
got := d.Names()
|
||||
want := []string{"aws", "azure", "gce", "softlayer"}
|
||||
want := []string{"aliyun", "aws", "azure", "digitalocean", "gce", "os", "scaleway", "softlayer"}
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Fatalf("got go-discover providers %v want %v", got, want)
|
||||
}
|
||||
|
|
|
@ -21,25 +21,42 @@ sub packages. Additional providers can be added through the
|
|||
[Register](https://godoc.org/github.com/hashicorp/go-discover#Register)
|
||||
function.
|
||||
|
||||
* Amazon AWS [Config options](http://godoc.org/github.com/hashicorp/go-discover/provider/aws)
|
||||
* Google Cloud [Config options](http://godoc.org/github.com/hashicorp/go-discover/provider/gce)
|
||||
* Microsoft Azure [Config options](http://godoc.org/github.com/hashicorp/go-discover/provider/azure)
|
||||
* SoftLayer [Config options](http://godoc.org/github.com/hashicorp/go-discover/provider/softlayer)
|
||||
* Aliyun (Alibaba) Cloud [Config options](https://github.com/hashicorp/go-discover/blob/master/provider/aliyun/aliyun_discover.go#L15-L28)
|
||||
* Amazon AWS [Config options](https://github.com/hashicorp/go-discover/blob/master/provider/aws/aws_discover.go#L19-L33)
|
||||
* DigitalOcean [Config options](https://github.com/hashicorp/go-discover/blob/master/provider/digitalocean/digitalocean_discover.go#L16-L24)
|
||||
* Google Cloud [Config options](https://github.com/hashicorp/go-discover/blob/master/provider/gce/gce_discover.go#L17-L37)
|
||||
* Microsoft Azure [Config options](https://github.com/hashicorp/go-discover/blob/master/provider/azure/azure_discover.go#L16-L30)
|
||||
* Openstack [Config options](https://github.com/hashicorp/go-discover/blob/master/provider/os/os_discover.go#L23-L38)
|
||||
* Scaleway [Config options](https://github.com/hashicorp/go-discover/blob/master/provider/scaleway/scaleway_discover.go#L14-L22)
|
||||
* SoftLayer [Config options](https://github.com/hashicorp/go-discover/blob/master/provider/softlayer/softlayer_discover.go#L16-L25)
|
||||
|
||||
### Config Example
|
||||
|
||||
```
|
||||
# Aliyun (Alibaba) Cloud
|
||||
provider=aliyun region=... tag_key=consul tag_value=... access_key_id=... access_key_secret=...
|
||||
|
||||
# Amazon AWS
|
||||
provider=aws region=eu-west-1 tag_key=consul tag_value=... access_key_id=... secret_access_key=...
|
||||
|
||||
# DigitalOcean
|
||||
provider=digitalocean region=... tag_name=... api_token=...
|
||||
|
||||
# Google Cloud
|
||||
provider=gce project_name=... zone_pattern=eu-west-* tag_value=consul credentials_file=...
|
||||
|
||||
# Microsoft Azure
|
||||
provider=azure tag_name=consul tag_value=... tenant_id=... client_id=... subscription_id=... secret_access_key=...
|
||||
|
||||
# Openstack
|
||||
provider=os tag_key=consul tag_value=server username=... password=... auth_url=...
|
||||
|
||||
# Scaleway
|
||||
provider=scaleway organization=my-org tag_name=consul-server token=... region=...
|
||||
|
||||
# SoftLayer
|
||||
provider=softlayer datacenter=dal06 tag_value=consul username=... api_key=...
|
||||
|
||||
```
|
||||
|
||||
## Command Line Tool Usage
|
||||
|
|
|
@ -9,9 +9,13 @@ import (
|
|||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/hashicorp/go-discover/provider/aliyun"
|
||||
"github.com/hashicorp/go-discover/provider/aws"
|
||||
"github.com/hashicorp/go-discover/provider/azure"
|
||||
"github.com/hashicorp/go-discover/provider/digitalocean"
|
||||
"github.com/hashicorp/go-discover/provider/gce"
|
||||
"github.com/hashicorp/go-discover/provider/os"
|
||||
"github.com/hashicorp/go-discover/provider/scaleway"
|
||||
"github.com/hashicorp/go-discover/provider/softlayer"
|
||||
)
|
||||
|
||||
|
@ -28,10 +32,14 @@ type Provider interface {
|
|||
|
||||
// Providers contains all available providers.
|
||||
var Providers = map[string]Provider{
|
||||
"aws": &aws.Provider{},
|
||||
"azure": &azure.Provider{},
|
||||
"gce": &gce.Provider{},
|
||||
"softlayer": &softlayer.Provider{},
|
||||
"aliyun": &aliyun.Provider{},
|
||||
"aws": &aws.Provider{},
|
||||
"azure": &azure.Provider{},
|
||||
"digitalocean": &digitalocean.Provider{},
|
||||
"gce": &gce.Provider{},
|
||||
"os": &os.Provider{},
|
||||
"scaleway": &scaleway.Provider{},
|
||||
"softlayer": &softlayer.Provider{},
|
||||
}
|
||||
|
||||
// Discover looks up metadata in different cloud environments.
|
||||
|
|
93
vendor/github.com/hashicorp/go-discover/provider/aliyun/aliyun_discover.go
generated
vendored
Normal file
93
vendor/github.com/hashicorp/go-discover/provider/aliyun/aliyun_discover.go
generated
vendored
Normal file
|
@ -0,0 +1,93 @@
|
|||
// Package aliyun provides node discovery for Aliyun.
|
||||
package aliyun
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
"github.com/denverdino/aliyungo/ecs"
|
||||
)
|
||||
|
||||
type Provider struct{}
|
||||
|
||||
func (p *Provider) Help() string {
|
||||
return `Aliyun(Alibaba Cloud):
|
||||
|
||||
provider: "aliyun"
|
||||
region: The Aliyun region.
|
||||
tag_key: The tag key to filter on
|
||||
tag_value: The tag value to filter on
|
||||
access_key_id: The Aliyun access key to use
|
||||
access_key_secret: The Aliyun access key secret to use
|
||||
|
||||
The required RAM permission is 'ecs:DescribeInstances'.
|
||||
It is recommended you make a dedicated key used only for auto-joining.
|
||||
`
|
||||
}
|
||||
|
||||
func (p *Provider) Addrs(args map[string]string, l *log.Logger) ([]string, error) {
|
||||
if args["provider"] != "aliyun" {
|
||||
return nil, fmt.Errorf("discover-aliyun: invalid provider " + args["provider"])
|
||||
}
|
||||
|
||||
if l == nil {
|
||||
l = log.New(ioutil.Discard, "", 0)
|
||||
}
|
||||
|
||||
region := args["region"]
|
||||
tagKey := args["tag_key"]
|
||||
tagValue := args["tag_value"]
|
||||
accessKeyID := args["access_key_id"]
|
||||
accessKeySecret := args["access_key_secret"]
|
||||
|
||||
log.Printf("[DEBUG] discover-aliyun: Using region=%s tag_key=%s tag_value=%s", region, tagKey, tagValue)
|
||||
if accessKeyID == "" && accessKeySecret == "" {
|
||||
log.Printf("[DEBUG] discover-aliyun: No static credentials")
|
||||
} else {
|
||||
log.Printf("[DEBUG] discover-aliyun: Static credentials provided")
|
||||
}
|
||||
|
||||
if region == "" {
|
||||
l.Printf("[DEBUG] discover-aliyun: Region not provided")
|
||||
return nil, fmt.Errorf("discover-aliyun: invalid region")
|
||||
}
|
||||
l.Printf("[INFO] discover-aliyun: Region is %s", region)
|
||||
|
||||
svc := ecs.NewClient(accessKeyID, accessKeySecret)
|
||||
|
||||
l.Printf("[INFO] discover-aliyun: Filter instances with %s=%s", tagKey, tagValue)
|
||||
resp, err := svc.DescribeInstancesWithRaw(&ecs.DescribeInstancesArgs{
|
||||
RegionId: common.Region(region),
|
||||
Status: ecs.Running,
|
||||
Tag: map[string]string{
|
||||
tagKey: tagValue,
|
||||
}},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("discover-aliyun: DescribeInstancesWithRaw failed: %s", err)
|
||||
}
|
||||
|
||||
l.Printf("[DEBUG] discover-aliyun: Found total %d instances", resp.TotalCount)
|
||||
|
||||
var addrs []string
|
||||
for _, instanceAttributesType := range resp.Instances.Instance {
|
||||
switch instanceAttributesType.InstanceNetworkType {
|
||||
case "classic":
|
||||
for _, ipAddress := range instanceAttributesType.InnerIpAddress.IpAddress {
|
||||
l.Printf("[DEBUG] discover-aliyun: Instance %s has innner ip %s ", instanceAttributesType.InstanceId, ipAddress)
|
||||
addrs = append(addrs, ipAddress)
|
||||
}
|
||||
case "vpc":
|
||||
for _, ipAddress := range instanceAttributesType.VpcAttributes.PrivateIpAddress.IpAddress {
|
||||
l.Printf("[DEBUG] discover-aliyun: Instance %s has private ip %s ", instanceAttributesType.InstanceId, ipAddress)
|
||||
addrs = append(addrs, ipAddress)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
l.Printf("[DEBUG] discover-aliyun: Found ip addresses: %v", addrs)
|
||||
return addrs, nil
|
||||
}
|
191
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/LICENSE.txt
generated
vendored
Normal file
191
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/LICENSE.txt
generated
vendored
Normal file
|
@ -0,0 +1,191 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
https://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2015-2015 Li Yi (denverdino@gmail.com).
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
179
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/README.md
generated
vendored
Normal file
179
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/README.md
generated
vendored
Normal file
|
@ -0,0 +1,179 @@
|
|||
# AliyunGo: Go SDK for Aliyun Services
|
||||
|
||||
[![Build Status](https://travis-ci.org/denverdino/aliyungo.svg?branch=master)](https://travis-ci.org/denverdino/aliyungo) [![CircleCI](https://circleci.com/gh/denverdino/aliyungo.svg?style=svg)](https://circleci.com/gh/denverdino/aliyungo) [![Go Report Card](https://goreportcard.com/badge/github.com/denverdino/aliyungo)](https://goreportcard.com/report/github.com/denverdino/aliyungo)
|
||||
|
||||
This is an unofficial Go SDK for Aliyun Services. You are welcome for contribution.
|
||||
|
||||
## Package Structure
|
||||
|
||||
* cdn: [Content Delivery Network](https://help.aliyun.com/document_detail/27101.html)
|
||||
* cms: [Cloud Monitor Service](https://help.aliyun.com/document_detail/28615.html)
|
||||
* cs: [Container Service](https://help.aliyun.com/product/25972.html)
|
||||
* dm: [Direct Mail](https://help.aliyun.com/document_detail/29414.html)
|
||||
* dns: [DNS](https://help.aliyun.com/document_detail/dns/api-reference/summary.html)
|
||||
* ecs: [Elastic Compute Service](https://help.aliyun.com/document_detail/ecs/open-api/summary.html)
|
||||
* ess: [Auto Scaling](https://help.aliyun.com/document_detail/25857.html)
|
||||
* mns: [Message Service](https://help.aliyun.com/document_detail/27414.html)
|
||||
* mq: [Message Queue](https://help.aliyun.com/document_detail/29532.html)
|
||||
* nas: [Network Attached Storage](https://help.aliyun.com/document_detail/27518.html)
|
||||
* opensearch: [OpenSearch](https://help.aliyun.com/document_detail/29118.html)
|
||||
* oss: [Open Storage Service](https://help.aliyun.com/document_detail/oss/api-reference/abstract.html)
|
||||
* push: [Cloud Mobile Push](https://help.aliyun.com/document_detail/30049.html)
|
||||
* rds: [Relational Database Service](https://help.aliyun.com/document_detail/26226.html)
|
||||
* ram: [Resource Access Management](https://help.aliyun.com/document_detail/ram/ram-api-reference/intro/intro.html)
|
||||
* slb: [Server Load Balancer](https://help.aliyun.com/document_detail/slb/api-reference/brief-introduction.html)
|
||||
* sls: [Logging Service](https://help.aliyun.com/document_detail/sls/api/overview.html)
|
||||
* sms: [Short Message Service](https://help.aliyun.com/product/44282.html)
|
||||
* sts: [Security Token Service](https://help.aliyun.com/document_detail/28756.html)
|
||||
* common: Common libary of Aliyun Go SDK
|
||||
* util: Utility helpers
|
||||
|
||||
## Quick Start
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/denverdino/aliyungo/ecs"
|
||||
)
|
||||
|
||||
const ACCESS_KEY_ID = "<YOUR_ID>"
|
||||
const ACCESS_KEY_SECRET = "<****>"
|
||||
|
||||
func main() {
|
||||
client := ecs.NewClient(ACCESS_KEY_ID, ACCESS_KEY_SECRET)
|
||||
fmt.Print(client.DescribeRegions())
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
* CDN: [https://godoc.org/github.com/denverdino/aliyungo/cdn](https://godoc.org/github.com/denverdino/aliyungo/cdn)[![GoDoc](https://godoc.org/github.com/denverdino/aliyungo/cdn?status.svg)](https://godoc.org/github.com/denverdino/aliyungo/cdn)
|
||||
* CMS: [https://godoc.org/github.com/denverdino/aliyungo/cms](https://godoc.org/github.com/denverdino/aliyungo/cms) [![GoDoc](https://godoc.org/github.com/denverdino/aliyungo/cms?status.svg)](https://godoc.org/github.com/denverdino/aliyungo/cms)
|
||||
* CS: [https://godoc.org/github.com/denverdino/aliyungo/cs](https://godoc.org/github.com/denverdino/aliyungo/cs) [![GoDoc](https://godoc.org/github.com/denverdino/aliyungo/cs?status.svg)](https://godoc.org/github.com/denverdino/aliyungo/cs)
|
||||
* DM: [https://godoc.org/github.com/denverdino/aliyungo/dm](https://godoc.org/github.com/denverdino/aliyungo/dm) [![GoDoc](https://godoc.org/github.com/denverdino/aliyungo/dm?status.svg)](https://godoc.org/github.com/denverdino/aliyungo/dm)
|
||||
* DNS: [https://godoc.org/github.com/denverdino/aliyungo/dns](https://godoc.org/github.com/denverdino/aliyungo/dns) [![GoDoc](https://godoc.org/github.com/denverdino/aliyungo/dns?status.svg)](https://godoc.org/github.com/denverdino/aliyungo/dns)
|
||||
* ECS: [https://godoc.org/github.com/denverdino/aliyungo/ecs](https://godoc.org/github.com/denverdino/aliyungo/ecs) [![GoDoc](https://godoc.org/github.com/denverdino/aliyungo/ecs?status.svg)](https://godoc.org/github.com/denverdino/aliyungo/ecs)
|
||||
* ESS: [https://godoc.org/github.com/denverdino/aliyungo/ess](https://godoc.org/github.com/denverdino/aliyungo/ess)[![GoDoc](https://godoc.org/github.com/denverdino/aliyungo/ess?status.svg)](https://godoc.org/github.com/denverdino/aliyungo/ess)
|
||||
* MNS: [https://godoc.org/github.com/denverdino/aliyungo/mns](https://godoc.org/github.com/denverdino/aliyungo/mns)[![GoDoc](https://godoc.org/github.com/denverdino/aliyungo/mns?status.svg)](https://godoc.org/github.com/denverdino/aliyungo/mns)
|
||||
* MQ: [https://godoc.org/github.com/denverdino/aliyungo/mq](https://godoc.org/github.com/denverdino/aliyungo/mq) [![GoDoc](https://godoc.org/github.com/denverdino/aliyungo/mq?status.svg)](https://godoc.org/github.com/denverdino/aliyungo/mq)
|
||||
* NAS: [https://godoc.org/github.com/denverdino/aliyungo/nas](https://godoc.org/github.com/denverdino/aliyungo/nas) [![GoDoc](https://godoc.org/github.com/denverdino/aliyungo/nas?status.svg)](https://godoc.org/github.com/denverdino/aliyungo/nas)
|
||||
* OPENSEARCH: [https://godoc.org/github.com/denverdino/aliyungo/opensearch](https://godoc.org/github.com/denverdino/aliyungo/opensearch) [![GoDoc](https://godoc.org/github.com/denverdino/aliyungo/opensearch?status.svg)](https://godoc.org/github.com/denverdino/aliyungo/opensearch)
|
||||
* OSS: [https://godoc.org/github.com/denverdino/aliyungo/oss](https://godoc.org/github.com/denverdino/aliyungo/oss) [![GoDoc](https://godoc.org/github.com/denverdino/aliyungo/oss?status.svg)](https://godoc.org/github.com/denverdino/aliyungo/oss)
|
||||
* PUSH: [https://godoc.org/github.com/denverdino/aliyungo/push](https://godoc.org/github.com/denverdino/aliyungo/push) [![GoDoc](https://godoc.org/github.com/denverdino/aliyungo/push?status.svg)](https://godoc.org/github.com/denverdino/aliyungo/push)
|
||||
* RAM: [https://godoc.org/github.com/denverdino/aliyungo/ram](https://godoc.org/github.com/denverdino/aliyungo/ram) [![GoDoc](https://godoc.org/github.com/denverdino/aliyungo/ram?status.svg)](https://godoc.org/github.com/denverdino/aliyungo/ram)
|
||||
* RDS: [https://godoc.org/github.com/denverdino/aliyungo/rds](https://godoc.org/github.com/denverdino/aliyungo/rds) [![GoDoc](https://godoc.org/github.com/denverdino/aliyungo/rds?status.svg)](https://godoc.org/github.com/denverdino/aliyungo/rds)
|
||||
* SLB: [https://godoc.org/github.com/denverdino/aliyungo/slb](https://godoc.org/github.com/denverdino/aliyungo/slb) [![GoDoc](https://godoc.org/github.com/denverdino/aliyungo/slb?status.svg)](https://godoc.org/github.com/denverdino/aliyungo/slb)
|
||||
* SLS: [https://godoc.org/github.com/denverdino/aliyungo/sls](https://godoc.org/github.com/denverdino/aliyungo/sls) [![GoDoc](https://godoc.org/github.com/denverdino/aliyungo/sls?status.svg)](https://godoc.org/github.com/denverdino/aliyungo/sls)
|
||||
* SMS: [https://godoc.org/github.com/denverdino/aliyungo/sms](https://godoc.org/github.com/denverdino/aliyungo/sms) [![GoDoc](https://godoc.org/github.com/denverdino/aliyungo/sms?status.svg)](https://godoc.org/github.com/denverdino/aliyungo/sms)
|
||||
* STS: [https://godoc.org/github.com/denverdino/aliyungo/sts](https://godoc.org/github.com/denverdino/aliyungo/sts) [![GoDoc](https://godoc.org/github.com/denverdino/aliyungo/sts?status.svg)](https://godoc.org/github.com/denverdino/aliyungo/sts)
|
||||
|
||||
## Build and Install
|
||||
|
||||
go get:
|
||||
|
||||
```sh
|
||||
go get github.com/denverdino/aliyungo
|
||||
```
|
||||
|
||||
## Test ECS
|
||||
|
||||
Modify "ecs/config_test.go"
|
||||
|
||||
```sh
|
||||
TestAccessKeyId = "MY_ACCESS_KEY_ID"
|
||||
TestAccessKeySecret = "MY_ACCESS_KEY_ID"
|
||||
TestInstanceId = "MY_INSTANCE_ID"
|
||||
TestIAmRich = false
|
||||
```
|
||||
|
||||
* TestAccessKeyId: the Access Key Id
|
||||
* TestAccessKeySecret: the Access Key Secret.
|
||||
* TestInstanceId: the existing instance id for testing. It will be stopped and restarted during testing.
|
||||
* TestIAmRich(Optional): If it is set to true, it will perform tests to create virtual machines and disks under your account. And you will pay the bill. :-)
|
||||
|
||||
Under "ecs" and run
|
||||
|
||||
```sh
|
||||
go test
|
||||
```
|
||||
|
||||
## Test OSS
|
||||
|
||||
Modify "oss/config_test.go"
|
||||
|
||||
```sh
|
||||
TestAccessKeyId = "MY_ACCESS_KEY_ID"
|
||||
TestAccessKeySecret = "MY_ACCESS_KEY_ID"
|
||||
TestRegion = oss.Beijing
|
||||
TestBucket = "denverdino"
|
||||
```
|
||||
|
||||
* TestAccessKeyId: the Access Key Id
|
||||
* TestAccessKeySecret: the Access Key Secret.
|
||||
* TestRegion: the region of OSS for testing
|
||||
* TestBucket: the bucket name for testing
|
||||
|
||||
Under "oss" and run
|
||||
|
||||
```sh
|
||||
go test
|
||||
```
|
||||
|
||||
## Contributors
|
||||
|
||||
* Li Yi (denverdino@gmail.com)
|
||||
* Boshi Lian (farmer1992@gmail.com)
|
||||
* Yu Zhou (oscarrr110@gmail.com)
|
||||
* Yufei Zhang
|
||||
* linuxlikerqq
|
||||
* Changhai Yan
|
||||
* Jizhong Jiang (jiangjizhong@gmail.com)
|
||||
* Kent Wang (pragkent@gmail.com)
|
||||
* ringtail
|
||||
* aiden0z (aiden0xz@gmail.com)
|
||||
* jimmycmh
|
||||
* menglingwei
|
||||
* mingang.he (dustgle@gmail.com)
|
||||
* Young Chen (chainone@gmail.com)
|
||||
* johnzeng
|
||||
* spacexnice (445436286@qq.com)
|
||||
* xiaoheihero
|
||||
* hmgle (dustgle@gmail.com)
|
||||
* jzwlqx (jiangjizhong@gmail.com)
|
||||
* Linhua Tan (toolchainX@gmail.com)
|
||||
* Plutonist (p@vecsight.com)
|
||||
* Bin Liu
|
||||
* wangyue
|
||||
* demonwy
|
||||
* yarous224
|
||||
* yufeizyf (xazyf9111@sina.cn)
|
||||
* keontang (ikeontang@gmail.com)
|
||||
* Cholerae Hu (me@cholerae.com)
|
||||
* Zach Bergh (berghzach@gmail.com)
|
||||
* Bingshen Wang
|
||||
* xiaozhu36
|
||||
* Russell (yufeiwu@gmail.com)
|
||||
* zhuzhih2017
|
||||
* cheyang
|
||||
* Hobo Chen
|
||||
* Shuwei Yin
|
||||
* Xujin Zheng (xujinzheng@gmail.com)
|
||||
* Dino Lai (dinos80152@gmail.com)
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the Apache License, Version 2.0. See [LICENSE](https://github.com/denverdino/aliyungo/blob/master/LICENSE.txt) for the full license text.
|
||||
|
||||
## Related projects
|
||||
|
||||
* Aliyun ECS driver for Docker Machine: [Pull request](https://github.com/docker/machine/pull/1182)
|
||||
|
||||
* Aliyun OSS driver for Docker Registry V2: [Pull request](https://github.com/docker/distribution/pull/514)
|
||||
|
||||
## References
|
||||
|
||||
The GO API design of OSS refer the implementation from [https://github.com/AdRoll/goamz](https://github.com/AdRoll)
|
357
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/common/client.go
generated
vendored
Executable file
357
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/common/client.go
generated
vendored
Executable file
|
@ -0,0 +1,357 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/denverdino/aliyungo/util"
|
||||
)
|
||||
|
||||
// RemovalPolicy.N add index to array item
|
||||
// RemovalPolicy=["a", "b"] => RemovalPolicy.1="a" RemovalPolicy.2="b"
|
||||
type FlattenArray []string
|
||||
|
||||
// string contains underline which will be replaced with dot
|
||||
// SystemDisk_Category => SystemDisk.Category
|
||||
type UnderlineString string
|
||||
|
||||
// A Client represents a client of ECS services
|
||||
type Client struct {
|
||||
AccessKeyId string //Access Key Id
|
||||
AccessKeySecret string //Access Key Secret
|
||||
debug bool
|
||||
httpClient *http.Client
|
||||
endpoint string
|
||||
version string
|
||||
serviceCode string
|
||||
regionID Region
|
||||
businessInfo string
|
||||
userAgent string
|
||||
}
|
||||
|
||||
// NewClient creates a new instance of ECS client
|
||||
func (client *Client) Init(endpoint, version, accessKeyId, accessKeySecret string) {
|
||||
client.AccessKeyId = accessKeyId
|
||||
client.AccessKeySecret = accessKeySecret + "&"
|
||||
client.debug = false
|
||||
client.httpClient = &http.Client{}
|
||||
client.endpoint = endpoint
|
||||
client.version = version
|
||||
}
|
||||
|
||||
func (client *Client) NewInit(endpoint, version, accessKeyId, accessKeySecret, serviceCode string, regionID Region) {
|
||||
client.Init(endpoint, version, accessKeyId, accessKeySecret)
|
||||
client.serviceCode = serviceCode
|
||||
client.regionID = regionID
|
||||
client.setEndpointByLocation(regionID, serviceCode, accessKeyId, accessKeySecret)
|
||||
}
|
||||
|
||||
//NewClient using location service
|
||||
func (client *Client) setEndpointByLocation(region Region, serviceCode, accessKeyId, accessKeySecret string) {
|
||||
locationClient := NewLocationClient(accessKeyId, accessKeySecret)
|
||||
ep := locationClient.DescribeOpenAPIEndpoint(region, serviceCode)
|
||||
if ep == "" {
|
||||
ep = loadEndpointFromFile(region, serviceCode)
|
||||
}
|
||||
|
||||
if ep != "" {
|
||||
client.endpoint = ep
|
||||
}
|
||||
}
|
||||
|
||||
// SetEndpoint sets custom endpoint
|
||||
func (client *Client) SetEndpoint(endpoint string) {
|
||||
client.endpoint = endpoint
|
||||
}
|
||||
|
||||
// SetEndpoint sets custom version
|
||||
func (client *Client) SetVersion(version string) {
|
||||
client.version = version
|
||||
}
|
||||
|
||||
func (client *Client) SetRegionID(regionID Region) {
|
||||
client.regionID = regionID
|
||||
}
|
||||
|
||||
//SetServiceCode sets serviceCode
|
||||
func (client *Client) SetServiceCode(serviceCode string) {
|
||||
client.serviceCode = serviceCode
|
||||
}
|
||||
|
||||
// SetAccessKeyId sets new AccessKeyId
|
||||
func (client *Client) SetAccessKeyId(id string) {
|
||||
client.AccessKeyId = id
|
||||
}
|
||||
|
||||
// SetAccessKeySecret sets new AccessKeySecret
|
||||
func (client *Client) SetAccessKeySecret(secret string) {
|
||||
client.AccessKeySecret = secret + "&"
|
||||
}
|
||||
|
||||
// SetDebug sets debug mode to log the request/response message
|
||||
func (client *Client) SetDebug(debug bool) {
|
||||
client.debug = debug
|
||||
}
|
||||
|
||||
// SetBusinessInfo sets business info to log the request/response message
|
||||
func (client *Client) SetBusinessInfo(businessInfo string) {
|
||||
if strings.HasPrefix(businessInfo, "/") {
|
||||
client.businessInfo = businessInfo
|
||||
} else if businessInfo != "" {
|
||||
client.businessInfo = "/" + businessInfo
|
||||
}
|
||||
}
|
||||
|
||||
// SetUserAgent sets user agent to the request/response message
|
||||
func (client *Client) SetUserAgent(userAgent string) {
|
||||
client.userAgent = userAgent
|
||||
}
|
||||
|
||||
// Invoke sends the raw HTTP request for ECS services
|
||||
func (client *Client) Invoke(action string, args interface{}, response interface{}) error {
|
||||
|
||||
request := Request{}
|
||||
request.init(client.version, action, client.AccessKeyId)
|
||||
|
||||
query := util.ConvertToQueryValues(request)
|
||||
util.SetQueryValues(args, &query)
|
||||
|
||||
// Sign request
|
||||
signature := util.CreateSignatureForRequest(ECSRequestMethod, &query, client.AccessKeySecret)
|
||||
|
||||
// Generate the request URL
|
||||
requestURL := client.endpoint + "?" + query.Encode() + "&Signature=" + url.QueryEscape(signature)
|
||||
|
||||
httpReq, err := http.NewRequest(ECSRequestMethod, requestURL, nil)
|
||||
|
||||
if err != nil {
|
||||
return GetClientError(err)
|
||||
}
|
||||
|
||||
// TODO move to util and add build val flag
|
||||
httpReq.Header.Set("X-SDK-Client", `AliyunGO/`+Version+client.businessInfo)
|
||||
|
||||
httpReq.Header.Set("User-Agent", httpReq.UserAgent()+ " " +client.userAgent)
|
||||
|
||||
t0 := time.Now()
|
||||
httpResp, err := client.httpClient.Do(httpReq)
|
||||
t1 := time.Now()
|
||||
if err != nil {
|
||||
return GetClientError(err)
|
||||
}
|
||||
statusCode := httpResp.StatusCode
|
||||
|
||||
if client.debug {
|
||||
log.Printf("Invoke %s %s %d (%v)", ECSRequestMethod, requestURL, statusCode, t1.Sub(t0))
|
||||
}
|
||||
|
||||
defer httpResp.Body.Close()
|
||||
body, err := ioutil.ReadAll(httpResp.Body)
|
||||
|
||||
if err != nil {
|
||||
return GetClientError(err)
|
||||
}
|
||||
|
||||
if client.debug {
|
||||
var prettyJSON bytes.Buffer
|
||||
err = json.Indent(&prettyJSON, body, "", " ")
|
||||
log.Println(string(prettyJSON.Bytes()))
|
||||
}
|
||||
|
||||
if statusCode >= 400 && statusCode <= 599 {
|
||||
errorResponse := ErrorResponse{}
|
||||
err = json.Unmarshal(body, &errorResponse)
|
||||
ecsError := &Error{
|
||||
ErrorResponse: errorResponse,
|
||||
StatusCode: statusCode,
|
||||
}
|
||||
return ecsError
|
||||
}
|
||||
|
||||
err = json.Unmarshal(body, response)
|
||||
//log.Printf("%++v", response)
|
||||
if err != nil {
|
||||
return GetClientError(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Invoke sends the raw HTTP request for ECS services
|
||||
func (client *Client) InvokeByFlattenMethod(action string, args interface{}, response interface{}) error {
|
||||
|
||||
request := Request{}
|
||||
request.init(client.version, action, client.AccessKeyId)
|
||||
|
||||
query := util.ConvertToQueryValues(request)
|
||||
|
||||
util.SetQueryValueByFlattenMethod(args, &query)
|
||||
|
||||
// Sign request
|
||||
signature := util.CreateSignatureForRequest(ECSRequestMethod, &query, client.AccessKeySecret)
|
||||
|
||||
// Generate the request URL
|
||||
requestURL := client.endpoint + "?" + query.Encode() + "&Signature=" + url.QueryEscape(signature)
|
||||
|
||||
httpReq, err := http.NewRequest(ECSRequestMethod, requestURL, nil)
|
||||
|
||||
if err != nil {
|
||||
return GetClientError(err)
|
||||
}
|
||||
|
||||
// TODO move to util and add build val flag
|
||||
httpReq.Header.Set("X-SDK-Client", `AliyunGO/`+Version+client.businessInfo)
|
||||
|
||||
httpReq.Header.Set("User-Agent", httpReq.UserAgent()+ " " +client.userAgent)
|
||||
|
||||
t0 := time.Now()
|
||||
httpResp, err := client.httpClient.Do(httpReq)
|
||||
t1 := time.Now()
|
||||
if err != nil {
|
||||
return GetClientError(err)
|
||||
}
|
||||
statusCode := httpResp.StatusCode
|
||||
|
||||
if client.debug {
|
||||
log.Printf("Invoke %s %s %d (%v)", ECSRequestMethod, requestURL, statusCode, t1.Sub(t0))
|
||||
}
|
||||
|
||||
defer httpResp.Body.Close()
|
||||
body, err := ioutil.ReadAll(httpResp.Body)
|
||||
|
||||
if err != nil {
|
||||
return GetClientError(err)
|
||||
}
|
||||
|
||||
if client.debug {
|
||||
var prettyJSON bytes.Buffer
|
||||
err = json.Indent(&prettyJSON, body, "", " ")
|
||||
log.Println(string(prettyJSON.Bytes()))
|
||||
}
|
||||
|
||||
if statusCode >= 400 && statusCode <= 599 {
|
||||
errorResponse := ErrorResponse{}
|
||||
err = json.Unmarshal(body, &errorResponse)
|
||||
ecsError := &Error{
|
||||
ErrorResponse: errorResponse,
|
||||
StatusCode: statusCode,
|
||||
}
|
||||
return ecsError
|
||||
}
|
||||
|
||||
err = json.Unmarshal(body, response)
|
||||
//log.Printf("%++v", response)
|
||||
if err != nil {
|
||||
return GetClientError(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Invoke sends the raw HTTP request for ECS services
|
||||
//改进了一下上面那个方法,可以使用各种Http方法
|
||||
//2017.1.30 增加了一个path参数,用来拓展访问的地址
|
||||
func (client *Client) InvokeByAnyMethod(method, action, path string, args interface{}, response interface{}) error {
|
||||
|
||||
request := Request{}
|
||||
request.init(client.version, action, client.AccessKeyId)
|
||||
|
||||
data := util.ConvertToQueryValues(request)
|
||||
util.SetQueryValues(args, &data)
|
||||
|
||||
// Sign request
|
||||
signature := util.CreateSignatureForRequest(method, &data, client.AccessKeySecret)
|
||||
|
||||
data.Add("Signature", signature)
|
||||
// Generate the request URL
|
||||
var (
|
||||
httpReq *http.Request
|
||||
err error
|
||||
)
|
||||
if method == http.MethodGet {
|
||||
requestURL := client.endpoint + path + "?" + data.Encode()
|
||||
//fmt.Println(requestURL)
|
||||
httpReq, err = http.NewRequest(method, requestURL, nil)
|
||||
} else {
|
||||
//fmt.Println(client.endpoint + path)
|
||||
httpReq, err = http.NewRequest(method, client.endpoint+path, strings.NewReader(data.Encode()))
|
||||
httpReq.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return GetClientError(err)
|
||||
}
|
||||
|
||||
// TODO move to util and add build val flag
|
||||
httpReq.Header.Set("X-SDK-Client", `AliyunGO/`+Version+client.businessInfo)
|
||||
|
||||
httpReq.Header.Set("User-Agent", httpReq.Header.Get("User-Agent")+ " " +client.userAgent)
|
||||
|
||||
t0 := time.Now()
|
||||
httpResp, err := client.httpClient.Do(httpReq)
|
||||
t1 := time.Now()
|
||||
if err != nil {
|
||||
return GetClientError(err)
|
||||
}
|
||||
statusCode := httpResp.StatusCode
|
||||
|
||||
if client.debug {
|
||||
log.Printf("Invoke %s %s %d (%v) %v", ECSRequestMethod, client.endpoint, statusCode, t1.Sub(t0), data.Encode())
|
||||
}
|
||||
|
||||
defer httpResp.Body.Close()
|
||||
body, err := ioutil.ReadAll(httpResp.Body)
|
||||
|
||||
if err != nil {
|
||||
return GetClientError(err)
|
||||
}
|
||||
|
||||
if client.debug {
|
||||
var prettyJSON bytes.Buffer
|
||||
err = json.Indent(&prettyJSON, body, "", " ")
|
||||
log.Println(string(prettyJSON.Bytes()))
|
||||
}
|
||||
|
||||
if statusCode >= 400 && statusCode <= 599 {
|
||||
errorResponse := ErrorResponse{}
|
||||
err = json.Unmarshal(body, &errorResponse)
|
||||
ecsError := &Error{
|
||||
ErrorResponse: errorResponse,
|
||||
StatusCode: statusCode,
|
||||
}
|
||||
return ecsError
|
||||
}
|
||||
|
||||
err = json.Unmarshal(body, response)
|
||||
//log.Printf("%++v", response)
|
||||
if err != nil {
|
||||
return GetClientError(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GenerateClientToken generates the Client Token with random string
|
||||
func (client *Client) GenerateClientToken() string {
|
||||
return util.CreateRandomString()
|
||||
}
|
||||
|
||||
func GetClientErrorFromString(str string) error {
|
||||
return &Error{
|
||||
ErrorResponse: ErrorResponse{
|
||||
Code: "AliyunGoClientFailure",
|
||||
Message: str,
|
||||
},
|
||||
StatusCode: -1,
|
||||
}
|
||||
}
|
||||
|
||||
func GetClientError(err error) error {
|
||||
return GetClientErrorFromString(err.Error())
|
||||
}
|
118
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/common/endpoint.go
generated
vendored
Normal file
118
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/common/endpoint.go
generated
vendored
Normal file
|
@ -0,0 +1,118 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
// LocationDefaultEndpoint is the default API endpoint of Location services
|
||||
locationDefaultEndpoint = "https://location.aliyuncs.com"
|
||||
locationAPIVersion = "2015-06-12"
|
||||
HTTP_PROTOCOL = "http"
|
||||
HTTPS_PROTOCOL = "https"
|
||||
)
|
||||
|
||||
var (
|
||||
endpoints = make(map[Region]map[string]string)
|
||||
)
|
||||
|
||||
//init endpoints from file
|
||||
func init() {
|
||||
|
||||
}
|
||||
|
||||
func NewLocationClient(accessKeyId, accessKeySecret string) *Client {
|
||||
endpoint := os.Getenv("LOCATION_ENDPOINT")
|
||||
if endpoint == "" {
|
||||
endpoint = locationDefaultEndpoint
|
||||
}
|
||||
|
||||
client := &Client{}
|
||||
client.Init(endpoint, locationAPIVersion, accessKeyId, accessKeySecret)
|
||||
return client
|
||||
}
|
||||
|
||||
func (client *Client) DescribeEndpoint(args *DescribeEndpointArgs) (*DescribeEndpointResponse, error) {
|
||||
response := &DescribeEndpointResponse{}
|
||||
err := client.Invoke("DescribeEndpoint", args, response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return response, err
|
||||
}
|
||||
|
||||
func getProductRegionEndpoint(region Region, serviceCode string) string {
|
||||
if sp, ok := endpoints[region]; ok {
|
||||
if endpoint, ok := sp[serviceCode]; ok {
|
||||
return endpoint
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func setProductRegionEndpoint(region Region, serviceCode string, endpoint string) {
|
||||
endpoints[region] = map[string]string{
|
||||
serviceCode: endpoint,
|
||||
}
|
||||
}
|
||||
|
||||
func (client *Client) DescribeOpenAPIEndpoint(region Region, serviceCode string) string {
|
||||
if endpoint := getProductRegionEndpoint(region, serviceCode); endpoint != "" {
|
||||
return endpoint
|
||||
}
|
||||
|
||||
defaultProtocols := HTTP_PROTOCOL
|
||||
|
||||
args := &DescribeEndpointArgs{
|
||||
Id: region,
|
||||
ServiceCode: serviceCode,
|
||||
Type: "openAPI",
|
||||
}
|
||||
|
||||
endpoint, err := client.DescribeEndpoint(args)
|
||||
if err != nil || endpoint.Endpoint == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
for _, protocol := range endpoint.Protocols.Protocols {
|
||||
if strings.ToLower(protocol) == HTTPS_PROTOCOL {
|
||||
defaultProtocols = HTTPS_PROTOCOL
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
ep := fmt.Sprintf("%s://%s", defaultProtocols, endpoint.Endpoint)
|
||||
|
||||
setProductRegionEndpoint(region, serviceCode, ep)
|
||||
return ep
|
||||
}
|
||||
|
||||
func loadEndpointFromFile(region Region, serviceCode string) string {
|
||||
data, err := ioutil.ReadFile("./endpoints.xml")
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
var endpoints Endpoints
|
||||
err = xml.Unmarshal(data, &endpoints)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
for _, endpoint := range endpoints.Endpoint {
|
||||
if endpoint.RegionIds.RegionId == string(region) {
|
||||
for _, product := range endpoint.Products.Product {
|
||||
if strings.ToLower(product.ProductName) == serviceCode {
|
||||
return fmt.Sprintf("%s://%s", HTTPS_PROTOCOL, product.DomainName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
1349
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/common/endpoints.xml
generated
vendored
Normal file
1349
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/common/endpoints.xml
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
34
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/common/regions.go
generated
vendored
Normal file
34
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/common/regions.go
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
package common
|
||||
|
||||
// Region represents ECS region
|
||||
type Region string
|
||||
|
||||
// Constants of region definition
|
||||
const (
|
||||
Hangzhou = Region("cn-hangzhou")
|
||||
Qingdao = Region("cn-qingdao")
|
||||
Beijing = Region("cn-beijing")
|
||||
Hongkong = Region("cn-hongkong")
|
||||
Shenzhen = Region("cn-shenzhen")
|
||||
Shanghai = Region("cn-shanghai")
|
||||
Zhangjiakou = Region("cn-zhangjiakou")
|
||||
|
||||
APSouthEast1 = Region("ap-southeast-1")
|
||||
APNorthEast1 = Region("ap-northeast-1")
|
||||
APSouthEast2 = Region("ap-southeast-2")
|
||||
|
||||
USWest1 = Region("us-west-1")
|
||||
USEast1 = Region("us-east-1")
|
||||
|
||||
MEEast1 = Region("me-east-1")
|
||||
|
||||
EUCentral1 = Region("eu-central-1")
|
||||
)
|
||||
|
||||
var ValidRegions = []Region{
|
||||
Hangzhou, Qingdao, Beijing, Shenzhen, Hongkong, Shanghai, Zhangjiakou,
|
||||
USWest1, USEast1,
|
||||
APNorthEast1, APSouthEast1, APSouthEast2,
|
||||
MEEast1,
|
||||
EUCentral1,
|
||||
}
|
101
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/common/request.go
generated
vendored
Normal file
101
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/common/request.go
generated
vendored
Normal file
|
@ -0,0 +1,101 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/denverdino/aliyungo/util"
|
||||
)
|
||||
|
||||
// Constants for Aliyun API requests
|
||||
const (
|
||||
SignatureVersion = "1.0"
|
||||
SignatureMethod = "HMAC-SHA1"
|
||||
JSONResponseFormat = "JSON"
|
||||
XMLResponseFormat = "XML"
|
||||
ECSRequestMethod = "GET"
|
||||
)
|
||||
|
||||
type Request struct {
|
||||
Format string
|
||||
Version string
|
||||
AccessKeyId string
|
||||
Signature string
|
||||
SignatureMethod string
|
||||
Timestamp util.ISO6801Time
|
||||
SignatureVersion string
|
||||
SignatureNonce string
|
||||
ResourceOwnerAccount string
|
||||
Action string
|
||||
}
|
||||
|
||||
func (request *Request) init(version string, action string, AccessKeyId string) {
|
||||
request.Format = JSONResponseFormat
|
||||
request.Timestamp = util.NewISO6801Time(time.Now().UTC())
|
||||
request.Version = version
|
||||
request.SignatureVersion = SignatureVersion
|
||||
request.SignatureMethod = SignatureMethod
|
||||
request.SignatureNonce = util.CreateRandomString()
|
||||
request.Action = action
|
||||
request.AccessKeyId = AccessKeyId
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
RequestId string
|
||||
}
|
||||
|
||||
type ErrorResponse struct {
|
||||
Response
|
||||
HostId string
|
||||
Code string
|
||||
Message string
|
||||
}
|
||||
|
||||
// An Error represents a custom error for Aliyun API failure response
|
||||
type Error struct {
|
||||
ErrorResponse
|
||||
StatusCode int //Status Code of HTTP Response
|
||||
}
|
||||
|
||||
func (e *Error) Error() string {
|
||||
return fmt.Sprintf("Aliyun API Error: RequestId: %s Status Code: %d Code: %s Message: %s", e.RequestId, e.StatusCode, e.Code, e.Message)
|
||||
}
|
||||
|
||||
type Pagination struct {
|
||||
PageNumber int
|
||||
PageSize int
|
||||
}
|
||||
|
||||
func (p *Pagination) SetPageSize(size int) {
|
||||
p.PageSize = size
|
||||
}
|
||||
|
||||
func (p *Pagination) Validate() {
|
||||
if p.PageNumber < 0 {
|
||||
log.Printf("Invalid PageNumber: %d", p.PageNumber)
|
||||
p.PageNumber = 1
|
||||
}
|
||||
if p.PageSize < 0 {
|
||||
log.Printf("Invalid PageSize: %d", p.PageSize)
|
||||
p.PageSize = 10
|
||||
} else if p.PageSize > 50 {
|
||||
log.Printf("Invalid PageSize: %d", p.PageSize)
|
||||
p.PageSize = 50
|
||||
}
|
||||
}
|
||||
|
||||
// A PaginationResponse represents a response with pagination information
|
||||
type PaginationResult struct {
|
||||
TotalCount int
|
||||
PageNumber int
|
||||
PageSize int
|
||||
}
|
||||
|
||||
// NextPage gets the next page of the result set
|
||||
func (r *PaginationResult) NextPage() *Pagination {
|
||||
if r.PageNumber*r.PageSize >= r.TotalCount {
|
||||
return nil
|
||||
}
|
||||
return &Pagination{PageNumber: r.PageNumber + 1, PageSize: r.PageSize}
|
||||
}
|
89
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/common/types.go
generated
vendored
Normal file
89
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/common/types.go
generated
vendored
Normal file
|
@ -0,0 +1,89 @@
|
|||
package common
|
||||
|
||||
type InternetChargeType string
|
||||
|
||||
const (
|
||||
PayByBandwidth = InternetChargeType("PayByBandwidth")
|
||||
PayByTraffic = InternetChargeType("PayByTraffic")
|
||||
)
|
||||
|
||||
type InstanceChargeType string
|
||||
|
||||
const (
|
||||
PrePaid = InstanceChargeType("PrePaid")
|
||||
PostPaid = InstanceChargeType("PostPaid")
|
||||
)
|
||||
|
||||
type DescribeEndpointArgs struct {
|
||||
Id Region
|
||||
ServiceCode string
|
||||
Type string
|
||||
}
|
||||
|
||||
type EndpointItem struct {
|
||||
Protocols struct {
|
||||
Protocols []string
|
||||
}
|
||||
Type string
|
||||
Namespace string
|
||||
Id Region
|
||||
SerivceCode string
|
||||
Endpoint string
|
||||
}
|
||||
|
||||
type DescribeEndpointResponse struct {
|
||||
Response
|
||||
EndpointItem
|
||||
}
|
||||
|
||||
type NetType string
|
||||
|
||||
const (
|
||||
Internet = NetType("Internet")
|
||||
Intranet = NetType("Intranet")
|
||||
)
|
||||
|
||||
type TimeType string
|
||||
|
||||
const (
|
||||
Hour = TimeType("Hour")
|
||||
Day = TimeType("Day")
|
||||
Month = TimeType("Month")
|
||||
Year = TimeType("Year")
|
||||
)
|
||||
|
||||
type NetworkType string
|
||||
|
||||
const (
|
||||
Classic = NetworkType("Classic")
|
||||
VPC = NetworkType("VPC")
|
||||
)
|
||||
|
||||
type BusinessInfo struct {
|
||||
Pack string `json:"pack,omitempty"`
|
||||
ActivityId string `json:"activityId,omitempty"`
|
||||
}
|
||||
|
||||
//xml
|
||||
type Endpoints struct {
|
||||
Endpoint []Endpoint `xml:"Endpoint"`
|
||||
}
|
||||
|
||||
type Endpoint struct {
|
||||
Name string `xml:"name,attr"`
|
||||
RegionIds RegionIds `xml:"RegionIds"`
|
||||
Products Products `xml:"Products"`
|
||||
}
|
||||
|
||||
type RegionIds struct {
|
||||
RegionId string `xml:"RegionId"`
|
||||
}
|
||||
|
||||
type Products struct {
|
||||
Product []Product `xml:"Product"`
|
||||
}
|
||||
|
||||
type Product struct {
|
||||
ProductName string `xml:"ProductName"`
|
||||
DomainName string `xml:"DomainName"`
|
||||
}
|
3
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/common/version.go
generated
vendored
Normal file
3
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/common/version.go
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
package common
|
||||
|
||||
const Version = "0.1"
|
74
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/client.go
generated
vendored
Normal file
74
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/client.go
generated
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
package ecs
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
)
|
||||
|
||||
// Interval for checking status in WaitForXXX method
|
||||
const DefaultWaitForInterval = 5
|
||||
|
||||
// Default timeout value for WaitForXXX method
|
||||
const DefaultTimeout = 60
|
||||
|
||||
type Client struct {
|
||||
common.Client
|
||||
}
|
||||
|
||||
const (
|
||||
// ECSDefaultEndpoint is the default API endpoint of ECS services
|
||||
ECSDefaultEndpoint = "https://ecs-cn-hangzhou.aliyuncs.com"
|
||||
ECSAPIVersion = "2014-05-26"
|
||||
|
||||
ECSServiceCode = "ecs"
|
||||
|
||||
VPCDefaultEndpoint = "https://vpc.aliyuncs.com"
|
||||
VPCAPIVersion = "2016-04-28"
|
||||
VPCServiceCode = "vpc"
|
||||
)
|
||||
|
||||
// NewClient creates a new instance of ECS client
|
||||
func NewClient(accessKeyId, accessKeySecret string) *Client {
|
||||
endpoint := os.Getenv("ECS_ENDPOINT")
|
||||
if endpoint == "" {
|
||||
endpoint = ECSDefaultEndpoint
|
||||
}
|
||||
return NewClientWithEndpoint(endpoint, accessKeyId, accessKeySecret)
|
||||
}
|
||||
|
||||
func NewECSClient(accessKeyId, accessKeySecret string, regionID common.Region) *Client {
|
||||
endpoint := os.Getenv("ECS_ENDPOINT")
|
||||
if endpoint == "" {
|
||||
endpoint = ECSDefaultEndpoint
|
||||
}
|
||||
|
||||
return NewClientWithRegion(endpoint, accessKeyId, accessKeySecret, regionID)
|
||||
}
|
||||
|
||||
func NewClientWithRegion(endpoint string, accessKeyId, accessKeySecret string, regionID common.Region) *Client {
|
||||
client := &Client{}
|
||||
client.NewInit(endpoint, ECSAPIVersion, accessKeyId, accessKeySecret, ECSServiceCode, regionID)
|
||||
return client
|
||||
}
|
||||
|
||||
func NewClientWithEndpoint(endpoint string, accessKeyId, accessKeySecret string) *Client {
|
||||
client := &Client{}
|
||||
client.Init(endpoint, ECSAPIVersion, accessKeyId, accessKeySecret)
|
||||
return client
|
||||
}
|
||||
|
||||
func NewVPCClient(accessKeyId, accessKeySecret string, regionID common.Region) *Client {
|
||||
endpoint := os.Getenv("VPC_ENDPOINT")
|
||||
if endpoint == "" {
|
||||
endpoint = VPCDefaultEndpoint
|
||||
}
|
||||
|
||||
return NewVPCClientWithRegion(endpoint, accessKeyId, accessKeySecret, regionID)
|
||||
}
|
||||
|
||||
func NewVPCClientWithRegion(endpoint string, accessKeyId, accessKeySecret string, regionID common.Region) *Client {
|
||||
client := &Client{}
|
||||
client.NewInit(endpoint, VPCAPIVersion, accessKeyId, accessKeySecret, VPCServiceCode, regionID)
|
||||
return client
|
||||
}
|
340
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/disks.go
generated
vendored
Normal file
340
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/disks.go
generated
vendored
Normal file
|
@ -0,0 +1,340 @@
|
|||
package ecs
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
"github.com/denverdino/aliyungo/util"
|
||||
)
|
||||
|
||||
// Types of disks
|
||||
type DiskType string
|
||||
|
||||
const (
|
||||
DiskTypeAll = DiskType("all") //Default
|
||||
DiskTypeAllSystem = DiskType("system")
|
||||
DiskTypeAllData = DiskType("data")
|
||||
)
|
||||
|
||||
// Categories of disks
|
||||
type DiskCategory string
|
||||
|
||||
const (
|
||||
DiskCategoryAll = DiskCategory("all") //Default
|
||||
DiskCategoryCloud = DiskCategory("cloud")
|
||||
DiskCategoryEphemeral = DiskCategory("ephemeral")
|
||||
DiskCategoryEphemeralSSD = DiskCategory("ephemeral_ssd")
|
||||
DiskCategoryCloudEfficiency = DiskCategory("cloud_efficiency")
|
||||
DiskCategoryCloudSSD = DiskCategory("cloud_ssd")
|
||||
)
|
||||
|
||||
// Status of disks
|
||||
type DiskStatus string
|
||||
|
||||
const (
|
||||
DiskStatusInUse = DiskStatus("In_use")
|
||||
DiskStatusAvailable = DiskStatus("Available")
|
||||
DiskStatusAttaching = DiskStatus("Attaching")
|
||||
DiskStatusDetaching = DiskStatus("Detaching")
|
||||
DiskStatusCreating = DiskStatus("Creating")
|
||||
DiskStatusReIniting = DiskStatus("ReIniting")
|
||||
DiskStatusAll = DiskStatus("All") //Default
|
||||
)
|
||||
|
||||
// Charge type of disks
|
||||
type DiskChargeType string
|
||||
|
||||
const (
|
||||
PrePaid = DiskChargeType("PrePaid")
|
||||
PostPaid = DiskChargeType("PostPaid")
|
||||
)
|
||||
|
||||
// A DescribeDisksArgs defines the arguments to describe disks
|
||||
type DescribeDisksArgs struct {
|
||||
RegionId common.Region
|
||||
ZoneId string
|
||||
DiskIds []string
|
||||
InstanceId string
|
||||
DiskType DiskType //enum for all(default) | system | data
|
||||
Category DiskCategory //enum for all(default) | cloud | ephemeral
|
||||
Status DiskStatus //enum for In_use | Available | Attaching | Detaching | Creating | ReIniting | All(default)
|
||||
SnapshotId string
|
||||
Name string
|
||||
Portable *bool //optional
|
||||
DeleteWithInstance *bool //optional
|
||||
DeleteAutoSnapshot *bool //optional
|
||||
EnableAutoSnapshot *bool //optional
|
||||
DiskChargeType DiskChargeType
|
||||
Tag map[string]string
|
||||
common.Pagination
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&diskitemtype
|
||||
type DiskItemType struct {
|
||||
DiskId string
|
||||
RegionId common.Region
|
||||
ZoneId string
|
||||
DiskName string
|
||||
Description string
|
||||
Type DiskType
|
||||
Category DiskCategory
|
||||
Size int
|
||||
ImageId string
|
||||
SourceSnapshotId string
|
||||
ProductCode string
|
||||
Portable bool
|
||||
Status DiskStatus
|
||||
OperationLocks OperationLocksType
|
||||
InstanceId string
|
||||
Device string
|
||||
DeleteWithInstance bool
|
||||
DeleteAutoSnapshot bool
|
||||
EnableAutoSnapshot bool
|
||||
CreationTime util.ISO6801Time
|
||||
AttachedTime util.ISO6801Time
|
||||
DetachedTime util.ISO6801Time
|
||||
DiskChargeType DiskChargeType
|
||||
}
|
||||
|
||||
type DescribeDisksResponse struct {
|
||||
common.Response
|
||||
common.PaginationResult
|
||||
RegionId common.Region
|
||||
Disks struct {
|
||||
Disk []DiskItemType
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeDisks describes Disks
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/disk&describedisks
|
||||
func (client *Client) DescribeDisks(args *DescribeDisksArgs) (disks []DiskItemType, pagination *common.PaginationResult, err error) {
|
||||
response, err := client.DescribeDisksWithRaw(args)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return response.Disks.Disk, &response.PaginationResult, err
|
||||
}
|
||||
|
||||
func (client *Client) DescribeDisksWithRaw(args *DescribeDisksArgs) (response *DescribeDisksResponse, err error) {
|
||||
response = &DescribeDisksResponse{}
|
||||
|
||||
err = client.Invoke("DescribeDisks", args, response)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return response, err
|
||||
}
|
||||
|
||||
type CreateDiskArgs struct {
|
||||
RegionId common.Region
|
||||
ZoneId string
|
||||
DiskName string
|
||||
Description string
|
||||
Encrypted bool
|
||||
DiskCategory DiskCategory
|
||||
Size int
|
||||
SnapshotId string
|
||||
ClientToken string
|
||||
}
|
||||
|
||||
type CreateDisksResponse struct {
|
||||
common.Response
|
||||
DiskId string
|
||||
}
|
||||
|
||||
// CreateDisk creates a new disk
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/disk&createdisk
|
||||
func (client *Client) CreateDisk(args *CreateDiskArgs) (diskId string, err error) {
|
||||
response := CreateDisksResponse{}
|
||||
err = client.Invoke("CreateDisk", args, &response)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return response.DiskId, err
|
||||
}
|
||||
|
||||
type DeleteDiskArgs struct {
|
||||
DiskId string
|
||||
}
|
||||
|
||||
type DeleteDiskResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// DeleteDisk deletes disk
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/disk&deletedisk
|
||||
func (client *Client) DeleteDisk(diskId string) error {
|
||||
args := DeleteDiskArgs{
|
||||
DiskId: diskId,
|
||||
}
|
||||
response := DeleteDiskResponse{}
|
||||
err := client.Invoke("DeleteDisk", &args, &response)
|
||||
return err
|
||||
}
|
||||
|
||||
type ReInitDiskArgs struct {
|
||||
DiskId string
|
||||
}
|
||||
|
||||
type ReInitDiskResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// ReInitDisk reinitizes disk
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/disk&reinitdisk
|
||||
func (client *Client) ReInitDisk(diskId string) error {
|
||||
args := ReInitDiskArgs{
|
||||
DiskId: diskId,
|
||||
}
|
||||
response := ReInitDiskResponse{}
|
||||
err := client.Invoke("ReInitDisk", &args, &response)
|
||||
return err
|
||||
}
|
||||
|
||||
type AttachDiskArgs struct {
|
||||
InstanceId string
|
||||
DiskId string
|
||||
Device string
|
||||
DeleteWithInstance bool
|
||||
}
|
||||
|
||||
type AttachDiskResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// AttachDisk attaches disk to instance
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/disk&attachdisk
|
||||
func (client *Client) AttachDisk(args *AttachDiskArgs) error {
|
||||
response := AttachDiskResponse{}
|
||||
err := client.Invoke("AttachDisk", args, &response)
|
||||
return err
|
||||
}
|
||||
|
||||
type DetachDiskArgs struct {
|
||||
InstanceId string
|
||||
DiskId string
|
||||
}
|
||||
|
||||
type DetachDiskResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// DetachDisk detaches disk from instance
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/disk&detachdisk
|
||||
func (client *Client) DetachDisk(instanceId string, diskId string) error {
|
||||
args := DetachDiskArgs{
|
||||
InstanceId: instanceId,
|
||||
DiskId: diskId,
|
||||
}
|
||||
response := DetachDiskResponse{}
|
||||
err := client.Invoke("DetachDisk", &args, &response)
|
||||
return err
|
||||
}
|
||||
|
||||
type ResetDiskArgs struct {
|
||||
DiskId string
|
||||
SnapshotId string
|
||||
}
|
||||
|
||||
type ResetDiskResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// ResetDisk resets disk to original status
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/disk&resetdisk
|
||||
func (client *Client) ResetDisk(diskId string, snapshotId string) error {
|
||||
args := ResetDiskArgs{
|
||||
SnapshotId: snapshotId,
|
||||
DiskId: diskId,
|
||||
}
|
||||
response := ResetDiskResponse{}
|
||||
err := client.Invoke("ResetDisk", &args, &response)
|
||||
return err
|
||||
}
|
||||
|
||||
type ModifyDiskAttributeArgs struct {
|
||||
DiskId string
|
||||
DiskName string
|
||||
Description string
|
||||
DeleteWithInstance *bool
|
||||
DeleteAutoSnapshot *bool
|
||||
EnableAutoSnapshot *bool
|
||||
}
|
||||
|
||||
type ModifyDiskAttributeResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// ModifyDiskAttribute modifies disk attribute
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/disk&modifydiskattribute
|
||||
func (client *Client) ModifyDiskAttribute(args *ModifyDiskAttributeArgs) error {
|
||||
response := ModifyDiskAttributeResponse{}
|
||||
err := client.Invoke("ModifyDiskAttribute", args, &response)
|
||||
return err
|
||||
}
|
||||
|
||||
type ReplaceSystemDiskArgs struct {
|
||||
InstanceId string
|
||||
ImageId string
|
||||
SystemDisk SystemDiskType
|
||||
ClientToken string
|
||||
}
|
||||
|
||||
type ReplaceSystemDiskResponse struct {
|
||||
common.Response
|
||||
DiskId string
|
||||
}
|
||||
|
||||
// ReplaceSystemDisk replace system disk
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/ecs/open-api/disk/replacesystemdisk.html
|
||||
func (client *Client) ReplaceSystemDisk(args *ReplaceSystemDiskArgs) (diskId string, err error) {
|
||||
response := ReplaceSystemDiskResponse{}
|
||||
err = client.Invoke("ReplaceSystemDisk", args, &response)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return response.DiskId, nil
|
||||
}
|
||||
|
||||
// WaitForDisk waits for disk to given status
|
||||
func (client *Client) WaitForDisk(regionId common.Region, diskId string, status DiskStatus, timeout int) error {
|
||||
if timeout <= 0 {
|
||||
timeout = DefaultTimeout
|
||||
}
|
||||
args := DescribeDisksArgs{
|
||||
RegionId: regionId,
|
||||
DiskIds: []string{diskId},
|
||||
}
|
||||
|
||||
for {
|
||||
disks, _, err := client.DescribeDisks(&args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if disks == nil || len(disks) == 0 {
|
||||
return common.GetClientErrorFromString("Not found")
|
||||
}
|
||||
if disks[0].Status == status {
|
||||
break
|
||||
}
|
||||
timeout = timeout - DefaultWaitForInterval
|
||||
if timeout <= 0 {
|
||||
return common.GetClientErrorFromString("Timeout")
|
||||
}
|
||||
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||
}
|
||||
return nil
|
||||
}
|
112
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/forward_entry.go
generated
vendored
Normal file
112
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/forward_entry.go
generated
vendored
Normal file
|
@ -0,0 +1,112 @@
|
|||
package ecs
|
||||
|
||||
import "github.com/denverdino/aliyungo/common"
|
||||
|
||||
type CreateForwardEntryArgs struct {
|
||||
RegionId common.Region
|
||||
ForwardTableId string
|
||||
ExternalIp string
|
||||
ExternalPort string
|
||||
IpProtocol string
|
||||
InternalIp string
|
||||
InternalPort string
|
||||
}
|
||||
|
||||
type CreateForwardEntryResponse struct {
|
||||
common.Response
|
||||
ForwardEntryId string
|
||||
}
|
||||
|
||||
type DescribeForwardTableEntriesArgs struct {
|
||||
RegionId common.Region
|
||||
ForwardTableId string
|
||||
common.Pagination
|
||||
}
|
||||
|
||||
type ForwardTableEntrySetType struct {
|
||||
RegionId common.Region
|
||||
ExternalIp string
|
||||
ExternalPort string
|
||||
ForwardEntryId string
|
||||
ForwardTableId string
|
||||
InternalIp string
|
||||
InternalPort string
|
||||
IpProtocol string
|
||||
Status string
|
||||
}
|
||||
|
||||
type DescribeForwardTableEntriesResponse struct {
|
||||
common.Response
|
||||
common.PaginationResult
|
||||
ForwardTableEntries struct {
|
||||
ForwardTableEntry []ForwardTableEntrySetType
|
||||
}
|
||||
}
|
||||
|
||||
type ModifyForwardEntryArgs struct {
|
||||
RegionId common.Region
|
||||
ForwardTableId string
|
||||
ForwardEntryId string
|
||||
ExternalIp string
|
||||
IpProtocol string
|
||||
ExternalPort string
|
||||
InternalIp string
|
||||
InternalPort string
|
||||
}
|
||||
|
||||
type ModifyForwardEntryResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
type DeleteForwardEntryArgs struct {
|
||||
RegionId common.Region
|
||||
ForwardTableId string
|
||||
ForwardEntryId string
|
||||
}
|
||||
|
||||
type DeleteForwardEntryResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
func (client *Client) CreateForwardEntry(args *CreateForwardEntryArgs) (resp *CreateForwardEntryResponse, err error) {
|
||||
response := CreateForwardEntryResponse{}
|
||||
err = client.Invoke("CreateForwardEntry", args, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &response, err
|
||||
}
|
||||
|
||||
func (client *Client) DescribeForwardTableEntries(args *DescribeForwardTableEntriesArgs) (forwardTableEntries []ForwardTableEntrySetType,
|
||||
pagination *common.PaginationResult, err error) {
|
||||
response, err := client.DescribeForwardTableEntriesWithRaw(args)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return response.ForwardTableEntries.ForwardTableEntry, &response.PaginationResult, nil
|
||||
}
|
||||
|
||||
func (client *Client) DescribeForwardTableEntriesWithRaw(args *DescribeForwardTableEntriesArgs) (response *DescribeForwardTableEntriesResponse, err error) {
|
||||
args.Validate()
|
||||
response = &DescribeForwardTableEntriesResponse{}
|
||||
|
||||
err = client.Invoke("DescribeForwardTableEntries", args, response)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (client *Client) ModifyForwardEntry(args *ModifyForwardEntryArgs) error {
|
||||
response := ModifyForwardEntryResponse{}
|
||||
return client.Invoke("ModifyForwardEntry", args, &response)
|
||||
}
|
||||
|
||||
func (client *Client) DeleteForwardEntry(args *DeleteForwardEntryArgs) error {
|
||||
response := DeleteForwardEntryResponse{}
|
||||
err := client.Invoke("DeleteForwardEntry", args, &response)
|
||||
return err
|
||||
}
|
323
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/images.go
generated
vendored
Normal file
323
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/images.go
generated
vendored
Normal file
|
@ -0,0 +1,323 @@
|
|||
package ecs
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
"github.com/denverdino/aliyungo/util"
|
||||
)
|
||||
|
||||
// ImageOwnerAlias represents image owner
|
||||
type ImageOwnerAlias string
|
||||
|
||||
// Constants of image owner
|
||||
const (
|
||||
ImageOwnerSystem = ImageOwnerAlias("system")
|
||||
ImageOwnerSelf = ImageOwnerAlias("self")
|
||||
ImageOwnerOthers = ImageOwnerAlias("others")
|
||||
ImageOwnerMarketplace = ImageOwnerAlias("marketplace")
|
||||
ImageOwnerDefault = ImageOwnerAlias("") //Return the values for system, self, and others
|
||||
)
|
||||
|
||||
type ImageStatus string
|
||||
|
||||
const (
|
||||
ImageStatusAvailable = ImageStatus("Available")
|
||||
ImageStatusUnAvailable = ImageStatus("UnAvailable")
|
||||
ImageStatusCreating = ImageStatus("Creating")
|
||||
ImageStatusCreateFailed = ImageStatus("CreateFailed")
|
||||
)
|
||||
|
||||
type ImageUsage string
|
||||
|
||||
const (
|
||||
ImageUsageInstance = ImageUsage("instance")
|
||||
ImageUsageNone = ImageUsage("none")
|
||||
)
|
||||
|
||||
// DescribeImagesArgs repsents arguments to describe images
|
||||
type DescribeImagesArgs struct {
|
||||
RegionId common.Region
|
||||
ImageId string
|
||||
SnapshotId string
|
||||
ImageName string
|
||||
Status ImageStatus
|
||||
ImageOwnerAlias ImageOwnerAlias
|
||||
common.Pagination
|
||||
}
|
||||
|
||||
type DescribeImagesResponse struct {
|
||||
common.Response
|
||||
common.PaginationResult
|
||||
|
||||
RegionId common.Region
|
||||
Images struct {
|
||||
Image []ImageType
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&diskdevicemapping
|
||||
type DiskDeviceMapping struct {
|
||||
SnapshotId string
|
||||
//Why Size Field is string-type.
|
||||
Size string
|
||||
Device string
|
||||
//For import images
|
||||
Format string
|
||||
OSSBucket string
|
||||
OSSObject string
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&imagetype
|
||||
type ImageType struct {
|
||||
ImageId string
|
||||
ImageVersion string
|
||||
Architecture string
|
||||
ImageName string
|
||||
Description string
|
||||
Size int
|
||||
ImageOwnerAlias string
|
||||
OSName string
|
||||
OSType string
|
||||
Platform string
|
||||
DiskDeviceMappings struct {
|
||||
DiskDeviceMapping []DiskDeviceMapping
|
||||
}
|
||||
ProductCode string
|
||||
IsSubscribed bool
|
||||
IsSelfShared string
|
||||
IsCopied bool
|
||||
IsSupportIoOptimized bool
|
||||
Progress string
|
||||
Usage ImageUsage
|
||||
Status ImageStatus
|
||||
CreationTime util.ISO6801Time
|
||||
}
|
||||
|
||||
// DescribeImages describes images
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/image&describeimages
|
||||
func (client *Client) DescribeImages(args *DescribeImagesArgs) (images []ImageType, pagination *common.PaginationResult, err error) {
|
||||
response, err := client.DescribeImagesWithRaw(args)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return response.Images.Image, &response.PaginationResult, nil
|
||||
}
|
||||
|
||||
func (client *Client) DescribeImagesWithRaw(args *DescribeImagesArgs) (response *DescribeImagesResponse, err error) {
|
||||
args.Validate()
|
||||
response = &DescribeImagesResponse{}
|
||||
err = client.Invoke("DescribeImages", args, response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// CreateImageArgs repsents arguments to create image
|
||||
type CreateImageArgs struct {
|
||||
RegionId common.Region
|
||||
SnapshotId string
|
||||
InstanceId string
|
||||
ImageName string
|
||||
ImageVersion string
|
||||
Description string
|
||||
ClientToken string
|
||||
}
|
||||
|
||||
type CreateImageResponse struct {
|
||||
common.Response
|
||||
|
||||
ImageId string
|
||||
}
|
||||
|
||||
// CreateImage creates a new image
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/image&createimage
|
||||
func (client *Client) CreateImage(args *CreateImageArgs) (imageId string, err error) {
|
||||
response := &CreateImageResponse{}
|
||||
err = client.Invoke("CreateImage", args, &response)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return response.ImageId, nil
|
||||
}
|
||||
|
||||
type DeleteImageArgs struct {
|
||||
RegionId common.Region
|
||||
ImageId string
|
||||
}
|
||||
|
||||
type DeleteImageResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// DeleteImage deletes Image
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/image&deleteimage
|
||||
func (client *Client) DeleteImage(regionId common.Region, imageId string) error {
|
||||
args := DeleteImageArgs{
|
||||
RegionId: regionId,
|
||||
ImageId: imageId,
|
||||
}
|
||||
|
||||
response := &DeleteImageResponse{}
|
||||
return client.Invoke("DeleteImage", &args, &response)
|
||||
}
|
||||
|
||||
// ModifyImageSharePermission repsents arguments to share image
|
||||
type ModifyImageSharePermissionArgs struct {
|
||||
RegionId common.Region
|
||||
ImageId string
|
||||
AddAccount []string
|
||||
RemoveAccount []string
|
||||
}
|
||||
|
||||
// You can read doc at http://help.aliyun.com/document_detail/ecs/open-api/image/modifyimagesharepermission.html
|
||||
func (client *Client) ModifyImageSharePermission(args *ModifyImageSharePermissionArgs) error {
|
||||
req := url.Values{}
|
||||
req.Add("RegionId", string(args.RegionId))
|
||||
req.Add("ImageId", args.ImageId)
|
||||
|
||||
for i, item := range args.AddAccount {
|
||||
req.Add("AddAccount."+strconv.Itoa(i+1), item)
|
||||
}
|
||||
for i, item := range args.RemoveAccount {
|
||||
req.Add("RemoveAccount."+strconv.Itoa(i+1), item)
|
||||
}
|
||||
|
||||
return client.Invoke("ModifyImageSharePermission", req, &common.Response{})
|
||||
}
|
||||
|
||||
type AccountType struct {
|
||||
AliyunId string
|
||||
}
|
||||
type ImageSharePermissionResponse struct {
|
||||
common.Response
|
||||
ImageId string
|
||||
RegionId string
|
||||
Accounts struct {
|
||||
Account []AccountType
|
||||
}
|
||||
TotalCount int
|
||||
PageNumber int
|
||||
PageSize int
|
||||
}
|
||||
|
||||
func (client *Client) DescribeImageSharePermission(args *ModifyImageSharePermissionArgs) (*ImageSharePermissionResponse, error) {
|
||||
response := ImageSharePermissionResponse{}
|
||||
err := client.Invoke("DescribeImageSharePermission", args, &response)
|
||||
return &response, err
|
||||
}
|
||||
|
||||
type CopyImageArgs struct {
|
||||
RegionId common.Region
|
||||
ImageId string
|
||||
DestinationRegionId common.Region
|
||||
DestinationImageName string
|
||||
DestinationDescription string
|
||||
ClientToken string
|
||||
}
|
||||
|
||||
type CopyImageResponse struct {
|
||||
common.Response
|
||||
ImageId string
|
||||
}
|
||||
|
||||
// You can read doc at https://help.aliyun.com/document_detail/25538.html
|
||||
func (client *Client) CopyImage(args *CopyImageArgs) (string, error) {
|
||||
response := &CopyImageResponse{}
|
||||
err := client.Invoke("CopyImage", args, &response)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return response.ImageId, nil
|
||||
}
|
||||
|
||||
// ImportImageArgs repsents arguments to import image from oss
|
||||
type ImportImageArgs struct {
|
||||
RegionId common.Region
|
||||
ImageName string
|
||||
ImageVersion string
|
||||
Description string
|
||||
ClientToken string
|
||||
Architecture string
|
||||
OSType string
|
||||
Platform string
|
||||
DiskDeviceMappings struct {
|
||||
DiskDeviceMapping []DiskDeviceMapping
|
||||
}
|
||||
}
|
||||
|
||||
func (client *Client) ImportImage(args *ImportImageArgs) (string, error) {
|
||||
response := &CopyImageResponse{}
|
||||
err := client.Invoke("ImportImage", args, &response)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return response.ImageId, nil
|
||||
}
|
||||
|
||||
type ImportImageResponse struct {
|
||||
common.Response
|
||||
RegionId common.Region
|
||||
ImageId string
|
||||
ImportTaskId string
|
||||
}
|
||||
|
||||
// Default timeout value for WaitForImageReady method
|
||||
const ImageDefaultTimeout = 120
|
||||
|
||||
//Wait Image ready
|
||||
func (client *Client) WaitForImageReady(regionId common.Region, imageId string, timeout int) error {
|
||||
if timeout <= 0 {
|
||||
timeout = ImageDefaultTimeout
|
||||
}
|
||||
for {
|
||||
args := DescribeImagesArgs{
|
||||
RegionId: regionId,
|
||||
ImageId: imageId,
|
||||
Status: ImageStatusCreating,
|
||||
}
|
||||
|
||||
images, _, err := client.DescribeImages(&args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if images == nil || len(images) == 0 {
|
||||
args.Status = ImageStatusAvailable
|
||||
images, _, er := client.DescribeImages(&args)
|
||||
if er == nil && len(images) == 1 {
|
||||
break
|
||||
} else {
|
||||
return common.GetClientErrorFromString("Not found")
|
||||
}
|
||||
}
|
||||
if images[0].Progress == "100%" {
|
||||
break
|
||||
}
|
||||
timeout = timeout - DefaultWaitForInterval
|
||||
if timeout <= 0 {
|
||||
return common.GetClientErrorFromString("Timeout")
|
||||
}
|
||||
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type CancelCopyImageRequest struct {
|
||||
regionId common.Region
|
||||
ImageId string
|
||||
}
|
||||
|
||||
// You can read doc at https://help.aliyun.com/document_detail/25539.html
|
||||
func (client *Client) CancelCopyImage(regionId common.Region, imageId string) error {
|
||||
response := &common.Response{}
|
||||
err := client.Invoke("CancelCopyImage", &CancelCopyImageRequest{regionId, imageId}, &response)
|
||||
return err
|
||||
}
|
82
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/instance_types.go
generated
vendored
Normal file
82
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/instance_types.go
generated
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
package ecs
|
||||
|
||||
import "github.com/denverdino/aliyungo/common"
|
||||
|
||||
type DescribeInstanceTypesArgs struct {
|
||||
InstanceTypeFamily string
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&instancetypeitemtype
|
||||
type InstanceTypeItemType struct {
|
||||
InstanceTypeId string
|
||||
CpuCoreCount int
|
||||
MemorySize float64
|
||||
InstanceTypeFamily string
|
||||
}
|
||||
|
||||
type DescribeInstanceTypesResponse struct {
|
||||
common.Response
|
||||
InstanceTypes struct {
|
||||
InstanceType []InstanceTypeItemType
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeInstanceTypes describes all instance types
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/other&describeinstancetypes
|
||||
func (client *Client) DescribeInstanceTypes() (instanceTypes []InstanceTypeItemType, err error) {
|
||||
response := DescribeInstanceTypesResponse{}
|
||||
|
||||
err = client.Invoke("DescribeInstanceTypes", &DescribeInstanceTypesArgs{}, &response)
|
||||
|
||||
if err != nil {
|
||||
return []InstanceTypeItemType{}, err
|
||||
}
|
||||
return response.InstanceTypes.InstanceType, nil
|
||||
|
||||
}
|
||||
|
||||
// support user args
|
||||
func (client *Client) DescribeInstanceTypesNew(args *DescribeInstanceTypesArgs) (instanceTypes []InstanceTypeItemType, err error) {
|
||||
response := DescribeInstanceTypesResponse{}
|
||||
|
||||
err = client.Invoke("DescribeInstanceTypes", args, &response)
|
||||
|
||||
if err != nil {
|
||||
return []InstanceTypeItemType{}, err
|
||||
}
|
||||
return response.InstanceTypes.InstanceType, nil
|
||||
|
||||
}
|
||||
|
||||
type DescribeInstanceTypeFamiliesArgs struct {
|
||||
RegionId common.Region
|
||||
Generation string
|
||||
}
|
||||
|
||||
type InstanceTypeFamilies struct {
|
||||
InstanceTypeFamily []InstanceTypeFamily
|
||||
}
|
||||
|
||||
type InstanceTypeFamily struct {
|
||||
InstanceTypeFamilyId string
|
||||
Generation string
|
||||
}
|
||||
|
||||
type DescribeInstanceTypeFamiliesResponse struct {
|
||||
common.Response
|
||||
|
||||
InstanceTypeFamilies InstanceTypeFamilies
|
||||
}
|
||||
|
||||
func (client *Client) DescribeInstanceTypeFamilies(args *DescribeInstanceTypeFamiliesArgs) (*DescribeInstanceTypeFamiliesResponse, error) {
|
||||
response := &DescribeInstanceTypeFamiliesResponse{}
|
||||
|
||||
err := client.Invoke("DescribeInstanceTypeFamilies", args, response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
681
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/instances.go
generated
vendored
Normal file
681
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/instances.go
generated
vendored
Normal file
|
@ -0,0 +1,681 @@
|
|||
package ecs
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
"github.com/denverdino/aliyungo/util"
|
||||
)
|
||||
|
||||
// InstanceStatus represents instance status
|
||||
type InstanceStatus string
|
||||
|
||||
// Constants of InstanceStatus
|
||||
const (
|
||||
Creating = InstanceStatus("Creating") // For backward compatibility
|
||||
Pending = InstanceStatus("Pending")
|
||||
Running = InstanceStatus("Running")
|
||||
Starting = InstanceStatus("Starting")
|
||||
|
||||
Stopped = InstanceStatus("Stopped")
|
||||
Stopping = InstanceStatus("Stopping")
|
||||
Deleted = InstanceStatus("Deleted")
|
||||
)
|
||||
|
||||
type LockReason string
|
||||
|
||||
const (
|
||||
LockReasonFinancial = LockReason("financial")
|
||||
LockReasonSecurity = LockReason("security")
|
||||
)
|
||||
|
||||
type LockReasonType struct {
|
||||
LockReason LockReason
|
||||
}
|
||||
|
||||
type DescribeUserdataArgs struct {
|
||||
RegionId common.Region
|
||||
InstanceId string
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&instancestatusitemtype
|
||||
type DescribeUserdataItemType struct {
|
||||
UserData string
|
||||
InstanceId string
|
||||
RegionId string
|
||||
}
|
||||
|
||||
type DescribeUserdataResponse struct {
|
||||
common.Response
|
||||
DescribeUserdataItemType
|
||||
}
|
||||
|
||||
// DescribeInstanceStatus describes instance status
|
||||
//
|
||||
// You can read doc at https://intl.aliyun.com/help/doc-detail/49227.htm
|
||||
func (client *Client) DescribeUserdata(args *DescribeUserdataArgs) (userData *DescribeUserdataItemType, err error) {
|
||||
response := DescribeUserdataResponse{}
|
||||
|
||||
err = client.Invoke("DescribeUserdata", args, &response)
|
||||
|
||||
if err == nil {
|
||||
return &response.DescribeUserdataItemType, nil
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
type DescribeInstanceStatusArgs struct {
|
||||
RegionId common.Region
|
||||
ZoneId string
|
||||
common.Pagination
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&instancestatusitemtype
|
||||
type InstanceStatusItemType struct {
|
||||
InstanceId string
|
||||
Status InstanceStatus
|
||||
}
|
||||
|
||||
type DescribeInstanceStatusResponse struct {
|
||||
common.Response
|
||||
common.PaginationResult
|
||||
InstanceStatuses struct {
|
||||
InstanceStatus []InstanceStatusItemType
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeInstanceStatus describes instance status
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/instance&describeinstancestatus
|
||||
func (client *Client) DescribeInstanceStatus(args *DescribeInstanceStatusArgs) (instanceStatuses []InstanceStatusItemType, pagination *common.PaginationResult, err error) {
|
||||
response, err := client.DescribeInstanceStatusWithRaw(args)
|
||||
|
||||
if err == nil {
|
||||
return response.InstanceStatuses.InstanceStatus, &response.PaginationResult, nil
|
||||
}
|
||||
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
func (client *Client) DescribeInstanceStatusWithRaw(args *DescribeInstanceStatusArgs) (response *DescribeInstanceStatusResponse, err error) {
|
||||
args.Validate()
|
||||
response = &DescribeInstanceStatusResponse{}
|
||||
|
||||
err = client.Invoke("DescribeInstanceStatus", args, response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
type StopInstanceArgs struct {
|
||||
InstanceId string
|
||||
ForceStop bool
|
||||
}
|
||||
|
||||
type StopInstanceResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// StopInstance stops instance
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/instance&stopinstance
|
||||
func (client *Client) StopInstance(instanceId string, forceStop bool) error {
|
||||
args := StopInstanceArgs{
|
||||
InstanceId: instanceId,
|
||||
ForceStop: forceStop,
|
||||
}
|
||||
response := StopInstanceResponse{}
|
||||
err := client.Invoke("StopInstance", &args, &response)
|
||||
return err
|
||||
}
|
||||
|
||||
type StartInstanceArgs struct {
|
||||
InstanceId string
|
||||
}
|
||||
|
||||
type StartInstanceResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// StartInstance starts instance
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/instance&startinstance
|
||||
func (client *Client) StartInstance(instanceId string) error {
|
||||
args := StartInstanceArgs{InstanceId: instanceId}
|
||||
response := StartInstanceResponse{}
|
||||
err := client.Invoke("StartInstance", &args, &response)
|
||||
return err
|
||||
}
|
||||
|
||||
type RebootInstanceArgs struct {
|
||||
InstanceId string
|
||||
ForceStop bool
|
||||
}
|
||||
|
||||
type RebootInstanceResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// RebootInstance reboot instance
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/instance&rebootinstance
|
||||
func (client *Client) RebootInstance(instanceId string, forceStop bool) error {
|
||||
request := RebootInstanceArgs{
|
||||
InstanceId: instanceId,
|
||||
ForceStop: forceStop,
|
||||
}
|
||||
response := RebootInstanceResponse{}
|
||||
err := client.Invoke("RebootInstance", &request, &response)
|
||||
return err
|
||||
}
|
||||
|
||||
type DescribeInstanceAttributeArgs struct {
|
||||
InstanceId string
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&operationlockstype
|
||||
type OperationLocksType struct {
|
||||
LockReason []LockReasonType //enum for financial, security
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&securitygroupidsettype
|
||||
type SecurityGroupIdSetType struct {
|
||||
SecurityGroupId string
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&ipaddresssettype
|
||||
type IpAddressSetType struct {
|
||||
IpAddress []string
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&vpcattributestype
|
||||
type VpcAttributesType struct {
|
||||
VpcId string
|
||||
VSwitchId string
|
||||
PrivateIpAddress IpAddressSetType
|
||||
NatIpAddress string
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&eipaddressassociatetype
|
||||
type EipAddressAssociateType struct {
|
||||
AllocationId string
|
||||
IpAddress string
|
||||
Bandwidth int
|
||||
InternetChargeType common.InternetChargeType
|
||||
}
|
||||
|
||||
// Experimental feature
|
||||
type SpotStrategyType string
|
||||
|
||||
// Constants of SpotStrategyType
|
||||
const (
|
||||
NoSpot = SpotStrategyType("NoSpot")
|
||||
SpotWithPriceLimit = SpotStrategyType("SpotWithPriceLimit")
|
||||
)
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&instanceattributestype
|
||||
type InstanceAttributesType struct {
|
||||
InstanceId string
|
||||
InstanceName string
|
||||
Description string
|
||||
ImageId string
|
||||
RegionId common.Region
|
||||
ZoneId string
|
||||
CPU int
|
||||
Memory int
|
||||
ClusterId string
|
||||
InstanceType string
|
||||
InstanceTypeFamily string
|
||||
HostName string
|
||||
SerialNumber string
|
||||
Status InstanceStatus
|
||||
OperationLocks OperationLocksType
|
||||
SecurityGroupIds struct {
|
||||
SecurityGroupId []string
|
||||
}
|
||||
PublicIpAddress IpAddressSetType
|
||||
InnerIpAddress IpAddressSetType
|
||||
InstanceNetworkType string //enum Classic | Vpc
|
||||
InternetMaxBandwidthIn int
|
||||
InternetMaxBandwidthOut int
|
||||
InternetChargeType common.InternetChargeType
|
||||
CreationTime util.ISO6801Time //time.Time
|
||||
VpcAttributes VpcAttributesType
|
||||
EipAddress EipAddressAssociateType
|
||||
IoOptimized StringOrBool
|
||||
InstanceChargeType common.InstanceChargeType
|
||||
ExpiredTime util.ISO6801Time
|
||||
Tags struct {
|
||||
Tag []TagItemType
|
||||
}
|
||||
SpotStrategy SpotStrategyType
|
||||
KeyPairName string
|
||||
}
|
||||
|
||||
type DescribeInstanceAttributeResponse struct {
|
||||
common.Response
|
||||
InstanceAttributesType
|
||||
}
|
||||
|
||||
// DescribeInstanceAttribute describes instance attribute
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/instance&describeinstanceattribute
|
||||
func (client *Client) DescribeInstanceAttribute(instanceId string) (instance *InstanceAttributesType, err error) {
|
||||
args := DescribeInstanceAttributeArgs{InstanceId: instanceId}
|
||||
|
||||
response := DescribeInstanceAttributeResponse{}
|
||||
err = client.Invoke("DescribeInstanceAttribute", &args, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &response.InstanceAttributesType, err
|
||||
}
|
||||
|
||||
type ModifyInstanceAttributeArgs struct {
|
||||
InstanceId string
|
||||
InstanceName string
|
||||
Description string
|
||||
Password string
|
||||
HostName string
|
||||
UserData string
|
||||
}
|
||||
|
||||
type ModifyInstanceAttributeResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
//ModifyInstanceAttribute modify instance attrbute
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/ecs/open-api/instance/modifyinstanceattribute.html
|
||||
func (client *Client) ModifyInstanceAttribute(args *ModifyInstanceAttributeArgs) error {
|
||||
response := ModifyInstanceAttributeResponse{}
|
||||
err := client.Invoke("ModifyInstanceAttribute", args, &response)
|
||||
return err
|
||||
}
|
||||
|
||||
// Default timeout value for WaitForInstance method
|
||||
const InstanceDefaultTimeout = 120
|
||||
|
||||
// WaitForInstance waits for instance to given status
|
||||
func (client *Client) WaitForInstance(instanceId string, status InstanceStatus, timeout int) error {
|
||||
if timeout <= 0 {
|
||||
timeout = InstanceDefaultTimeout
|
||||
}
|
||||
for {
|
||||
instance, err := client.DescribeInstanceAttribute(instanceId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if instance.Status == status {
|
||||
//TODO
|
||||
//Sleep one more time for timing issues
|
||||
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||
break
|
||||
}
|
||||
timeout = timeout - DefaultWaitForInterval
|
||||
if timeout <= 0 {
|
||||
return common.GetClientErrorFromString("Timeout")
|
||||
}
|
||||
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WaitForInstance waits for instance to given status
|
||||
// when instance.NotFound wait until timeout
|
||||
func (client *Client) WaitForInstanceAsyn(instanceId string, status InstanceStatus, timeout int) error {
|
||||
if timeout <= 0 {
|
||||
timeout = InstanceDefaultTimeout
|
||||
}
|
||||
for {
|
||||
instance, err := client.DescribeInstanceAttribute(instanceId)
|
||||
if err != nil {
|
||||
e, _ := err.(*common.Error)
|
||||
if e.Code != "InvalidInstanceId.NotFound" && e.Code != "Forbidden.InstanceNotFound" {
|
||||
return err
|
||||
}
|
||||
} else if instance != nil && instance.Status == status {
|
||||
//TODO
|
||||
break
|
||||
}
|
||||
timeout = timeout - DefaultWaitForInterval
|
||||
if timeout <= 0 {
|
||||
return common.GetClientErrorFromString("Timeout")
|
||||
}
|
||||
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type DescribeInstanceVncUrlArgs struct {
|
||||
RegionId common.Region
|
||||
InstanceId string
|
||||
}
|
||||
|
||||
type DescribeInstanceVncUrlResponse struct {
|
||||
common.Response
|
||||
VncUrl string
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/instance&describeinstancevncurl
|
||||
func (client *Client) DescribeInstanceVncUrl(args *DescribeInstanceVncUrlArgs) (string, error) {
|
||||
response := DescribeInstanceVncUrlResponse{}
|
||||
|
||||
err := client.Invoke("DescribeInstanceVncUrl", args, &response)
|
||||
|
||||
if err == nil {
|
||||
return response.VncUrl, nil
|
||||
}
|
||||
|
||||
return "", err
|
||||
}
|
||||
|
||||
type DescribeInstancesArgs struct {
|
||||
RegionId common.Region
|
||||
VpcId string
|
||||
VSwitchId string
|
||||
ZoneId string
|
||||
InstanceIds string
|
||||
InstanceNetworkType string
|
||||
InstanceName string
|
||||
Status InstanceStatus
|
||||
PrivateIpAddresses string
|
||||
InnerIpAddresses string
|
||||
PublicIpAddresses string
|
||||
SecurityGroupId string
|
||||
Tag map[string]string
|
||||
InstanceType string
|
||||
SpotStrategy SpotStrategyType
|
||||
common.Pagination
|
||||
}
|
||||
|
||||
type DescribeInstancesResponse struct {
|
||||
common.Response
|
||||
common.PaginationResult
|
||||
Instances struct {
|
||||
Instance []InstanceAttributesType
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeInstances describes instances
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/instance&describeinstances
|
||||
func (client *Client) DescribeInstances(args *DescribeInstancesArgs) (instances []InstanceAttributesType, pagination *common.PaginationResult, err error) {
|
||||
response, err := client.DescribeInstancesWithRaw(args)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return response.Instances.Instance, &response.PaginationResult, nil
|
||||
}
|
||||
|
||||
func (client *Client) DescribeInstancesWithRaw(args *DescribeInstancesArgs) (response *DescribeInstancesResponse, err error) {
|
||||
args.Validate()
|
||||
response = &DescribeInstancesResponse{}
|
||||
|
||||
err = client.Invoke("DescribeInstances", args, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
type DeleteInstanceArgs struct {
|
||||
InstanceId string
|
||||
}
|
||||
|
||||
type DeleteInstanceResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// DeleteInstance deletes instance
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/instance&deleteinstance
|
||||
func (client *Client) DeleteInstance(instanceId string) error {
|
||||
args := DeleteInstanceArgs{InstanceId: instanceId}
|
||||
response := DeleteInstanceResponse{}
|
||||
err := client.Invoke("DeleteInstance", &args, &response)
|
||||
return err
|
||||
}
|
||||
|
||||
type DataDiskType struct {
|
||||
Size int
|
||||
Category DiskCategory //Enum cloud, ephemeral, ephemeral_ssd
|
||||
SnapshotId string
|
||||
DiskName string
|
||||
Description string
|
||||
Device string
|
||||
DeleteWithInstance bool
|
||||
}
|
||||
|
||||
type SystemDiskType struct {
|
||||
Size int
|
||||
Category DiskCategory //Enum cloud, ephemeral, ephemeral_ssd
|
||||
DiskName string
|
||||
Description string
|
||||
}
|
||||
|
||||
type IoOptimized string
|
||||
|
||||
type StringOrBool struct {
|
||||
Value bool
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaller interface.
|
||||
func (io *StringOrBool) UnmarshalJSON(value []byte) error {
|
||||
if value[0] == '"' {
|
||||
var str string
|
||||
err := json.Unmarshal(value, &str)
|
||||
if err == nil {
|
||||
io.Value = (str == "true" || str == "optimized")
|
||||
}
|
||||
return err
|
||||
}
|
||||
var boolVal bool
|
||||
err := json.Unmarshal(value, &boolVal)
|
||||
if err == nil {
|
||||
io.Value = boolVal
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (io StringOrBool) Bool() bool {
|
||||
return io.Value
|
||||
}
|
||||
|
||||
func (io StringOrBool) String() string {
|
||||
return strconv.FormatBool(io.Value)
|
||||
}
|
||||
|
||||
var (
|
||||
IoOptimizedNone = IoOptimized("none")
|
||||
IoOptimizedOptimized = IoOptimized("optimized")
|
||||
)
|
||||
|
||||
type CreateInstanceArgs struct {
|
||||
RegionId common.Region
|
||||
ZoneId string
|
||||
ImageId string
|
||||
InstanceType string
|
||||
SecurityGroupId string
|
||||
InstanceName string
|
||||
Description string
|
||||
InternetChargeType common.InternetChargeType
|
||||
InternetMaxBandwidthIn int
|
||||
InternetMaxBandwidthOut int
|
||||
HostName string
|
||||
Password string
|
||||
IoOptimized IoOptimized
|
||||
SystemDisk SystemDiskType
|
||||
DataDisk []DataDiskType
|
||||
VSwitchId string
|
||||
PrivateIpAddress string
|
||||
ClientToken string
|
||||
InstanceChargeType common.InstanceChargeType
|
||||
Period int
|
||||
UserData string
|
||||
AutoRenew bool
|
||||
AutoRenewPeriod int
|
||||
SpotStrategy SpotStrategyType
|
||||
KeyPairName string
|
||||
RamRoleName string
|
||||
}
|
||||
|
||||
type CreateInstanceResponse struct {
|
||||
common.Response
|
||||
InstanceId string
|
||||
}
|
||||
|
||||
// CreateInstance creates instance
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/instance&createinstance
|
||||
func (client *Client) CreateInstance(args *CreateInstanceArgs) (instanceId string, err error) {
|
||||
if args.UserData != "" {
|
||||
// Encode to base64 string
|
||||
args.UserData = base64.StdEncoding.EncodeToString([]byte(args.UserData))
|
||||
}
|
||||
response := CreateInstanceResponse{}
|
||||
err = client.Invoke("CreateInstance", args, &response)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return response.InstanceId, err
|
||||
}
|
||||
|
||||
type RunInstanceArgs struct {
|
||||
CreateInstanceArgs
|
||||
MinAmount int
|
||||
MaxAmount int
|
||||
AutoReleaseTime string
|
||||
NetworkType string
|
||||
InnerIpAddress string
|
||||
BusinessInfo string
|
||||
}
|
||||
|
||||
type RunInstanceResponse struct {
|
||||
common.Response
|
||||
InstanceIdSets InstanceIdSets
|
||||
}
|
||||
|
||||
type InstanceIdSets struct {
|
||||
InstanceIdSet []string
|
||||
}
|
||||
|
||||
type BusinessInfo struct {
|
||||
Pack string `json:"pack,omitempty"`
|
||||
ActivityId string `json:"activityId,omitempty"`
|
||||
}
|
||||
|
||||
func (client *Client) RunInstances(args *RunInstanceArgs) (instanceIdSet []string, err error) {
|
||||
if args.UserData != "" {
|
||||
// Encode to base64 string
|
||||
args.UserData = base64.StdEncoding.EncodeToString([]byte(args.UserData))
|
||||
}
|
||||
response := RunInstanceResponse{}
|
||||
err = client.Invoke("RunInstances", args, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return response.InstanceIdSets.InstanceIdSet, err
|
||||
}
|
||||
|
||||
type SecurityGroupArgs struct {
|
||||
InstanceId string
|
||||
SecurityGroupId string
|
||||
}
|
||||
|
||||
type SecurityGroupResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
//JoinSecurityGroup
|
||||
//
|
||||
//You can read doc at https://help.aliyun.com/document_detail/ecs/open-api/instance/joinsecuritygroup.html
|
||||
func (client *Client) JoinSecurityGroup(instanceId string, securityGroupId string) error {
|
||||
args := SecurityGroupArgs{InstanceId: instanceId, SecurityGroupId: securityGroupId}
|
||||
response := SecurityGroupResponse{}
|
||||
err := client.Invoke("JoinSecurityGroup", &args, &response)
|
||||
return err
|
||||
}
|
||||
|
||||
//LeaveSecurityGroup
|
||||
//
|
||||
//You can read doc at https://help.aliyun.com/document_detail/ecs/open-api/instance/leavesecuritygroup.html
|
||||
func (client *Client) LeaveSecurityGroup(instanceId string, securityGroupId string) error {
|
||||
args := SecurityGroupArgs{InstanceId: instanceId, SecurityGroupId: securityGroupId}
|
||||
response := SecurityGroupResponse{}
|
||||
err := client.Invoke("LeaveSecurityGroup", &args, &response)
|
||||
return err
|
||||
}
|
||||
|
||||
type AttachInstancesArgs struct {
|
||||
RegionId common.Region
|
||||
RamRoleName string
|
||||
InstanceIds string
|
||||
}
|
||||
|
||||
// AttachInstanceRamRole attach instances to ram role
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/54244.html?spm=5176.doc54245.6.811.zEJcS5
|
||||
func (client *Client) AttachInstanceRamRole(args *AttachInstancesArgs) (err error) {
|
||||
response := common.Response{}
|
||||
err = client.Invoke("AttachInstanceRamRole", args, &response)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DetachInstanceRamRole detach instances from ram role
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/54245.html?spm=5176.doc54243.6.813.bt8RB3
|
||||
func (client *Client) DetachInstanceRamRole(args *AttachInstancesArgs) (err error) {
|
||||
response := common.Response{}
|
||||
err = client.Invoke("DetachInstanceRamRole", args, &response)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type DescribeInstanceRamRoleResponse struct {
|
||||
common.Response
|
||||
InstanceRamRoleSets struct{
|
||||
InstanceRamRoleSet []InstanceRamRoleSetType
|
||||
}
|
||||
}
|
||||
|
||||
type InstanceRamRoleSetType struct {
|
||||
InstanceId string
|
||||
RamRoleName string
|
||||
}
|
||||
|
||||
// DescribeInstanceRamRole
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/54243.html?spm=5176.doc54245.6.812.RgNCoi
|
||||
func (client *Client) DescribeInstanceRamRole(args *AttachInstancesArgs) (resp *DescribeInstanceRamRoleResponse, err error) {
|
||||
response := &DescribeInstanceRamRoleResponse{}
|
||||
err = client.Invoke("DescribeInstanceRamRole", args, response)
|
||||
if err != nil {
|
||||
return response, err
|
||||
}
|
||||
return response, nil
|
||||
}
|
136
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/monitoring.go
generated
vendored
Normal file
136
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/monitoring.go
generated
vendored
Normal file
|
@ -0,0 +1,136 @@
|
|||
package ecs
|
||||
|
||||
import (
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
"github.com/denverdino/aliyungo/util"
|
||||
)
|
||||
|
||||
type DescribeInstanceMonitorDataArgs struct {
|
||||
InstanceId string
|
||||
StartTime util.ISO6801Time
|
||||
EndTime util.ISO6801Time
|
||||
Period int //Default 60s
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&instancemonitordatatype
|
||||
type InstanceMonitorDataType struct {
|
||||
InstanceId string
|
||||
CPU int
|
||||
IntranetRX int
|
||||
IntranetTX int
|
||||
IntranetBandwidth int
|
||||
InternetRX int
|
||||
InternetTX int
|
||||
InternetBandwidth int
|
||||
IOPSRead int
|
||||
IOPSWrite int
|
||||
BPSRead int
|
||||
BPSWrite int
|
||||
TimeStamp util.ISO6801Time
|
||||
}
|
||||
|
||||
type DescribeInstanceMonitorDataResponse struct {
|
||||
common.Response
|
||||
MonitorData struct {
|
||||
InstanceMonitorData []InstanceMonitorDataType
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeInstanceMonitorData describes instance monitoring data
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/monitor&describeinstancemonitordata
|
||||
func (client *Client) DescribeInstanceMonitorData(args *DescribeInstanceMonitorDataArgs) (monitorData []InstanceMonitorDataType, err error) {
|
||||
if args.Period == 0 {
|
||||
args.Period = 60
|
||||
}
|
||||
response := DescribeInstanceMonitorDataResponse{}
|
||||
err = client.Invoke("DescribeInstanceMonitorData", args, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return response.MonitorData.InstanceMonitorData, err
|
||||
}
|
||||
|
||||
type DescribeEipMonitorDataArgs struct {
|
||||
AllocationId string
|
||||
StartTime util.ISO6801Time
|
||||
EndTime util.ISO6801Time
|
||||
Period int //Default 60s
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&eipmonitordatatype
|
||||
type EipMonitorDataType struct {
|
||||
EipRX int
|
||||
EipTX int
|
||||
EipFlow int
|
||||
EipBandwidth int
|
||||
EipPackets int
|
||||
TimeStamp util.ISO6801Time
|
||||
}
|
||||
|
||||
type DescribeEipMonitorDataResponse struct {
|
||||
common.Response
|
||||
EipMonitorDatas struct {
|
||||
EipMonitorData []EipMonitorDataType
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeEipMonitorData describes EIP monitoring data
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/monitor&describeeipmonitordata
|
||||
func (client *Client) DescribeEipMonitorData(args *DescribeEipMonitorDataArgs) (monitorData []EipMonitorDataType, err error) {
|
||||
if args.Period == 0 {
|
||||
args.Period = 60
|
||||
}
|
||||
response := DescribeEipMonitorDataResponse{}
|
||||
err = client.Invoke("DescribeEipMonitorData", args, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return response.EipMonitorDatas.EipMonitorData, err
|
||||
}
|
||||
|
||||
type DescribeDiskMonitorDataArgs struct {
|
||||
DiskId string
|
||||
StartTime util.ISO6801Time
|
||||
EndTime util.ISO6801Time
|
||||
Period int //Default 60s
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&diskmonitordatatype
|
||||
type DiskMonitorDataType struct {
|
||||
DiskId string
|
||||
IOPSRead int
|
||||
IOPSWrite int
|
||||
IOPSTotal int
|
||||
BPSRead int
|
||||
BPSWrite int
|
||||
BPSTotal int
|
||||
TimeStamp util.ISO6801Time
|
||||
}
|
||||
|
||||
type DescribeDiskMonitorDataResponse struct {
|
||||
common.Response
|
||||
TotalCount int
|
||||
MonitorData struct {
|
||||
DiskMonitorData []DiskMonitorDataType
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeDiskMonitorData describes disk monitoring data
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/monitor&describediskmonitordata
|
||||
func (client *Client) DescribeDiskMonitorData(args *DescribeDiskMonitorDataArgs) (monitorData []DiskMonitorDataType, totalCount int, err error) {
|
||||
if args.Period == 0 {
|
||||
args.Period = 60
|
||||
}
|
||||
response := DescribeDiskMonitorDataResponse{}
|
||||
err = client.Invoke("DescribeDiskMonitorData", args, &response)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return response.MonitorData.DiskMonitorData, response.TotalCount, err
|
||||
}
|
210
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/nat_gateway.go
generated
vendored
Normal file
210
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/nat_gateway.go
generated
vendored
Normal file
|
@ -0,0 +1,210 @@
|
|||
package ecs
|
||||
|
||||
import (
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
)
|
||||
|
||||
type BandwidthPackageType struct {
|
||||
IpCount int
|
||||
Bandwidth int
|
||||
Zone string
|
||||
}
|
||||
|
||||
type CreateNatGatewayArgs struct {
|
||||
RegionId common.Region
|
||||
VpcId string
|
||||
Spec string
|
||||
BandwidthPackage []BandwidthPackageType
|
||||
Name string
|
||||
Description string
|
||||
ClientToken string
|
||||
}
|
||||
|
||||
type ForwardTableIdType struct {
|
||||
ForwardTableId []string
|
||||
}
|
||||
|
||||
type SnatTableIdType struct {
|
||||
SnatTableId []string
|
||||
}
|
||||
|
||||
type BandwidthPackageIdType struct {
|
||||
BandwidthPackageId []string
|
||||
}
|
||||
|
||||
type CreateNatGatewayResponse struct {
|
||||
common.Response
|
||||
NatGatewayId string
|
||||
ForwardTableIds ForwardTableIdType
|
||||
BandwidthPackageIds BandwidthPackageIdType
|
||||
}
|
||||
|
||||
// CreateNatGateway creates Virtual Private Cloud
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/vpc&createvpc
|
||||
func (client *Client) CreateNatGateway(args *CreateNatGatewayArgs) (resp *CreateNatGatewayResponse, err error) {
|
||||
response := CreateNatGatewayResponse{}
|
||||
err = client.Invoke("CreateNatGateway", args, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &response, err
|
||||
}
|
||||
|
||||
type NatGatewaySetType struct {
|
||||
BusinessStatus string
|
||||
Description string
|
||||
BandwidthPackageIds BandwidthPackageIdType
|
||||
ForwardTableIds ForwardTableIdType
|
||||
SnatTableIds SnatTableIdType
|
||||
InstanceChargeType string
|
||||
Name string
|
||||
NatGatewayId string
|
||||
RegionId common.Region
|
||||
Spec string
|
||||
Status string
|
||||
VpcId string
|
||||
}
|
||||
|
||||
type DescribeNatGatewayResponse struct {
|
||||
common.Response
|
||||
common.PaginationResult
|
||||
NatGateways struct {
|
||||
NatGateway []NatGatewaySetType
|
||||
}
|
||||
}
|
||||
|
||||
type DescribeNatGatewaysArgs struct {
|
||||
RegionId common.Region
|
||||
NatGatewayId string
|
||||
VpcId string
|
||||
common.Pagination
|
||||
}
|
||||
|
||||
func (client *Client) DescribeNatGateways(args *DescribeNatGatewaysArgs) (natGateways []NatGatewaySetType,
|
||||
pagination *common.PaginationResult, err error) {
|
||||
response, err := client.DescribeNatGatewaysWithRaw(args)
|
||||
if err == nil {
|
||||
return response.NatGateways.NatGateway, &response.PaginationResult, nil
|
||||
}
|
||||
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
func (client *Client) DescribeNatGatewaysWithRaw(args *DescribeNatGatewaysArgs) (response *DescribeNatGatewayResponse, err error) {
|
||||
args.Validate()
|
||||
response = &DescribeNatGatewayResponse{}
|
||||
|
||||
err = client.Invoke("DescribeNatGateways", args, response)
|
||||
|
||||
if err == nil {
|
||||
return response, nil
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
type ModifyNatGatewayAttributeArgs struct {
|
||||
RegionId common.Region
|
||||
NatGatewayId string
|
||||
Name string
|
||||
Description string
|
||||
}
|
||||
|
||||
type ModifyNatGatewayAttributeResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
func (client *Client) ModifyNatGatewayAttribute(args *ModifyNatGatewayAttributeArgs) error {
|
||||
response := ModifyNatGatewayAttributeResponse{}
|
||||
return client.Invoke("ModifyNatGatewayAttribute", args, &response)
|
||||
}
|
||||
|
||||
type ModifyNatGatewaySpecArgs struct {
|
||||
RegionId common.Region
|
||||
NatGatewayId string
|
||||
Spec NatGatewaySpec
|
||||
}
|
||||
|
||||
func (client *Client) ModifyNatGatewaySpec(args *ModifyNatGatewaySpecArgs) error {
|
||||
response := ModifyNatGatewayAttributeResponse{}
|
||||
return client.Invoke("ModifyNatGatewaySpec", args, &response)
|
||||
}
|
||||
|
||||
type DeleteNatGatewayArgs struct {
|
||||
RegionId common.Region
|
||||
NatGatewayId string
|
||||
}
|
||||
|
||||
type DeleteNatGatewayResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
func (client *Client) DeleteNatGateway(args *DeleteNatGatewayArgs) error {
|
||||
response := DeleteNatGatewayResponse{}
|
||||
err := client.Invoke("DeleteNatGateway", args, &response)
|
||||
return err
|
||||
}
|
||||
|
||||
type DescribeBandwidthPackagesArgs struct {
|
||||
RegionId common.Region
|
||||
BandwidthPackageId string
|
||||
NatGatewayId string
|
||||
}
|
||||
|
||||
type PublicIpAddresseType struct {
|
||||
AllocationId string
|
||||
IpAddress string
|
||||
}
|
||||
|
||||
type DescribeBandwidthPackageType struct {
|
||||
Bandwidth string
|
||||
BandwidthPackageId string
|
||||
IpCount string
|
||||
PublicIpAddresses struct {
|
||||
PublicIpAddresse []PublicIpAddresseType
|
||||
}
|
||||
|
||||
ZoneId string
|
||||
}
|
||||
|
||||
type DescribeBandwidthPackagesResponse struct {
|
||||
common.Response
|
||||
BandwidthPackages struct {
|
||||
BandwidthPackage []DescribeBandwidthPackageType
|
||||
}
|
||||
}
|
||||
|
||||
func (client *Client) DescribeBandwidthPackages(args *DescribeBandwidthPackagesArgs) ([]DescribeBandwidthPackageType, error) {
|
||||
response := &DescribeBandwidthPackagesResponse{}
|
||||
|
||||
err := client.Invoke("DescribeBandwidthPackages", args, response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return response.BandwidthPackages.BandwidthPackage, err
|
||||
}
|
||||
|
||||
type DeleteBandwidthPackageArgs struct {
|
||||
RegionId common.Region
|
||||
BandwidthPackageId string
|
||||
}
|
||||
|
||||
type DeleteBandwidthPackageResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
func (client *Client) DeleteBandwidthPackage(args *DeleteBandwidthPackageArgs) error {
|
||||
response := DeleteBandwidthPackageResponse{}
|
||||
err := client.Invoke("DeleteBandwidthPackage", args, &response)
|
||||
return err
|
||||
}
|
||||
|
||||
type NatGatewaySpec string
|
||||
|
||||
const (
|
||||
NatGatewaySmallSpec = NatGatewaySpec("Small")
|
||||
NatGatewayMiddleSpec = NatGatewaySpec("Middle")
|
||||
NatGatewayLargeSpec = NatGatewaySpec("Large")
|
||||
)
|
258
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/networks.go
generated
vendored
Normal file
258
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/networks.go
generated
vendored
Normal file
|
@ -0,0 +1,258 @@
|
|||
// API on Network
|
||||
|
||||
package ecs
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
"github.com/denverdino/aliyungo/util"
|
||||
)
|
||||
|
||||
type AllocatePublicIpAddressArgs struct {
|
||||
InstanceId string
|
||||
}
|
||||
|
||||
type AllocatePublicIpAddressResponse struct {
|
||||
common.Response
|
||||
|
||||
IpAddress string
|
||||
}
|
||||
|
||||
// AllocatePublicIpAddress allocates Public Ip Address
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/network&allocatepublicipaddress
|
||||
func (client *Client) AllocatePublicIpAddress(instanceId string) (ipAddress string, err error) {
|
||||
args := AllocatePublicIpAddressArgs{
|
||||
InstanceId: instanceId,
|
||||
}
|
||||
response := AllocatePublicIpAddressResponse{}
|
||||
err = client.Invoke("AllocatePublicIpAddress", &args, &response)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return response.IpAddress, nil
|
||||
}
|
||||
|
||||
type ModifyInstanceNetworkSpec struct {
|
||||
InstanceId string
|
||||
InternetMaxBandwidthOut int
|
||||
InternetMaxBandwidthIn int
|
||||
}
|
||||
|
||||
type ModifyInstanceNetworkSpecResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// ModifyInstanceNetworkSpec modifies instance network spec
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/network&modifyinstancenetworkspec
|
||||
func (client *Client) ModifyInstanceNetworkSpec(args *ModifyInstanceNetworkSpec) error {
|
||||
|
||||
response := ModifyInstanceNetworkSpecResponse{}
|
||||
return client.Invoke("ModifyInstanceNetworkSpec", args, &response)
|
||||
}
|
||||
|
||||
type AllocateEipAddressArgs struct {
|
||||
RegionId common.Region
|
||||
Bandwidth int
|
||||
InternetChargeType common.InternetChargeType
|
||||
ClientToken string
|
||||
}
|
||||
|
||||
type AllocateEipAddressResponse struct {
|
||||
common.Response
|
||||
EipAddress string
|
||||
AllocationId string
|
||||
}
|
||||
|
||||
// AllocateEipAddress allocates Eip Address
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/network&allocateeipaddress
|
||||
func (client *Client) AllocateEipAddress(args *AllocateEipAddressArgs) (EipAddress string, AllocationId string, err error) {
|
||||
if args.Bandwidth == 0 {
|
||||
args.Bandwidth = 5
|
||||
}
|
||||
response := AllocateEipAddressResponse{}
|
||||
err = client.Invoke("AllocateEipAddress", args, &response)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
return response.EipAddress, response.AllocationId, nil
|
||||
}
|
||||
|
||||
type AssociateEipAddressArgs struct {
|
||||
AllocationId string
|
||||
InstanceId string
|
||||
}
|
||||
|
||||
type AssociateEipAddressResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// AssociateEipAddress associates EIP address to VM instance
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/network&associateeipaddress
|
||||
func (client *Client) AssociateEipAddress(allocationId string, instanceId string) error {
|
||||
args := AssociateEipAddressArgs{
|
||||
AllocationId: allocationId,
|
||||
InstanceId: instanceId,
|
||||
}
|
||||
response := ModifyInstanceNetworkSpecResponse{}
|
||||
return client.Invoke("AssociateEipAddress", &args, &response)
|
||||
}
|
||||
|
||||
// Status of disks
|
||||
type EipStatus string
|
||||
|
||||
const (
|
||||
EipStatusAssociating = EipStatus("Associating")
|
||||
EipStatusUnassociating = EipStatus("Unassociating")
|
||||
EipStatusInUse = EipStatus("InUse")
|
||||
EipStatusAvailable = EipStatus("Available")
|
||||
)
|
||||
|
||||
type DescribeEipAddressesArgs struct {
|
||||
RegionId common.Region
|
||||
Status EipStatus //enum Associating | Unassociating | InUse | Available
|
||||
EipAddress string
|
||||
AllocationId string
|
||||
common.Pagination
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&eipaddresssettype
|
||||
type EipAddressSetType struct {
|
||||
RegionId common.Region
|
||||
IpAddress string
|
||||
AllocationId string
|
||||
Status EipStatus
|
||||
InstanceId string
|
||||
Bandwidth string // Why string
|
||||
InternetChargeType common.InternetChargeType
|
||||
OperationLocks OperationLocksType
|
||||
AllocationTime util.ISO6801Time
|
||||
}
|
||||
|
||||
type DescribeEipAddressesResponse struct {
|
||||
common.Response
|
||||
common.PaginationResult
|
||||
EipAddresses struct {
|
||||
EipAddress []EipAddressSetType
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeInstanceStatus describes instance status
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/network&describeeipaddresses
|
||||
func (client *Client) DescribeEipAddresses(args *DescribeEipAddressesArgs) (eipAddresses []EipAddressSetType, pagination *common.PaginationResult, err error) {
|
||||
response, err := client.DescribeEipAddressesWithRaw(args)
|
||||
if err == nil {
|
||||
return response.EipAddresses.EipAddress, &response.PaginationResult, nil
|
||||
}
|
||||
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
func (client *Client) DescribeEipAddressesWithRaw(args *DescribeEipAddressesArgs) (response *DescribeEipAddressesResponse, err error) {
|
||||
args.Validate()
|
||||
response = &DescribeEipAddressesResponse{}
|
||||
|
||||
err = client.Invoke("DescribeEipAddresses", args, response)
|
||||
|
||||
if err == nil {
|
||||
return response, nil
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
type ModifyEipAddressAttributeArgs struct {
|
||||
AllocationId string
|
||||
Bandwidth int
|
||||
}
|
||||
|
||||
type ModifyEipAddressAttributeResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// ModifyEipAddressAttribute Modifies EIP attribute
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/network&modifyeipaddressattribute
|
||||
func (client *Client) ModifyEipAddressAttribute(allocationId string, bandwidth int) error {
|
||||
args := ModifyEipAddressAttributeArgs{
|
||||
AllocationId: allocationId,
|
||||
Bandwidth: bandwidth,
|
||||
}
|
||||
response := ModifyEipAddressAttributeResponse{}
|
||||
return client.Invoke("ModifyEipAddressAttribute", &args, &response)
|
||||
}
|
||||
|
||||
type UnallocateEipAddressArgs struct {
|
||||
AllocationId string
|
||||
InstanceId string
|
||||
}
|
||||
|
||||
type UnallocateEipAddressResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// UnassociateEipAddress unallocates Eip Address from instance
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/network&unassociateeipaddress
|
||||
func (client *Client) UnassociateEipAddress(allocationId string, instanceId string) error {
|
||||
args := UnallocateEipAddressArgs{
|
||||
AllocationId: allocationId,
|
||||
InstanceId: instanceId,
|
||||
}
|
||||
response := UnallocateEipAddressResponse{}
|
||||
return client.Invoke("UnassociateEipAddress", &args, &response)
|
||||
}
|
||||
|
||||
type ReleaseEipAddressArgs struct {
|
||||
AllocationId string
|
||||
}
|
||||
|
||||
type ReleaseEipAddressResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// ReleaseEipAddress releases Eip address
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/network&releaseeipaddress
|
||||
func (client *Client) ReleaseEipAddress(allocationId string) error {
|
||||
args := ReleaseEipAddressArgs{
|
||||
AllocationId: allocationId,
|
||||
}
|
||||
response := ReleaseEipAddressResponse{}
|
||||
return client.Invoke("ReleaseEipAddress", &args, &response)
|
||||
}
|
||||
|
||||
// WaitForVSwitchAvailable waits for VSwitch to given status
|
||||
func (client *Client) WaitForEip(regionId common.Region, allocationId string, status EipStatus, timeout int) error {
|
||||
if timeout <= 0 {
|
||||
timeout = DefaultTimeout
|
||||
}
|
||||
args := DescribeEipAddressesArgs{
|
||||
RegionId: regionId,
|
||||
AllocationId: allocationId,
|
||||
}
|
||||
for {
|
||||
eips, _, err := client.DescribeEipAddresses(&args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(eips) == 0 {
|
||||
return common.GetClientErrorFromString("Not found")
|
||||
}
|
||||
if eips[0].Status == status {
|
||||
break
|
||||
}
|
||||
timeout = timeout - DefaultWaitForInterval
|
||||
if timeout <= 0 {
|
||||
return common.GetClientErrorFromString("Timeout")
|
||||
}
|
||||
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||
}
|
||||
return nil
|
||||
}
|
34
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/regions.go
generated
vendored
Normal file
34
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/regions.go
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
package ecs
|
||||
|
||||
import "github.com/denverdino/aliyungo/common"
|
||||
|
||||
type DescribeRegionsArgs struct {
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype®iontype
|
||||
type RegionType struct {
|
||||
RegionId common.Region
|
||||
LocalName string
|
||||
}
|
||||
|
||||
type DescribeRegionsResponse struct {
|
||||
common.Response
|
||||
Regions struct {
|
||||
Region []RegionType
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeRegions describes regions
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/region&describeregions
|
||||
func (client *Client) DescribeRegions() (regions []RegionType, err error) {
|
||||
response := DescribeRegionsResponse{}
|
||||
|
||||
err = client.Invoke("DescribeRegions", &DescribeRegionsArgs{}, &response)
|
||||
|
||||
if err != nil {
|
||||
return []RegionType{}, err
|
||||
}
|
||||
return response.Regions.Region, nil
|
||||
}
|
186
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/route_tables.go
generated
vendored
Normal file
186
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/route_tables.go
generated
vendored
Normal file
|
@ -0,0 +1,186 @@
|
|||
package ecs
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
"github.com/denverdino/aliyungo/util"
|
||||
)
|
||||
|
||||
type DescribeRouteTablesArgs struct {
|
||||
VRouterId string
|
||||
RouteTableId string
|
||||
common.Pagination
|
||||
}
|
||||
|
||||
type RouteTableType string
|
||||
|
||||
const (
|
||||
RouteTableSystem = RouteTableType("System")
|
||||
RouteTableCustom = RouteTableType("Custom")
|
||||
)
|
||||
|
||||
type RouteEntryStatus string
|
||||
|
||||
const (
|
||||
RouteEntryStatusPending = RouteEntryStatus("Pending")
|
||||
RouteEntryStatusAvailable = RouteEntryStatus("Available")
|
||||
RouteEntryStatusModifying = RouteEntryStatus("Modifying")
|
||||
)
|
||||
|
||||
type NextHopListType struct {
|
||||
NextHopList struct {
|
||||
NextHopItem []NextHopItemType
|
||||
}
|
||||
}
|
||||
|
||||
type NextHopItemType struct {
|
||||
NextHopType string
|
||||
NextHopId string
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&routeentrysettype
|
||||
type RouteEntrySetType struct {
|
||||
RouteTableId string
|
||||
DestinationCidrBlock string
|
||||
Type RouteTableType
|
||||
NextHopType string
|
||||
NextHopId string
|
||||
NextHopList NextHopListType
|
||||
InstanceId string
|
||||
Status RouteEntryStatus // enum Pending | Available | Modifying
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&routetablesettype
|
||||
type RouteTableSetType struct {
|
||||
VRouterId string
|
||||
RouteTableId string
|
||||
RouteEntrys struct {
|
||||
RouteEntry []RouteEntrySetType
|
||||
}
|
||||
RouteTableType RouteTableType
|
||||
CreationTime util.ISO6801Time
|
||||
}
|
||||
|
||||
type DescribeRouteTablesResponse struct {
|
||||
common.Response
|
||||
common.PaginationResult
|
||||
RouteTables struct {
|
||||
RouteTable []RouteTableSetType
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeRouteTables describes Virtual Routers
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/routertable&describeroutetables
|
||||
func (client *Client) DescribeRouteTables(args *DescribeRouteTablesArgs) (routeTables []RouteTableSetType, pagination *common.PaginationResult, err error) {
|
||||
response, err := client.DescribeRouteTablesWithRaw(args)
|
||||
if err == nil {
|
||||
return response.RouteTables.RouteTable, &response.PaginationResult, nil
|
||||
}
|
||||
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
func (client *Client) DescribeRouteTablesWithRaw(args *DescribeRouteTablesArgs) (response *DescribeRouteTablesResponse, err error) {
|
||||
args.Validate()
|
||||
response = &DescribeRouteTablesResponse{}
|
||||
|
||||
err = client.Invoke("DescribeRouteTables", args, &response)
|
||||
|
||||
if err == nil {
|
||||
return response, nil
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
type NextHopType string
|
||||
|
||||
const (
|
||||
NextHopIntance = NextHopType("Instance") //Default
|
||||
NextHopTunnel = NextHopType("Tunnel")
|
||||
NextHopTunnelRouterInterface = NextHopType("RouterInterface")
|
||||
)
|
||||
|
||||
type CreateRouteEntryArgs struct {
|
||||
RouteTableId string
|
||||
DestinationCidrBlock string
|
||||
NextHopType NextHopType
|
||||
NextHopId string
|
||||
ClientToken string
|
||||
}
|
||||
|
||||
type CreateRouteEntryResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// CreateRouteEntry creates route entry
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/routertable&createrouteentry
|
||||
func (client *Client) CreateRouteEntry(args *CreateRouteEntryArgs) error {
|
||||
response := CreateRouteEntryResponse{}
|
||||
return client.Invoke("CreateRouteEntry", args, &response)
|
||||
}
|
||||
|
||||
type DeleteRouteEntryArgs struct {
|
||||
RouteTableId string
|
||||
DestinationCidrBlock string
|
||||
NextHopId string
|
||||
}
|
||||
|
||||
type DeleteRouteEntryResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// DeleteRouteEntry deletes route entry
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/routertable&deleterouteentry
|
||||
func (client *Client) DeleteRouteEntry(args *DeleteRouteEntryArgs) error {
|
||||
response := DeleteRouteEntryResponse{}
|
||||
return client.Invoke("DeleteRouteEntry", args, &response)
|
||||
}
|
||||
|
||||
// WaitForAllRouteEntriesAvailable waits for all route entries to Available status
|
||||
func (client *Client) WaitForAllRouteEntriesAvailable(vrouterId string, routeTableId string, timeout int) error {
|
||||
if timeout <= 0 {
|
||||
timeout = DefaultTimeout
|
||||
}
|
||||
args := DescribeRouteTablesArgs{
|
||||
VRouterId: vrouterId,
|
||||
RouteTableId: routeTableId,
|
||||
}
|
||||
for {
|
||||
|
||||
routeTables, _, err := client.DescribeRouteTables(&args)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(routeTables) == 0 {
|
||||
return common.GetClientErrorFromString("Not found")
|
||||
}
|
||||
success := true
|
||||
|
||||
loop:
|
||||
for _, routeTable := range routeTables {
|
||||
for _, routeEntry := range routeTable.RouteEntrys.RouteEntry {
|
||||
if routeEntry.Status != RouteEntryStatusAvailable {
|
||||
success = false
|
||||
break loop
|
||||
}
|
||||
}
|
||||
}
|
||||
if success {
|
||||
break
|
||||
}
|
||||
timeout = timeout - DefaultWaitForInterval
|
||||
if timeout <= 0 {
|
||||
return common.GetClientErrorFromString("Timeout")
|
||||
}
|
||||
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||
}
|
||||
return nil
|
||||
}
|
227
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/router_interface.go
generated
vendored
Normal file
227
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/router_interface.go
generated
vendored
Normal file
|
@ -0,0 +1,227 @@
|
|||
package ecs
|
||||
|
||||
import (
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
)
|
||||
|
||||
type EcsCommonResponse struct {
|
||||
common.Response
|
||||
}
|
||||
type RouterType string
|
||||
type InterfaceStatus string
|
||||
type Role string
|
||||
type Spec string
|
||||
|
||||
const (
|
||||
VRouter = RouterType("VRouter")
|
||||
VBR = RouterType("VBR")
|
||||
|
||||
Idl = InterfaceStatus("Idl")
|
||||
Active = InterfaceStatus("Active")
|
||||
Inactive = InterfaceStatus("Inactive")
|
||||
|
||||
InitiatingSide = Role("InitiatingSide")
|
||||
AcceptingSide = Role("AcceptingSide")
|
||||
|
||||
Small1 = Spec("Small.1")
|
||||
Small2 = Spec("Small.2")
|
||||
Small5 = Spec("Small.5")
|
||||
Middle1 = Spec("Middle.1")
|
||||
Middle2 = Spec("Middle.2")
|
||||
Middle5 = Spec("Middle.5")
|
||||
Large1 = Spec("Large.1")
|
||||
Large2 = Spec("Large.2")
|
||||
)
|
||||
|
||||
type CreateRouterInterfaceArgs struct {
|
||||
RegionId common.Region
|
||||
OppositeRegionId common.Region
|
||||
RouterType RouterType
|
||||
OppositeRouterType RouterType
|
||||
RouterId string
|
||||
OppositeRouterId string
|
||||
Role Role
|
||||
Spec Spec
|
||||
AccessPointId string
|
||||
OppositeAccessPointId string
|
||||
OppositeInterfaceId string
|
||||
OppositeInterfaceOwnerId string
|
||||
Name string
|
||||
Description string
|
||||
HealthCheckSourceIp string
|
||||
HealthCheckTargetIp string
|
||||
}
|
||||
|
||||
type CreateRouterInterfaceResponse struct {
|
||||
common.Response
|
||||
RouterInterfaceId string
|
||||
}
|
||||
|
||||
// CreateRouterInterface create Router interface
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/36032.html?spm=5176.product27706.6.664.EbBsxC
|
||||
func (client *Client) CreateRouterInterface(args *CreateRouterInterfaceArgs) (response *CreateRouterInterfaceResponse, err error) {
|
||||
response = &CreateRouterInterfaceResponse{}
|
||||
err = client.Invoke("CreateRouterInterface", args, &response)
|
||||
if err != nil {
|
||||
return response, err
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
type Filter struct {
|
||||
Key string
|
||||
Value []string
|
||||
}
|
||||
|
||||
type DescribeRouterInterfacesArgs struct {
|
||||
RegionId common.Region
|
||||
common.Pagination
|
||||
Filter []Filter
|
||||
}
|
||||
|
||||
type RouterInterfaceItemType struct {
|
||||
ChargeType string
|
||||
RouterInterfaceId string
|
||||
AccessPointId string
|
||||
OppositeRegionId string
|
||||
OppositeAccessPointId string
|
||||
Role Role
|
||||
Spec Spec
|
||||
Name string
|
||||
Description string
|
||||
RouterId string
|
||||
RouterType RouterType
|
||||
CreationTime string
|
||||
Status string
|
||||
BusinessStatus string
|
||||
ConnectedTime string
|
||||
OppositeInterfaceId string
|
||||
OppositeInterfaceSpec string
|
||||
OppositeInterfaceStatus string
|
||||
OppositeInterfaceBusinessStatus string
|
||||
OppositeRouterId string
|
||||
OppositeRouterType RouterType
|
||||
OppositeInterfaceOwnerId string
|
||||
HealthCheckSourceIp string
|
||||
HealthCheckTargetIp string
|
||||
}
|
||||
|
||||
type DescribeRouterInterfacesResponse struct {
|
||||
RouterInterfaceSet struct {
|
||||
RouterInterfaceType []RouterInterfaceItemType
|
||||
}
|
||||
common.PaginationResult
|
||||
}
|
||||
|
||||
// DescribeRouterInterfaces describe Router interfaces
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/36032.html?spm=5176.product27706.6.664.EbBsxC
|
||||
func (client *Client) DescribeRouterInterfaces(args *DescribeRouterInterfacesArgs) (response *DescribeRouterInterfacesResponse, err error) {
|
||||
response = &DescribeRouterInterfacesResponse{}
|
||||
err = client.Invoke("DescribeRouterInterfaces", args, &response)
|
||||
if err != nil {
|
||||
return response, err
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
type OperateRouterInterfaceArgs struct {
|
||||
RegionId common.Region
|
||||
RouterInterfaceId string
|
||||
}
|
||||
|
||||
// ConnectRouterInterface
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/36031.html?spm=5176.doc36035.6.666.wkyljN
|
||||
func (client *Client) ConnectRouterInterface(args *OperateRouterInterfaceArgs) (response *EcsCommonResponse, err error) {
|
||||
response = &EcsCommonResponse{}
|
||||
err = client.Invoke("ConnectRouterInterface", args, &response)
|
||||
if err != nil {
|
||||
return response, err
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// ActivateRouterInterface active Router Interface
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/36030.html?spm=5176.doc36031.6.667.DAuZLD
|
||||
func (client *Client) ActivateRouterInterface(args *OperateRouterInterfaceArgs) (response *EcsCommonResponse, err error) {
|
||||
response = &EcsCommonResponse{}
|
||||
err = client.Invoke("ActivateRouterInterface", args, &response)
|
||||
if err != nil {
|
||||
return response, err
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// DeactivateRouterInterface deactivate Router Interface
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/36033.html?spm=5176.doc36030.6.668.JqCWUz
|
||||
func (client *Client) DeactivateRouterInterface(args *OperateRouterInterfaceArgs) (response *EcsCommonResponse, err error) {
|
||||
response = &EcsCommonResponse{}
|
||||
err = client.Invoke("DeactivateRouterInterface", args, &response)
|
||||
if err != nil {
|
||||
return response, err
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
type ModifyRouterInterfaceSpecArgs struct {
|
||||
RegionId common.Region
|
||||
RouterInterfaceId string
|
||||
Spec Spec
|
||||
}
|
||||
|
||||
type ModifyRouterInterfaceSpecResponse struct {
|
||||
common.Response
|
||||
Spec Spec
|
||||
}
|
||||
|
||||
// ModifyRouterInterfaceSpec
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/36037.html?spm=5176.doc36036.6.669.McKiye
|
||||
func (client *Client) ModifyRouterInterfaceSpec(args *ModifyRouterInterfaceSpecArgs) (response *ModifyRouterInterfaceSpecResponse, err error) {
|
||||
response = &ModifyRouterInterfaceSpecResponse{}
|
||||
err = client.Invoke("ModifyRouterInterfaceSpec", args, &response)
|
||||
if err != nil {
|
||||
return response, err
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
type ModifyRouterInterfaceAttributeArgs struct {
|
||||
RegionId common.Region
|
||||
RouterInterfaceId string
|
||||
Name string
|
||||
Description string
|
||||
OppositeInterfaceId string
|
||||
OppositeRouterId string
|
||||
OppositeInterfaceOwnerId string
|
||||
HealthCheckSourceIp string
|
||||
HealthCheckTargetIp string
|
||||
}
|
||||
|
||||
// ModifyRouterInterfaceAttribute
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/36036.html?spm=5176.doc36037.6.670.Dcz3xS
|
||||
func (client *Client) ModifyRouterInterfaceAttribute(args *ModifyRouterInterfaceAttributeArgs) (response *EcsCommonResponse, err error) {
|
||||
response = &EcsCommonResponse{}
|
||||
err = client.Invoke("ModifyRouterInterfaceAttribute", args, &response)
|
||||
if err != nil {
|
||||
return response, err
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// DeleteRouterInterface delete Router Interface
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/36034.html?spm=5176.doc36036.6.671.y2xpNt
|
||||
func (client *Client) DeleteRouterInterface(args *OperateRouterInterfaceArgs) (response *EcsCommonResponse, err error) {
|
||||
response = &EcsCommonResponse{}
|
||||
err = client.Invoke("DeleteRouterInterface", args, &response)
|
||||
if err != nil {
|
||||
return response, err
|
||||
}
|
||||
return response, nil
|
||||
}
|
282
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/security_groups.go
generated
vendored
Normal file
282
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/security_groups.go
generated
vendored
Normal file
|
@ -0,0 +1,282 @@
|
|||
package ecs
|
||||
|
||||
import (
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
"github.com/denverdino/aliyungo/util"
|
||||
)
|
||||
|
||||
type NicType string
|
||||
|
||||
const (
|
||||
NicTypeInternet = NicType("internet")
|
||||
NicTypeIntranet = NicType("intranet")
|
||||
)
|
||||
|
||||
type IpProtocol string
|
||||
|
||||
const (
|
||||
IpProtocolAll = IpProtocol("all")
|
||||
IpProtocolTCP = IpProtocol("tcp")
|
||||
IpProtocolUDP = IpProtocol("udp")
|
||||
IpProtocolICMP = IpProtocol("icmp")
|
||||
IpProtocolGRE = IpProtocol("gre")
|
||||
)
|
||||
|
||||
type PermissionPolicy string
|
||||
|
||||
const (
|
||||
PermissionPolicyAccept = PermissionPolicy("accept")
|
||||
PermissionPolicyDrop = PermissionPolicy("drop")
|
||||
)
|
||||
|
||||
type DescribeSecurityGroupAttributeArgs struct {
|
||||
SecurityGroupId string
|
||||
RegionId common.Region
|
||||
NicType NicType //enum for internet (default) |intranet
|
||||
Direction string // enum ingress egress
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&permissiontype
|
||||
type PermissionType struct {
|
||||
IpProtocol IpProtocol
|
||||
PortRange string
|
||||
SourceCidrIp string
|
||||
SourceGroupId string
|
||||
SourceGroupOwnerAccount string
|
||||
DestCidrIp string
|
||||
DestGroupId string
|
||||
DestGroupOwnerAccount string
|
||||
Policy PermissionPolicy
|
||||
NicType NicType
|
||||
Priority int
|
||||
Direction string
|
||||
Description string
|
||||
}
|
||||
|
||||
type DescribeSecurityGroupAttributeResponse struct {
|
||||
common.Response
|
||||
|
||||
SecurityGroupId string
|
||||
SecurityGroupName string
|
||||
RegionId common.Region
|
||||
Description string
|
||||
Permissions struct {
|
||||
Permission []PermissionType
|
||||
}
|
||||
VpcId string
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/securitygroup&describesecuritygroupattribute
|
||||
func (client *Client) DescribeSecurityGroupAttribute(args *DescribeSecurityGroupAttributeArgs) (response *DescribeSecurityGroupAttributeResponse, err error) {
|
||||
response = &DescribeSecurityGroupAttributeResponse{}
|
||||
err = client.Invoke("DescribeSecurityGroupAttribute", args, response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
type DescribeSecurityGroupsArgs struct {
|
||||
RegionId common.Region
|
||||
VpcId string
|
||||
common.Pagination
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&securitygroupitemtype
|
||||
type SecurityGroupItemType struct {
|
||||
SecurityGroupId string
|
||||
SecurityGroupName string
|
||||
Description string
|
||||
VpcId string
|
||||
CreationTime util.ISO6801Time
|
||||
}
|
||||
|
||||
type DescribeSecurityGroupsResponse struct {
|
||||
common.Response
|
||||
common.PaginationResult
|
||||
|
||||
RegionId common.Region
|
||||
SecurityGroups struct {
|
||||
SecurityGroup []SecurityGroupItemType
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeSecurityGroups describes security groups
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/securitygroup&describesecuritygroups
|
||||
func (client *Client) DescribeSecurityGroups(args *DescribeSecurityGroupsArgs) (securityGroupItems []SecurityGroupItemType, pagination *common.PaginationResult, err error) {
|
||||
response, err := client.DescribeSecurityGroupsWithRaw(args)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return response.SecurityGroups.SecurityGroup, &response.PaginationResult, nil
|
||||
}
|
||||
|
||||
func (client *Client) DescribeSecurityGroupsWithRaw(args *DescribeSecurityGroupsArgs) (response *DescribeSecurityGroupsResponse, err error) {
|
||||
args.Validate()
|
||||
response = &DescribeSecurityGroupsResponse{}
|
||||
|
||||
err = client.Invoke("DescribeSecurityGroups", args, response)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
type CreateSecurityGroupArgs struct {
|
||||
RegionId common.Region
|
||||
SecurityGroupName string
|
||||
Description string
|
||||
VpcId string
|
||||
ClientToken string
|
||||
}
|
||||
|
||||
type CreateSecurityGroupResponse struct {
|
||||
common.Response
|
||||
|
||||
SecurityGroupId string
|
||||
}
|
||||
|
||||
// CreateSecurityGroup creates security group
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/securitygroup&createsecuritygroup
|
||||
func (client *Client) CreateSecurityGroup(args *CreateSecurityGroupArgs) (securityGroupId string, err error) {
|
||||
response := CreateSecurityGroupResponse{}
|
||||
err = client.Invoke("CreateSecurityGroup", args, &response)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return response.SecurityGroupId, err
|
||||
}
|
||||
|
||||
type DeleteSecurityGroupArgs struct {
|
||||
RegionId common.Region
|
||||
SecurityGroupId string
|
||||
}
|
||||
|
||||
type DeleteSecurityGroupResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// DeleteSecurityGroup deletes security group
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/securitygroup&deletesecuritygroup
|
||||
func (client *Client) DeleteSecurityGroup(regionId common.Region, securityGroupId string) error {
|
||||
args := DeleteSecurityGroupArgs{
|
||||
RegionId: regionId,
|
||||
SecurityGroupId: securityGroupId,
|
||||
}
|
||||
response := DeleteSecurityGroupResponse{}
|
||||
err := client.Invoke("DeleteSecurityGroup", &args, &response)
|
||||
return err
|
||||
}
|
||||
|
||||
type ModifySecurityGroupAttributeArgs struct {
|
||||
RegionId common.Region
|
||||
SecurityGroupId string
|
||||
SecurityGroupName string
|
||||
Description string
|
||||
}
|
||||
|
||||
type ModifySecurityGroupAttributeResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// ModifySecurityGroupAttribute modifies attribute of security group
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/securitygroup&modifysecuritygroupattribute
|
||||
func (client *Client) ModifySecurityGroupAttribute(args *ModifySecurityGroupAttributeArgs) error {
|
||||
response := ModifySecurityGroupAttributeResponse{}
|
||||
err := client.Invoke("ModifySecurityGroupAttribute", args, &response)
|
||||
return err
|
||||
}
|
||||
|
||||
type AuthorizeSecurityGroupArgs struct {
|
||||
SecurityGroupId string
|
||||
RegionId common.Region
|
||||
IpProtocol IpProtocol
|
||||
PortRange string
|
||||
SourceGroupId string
|
||||
SourceGroupOwnerAccount string
|
||||
SourceGroupOwnerID string
|
||||
SourceCidrIp string // IPv4 only, default 0.0.0.0/0
|
||||
Policy PermissionPolicy // enum of accept (default) | drop
|
||||
Priority int // 1 - 100, default 1
|
||||
NicType NicType // enum of internet | intranet (default)
|
||||
}
|
||||
|
||||
type AuthorizeSecurityGroupResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// AuthorizeSecurityGroup authorize permissions to security group
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/securitygroup&authorizesecuritygroup
|
||||
func (client *Client) AuthorizeSecurityGroup(args *AuthorizeSecurityGroupArgs) error {
|
||||
response := AuthorizeSecurityGroupResponse{}
|
||||
err := client.Invoke("AuthorizeSecurityGroup", args, &response)
|
||||
return err
|
||||
}
|
||||
|
||||
type RevokeSecurityGroupArgs struct {
|
||||
AuthorizeSecurityGroupArgs
|
||||
}
|
||||
|
||||
type RevokeSecurityGroupResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// You can read doc at https://help.aliyun.com/document_detail/25557.html?spm=5176.doc25554.6.755.O6Tjz0
|
||||
func (client *Client) RevokeSecurityGroup(args *RevokeSecurityGroupArgs) error {
|
||||
response := RevokeSecurityGroupResponse{}
|
||||
err := client.Invoke("RevokeSecurityGroup", args, &response)
|
||||
return err
|
||||
}
|
||||
|
||||
type AuthorizeSecurityGroupEgressArgs struct {
|
||||
SecurityGroupId string
|
||||
RegionId common.Region
|
||||
IpProtocol IpProtocol
|
||||
PortRange string
|
||||
DestGroupId string
|
||||
DestGroupOwnerAccount string
|
||||
DestGroupOwnerId string
|
||||
DestCidrIp string // IPv4 only, default 0.0.0.0/0
|
||||
Policy PermissionPolicy // enum of accept (default) | drop
|
||||
Priority int // 1 - 100, default 1
|
||||
NicType NicType // enum of internet | intranet (default)
|
||||
}
|
||||
|
||||
type AuthorizeSecurityGroupEgressResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// AuthorizeSecurityGroup authorize permissions to security group
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/25560.html
|
||||
func (client *Client) AuthorizeSecurityGroupEgress(args *AuthorizeSecurityGroupEgressArgs) error {
|
||||
response := AuthorizeSecurityGroupEgressResponse{}
|
||||
err := client.Invoke("AuthorizeSecurityGroupEgress", args, &response)
|
||||
return err
|
||||
}
|
||||
|
||||
type RevokeSecurityGroupEgressArgs struct {
|
||||
AuthorizeSecurityGroupEgressArgs
|
||||
}
|
||||
|
||||
type RevokeSecurityGroupEgressResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// You can read doc at https://help.aliyun.com/document_detail/25561.html?spm=5176.doc25557.6.759.qcR4Az
|
||||
func (client *Client) RevokeSecurityGroupEgress(args *RevokeSecurityGroupEgressArgs) error {
|
||||
response := RevokeSecurityGroupEgressResponse{}
|
||||
err := client.Invoke("RevokeSecurityGroupEgress", args, &response)
|
||||
return err
|
||||
}
|
140
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/snapshots.go
generated
vendored
Normal file
140
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/snapshots.go
generated
vendored
Normal file
|
@ -0,0 +1,140 @@
|
|||
package ecs
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
"github.com/denverdino/aliyungo/util"
|
||||
)
|
||||
|
||||
type DescribeSnapshotsArgs struct {
|
||||
RegionId common.Region
|
||||
InstanceId string
|
||||
DiskId string
|
||||
SnapshotIds []string //["s-xxxxxxxxx", "s-yyyyyyyyy", ..."s-zzzzzzzzz"]
|
||||
common.Pagination
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&snapshottype
|
||||
type SnapshotType struct {
|
||||
SnapshotId string
|
||||
SnapshotName string
|
||||
Description string
|
||||
Progress string
|
||||
SourceDiskId string
|
||||
SourceDiskSize int
|
||||
SourceDiskType string //enum for System | Data
|
||||
ProductCode string
|
||||
CreationTime util.ISO6801Time
|
||||
}
|
||||
|
||||
type DescribeSnapshotsResponse struct {
|
||||
common.Response
|
||||
common.PaginationResult
|
||||
Snapshots struct {
|
||||
Snapshot []SnapshotType
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeSnapshots describe snapshots
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/snapshot&describesnapshots
|
||||
func (client *Client) DescribeSnapshots(args *DescribeSnapshotsArgs) (snapshots []SnapshotType, pagination *common.PaginationResult, err error) {
|
||||
response, err := client.DescribeSnapshotsWithRaw(args)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return response.Snapshots.Snapshot, &response.PaginationResult, nil
|
||||
|
||||
}
|
||||
|
||||
func (client *Client) DescribeSnapshotsWithRaw(args *DescribeSnapshotsArgs) (response *DescribeSnapshotsResponse, err error) {
|
||||
args.Validate()
|
||||
response = &DescribeSnapshotsResponse{}
|
||||
|
||||
err = client.Invoke("DescribeSnapshots", args, response)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return response, nil
|
||||
|
||||
}
|
||||
|
||||
type DeleteSnapshotArgs struct {
|
||||
SnapshotId string
|
||||
}
|
||||
|
||||
type DeleteSnapshotResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// DeleteSnapshot deletes snapshot
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/snapshot&deletesnapshot
|
||||
func (client *Client) DeleteSnapshot(snapshotId string) error {
|
||||
args := DeleteSnapshotArgs{SnapshotId: snapshotId}
|
||||
response := DeleteSnapshotResponse{}
|
||||
|
||||
return client.Invoke("DeleteSnapshot", &args, &response)
|
||||
}
|
||||
|
||||
type CreateSnapshotArgs struct {
|
||||
DiskId string
|
||||
SnapshotName string
|
||||
Description string
|
||||
ClientToken string
|
||||
}
|
||||
|
||||
type CreateSnapshotResponse struct {
|
||||
common.Response
|
||||
SnapshotId string
|
||||
}
|
||||
|
||||
// CreateSnapshot creates a new snapshot
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/snapshot&createsnapshot
|
||||
func (client *Client) CreateSnapshot(args *CreateSnapshotArgs) (snapshotId string, err error) {
|
||||
|
||||
response := CreateSnapshotResponse{}
|
||||
|
||||
err = client.Invoke("CreateSnapshot", args, &response)
|
||||
if err == nil {
|
||||
snapshotId = response.SnapshotId
|
||||
}
|
||||
return snapshotId, err
|
||||
}
|
||||
|
||||
// Default timeout value for WaitForSnapShotReady method
|
||||
const SnapshotDefaultTimeout = 120
|
||||
|
||||
// WaitForSnapShotReady waits for snapshot ready
|
||||
func (client *Client) WaitForSnapShotReady(regionId common.Region, snapshotId string, timeout int) error {
|
||||
if timeout <= 0 {
|
||||
timeout = SnapshotDefaultTimeout
|
||||
}
|
||||
for {
|
||||
args := DescribeSnapshotsArgs{
|
||||
RegionId: regionId,
|
||||
SnapshotIds: []string{snapshotId},
|
||||
}
|
||||
|
||||
snapshots, _, err := client.DescribeSnapshots(&args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if snapshots == nil || len(snapshots) == 0 {
|
||||
return common.GetClientErrorFromString("Not found")
|
||||
}
|
||||
if snapshots[0].Progress == "100%" {
|
||||
break
|
||||
}
|
||||
timeout = timeout - DefaultWaitForInterval
|
||||
if timeout <= 0 {
|
||||
return common.GetClientErrorFromString("Timeout")
|
||||
}
|
||||
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||
}
|
||||
return nil
|
||||
}
|
103
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/snat_entry.go
generated
vendored
Normal file
103
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/snat_entry.go
generated
vendored
Normal file
|
@ -0,0 +1,103 @@
|
|||
package ecs
|
||||
|
||||
import "github.com/denverdino/aliyungo/common"
|
||||
|
||||
type CreateSnatEntryArgs struct {
|
||||
RegionId common.Region
|
||||
SnatTableId string
|
||||
SourceVSwitchId string
|
||||
SnatIp string
|
||||
}
|
||||
|
||||
type CreateSnatEntryResponse struct {
|
||||
common.Response
|
||||
SnatEntryId string
|
||||
}
|
||||
|
||||
type SnatEntrySetType struct {
|
||||
RegionId common.Region
|
||||
SnatEntryId string
|
||||
SnatIp string
|
||||
SnatTableId string
|
||||
SourceCIDR string
|
||||
SourceVSwitchId string
|
||||
Status string
|
||||
}
|
||||
|
||||
type DescribeSnatTableEntriesArgs struct {
|
||||
RegionId common.Region
|
||||
SnatTableId string
|
||||
common.Pagination
|
||||
}
|
||||
|
||||
type DescribeSnatTableEntriesResponse struct {
|
||||
common.Response
|
||||
common.PaginationResult
|
||||
SnatTableEntries struct {
|
||||
SnatTableEntry []SnatEntrySetType
|
||||
}
|
||||
}
|
||||
|
||||
type ModifySnatEntryArgs struct {
|
||||
RegionId common.Region
|
||||
SnatTableId string
|
||||
SnatEntryId string
|
||||
SnatIp string
|
||||
}
|
||||
|
||||
type ModifySnatEntryResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
type DeleteSnatEntryArgs struct {
|
||||
RegionId common.Region
|
||||
SnatTableId string
|
||||
SnatEntryId string
|
||||
}
|
||||
|
||||
type DeleteSnatEntryResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
func (client *Client) CreateSnatEntry(args *CreateSnatEntryArgs) (resp *CreateSnatEntryResponse, err error) {
|
||||
response := CreateSnatEntryResponse{}
|
||||
err = client.Invoke("CreateSnatEntry", args, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &response, err
|
||||
}
|
||||
|
||||
func (client *Client) DescribeSnatTableEntries(args *DescribeSnatTableEntriesArgs) (snatTableEntries []SnatEntrySetType,
|
||||
pagination *common.PaginationResult, err error) {
|
||||
response, err := client.DescribeSnatTableEntriesWithRaw(args)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return response.SnatTableEntries.SnatTableEntry, &response.PaginationResult, nil
|
||||
}
|
||||
|
||||
func (client *Client) DescribeSnatTableEntriesWithRaw(args *DescribeSnatTableEntriesArgs) ( response *DescribeSnatTableEntriesResponse, err error) {
|
||||
args.Validate()
|
||||
response = &DescribeSnatTableEntriesResponse{}
|
||||
|
||||
err = client.Invoke("DescribeSnatTableEntries", args, response)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (client *Client) ModifySnatEntry(args *ModifySnatEntryArgs) error {
|
||||
response := ModifySnatEntryResponse{}
|
||||
return client.Invoke("ModifySnatEntry", args, &response)
|
||||
}
|
||||
|
||||
func (client *Client) DeleteSnatEntry(args *DeleteSnatEntryArgs) error {
|
||||
response := DeleteSnatEntryResponse{}
|
||||
err := client.Invoke("DeleteSnatEntry", args, &response)
|
||||
return err
|
||||
}
|
153
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/ssh_key_pair.go
generated
vendored
Normal file
153
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/ssh_key_pair.go
generated
vendored
Normal file
|
@ -0,0 +1,153 @@
|
|||
package ecs
|
||||
|
||||
import (
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
)
|
||||
|
||||
type CreateKeyPairArgs struct {
|
||||
RegionId common.Region
|
||||
KeyPairName string
|
||||
}
|
||||
|
||||
type CreateKeyPairResponse struct {
|
||||
common.Response
|
||||
KeyPairName string
|
||||
KeyPairFingerPrint string
|
||||
PrivateKeyBody string
|
||||
}
|
||||
|
||||
// CreateKeyPair creates keypair
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/51771.html?spm=5176.doc51775.6.910.cedjfr
|
||||
func (client *Client) CreateKeyPair(args *CreateKeyPairArgs) (resp *CreateKeyPairResponse,err error) {
|
||||
response := CreateKeyPairResponse{}
|
||||
err = client.Invoke("CreateKeyPair", args, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &response, err
|
||||
}
|
||||
|
||||
type ImportKeyPairArgs struct {
|
||||
RegionId common.Region
|
||||
PublicKeyBody string
|
||||
KeyPairName string
|
||||
}
|
||||
|
||||
type ImportKeyPairResponse struct {
|
||||
common.Response
|
||||
KeyPairName string
|
||||
KeyPairFingerPrint string
|
||||
}
|
||||
|
||||
// ImportKeyPair import keypair
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/51774.html?spm=5176.doc51771.6.911.BicQq2
|
||||
func (client *Client) ImportKeyPair(args *ImportKeyPairArgs) (resp *ImportKeyPairResponse,err error) {
|
||||
response := ImportKeyPairResponse{}
|
||||
err = client.Invoke("ImportKeyPair", args, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &response, err
|
||||
}
|
||||
|
||||
type DescribeKeyPairsArgs struct {
|
||||
RegionId common.Region
|
||||
KeyPairFingerPrint string
|
||||
KeyPairName string
|
||||
common.Pagination
|
||||
}
|
||||
|
||||
type KeyPairItemType struct {
|
||||
KeyPairName string
|
||||
KeyPairFingerPrint string
|
||||
}
|
||||
|
||||
type DescribeKeyPairsResponse struct {
|
||||
common.Response
|
||||
common.PaginationResult
|
||||
RegionId common.Region
|
||||
KeyPairs struct {
|
||||
KeyPair []KeyPairItemType
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeKeyPairs describe keypairs
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/51773.html?spm=5176.doc51774.6.912.lyE0iX
|
||||
func (client *Client) DescribeKeyPairs(args *DescribeKeyPairsArgs) (KeyPairs []KeyPairItemType, pagination *common.PaginationResult, err error) {
|
||||
response, err := client.DescribeKeyPairsWithRaw(args)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return response.KeyPairs.KeyPair, &response.PaginationResult, err
|
||||
}
|
||||
|
||||
func (client *Client) DescribeKeyPairsWithRaw(args *DescribeKeyPairsArgs) (response *DescribeKeyPairsResponse, err error) {
|
||||
response = &DescribeKeyPairsResponse{}
|
||||
|
||||
err = client.Invoke("DescribeKeyPairs", args, response)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return response, err
|
||||
}
|
||||
|
||||
type AttachKeyPairArgs struct {
|
||||
RegionId common.Region
|
||||
KeyPairName string
|
||||
InstanceIds string
|
||||
}
|
||||
|
||||
// AttachKeyPair keypars to instances
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/51775.html?spm=5176.doc51773.6.913.igEem4
|
||||
func (client *Client) AttachKeyPair(args *AttachKeyPairArgs) (err error) {
|
||||
response := common.Response{}
|
||||
err = client.Invoke("AttachKeyPair", args, &response)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type DetachKeyPairArgs struct {
|
||||
RegionId common.Region
|
||||
KeyPairName string
|
||||
InstanceIds string
|
||||
}
|
||||
|
||||
// DetachKeyPair keyparis from instances
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/51776.html?spm=5176.doc51775.6.914.DJ7Gmq
|
||||
func (client *Client) DetachKeyPair(args *DetachKeyPairArgs) (err error) {
|
||||
response := common.Response{}
|
||||
err = client.Invoke("DetachKeyPair", args, &response)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type DeleteKeyPairsArgs struct {
|
||||
RegionId common.Region
|
||||
KeyPairNames string
|
||||
}
|
||||
|
||||
// DeleteKeyPairs delete keypairs
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/51772.html?spm=5176.doc51776.6.915.Qqcv2Q
|
||||
func (client *Client) DeleteKeyPairs(args *DeleteKeyPairsArgs) (err error) {
|
||||
response := common.Response{}
|
||||
err = client.Invoke("DeleteKeyPairs", args, &response)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
128
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/tags.go
generated
vendored
Normal file
128
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/tags.go
generated
vendored
Normal file
|
@ -0,0 +1,128 @@
|
|||
package ecs
|
||||
|
||||
import "github.com/denverdino/aliyungo/common"
|
||||
|
||||
type TagResourceType string
|
||||
|
||||
const (
|
||||
TagResourceImage = TagResourceType("image")
|
||||
TagResourceInstance = TagResourceType("instance")
|
||||
TagResourceSnapshot = TagResourceType("snapshot")
|
||||
TagResourceDisk = TagResourceType("disk")
|
||||
)
|
||||
|
||||
type AddTagsArgs struct {
|
||||
ResourceId string
|
||||
ResourceType TagResourceType //image, instance, snapshot or disk
|
||||
RegionId common.Region
|
||||
Tag map[string]string
|
||||
}
|
||||
|
||||
type AddTagsResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// AddTags Add tags to resource
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/tags&addtags
|
||||
func (client *Client) AddTags(args *AddTagsArgs) error {
|
||||
response := AddTagsResponse{}
|
||||
err := client.Invoke("AddTags", args, &response)
|
||||
return err
|
||||
}
|
||||
|
||||
type RemoveTagsArgs struct {
|
||||
ResourceId string
|
||||
ResourceType TagResourceType //image, instance, snapshot or disk
|
||||
RegionId common.Region
|
||||
Tag map[string]string
|
||||
}
|
||||
|
||||
type RemoveTagsResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// RemoveTags remove tags to resource
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/tags&removetags
|
||||
func (client *Client) RemoveTags(args *RemoveTagsArgs) error {
|
||||
response := RemoveTagsResponse{}
|
||||
err := client.Invoke("RemoveTags", args, &response)
|
||||
return err
|
||||
}
|
||||
|
||||
type ResourceItemType struct {
|
||||
ResourceId string
|
||||
ResourceType TagResourceType
|
||||
RegionId common.Region
|
||||
}
|
||||
|
||||
type DescribeResourceByTagsArgs struct {
|
||||
ResourceType TagResourceType //image, instance, snapshot or disk
|
||||
RegionId common.Region
|
||||
Tag map[string]string
|
||||
common.Pagination
|
||||
}
|
||||
|
||||
type DescribeResourceByTagsResponse struct {
|
||||
common.Response
|
||||
common.PaginationResult
|
||||
Resources struct {
|
||||
Resource []ResourceItemType
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeResourceByTags describe resource by tags
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/tags&describeresourcebytags
|
||||
func (client *Client) DescribeResourceByTags(args *DescribeResourceByTagsArgs) (resources []ResourceItemType, pagination *common.PaginationResult, err error) {
|
||||
response, err := client.DescribeResourceByTagsWithRaw(args)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return response.Resources.Resource, &response.PaginationResult, nil
|
||||
}
|
||||
|
||||
func (client *Client) DescribeResourceByTagsWithRaw(args *DescribeResourceByTagsArgs) (response *DescribeResourceByTagsResponse, err error) {
|
||||
args.Validate()
|
||||
response = &DescribeResourceByTagsResponse{}
|
||||
err = client.Invoke("DescribeResourceByTags", args, response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
type TagItemType struct {
|
||||
TagKey string
|
||||
TagValue string
|
||||
}
|
||||
|
||||
type DescribeTagsArgs struct {
|
||||
RegionId common.Region
|
||||
ResourceType TagResourceType //image, instance, snapshot or disk
|
||||
ResourceId string
|
||||
Tag map[string]string
|
||||
common.Pagination
|
||||
}
|
||||
|
||||
type DescribeTagsResponse struct {
|
||||
common.Response
|
||||
common.PaginationResult
|
||||
Tags struct {
|
||||
Tag []TagItemType
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeResourceByTags describe resource by tags
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/tags&describeresourcebytags
|
||||
func (client *Client) DescribeTags(args *DescribeTagsArgs) (tags []TagItemType, pagination *common.PaginationResult, err error) {
|
||||
args.Validate()
|
||||
response := DescribeTagsResponse{}
|
||||
err = client.Invoke("DescribeTags", args, &response)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return response.Tags.Tag, &response.PaginationResult, nil
|
||||
}
|
160
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/vpcs.go
generated
vendored
Normal file
160
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/vpcs.go
generated
vendored
Normal file
|
@ -0,0 +1,160 @@
|
|||
package ecs
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
"github.com/denverdino/aliyungo/util"
|
||||
)
|
||||
|
||||
type CreateVpcArgs struct {
|
||||
RegionId common.Region
|
||||
CidrBlock string //192.168.0.0/16 or 172.16.0.0/16 (default)
|
||||
VpcName string
|
||||
Description string
|
||||
ClientToken string
|
||||
}
|
||||
|
||||
type CreateVpcResponse struct {
|
||||
common.Response
|
||||
VpcId string
|
||||
VRouterId string
|
||||
RouteTableId string
|
||||
}
|
||||
|
||||
// CreateVpc creates Virtual Private Cloud
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/vpc&createvpc
|
||||
func (client *Client) CreateVpc(args *CreateVpcArgs) (resp *CreateVpcResponse, err error) {
|
||||
response := CreateVpcResponse{}
|
||||
err = client.Invoke("CreateVpc", args, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &response, err
|
||||
}
|
||||
|
||||
type DeleteVpcArgs struct {
|
||||
VpcId string
|
||||
}
|
||||
|
||||
type DeleteVpcResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// DeleteVpc deletes Virtual Private Cloud
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/vpc&deletevpc
|
||||
func (client *Client) DeleteVpc(vpcId string) error {
|
||||
args := DeleteVpcArgs{
|
||||
VpcId: vpcId,
|
||||
}
|
||||
response := DeleteVpcResponse{}
|
||||
return client.Invoke("DeleteVpc", &args, &response)
|
||||
}
|
||||
|
||||
type VpcStatus string
|
||||
|
||||
const (
|
||||
VpcStatusPending = VpcStatus("Pending")
|
||||
VpcStatusAvailable = VpcStatus("Available")
|
||||
)
|
||||
|
||||
type DescribeVpcsArgs struct {
|
||||
VpcId string
|
||||
RegionId common.Region
|
||||
common.Pagination
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&vpcsettype
|
||||
type VpcSetType struct {
|
||||
VpcId string
|
||||
RegionId common.Region
|
||||
Status VpcStatus // enum Pending | Available
|
||||
VpcName string
|
||||
VSwitchIds struct {
|
||||
VSwitchId []string
|
||||
}
|
||||
CidrBlock string
|
||||
VRouterId string
|
||||
Description string
|
||||
IsDefault bool
|
||||
CreationTime util.ISO6801Time
|
||||
}
|
||||
|
||||
type DescribeVpcsResponse struct {
|
||||
common.Response
|
||||
common.PaginationResult
|
||||
Vpcs struct {
|
||||
Vpc []VpcSetType
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeInstanceStatus describes instance status
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/vpc&describevpcs
|
||||
func (client *Client) DescribeVpcs(args *DescribeVpcsArgs) (vpcs []VpcSetType, pagination *common.PaginationResult, err error) {
|
||||
response, err := client.DescribeVpcsWithRaw(args)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return response.Vpcs.Vpc, &response.PaginationResult, nil
|
||||
}
|
||||
|
||||
func (client *Client) DescribeVpcsWithRaw(args *DescribeVpcsArgs) (response *DescribeVpcsResponse, err error) {
|
||||
args.Validate()
|
||||
response = &DescribeVpcsResponse{}
|
||||
|
||||
err = client.Invoke("DescribeVpcs", args, response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return response, err
|
||||
}
|
||||
|
||||
type ModifyVpcAttributeArgs struct {
|
||||
VpcId string
|
||||
VpcName string
|
||||
Description string
|
||||
}
|
||||
|
||||
type ModifyVpcAttributeResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// ModifyVpcAttribute modifies attribute of Virtual Private Cloud
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/vpc&modifyvpcattribute
|
||||
func (client *Client) ModifyVpcAttribute(args *ModifyVpcAttributeArgs) error {
|
||||
response := ModifyVpcAttributeResponse{}
|
||||
return client.Invoke("ModifyVpcAttribute", args, &response)
|
||||
}
|
||||
|
||||
// WaitForInstance waits for instance to given status
|
||||
func (client *Client) WaitForVpcAvailable(regionId common.Region, vpcId string, timeout int) error {
|
||||
if timeout <= 0 {
|
||||
timeout = DefaultTimeout
|
||||
}
|
||||
args := DescribeVpcsArgs{
|
||||
RegionId: regionId,
|
||||
VpcId: vpcId,
|
||||
}
|
||||
for {
|
||||
vpcs, _, err := client.DescribeVpcs(&args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(vpcs) > 0 && vpcs[0].Status == VpcStatusAvailable {
|
||||
break
|
||||
}
|
||||
timeout = timeout - DefaultWaitForInterval
|
||||
if timeout <= 0 {
|
||||
return common.GetClientErrorFromString("Timeout")
|
||||
}
|
||||
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||
}
|
||||
return nil
|
||||
}
|
77
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/vrouters.go
generated
vendored
Normal file
77
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/vrouters.go
generated
vendored
Normal file
|
@ -0,0 +1,77 @@
|
|||
package ecs
|
||||
|
||||
import (
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
"github.com/denverdino/aliyungo/util"
|
||||
)
|
||||
|
||||
type DescribeVRoutersArgs struct {
|
||||
VRouterId string
|
||||
RegionId common.Region
|
||||
common.Pagination
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&vroutersettype
|
||||
type VRouterSetType struct {
|
||||
VRouterId string
|
||||
RegionId common.Region
|
||||
VpcId string
|
||||
RouteTableIds struct {
|
||||
RouteTableId []string
|
||||
}
|
||||
VRouterName string
|
||||
Description string
|
||||
CreationTime util.ISO6801Time
|
||||
}
|
||||
|
||||
type DescribeVRoutersResponse struct {
|
||||
common.Response
|
||||
common.PaginationResult
|
||||
VRouters struct {
|
||||
VRouter []VRouterSetType
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeVRouters describes Virtual Routers
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/vrouter&describevrouters
|
||||
func (client *Client) DescribeVRouters(args *DescribeVRoutersArgs) (vrouters []VRouterSetType, pagination *common.PaginationResult, err error) {
|
||||
response, err := client.DescribeVRoutersWithRaw(args)
|
||||
if err == nil {
|
||||
return response.VRouters.VRouter, &response.PaginationResult, nil
|
||||
}
|
||||
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
func (client *Client) DescribeVRoutersWithRaw(args *DescribeVRoutersArgs) (response *DescribeVRoutersResponse, err error) {
|
||||
args.Validate()
|
||||
response = &DescribeVRoutersResponse{}
|
||||
|
||||
err = client.Invoke("DescribeVRouters", args, response)
|
||||
|
||||
if err == nil {
|
||||
return response, nil
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
type ModifyVRouterAttributeArgs struct {
|
||||
VRouterId string
|
||||
VRouterName string
|
||||
Description string
|
||||
}
|
||||
|
||||
type ModifyVRouterAttributeResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// ModifyVRouterAttribute modifies attribute of Virtual Router
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/vrouter&modifyvrouterattribute
|
||||
func (client *Client) ModifyVRouterAttribute(args *ModifyVRouterAttributeArgs) error {
|
||||
response := ModifyVRouterAttributeResponse{}
|
||||
return client.Invoke("ModifyVRouterAttribute", args, &response)
|
||||
}
|
164
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/vswitches.go
generated
vendored
Normal file
164
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/vswitches.go
generated
vendored
Normal file
|
@ -0,0 +1,164 @@
|
|||
package ecs
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/denverdino/aliyungo/common"
|
||||
"github.com/denverdino/aliyungo/util"
|
||||
)
|
||||
|
||||
type CreateVSwitchArgs struct {
|
||||
ZoneId string
|
||||
CidrBlock string
|
||||
VpcId string
|
||||
VSwitchName string
|
||||
Description string
|
||||
ClientToken string
|
||||
}
|
||||
|
||||
type CreateVSwitchResponse struct {
|
||||
common.Response
|
||||
VSwitchId string
|
||||
}
|
||||
|
||||
// CreateVSwitch creates Virtual Switch
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/vswitch&createvswitch
|
||||
func (client *Client) CreateVSwitch(args *CreateVSwitchArgs) (vswitchId string, err error) {
|
||||
response := CreateVSwitchResponse{}
|
||||
err = client.Invoke("CreateVSwitch", args, &response)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return response.VSwitchId, err
|
||||
}
|
||||
|
||||
type DeleteVSwitchArgs struct {
|
||||
VSwitchId string
|
||||
}
|
||||
|
||||
type DeleteVSwitchResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// DeleteVSwitch deletes Virtual Switch
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/vswitch&deletevswitch
|
||||
func (client *Client) DeleteVSwitch(VSwitchId string) error {
|
||||
args := DeleteVSwitchArgs{
|
||||
VSwitchId: VSwitchId,
|
||||
}
|
||||
response := DeleteVSwitchResponse{}
|
||||
return client.Invoke("DeleteVSwitch", &args, &response)
|
||||
}
|
||||
|
||||
type DescribeVSwitchesArgs struct {
|
||||
RegionId common.Region
|
||||
VpcId string
|
||||
VSwitchId string
|
||||
ZoneId string
|
||||
common.Pagination
|
||||
}
|
||||
|
||||
type VSwitchStatus string
|
||||
|
||||
const (
|
||||
VSwitchStatusPending = VSwitchStatus("Pending")
|
||||
VSwitchStatusAvailable = VSwitchStatus("Available")
|
||||
)
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&vswitchsettype
|
||||
type VSwitchSetType struct {
|
||||
VSwitchId string
|
||||
VpcId string
|
||||
Status VSwitchStatus // enum Pending | Available
|
||||
CidrBlock string
|
||||
ZoneId string
|
||||
AvailableIpAddressCount int
|
||||
Description string
|
||||
VSwitchName string
|
||||
IsDefault bool
|
||||
CreationTime util.ISO6801Time
|
||||
}
|
||||
|
||||
type DescribeVSwitchesResponse struct {
|
||||
common.Response
|
||||
common.PaginationResult
|
||||
VSwitches struct {
|
||||
VSwitch []VSwitchSetType
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeVSwitches describes Virtual Switches
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/vswitch&describevswitches
|
||||
func (client *Client) DescribeVSwitches(args *DescribeVSwitchesArgs) (vswitches []VSwitchSetType, pagination *common.PaginationResult, err error) {
|
||||
args.Validate()
|
||||
response, err := client.DescribeVSwitchesWithRaw(args)
|
||||
if err == nil {
|
||||
return response.VSwitches.VSwitch, &response.PaginationResult, nil
|
||||
}
|
||||
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
func (client *Client) DescribeVSwitchesWithRaw(args *DescribeVSwitchesArgs) (response *DescribeVSwitchesResponse, err error) {
|
||||
args.Validate()
|
||||
response = &DescribeVSwitchesResponse{}
|
||||
|
||||
err = client.Invoke("DescribeVSwitches", args, &response)
|
||||
|
||||
if err == nil {
|
||||
return response, nil
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
type ModifyVSwitchAttributeArgs struct {
|
||||
VSwitchId string
|
||||
VSwitchName string
|
||||
Description string
|
||||
}
|
||||
|
||||
type ModifyVSwitchAttributeResponse struct {
|
||||
common.Response
|
||||
}
|
||||
|
||||
// ModifyVSwitchAttribute modifies attribute of Virtual Private Cloud
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/vswitch&modifyvswitchattribute
|
||||
func (client *Client) ModifyVSwitchAttribute(args *ModifyVSwitchAttributeArgs) error {
|
||||
response := ModifyVSwitchAttributeResponse{}
|
||||
return client.Invoke("ModifyVSwitchAttribute", args, &response)
|
||||
}
|
||||
|
||||
// WaitForVSwitchAvailable waits for VSwitch to given status
|
||||
func (client *Client) WaitForVSwitchAvailable(vpcId string, vswitchId string, timeout int) error {
|
||||
if timeout <= 0 {
|
||||
timeout = DefaultTimeout
|
||||
}
|
||||
args := DescribeVSwitchesArgs{
|
||||
VpcId: vpcId,
|
||||
VSwitchId: vswitchId,
|
||||
}
|
||||
for {
|
||||
vswitches, _, err := client.DescribeVSwitches(&args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(vswitches) == 0 {
|
||||
return common.GetClientErrorFromString("Not found")
|
||||
}
|
||||
if vswitches[0].Status == VSwitchStatusAvailable {
|
||||
break
|
||||
}
|
||||
timeout = timeout - DefaultWaitForInterval
|
||||
if timeout <= 0 {
|
||||
return common.GetClientErrorFromString("Timeout")
|
||||
}
|
||||
time.Sleep(DefaultWaitForInterval * time.Second)
|
||||
}
|
||||
return nil
|
||||
}
|
103
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/zones.go
generated
vendored
Normal file
103
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/ecs/zones.go
generated
vendored
Normal file
|
@ -0,0 +1,103 @@
|
|||
package ecs
|
||||
|
||||
import "github.com/denverdino/aliyungo/common"
|
||||
|
||||
type ResourceType string
|
||||
|
||||
const (
|
||||
ResourceTypeInstance = ResourceType("Instance")
|
||||
ResourceTypeDisk = ResourceType("Disk")
|
||||
ResourceTypeVSwitch = ResourceType("VSwitch")
|
||||
ResourceTypeIOOptimizedInstance = ResourceType("IoOptimized")
|
||||
)
|
||||
|
||||
// The sub-item of the type AvailableResourcesType
|
||||
type SupportedResourceType string
|
||||
|
||||
const (
|
||||
SupportedInstanceType = SupportedResourceType("supportedInstanceType")
|
||||
SupportedInstanceTypeFamily = SupportedResourceType("supportedInstanceTypeFamily")
|
||||
SupportedInstanceGeneration = SupportedResourceType("supportedInstanceGeneration")
|
||||
SupportedSystemDiskCategory = SupportedResourceType("supportedSystemDiskCategory")
|
||||
SupportedDataDiskCategory = SupportedResourceType("supportedDataDiskCategory")
|
||||
SupportedNetworkCategory = SupportedResourceType("supportedNetworkCategory")
|
||||
|
||||
)
|
||||
//
|
||||
// You can read doc at https://help.aliyun.com/document_detail/25670.html?spm=5176.doc25640.2.1.J24zQt
|
||||
type ResourcesInfoType struct {
|
||||
ResourcesInfo []AvailableResourcesType
|
||||
}
|
||||
// Because the sub-item of AvailableResourcesType starts with supported and golang struct cann't refer them, this uses map to parse ResourcesInfo
|
||||
type AvailableResourcesType struct {
|
||||
IoOptimized bool
|
||||
NetworkTypes map[SupportedResourceType][]string
|
||||
InstanceGenerations map[SupportedResourceType][]string
|
||||
InstanceTypeFamilies map[SupportedResourceType][]string
|
||||
InstanceTypes map[SupportedResourceType][]string
|
||||
SystemDiskCategories map[SupportedResourceType][]DiskCategory
|
||||
DataDiskCategories map[SupportedResourceType][]DiskCategory
|
||||
}
|
||||
|
||||
type DescribeZonesArgs struct {
|
||||
RegionId common.Region
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&availableresourcecreationtype
|
||||
type AvailableResourceCreationType struct {
|
||||
ResourceTypes []ResourceType //enum for Instance, Disk, VSwitch
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&availablediskcategoriestype
|
||||
type AvailableDiskCategoriesType struct {
|
||||
DiskCategories []DiskCategory //enum for cloud, ephemeral, ephemeral_ssd
|
||||
}
|
||||
|
||||
type AvailableInstanceTypesType struct {
|
||||
InstanceTypes []string
|
||||
}
|
||||
|
||||
//
|
||||
// You can read doc at http://docs.aliyun.com/#/pub/ecs/open-api/datatype&zonetype
|
||||
type ZoneType struct {
|
||||
ZoneId string
|
||||
LocalName string
|
||||
AvailableResources ResourcesInfoType
|
||||
AvailableInstanceTypes AvailableInstanceTypesType
|
||||
AvailableResourceCreation AvailableResourceCreationType
|
||||
AvailableDiskCategories AvailableDiskCategoriesType
|
||||
}
|
||||
|
||||
type DescribeZonesResponse struct {
|
||||
common.Response
|
||||
Zones struct {
|
||||
Zone []ZoneType
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeZones describes zones
|
||||
func (client *Client) DescribeZones(regionId common.Region) (zones []ZoneType, err error) {
|
||||
response, err := client.DescribeZonesWithRaw(regionId)
|
||||
if err == nil {
|
||||
return response.Zones.Zone, nil
|
||||
}
|
||||
|
||||
return []ZoneType{}, err
|
||||
}
|
||||
|
||||
func (client *Client) DescribeZonesWithRaw(regionId common.Region) (response *DescribeZonesResponse, err error) {
|
||||
args := DescribeZonesArgs{
|
||||
RegionId: regionId,
|
||||
}
|
||||
response = &DescribeZonesResponse{}
|
||||
|
||||
err = client.Invoke("DescribeZones", &args, response)
|
||||
|
||||
if err == nil {
|
||||
return response, nil
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
76
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/util/attempt.go
generated
vendored
Normal file
76
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/util/attempt.go
generated
vendored
Normal file
|
@ -0,0 +1,76 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// AttemptStrategy is reused from the goamz package
|
||||
|
||||
// AttemptStrategy represents a strategy for waiting for an action
|
||||
// to complete successfully. This is an internal type used by the
|
||||
// implementation of other packages.
|
||||
type AttemptStrategy struct {
|
||||
Total time.Duration // total duration of attempt.
|
||||
Delay time.Duration // interval between each try in the burst.
|
||||
Min int // minimum number of retries; overrides Total
|
||||
}
|
||||
|
||||
type Attempt struct {
|
||||
strategy AttemptStrategy
|
||||
last time.Time
|
||||
end time.Time
|
||||
force bool
|
||||
count int
|
||||
}
|
||||
|
||||
// Start begins a new sequence of attempts for the given strategy.
|
||||
func (s AttemptStrategy) Start() *Attempt {
|
||||
now := time.Now()
|
||||
return &Attempt{
|
||||
strategy: s,
|
||||
last: now,
|
||||
end: now.Add(s.Total),
|
||||
force: true,
|
||||
}
|
||||
}
|
||||
|
||||
// Next waits until it is time to perform the next attempt or returns
|
||||
// false if it is time to stop trying.
|
||||
func (a *Attempt) Next() bool {
|
||||
now := time.Now()
|
||||
sleep := a.nextSleep(now)
|
||||
if !a.force && !now.Add(sleep).Before(a.end) && a.strategy.Min <= a.count {
|
||||
return false
|
||||
}
|
||||
a.force = false
|
||||
if sleep > 0 && a.count > 0 {
|
||||
time.Sleep(sleep)
|
||||
now = time.Now()
|
||||
}
|
||||
a.count++
|
||||
a.last = now
|
||||
return true
|
||||
}
|
||||
|
||||
func (a *Attempt) nextSleep(now time.Time) time.Duration {
|
||||
sleep := a.strategy.Delay - now.Sub(a.last)
|
||||
if sleep < 0 {
|
||||
return 0
|
||||
}
|
||||
return sleep
|
||||
}
|
||||
|
||||
// HasNext returns whether another attempt will be made if the current
|
||||
// one fails. If it returns true, the following call to Next is
|
||||
// guaranteed to return true.
|
||||
func (a *Attempt) HasNext() bool {
|
||||
if a.force || a.strategy.Min > a.count {
|
||||
return true
|
||||
}
|
||||
now := time.Now()
|
||||
if now.Add(a.nextSleep(now)).Before(a.end) {
|
||||
a.force = true
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
314
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/util/encoding.go
generated
vendored
Normal file
314
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/util/encoding.go
generated
vendored
Normal file
|
@ -0,0 +1,314 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// change instance=["a", "b"]
|
||||
// to instance.1="a" instance.2="b"
|
||||
func FlattenFn(fieldName string, field reflect.Value, values *url.Values) {
|
||||
l := field.Len()
|
||||
if l > 0 {
|
||||
for i := 0; i < l; i++ {
|
||||
str := field.Index(i).String()
|
||||
values.Set(fieldName+"."+strconv.Itoa(i+1), str)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Underline2Dot(name string) string {
|
||||
return strings.Replace(name, "_", ".", -1)
|
||||
}
|
||||
|
||||
//ConvertToQueryValues converts the struct to url.Values
|
||||
func ConvertToQueryValues(ifc interface{}) url.Values {
|
||||
values := url.Values{}
|
||||
SetQueryValues(ifc, &values)
|
||||
return values
|
||||
}
|
||||
|
||||
//SetQueryValues sets the struct to existing url.Values following ECS encoding rules
|
||||
func SetQueryValues(ifc interface{}, values *url.Values) {
|
||||
setQueryValues(ifc, values, "")
|
||||
}
|
||||
|
||||
func SetQueryValueByFlattenMethod(ifc interface{}, values *url.Values) {
|
||||
setQueryValuesByFlattenMethod(ifc, values, "")
|
||||
}
|
||||
|
||||
func setQueryValues(i interface{}, values *url.Values, prefix string) {
|
||||
// add to support url.Values
|
||||
mapValues, ok := i.(url.Values)
|
||||
if ok {
|
||||
for k, _ := range mapValues {
|
||||
values.Set(k, mapValues.Get(k))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
elem := reflect.ValueOf(i)
|
||||
if elem.Kind() == reflect.Ptr {
|
||||
elem = elem.Elem()
|
||||
}
|
||||
elemType := elem.Type()
|
||||
for i := 0; i < elem.NumField(); i++ {
|
||||
|
||||
fieldName := elemType.Field(i).Name
|
||||
anonymous := elemType.Field(i).Anonymous
|
||||
field := elem.Field(i)
|
||||
// TODO Use Tag for validation
|
||||
// tag := typ.Field(i).Tag.Get("tagname")
|
||||
kind := field.Kind()
|
||||
if (kind == reflect.Ptr || kind == reflect.Array || kind == reflect.Slice || kind == reflect.Map || kind == reflect.Chan) && field.IsNil() {
|
||||
continue
|
||||
}
|
||||
if kind == reflect.Ptr {
|
||||
field = field.Elem()
|
||||
kind = field.Kind()
|
||||
}
|
||||
var value string
|
||||
//switch field.Interface().(type) {
|
||||
switch kind {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
i := field.Int()
|
||||
if i != 0 {
|
||||
value = strconv.FormatInt(i, 10)
|
||||
}
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
i := field.Uint()
|
||||
if i != 0 {
|
||||
value = strconv.FormatUint(i, 10)
|
||||
}
|
||||
case reflect.Float32:
|
||||
value = strconv.FormatFloat(field.Float(), 'f', 4, 32)
|
||||
case reflect.Float64:
|
||||
value = strconv.FormatFloat(field.Float(), 'f', 4, 64)
|
||||
case reflect.Bool:
|
||||
value = strconv.FormatBool(field.Bool())
|
||||
case reflect.String:
|
||||
value = field.String()
|
||||
case reflect.Map:
|
||||
ifc := field.Interface()
|
||||
m := ifc.(map[string]string)
|
||||
if m != nil {
|
||||
j := 0
|
||||
for k, v := range m {
|
||||
j++
|
||||
keyName := fmt.Sprintf("%s.%d.Key", fieldName, j)
|
||||
values.Set(keyName, k)
|
||||
valueName := fmt.Sprintf("%s.%d.Value", fieldName, j)
|
||||
values.Set(valueName, v)
|
||||
}
|
||||
}
|
||||
case reflect.Slice:
|
||||
switch field.Type().Elem().Kind() {
|
||||
case reflect.Uint8:
|
||||
value = string(field.Bytes())
|
||||
case reflect.String:
|
||||
l := field.Len()
|
||||
if l > 0 {
|
||||
strArray := make([]string, l)
|
||||
for i := 0; i < l; i++ {
|
||||
strArray[i] = field.Index(i).String()
|
||||
}
|
||||
bytes, err := json.Marshal(strArray)
|
||||
if err == nil {
|
||||
value = string(bytes)
|
||||
} else {
|
||||
log.Printf("Failed to convert JSON: %v", err)
|
||||
}
|
||||
}
|
||||
default:
|
||||
l := field.Len()
|
||||
for j := 0; j < l; j++ {
|
||||
prefixName := fmt.Sprintf("%s.%d.", fieldName, (j + 1))
|
||||
ifc := field.Index(j).Interface()
|
||||
//log.Printf("%s : %v", prefixName, ifc)
|
||||
if ifc != nil {
|
||||
setQueryValues(ifc, values, prefixName)
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
default:
|
||||
switch field.Interface().(type) {
|
||||
case ISO6801Time:
|
||||
t := field.Interface().(ISO6801Time)
|
||||
value = t.String()
|
||||
case time.Time:
|
||||
t := field.Interface().(time.Time)
|
||||
value = GetISO8601TimeStamp(t)
|
||||
default:
|
||||
ifc := field.Interface()
|
||||
if ifc != nil {
|
||||
if anonymous {
|
||||
SetQueryValues(ifc, values)
|
||||
} else {
|
||||
prefixName := fieldName + "."
|
||||
setQueryValues(ifc, values, prefixName)
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
if value != "" {
|
||||
name := elemType.Field(i).Tag.Get("ArgName")
|
||||
if name == "" {
|
||||
name = fieldName
|
||||
}
|
||||
if prefix != "" {
|
||||
name = prefix + name
|
||||
}
|
||||
values.Set(name, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setQueryValuesByFlattenMethod(i interface{}, values *url.Values, prefix string) {
|
||||
// add to support url.Values
|
||||
mapValues, ok := i.(url.Values)
|
||||
if ok {
|
||||
for k, _ := range mapValues {
|
||||
values.Set(k, mapValues.Get(k))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
elem := reflect.ValueOf(i)
|
||||
if elem.Kind() == reflect.Ptr {
|
||||
elem = elem.Elem()
|
||||
}
|
||||
elemType := elem.Type()
|
||||
for i := 0; i < elem.NumField(); i++ {
|
||||
|
||||
fieldName := elemType.Field(i).Name
|
||||
anonymous := elemType.Field(i).Anonymous
|
||||
field := elem.Field(i)
|
||||
|
||||
// TODO Use Tag for validation
|
||||
// tag := typ.Field(i).Tag.Get("tagname")
|
||||
kind := field.Kind()
|
||||
|
||||
if (kind == reflect.Ptr || kind == reflect.Array || kind == reflect.Slice || kind == reflect.Map || kind == reflect.Chan) && field.IsNil() {
|
||||
continue
|
||||
}
|
||||
if kind == reflect.Ptr {
|
||||
field = field.Elem()
|
||||
kind = field.Kind()
|
||||
}
|
||||
|
||||
var value string
|
||||
//switch field.Interface().(type) {
|
||||
switch kind {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
i := field.Int()
|
||||
if i != 0 {
|
||||
value = strconv.FormatInt(i, 10)
|
||||
}
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
i := field.Uint()
|
||||
if i != 0 {
|
||||
value = strconv.FormatUint(i, 10)
|
||||
}
|
||||
case reflect.Float32:
|
||||
value = strconv.FormatFloat(field.Float(), 'f', 4, 32)
|
||||
case reflect.Float64:
|
||||
value = strconv.FormatFloat(field.Float(), 'f', 4, 64)
|
||||
case reflect.Bool:
|
||||
value = strconv.FormatBool(field.Bool())
|
||||
case reflect.String:
|
||||
value = field.String()
|
||||
case reflect.Map:
|
||||
ifc := field.Interface()
|
||||
m := ifc.(map[string]string)
|
||||
if m != nil {
|
||||
j := 0
|
||||
for k, v := range m {
|
||||
j++
|
||||
keyName := fmt.Sprintf("%s.%d.Key", fieldName, j)
|
||||
values.Set(keyName, k)
|
||||
valueName := fmt.Sprintf("%s.%d.Value", fieldName, j)
|
||||
values.Set(valueName, v)
|
||||
}
|
||||
}
|
||||
case reflect.Slice:
|
||||
if field.Type().Name() == "FlattenArray" {
|
||||
FlattenFn(fieldName, field, values)
|
||||
} else {
|
||||
switch field.Type().Elem().Kind() {
|
||||
case reflect.Uint8:
|
||||
value = string(field.Bytes())
|
||||
case reflect.String:
|
||||
l := field.Len()
|
||||
if l > 0 {
|
||||
strArray := make([]string, l)
|
||||
for i := 0; i < l; i++ {
|
||||
strArray[i] = field.Index(i).String()
|
||||
}
|
||||
bytes, err := json.Marshal(strArray)
|
||||
if err == nil {
|
||||
value = string(bytes)
|
||||
} else {
|
||||
log.Printf("Failed to convert JSON: %v", err)
|
||||
}
|
||||
}
|
||||
default:
|
||||
l := field.Len()
|
||||
for j := 0; j < l; j++ {
|
||||
prefixName := fmt.Sprintf("%s.%d.", fieldName, (j + 1))
|
||||
ifc := field.Index(j).Interface()
|
||||
//log.Printf("%s : %v", prefixName, ifc)
|
||||
if ifc != nil {
|
||||
setQueryValuesByFlattenMethod(ifc, values, prefixName)
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
switch field.Interface().(type) {
|
||||
case ISO6801Time:
|
||||
t := field.Interface().(ISO6801Time)
|
||||
value = t.String()
|
||||
case time.Time:
|
||||
t := field.Interface().(time.Time)
|
||||
value = GetISO8601TimeStamp(t)
|
||||
default:
|
||||
|
||||
ifc := field.Interface()
|
||||
if ifc != nil {
|
||||
if anonymous {
|
||||
SetQueryValues(ifc, values)
|
||||
} else {
|
||||
prefixName := fieldName + "."
|
||||
setQueryValuesByFlattenMethod(ifc, values, prefixName)
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
if value != "" {
|
||||
name := elemType.Field(i).Tag.Get("ArgName")
|
||||
if name == "" {
|
||||
name = fieldName
|
||||
}
|
||||
if prefix != "" {
|
||||
name = prefix + name
|
||||
}
|
||||
// NOTE: here we will change name to underline style when the type is UnderlineString
|
||||
if field.Type().Name() == "UnderlineString" {
|
||||
name = Underline2Dot(name)
|
||||
}
|
||||
values.Set(name, value)
|
||||
}
|
||||
}
|
||||
}
|
80
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/util/iso6801.go
generated
vendored
Normal file
80
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/util/iso6801.go
generated
vendored
Normal file
|
@ -0,0 +1,80 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// GetISO8601TimeStamp gets timestamp string in ISO8601 format
|
||||
func GetISO8601TimeStamp(ts time.Time) string {
|
||||
t := ts.UTC()
|
||||
return fmt.Sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ", t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second())
|
||||
}
|
||||
|
||||
const formatISO8601 = "2006-01-02T15:04:05Z"
|
||||
const jsonFormatISO8601 = `"` + formatISO8601 + `"`
|
||||
const formatISO8601withoutSeconds = "2006-01-02T15:04Z"
|
||||
const jsonFormatISO8601withoutSeconds = `"` + formatISO8601withoutSeconds + `"`
|
||||
|
||||
// A ISO6801Time represents a time in ISO8601 format
|
||||
type ISO6801Time time.Time
|
||||
|
||||
// New constructs a new iso8601.Time instance from an existing
|
||||
// time.Time instance. This causes the nanosecond field to be set to
|
||||
// 0, and its time zone set to a fixed zone with no offset from UTC
|
||||
// (but it is *not* UTC itself).
|
||||
func NewISO6801Time(t time.Time) ISO6801Time {
|
||||
return ISO6801Time(time.Date(
|
||||
t.Year(),
|
||||
t.Month(),
|
||||
t.Day(),
|
||||
t.Hour(),
|
||||
t.Minute(),
|
||||
t.Second(),
|
||||
0,
|
||||
time.UTC,
|
||||
))
|
||||
}
|
||||
|
||||
// IsDefault checks if the time is default
|
||||
func (it *ISO6801Time) IsDefault() bool {
|
||||
return *it == ISO6801Time{}
|
||||
}
|
||||
|
||||
// MarshalJSON serializes the ISO6801Time into JSON string
|
||||
func (it ISO6801Time) MarshalJSON() ([]byte, error) {
|
||||
return []byte(time.Time(it).Format(jsonFormatISO8601)), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON deserializes the ISO6801Time from JSON string
|
||||
func (it *ISO6801Time) UnmarshalJSON(data []byte) error {
|
||||
str := string(data)
|
||||
|
||||
if str == "\"\"" || len(data) == 0 {
|
||||
return nil
|
||||
}
|
||||
var t time.Time
|
||||
var err error
|
||||
if str[0] == '"' {
|
||||
t, err = time.ParseInLocation(jsonFormatISO8601, str, time.UTC)
|
||||
if err != nil {
|
||||
t, err = time.ParseInLocation(jsonFormatISO8601withoutSeconds, str, time.UTC)
|
||||
}
|
||||
} else {
|
||||
var i int64
|
||||
i, err = strconv.ParseInt(str, 10, 64)
|
||||
if err == nil {
|
||||
t = time.Unix(i/1000, i%1000)
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
*it = ISO6801Time(t)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// String returns the time in ISO6801Time format
|
||||
func (it ISO6801Time) String() string {
|
||||
return time.Time(it).Format(formatISO8601)
|
||||
}
|
40
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/util/signature.go
generated
vendored
Normal file
40
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/util/signature.go
generated
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha1"
|
||||
"encoding/base64"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//CreateSignature creates signature for string following Aliyun rules
|
||||
func CreateSignature(stringToSignature, accessKeySecret string) string {
|
||||
// Crypto by HMAC-SHA1
|
||||
hmacSha1 := hmac.New(sha1.New, []byte(accessKeySecret))
|
||||
hmacSha1.Write([]byte(stringToSignature))
|
||||
sign := hmacSha1.Sum(nil)
|
||||
|
||||
// Encode to Base64
|
||||
base64Sign := base64.StdEncoding.EncodeToString(sign)
|
||||
|
||||
return base64Sign
|
||||
}
|
||||
|
||||
func percentReplace(str string) string {
|
||||
str = strings.Replace(str, "+", "%20", -1)
|
||||
str = strings.Replace(str, "*", "%2A", -1)
|
||||
str = strings.Replace(str, "%7E", "~", -1)
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
// CreateSignatureForRequest creates signature for query string values
|
||||
func CreateSignatureForRequest(method string, values *url.Values, accessKeySecret string) string {
|
||||
|
||||
canonicalizedQueryString := percentReplace(values.Encode())
|
||||
|
||||
stringToSign := method + "&%2F&" + url.QueryEscape(canonicalizedQueryString)
|
||||
|
||||
return CreateSignature(stringToSign, accessKeySecret)
|
||||
}
|
147
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/util/util.go
generated
vendored
Normal file
147
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/github.com/denverdino/aliyungo/util/util.go
generated
vendored
Normal file
|
@ -0,0 +1,147 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
srand "crypto/rand"
|
||||
"encoding/binary"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
|
||||
const dictionary = "_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
|
||||
//CreateRandomString create random string
|
||||
func CreateRandomString() string {
|
||||
b := make([]byte, 32)
|
||||
l := len(dictionary)
|
||||
|
||||
_, err := srand.Read(b)
|
||||
|
||||
if err != nil {
|
||||
// fail back to insecure rand
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
for i := range b {
|
||||
b[i] = dictionary[rand.Int()%l]
|
||||
}
|
||||
} else {
|
||||
for i, v := range b {
|
||||
b[i] = dictionary[v%byte(l)]
|
||||
}
|
||||
}
|
||||
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// Encode encodes the values into ``URL encoded'' form
|
||||
// ("acl&bar=baz&foo=quux") sorted by key.
|
||||
func Encode(v url.Values) string {
|
||||
if v == nil {
|
||||
return ""
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
keys := make([]string, 0, len(v))
|
||||
for k := range v {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, k := range keys {
|
||||
vs := v[k]
|
||||
prefix := url.QueryEscape(k)
|
||||
for _, v := range vs {
|
||||
if buf.Len() > 0 {
|
||||
buf.WriteByte('&')
|
||||
}
|
||||
buf.WriteString(prefix)
|
||||
if v != "" {
|
||||
buf.WriteString("=")
|
||||
buf.WriteString(url.QueryEscape(v))
|
||||
}
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func GetGMTime() string {
|
||||
return time.Now().UTC().Format(http.TimeFormat)
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
func randUint32() uint32 {
|
||||
return randUint32Slice(1)[0]
|
||||
}
|
||||
|
||||
func randUint32Slice(c int) []uint32 {
|
||||
b := make([]byte, c*4)
|
||||
|
||||
_, err := srand.Read(b)
|
||||
|
||||
if err != nil {
|
||||
// fail back to insecure rand
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
for i := range b {
|
||||
b[i] = byte(rand.Int())
|
||||
}
|
||||
}
|
||||
|
||||
n := make([]uint32, c)
|
||||
|
||||
for i := range n {
|
||||
n[i] = binary.BigEndian.Uint32(b[i*4 : i*4+4])
|
||||
}
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
func toByte(n uint32, st, ed byte) byte {
|
||||
return byte(n%uint32(ed-st+1) + uint32(st))
|
||||
}
|
||||
|
||||
func toDigit(n uint32) byte {
|
||||
return toByte(n, '0', '9')
|
||||
}
|
||||
|
||||
func toLowerLetter(n uint32) byte {
|
||||
return toByte(n, 'a', 'z')
|
||||
}
|
||||
|
||||
func toUpperLetter(n uint32) byte {
|
||||
return toByte(n, 'A', 'Z')
|
||||
}
|
||||
|
||||
type convFunc func(uint32) byte
|
||||
|
||||
var convFuncs = []convFunc{toDigit, toLowerLetter, toUpperLetter}
|
||||
|
||||
// tools for generating a random ECS instance password
|
||||
// from 8 to 30 char MUST contain digit upper, case letter and upper case letter
|
||||
// http://docs.aliyun.com/#/pub/ecs/open-api/instance&createinstance
|
||||
func GenerateRandomECSPassword() string {
|
||||
|
||||
// [8, 30]
|
||||
l := int(randUint32()%23 + 8)
|
||||
|
||||
n := randUint32Slice(l)
|
||||
|
||||
b := make([]byte, l)
|
||||
|
||||
b[0] = toDigit(n[0])
|
||||
b[1] = toLowerLetter(n[1])
|
||||
b[2] = toUpperLetter(n[2])
|
||||
|
||||
for i := 3; i < l; i++ {
|
||||
b[i] = convFuncs[n[i]%3](n[i])
|
||||
}
|
||||
|
||||
s := make([]byte, l)
|
||||
perm := rand.Perm(l)
|
||||
for i, v := range perm {
|
||||
s[v] = b[i]
|
||||
}
|
||||
|
||||
return string(s)
|
||||
|
||||
}
|
8
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/vendor.json
generated
vendored
Normal file
8
vendor/github.com/hashicorp/go-discover/provider/aliyun/vendor/vendor.json
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"comment": "",
|
||||
"ignore": "test",
|
||||
"package": [
|
||||
{"path":"github.com/denverdino/aliyungo","checksumSHA1":"oZQsGuJDCBW6OoQBgEo6sOfkmi4=","revision":"d3308649c66113b99e257dd5c92fbfdd779380c3","revisionTime":"2017-09-26T05:51:00Z"}
|
||||
],
|
||||
"rootPath": "github.com/hashicorp/go-discover/provider/aliyun"
|
||||
}
|
112
vendor/github.com/hashicorp/go-discover/provider/digitalocean/digitalocean_discover.go
generated
vendored
Normal file
112
vendor/github.com/hashicorp/go-discover/provider/digitalocean/digitalocean_discover.go
generated
vendored
Normal file
|
@ -0,0 +1,112 @@
|
|||
// Package digitalocean provides node discovery for DigitalOcean.
|
||||
package digitalocean
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
|
||||
"github.com/digitalocean/godo"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
type Provider struct{}
|
||||
|
||||
func (p *Provider) Help() string {
|
||||
return `DigitalOcean:
|
||||
|
||||
provider: "digitalocean"
|
||||
region: The DigitalOcean region to filter on
|
||||
tag_name: The tag name to filter on
|
||||
api_token: The DigitalOcean API token to use
|
||||
`
|
||||
}
|
||||
|
||||
type TokenSource struct {
|
||||
AccessToken string
|
||||
}
|
||||
|
||||
func (t *TokenSource) Token() (*oauth2.Token, error) {
|
||||
token := &oauth2.Token{
|
||||
AccessToken: t.AccessToken,
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func listDropletsByTag(c *godo.Client, tagName string) ([]godo.Droplet, error) {
|
||||
dropletList := []godo.Droplet{}
|
||||
pageOpt := &godo.ListOptions{
|
||||
Page: 1,
|
||||
PerPage: 200,
|
||||
}
|
||||
|
||||
for {
|
||||
droplets, resp, err := c.Droplets.ListByTag(context.TODO(), tagName, pageOpt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, d := range droplets {
|
||||
dropletList = append(dropletList, d)
|
||||
}
|
||||
|
||||
if resp.Links == nil || resp.Links.IsLastPage() {
|
||||
break
|
||||
}
|
||||
|
||||
page, err := resp.Links.CurrentPage()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pageOpt.Page = page + 1
|
||||
}
|
||||
|
||||
return dropletList, nil
|
||||
}
|
||||
|
||||
func (p *Provider) Addrs(args map[string]string, l *log.Logger) ([]string, error) {
|
||||
if args["provider"] != "digitalocean" {
|
||||
return nil, fmt.Errorf("discover-digitalocean: invalid provider " + args["provider"])
|
||||
}
|
||||
|
||||
if l == nil {
|
||||
l = log.New(ioutil.Discard, "", 0)
|
||||
}
|
||||
|
||||
region := args["region"]
|
||||
tagName := args["tag_name"]
|
||||
apiToken := args["api_token"]
|
||||
l.Printf("[DEBUG] discover-digitalocean: Using region=%s tag_name=%s", region, tagName)
|
||||
|
||||
tokenSource := &TokenSource{
|
||||
AccessToken: apiToken,
|
||||
}
|
||||
|
||||
oauthClient := oauth2.NewClient(context.TODO(), tokenSource)
|
||||
client := godo.NewClient(oauthClient)
|
||||
|
||||
droplets, err := listDropletsByTag(client, tagName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("discover-digitalocean: %s", err)
|
||||
}
|
||||
|
||||
var addrs []string
|
||||
for _, d := range droplets {
|
||||
if d.Region.Slug == region || region == "" {
|
||||
privateIP, err := d.PrivateIPv4()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("discover-digitalocean: %s", err)
|
||||
}
|
||||
|
||||
if privateIP != "" {
|
||||
l.Printf("[INFO] discover-digitalocean: Found instance %s (%d) with private IP: %s", d.Name, d.ID, privateIP)
|
||||
addrs = append(addrs, privateIP)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
l.Printf("[DEBUG] discover-digitalocean: Found ip addresses: %v", addrs)
|
||||
return addrs, nil
|
||||
}
|
20
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/CHANGELOG.md
generated
vendored
Normal file
20
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/CHANGELOG.md
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
# Change Log
|
||||
|
||||
## [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
|
||||
- #122 Add GetVolumeByName to StorageService. - @protochron
|
||||
- #113 Add context.Context to all calls. - @aybabtme
|
23
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/CONTRIBUTING.md
generated
vendored
Normal file
23
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/CONTRIBUTING.md
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Contributing
|
||||
|
||||
If you submit a pull request, please keep the following guidelines in mind:
|
||||
|
||||
1. Code should be `go fmt` compliant.
|
||||
2. Types, structs and funcs should be documented.
|
||||
3. Tests pass.
|
||||
|
||||
## Getting set up
|
||||
|
||||
Assuming your `$GOPATH` is set up according to your desires, run:
|
||||
|
||||
```sh
|
||||
go get github.com/digitalocean/godo
|
||||
```
|
||||
|
||||
## Running tests
|
||||
|
||||
When working on code in this repository, tests can be run via:
|
||||
|
||||
```sh
|
||||
go test .
|
||||
```
|
55
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/LICENSE.txt
generated
vendored
Normal file
55
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/LICENSE.txt
generated
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
Copyright (c) 2014-2016 The godo AUTHORS. All rights reserved.
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
======================
|
||||
Portions of the client are based on code at:
|
||||
https://github.com/google/go-github/
|
||||
|
||||
Copyright (c) 2013 The go-github AUTHORS. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
138
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/README.md
generated
vendored
Normal file
138
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/README.md
generated
vendored
Normal file
|
@ -0,0 +1,138 @@
|
|||
[![Build Status](https://travis-ci.org/digitalocean/godo.svg)](https://travis-ci.org/digitalocean/godo)
|
||||
|
||||
# Godo
|
||||
|
||||
Godo is a Go client library for accessing the DigitalOcean V2 API.
|
||||
|
||||
You can view the client API docs here: [http://godoc.org/github.com/digitalocean/godo](http://godoc.org/github.com/digitalocean/godo)
|
||||
|
||||
You can view DigitalOcean API docs here: [https://developers.digitalocean.com/documentation/v2/](https://developers.digitalocean.com/documentation/v2/)
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
import "github.com/digitalocean/godo"
|
||||
```
|
||||
|
||||
Create a new DigitalOcean client, then use the exposed services to
|
||||
access different parts of the DigitalOcean API.
|
||||
|
||||
### Authentication
|
||||
|
||||
Currently, Personal Access Token (PAT) is the only method of
|
||||
authenticating with the API. You can manage your tokens
|
||||
at the DigitalOcean Control Panel [Applications Page](https://cloud.digitalocean.com/settings/applications).
|
||||
|
||||
You can then use your token to create a new client:
|
||||
|
||||
```go
|
||||
import "golang.org/x/oauth2"
|
||||
|
||||
pat := "mytoken"
|
||||
type TokenSource struct {
|
||||
AccessToken string
|
||||
}
|
||||
|
||||
func (t *TokenSource) Token() (*oauth2.Token, error) {
|
||||
token := &oauth2.Token{
|
||||
AccessToken: t.AccessToken,
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
|
||||
tokenSource := &TokenSource{
|
||||
AccessToken: pat,
|
||||
}
|
||||
oauthClient := oauth2.NewClient(context.Background(), tokenSource)
|
||||
client := godo.NewClient(oauthClient)
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
|
||||
To create a new Droplet:
|
||||
|
||||
```go
|
||||
dropletName := "super-cool-droplet"
|
||||
|
||||
createRequest := &godo.DropletCreateRequest{
|
||||
Name: dropletName,
|
||||
Region: "nyc3",
|
||||
Size: "512mb",
|
||||
Image: godo.DropletCreateImage{
|
||||
Slug: "ubuntu-14-04-x64",
|
||||
},
|
||||
}
|
||||
|
||||
ctx := context.TODO()
|
||||
|
||||
newDroplet, _, err := client.Droplets.Create(ctx, createRequest)
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("Something bad happened: %s\n\n", err)
|
||||
return err
|
||||
}
|
||||
```
|
||||
|
||||
### Pagination
|
||||
|
||||
If a list of items is paginated by the API, you must request pages individually. For example, to fetch all Droplets:
|
||||
|
||||
```go
|
||||
func DropletList(ctx context.Context, client *godo.Client) ([]godo.Droplet, error) {
|
||||
// create a list to hold our droplets
|
||||
list := []godo.Droplet{}
|
||||
|
||||
// create options. initially, these will be blank
|
||||
opt := &godo.ListOptions{}
|
||||
for {
|
||||
droplets, resp, err := client.Droplets.List(ctx, opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// append the current page's droplets to our list
|
||||
for _, d := range droplets {
|
||||
list = append(list, d)
|
||||
}
|
||||
|
||||
// if we are at the last page, break out the for loop
|
||||
if resp.Links == nil || resp.Links.IsLastPage() {
|
||||
break
|
||||
}
|
||||
|
||||
page, err := resp.Links.CurrentPage()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// set the page we want for the next request
|
||||
opt.Page = page + 1
|
||||
}
|
||||
|
||||
return list, nil
|
||||
}
|
||||
```
|
||||
|
||||
## Versioning
|
||||
|
||||
Each version of the client is tagged and the version is updated accordingly.
|
||||
|
||||
Since Go does not have a built-in versioning, a package management tool is
|
||||
recommended - a good one that works with git tags is
|
||||
[gopkg.in](http://labix.org/gopkg.in).
|
||||
|
||||
To see the list of past versions, run `git tag`.
|
||||
|
||||
|
||||
## Documentation
|
||||
|
||||
For a comprehensive list of examples, check out the [API documentation](https://developers.digitalocean.com/documentation/v2/).
|
||||
|
||||
For details on all the functionality in this library, see the [GoDoc](http://godoc.org/github.com/digitalocean/godo) documentation.
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
We love pull requests! Please see the [contribution guidelines](CONTRIBUTING.md).
|
60
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/account.go
generated
vendored
Normal file
60
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/account.go
generated
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
package godo
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/digitalocean/godo/context"
|
||||
)
|
||||
|
||||
// AccountService is an interface for interfacing with the Account
|
||||
// endpoints of the DigitalOcean API
|
||||
// See: https://developers.digitalocean.com/documentation/v2/#account
|
||||
type AccountService interface {
|
||||
Get(context.Context) (*Account, *Response, error)
|
||||
}
|
||||
|
||||
// AccountServiceOp handles communication with the Account related methods of
|
||||
// the DigitalOcean API.
|
||||
type AccountServiceOp struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
var _ AccountService = &AccountServiceOp{}
|
||||
|
||||
// Account represents a DigitalOcean Account
|
||||
type Account struct {
|
||||
DropletLimit int `json:"droplet_limit,omitempty"`
|
||||
FloatingIPLimit int `json:"floating_ip_limit,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
UUID string `json:"uuid,omitempty"`
|
||||
EmailVerified bool `json:"email_verified,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
StatusMessage string `json:"status_message,omitempty"`
|
||||
}
|
||||
|
||||
type accountRoot struct {
|
||||
Account *Account `json:"account"`
|
||||
}
|
||||
|
||||
func (r Account) String() string {
|
||||
return Stringify(r)
|
||||
}
|
||||
|
||||
// Get DigitalOcean account info
|
||||
func (s *AccountServiceOp) Get(ctx context.Context) (*Account, *Response, error) {
|
||||
|
||||
path := "v2/account"
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(accountRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Account, resp, err
|
||||
}
|
105
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/action.go
generated
vendored
Normal file
105
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/action.go
generated
vendored
Normal file
|
@ -0,0 +1,105 @@
|
|||
package godo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/digitalocean/godo/context"
|
||||
)
|
||||
|
||||
const (
|
||||
actionsBasePath = "v2/actions"
|
||||
|
||||
// ActionInProgress is an in progress action status
|
||||
ActionInProgress = "in-progress"
|
||||
|
||||
//ActionCompleted is a completed action status
|
||||
ActionCompleted = "completed"
|
||||
)
|
||||
|
||||
// ActionsService handles communction with action related methods of the
|
||||
// DigitalOcean API: https://developers.digitalocean.com/documentation/v2#actions
|
||||
type ActionsService interface {
|
||||
List(context.Context, *ListOptions) ([]Action, *Response, error)
|
||||
Get(context.Context, int) (*Action, *Response, error)
|
||||
}
|
||||
|
||||
// ActionsServiceOp handles communition with the image action related methods of the
|
||||
// DigitalOcean API.
|
||||
type ActionsServiceOp struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
var _ ActionsService = &ActionsServiceOp{}
|
||||
|
||||
type actionsRoot struct {
|
||||
Actions []Action `json:"actions"`
|
||||
Links *Links `json:"links"`
|
||||
}
|
||||
|
||||
type actionRoot struct {
|
||||
Event *Action `json:"action"`
|
||||
}
|
||||
|
||||
// Action represents a DigitalOcean Action
|
||||
type Action struct {
|
||||
ID int `json:"id"`
|
||||
Status string `json:"status"`
|
||||
Type string `json:"type"`
|
||||
StartedAt *Timestamp `json:"started_at"`
|
||||
CompletedAt *Timestamp `json:"completed_at"`
|
||||
ResourceID int `json:"resource_id"`
|
||||
ResourceType string `json:"resource_type"`
|
||||
Region *Region `json:"region,omitempty"`
|
||||
RegionSlug string `json:"region_slug,omitempty"`
|
||||
}
|
||||
|
||||
// List all actions
|
||||
func (s *ActionsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Action, *Response, error) {
|
||||
path := actionsBasePath
|
||||
path, err := addOptions(path, opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(actionsRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
if l := root.Links; l != nil {
|
||||
resp.Links = l
|
||||
}
|
||||
|
||||
return root.Actions, resp, err
|
||||
}
|
||||
|
||||
// Get an action by ID.
|
||||
func (s *ActionsServiceOp) Get(ctx context.Context, id int) (*Action, *Response, error) {
|
||||
if id < 1 {
|
||||
return nil, nil, NewArgError("id", "cannot be less than 1")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%d", actionsBasePath, id)
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(actionRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Event, resp, err
|
||||
}
|
||||
|
||||
func (a Action) String() string {
|
||||
return Stringify(a)
|
||||
}
|
122
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/certificates.go
generated
vendored
Normal file
122
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/certificates.go
generated
vendored
Normal file
|
@ -0,0 +1,122 @@
|
|||
package godo
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"path"
|
||||
|
||||
"github.com/digitalocean/godo/context"
|
||||
)
|
||||
|
||||
const certificatesBasePath = "/v2/certificates"
|
||||
|
||||
// CertificatesService is an interface for managing certificates with the DigitalOcean API.
|
||||
// See: https://developers.digitalocean.com/documentation/v2/#certificates
|
||||
type CertificatesService interface {
|
||||
Get(context.Context, string) (*Certificate, *Response, error)
|
||||
List(context.Context, *ListOptions) ([]Certificate, *Response, error)
|
||||
Create(context.Context, *CertificateRequest) (*Certificate, *Response, error)
|
||||
Delete(context.Context, string) (*Response, error)
|
||||
}
|
||||
|
||||
// Certificate represents a DigitalOcean certificate configuration.
|
||||
type Certificate struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
NotAfter string `json:"not_after,omitempty"`
|
||||
SHA1Fingerprint string `json:"sha1_fingerprint,omitempty"`
|
||||
Created string `json:"created_at,omitempty"`
|
||||
}
|
||||
|
||||
// CertificateRequest represents configuration for a new certificate.
|
||||
type CertificateRequest struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
PrivateKey string `json:"private_key,omitempty"`
|
||||
LeafCertificate string `json:"leaf_certificate,omitempty"`
|
||||
CertificateChain string `json:"certificate_chain,omitempty"`
|
||||
}
|
||||
|
||||
type certificateRoot struct {
|
||||
Certificate *Certificate `json:"certificate"`
|
||||
}
|
||||
|
||||
type certificatesRoot struct {
|
||||
Certificates []Certificate `json:"certificates"`
|
||||
Links *Links `json:"links"`
|
||||
}
|
||||
|
||||
// CertificatesServiceOp handles communication with certificates methods of the DigitalOcean API.
|
||||
type CertificatesServiceOp struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
var _ CertificatesService = &CertificatesServiceOp{}
|
||||
|
||||
// Get an existing certificate by its identifier.
|
||||
func (c *CertificatesServiceOp) Get(ctx context.Context, cID string) (*Certificate, *Response, error) {
|
||||
urlStr := path.Join(certificatesBasePath, cID)
|
||||
|
||||
req, err := c.client.NewRequest(ctx, http.MethodGet, urlStr, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(certificateRoot)
|
||||
resp, err := c.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Certificate, resp, nil
|
||||
}
|
||||
|
||||
// List all certificates.
|
||||
func (c *CertificatesServiceOp) List(ctx context.Context, opt *ListOptions) ([]Certificate, *Response, error) {
|
||||
urlStr, err := addOptions(certificatesBasePath, opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
req, err := c.client.NewRequest(ctx, http.MethodGet, urlStr, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(certificatesRoot)
|
||||
resp, err := c.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
if l := root.Links; l != nil {
|
||||
resp.Links = l
|
||||
}
|
||||
|
||||
return root.Certificates, resp, nil
|
||||
}
|
||||
|
||||
// Create a new certificate with provided configuration.
|
||||
func (c *CertificatesServiceOp) Create(ctx context.Context, cr *CertificateRequest) (*Certificate, *Response, error) {
|
||||
req, err := c.client.NewRequest(ctx, http.MethodPost, certificatesBasePath, cr)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(certificateRoot)
|
||||
resp, err := c.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Certificate, resp, nil
|
||||
}
|
||||
|
||||
// Delete a certificate by its identifier.
|
||||
func (c *CertificatesServiceOp) Delete(ctx context.Context, cID string) (*Response, error) {
|
||||
urlStr := path.Join(certificatesBasePath, cID)
|
||||
|
||||
req, err := c.client.NewRequest(ctx, http.MethodDelete, urlStr, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return c.client.Do(ctx, req, nil)
|
||||
}
|
98
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/context/context.go
generated
vendored
Normal file
98
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/context/context.go
generated
vendored
Normal file
|
@ -0,0 +1,98 @@
|
|||
package context
|
||||
|
||||
import "time"
|
||||
|
||||
// A Context carries a deadline, a cancelation signal, and other values across
|
||||
// API boundaries.
|
||||
//
|
||||
// Context's methods may be called by multiple goroutines simultaneously.
|
||||
type Context interface {
|
||||
// Deadline returns the time when work done on behalf of this context
|
||||
// should be canceled. Deadline returns ok==false when no deadline is
|
||||
// set. Successive calls to Deadline return the same results.
|
||||
Deadline() (deadline time.Time, ok bool)
|
||||
|
||||
// Done returns a channel that's closed when work done on behalf of this
|
||||
// context should be canceled. Done may return nil if this context can
|
||||
// never be canceled. Successive calls to Done return the same value.
|
||||
//
|
||||
// WithCancel arranges for Done to be closed when cancel is called;
|
||||
// WithDeadline arranges for Done to be closed when the deadline
|
||||
// expires; WithTimeout arranges for Done to be closed when the timeout
|
||||
// elapses.
|
||||
//
|
||||
// Done is provided for use in select statements:s
|
||||
//
|
||||
// // Stream generates values with DoSomething and sends them to out
|
||||
// // until DoSomething returns an error or ctx.Done is closed.
|
||||
// func Stream(ctx context.Context, out chan<- Value) error {
|
||||
// for {
|
||||
// v, err := DoSomething(ctx)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// select {
|
||||
// case <-ctx.Done():
|
||||
// return ctx.Err()
|
||||
// case out <- v:
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// See http://blog.golang.org/pipelines for more examples of how to use
|
||||
// a Done channel for cancelation.
|
||||
Done() <-chan struct{}
|
||||
|
||||
// Err returns a non-nil error value after Done is closed. Err returns
|
||||
// Canceled if the context was canceled or DeadlineExceeded if the
|
||||
// context's deadline passed. No other values for Err are defined.
|
||||
// After Done is closed, successive calls to Err return the same value.
|
||||
Err() error
|
||||
|
||||
// Value returns the value associated with this context for key, or nil
|
||||
// if no value is associated with key. Successive calls to Value with
|
||||
// the same key returns the same result.
|
||||
//
|
||||
// Use context values only for request-scoped data that transits
|
||||
// processes and API boundaries, not for passing optional parameters to
|
||||
// functions.
|
||||
//
|
||||
// A key identifies a specific value in a Context. Functions that wish
|
||||
// to store values in Context typically allocate a key in a global
|
||||
// variable then use that key as the argument to context.WithValue and
|
||||
// Context.Value. A key can be any type that supports equality;
|
||||
// packages should define keys as an unexported type to avoid
|
||||
// collisions.
|
||||
//
|
||||
// Packages that define a Context key should provide type-safe accessors
|
||||
// for the values stores using that key:
|
||||
//
|
||||
// // Package user defines a User type that's stored in Contexts.
|
||||
// package user
|
||||
//
|
||||
// import "golang.org/x/net/context"
|
||||
//
|
||||
// // User is the type of value stored in the Contexts.
|
||||
// type User struct {...}
|
||||
//
|
||||
// // key is an unexported type for keys defined in this package.
|
||||
// // This prevents collisions with keys defined in other packages.
|
||||
// type key int
|
||||
//
|
||||
// // userKey is the key for user.User values in Contexts. It is
|
||||
// // unexported; clients use user.NewContext and user.FromContext
|
||||
// // instead of using this key directly.
|
||||
// var userKey key = 0
|
||||
//
|
||||
// // NewContext returns a new Context that carries value u.
|
||||
// func NewContext(ctx context.Context, u *User) context.Context {
|
||||
// return context.WithValue(ctx, userKey, u)
|
||||
// }
|
||||
//
|
||||
// // FromContext returns the User value stored in ctx, if any.
|
||||
// func FromContext(ctx context.Context) (*User, bool) {
|
||||
// u, ok := ctx.Value(userKey).(*User)
|
||||
// return u, ok
|
||||
// }
|
||||
Value(key interface{}) interface{}
|
||||
}
|
39
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/context/context_go17.go
generated
vendored
Normal file
39
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/context/context_go17.go
generated
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
// +build go1.7
|
||||
|
||||
package context
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// DoRequest submits an HTTP request.
|
||||
func DoRequest(ctx Context, req *http.Request) (*http.Response, error) {
|
||||
return DoRequestWithClient(ctx, http.DefaultClient, req)
|
||||
}
|
||||
|
||||
// DoRequestWithClient submits an HTTP request using the specified client.
|
||||
func DoRequestWithClient(
|
||||
ctx Context,
|
||||
client *http.Client,
|
||||
req *http.Request) (*http.Response, error) {
|
||||
req = req.WithContext(ctx)
|
||||
return client.Do(req)
|
||||
}
|
||||
|
||||
// TODO returns a non-nil, empty Context. Code should use context.TODO when
|
||||
// it's unclear which Context to use or it is not yet available (because the
|
||||
// surrounding function has not yet been extended to accept a Context
|
||||
// parameter). TODO is recognized by static analysis tools that determine
|
||||
// whether Contexts are propagated correctly in a program.
|
||||
func TODO() Context {
|
||||
return context.TODO()
|
||||
}
|
||||
|
||||
// Background returns a non-nil, empty Context. It is never canceled, has no
|
||||
// values, and has no deadline. It is typically used by the main function,
|
||||
// initialization, and tests, and as the top-level Context for incoming
|
||||
// requests.
|
||||
func Background() Context {
|
||||
return context.Background()
|
||||
}
|
41
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/context/context_pre_go17.go
generated
vendored
Normal file
41
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/context/context_pre_go17.go
generated
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
// +build !go1.7
|
||||
|
||||
package context
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
"golang.org/x/net/context/ctxhttp"
|
||||
)
|
||||
|
||||
// DoRequest submits an HTTP request.
|
||||
func DoRequest(ctx Context, req *http.Request) (*http.Response, error) {
|
||||
return DoRequestWithClient(ctx, http.DefaultClient, req)
|
||||
}
|
||||
|
||||
// DoRequestWithClient submits an HTTP request using the specified client.
|
||||
func DoRequestWithClient(
|
||||
ctx Context,
|
||||
client *http.Client,
|
||||
req *http.Request) (*http.Response, error) {
|
||||
|
||||
return ctxhttp.Do(ctx, client, req)
|
||||
}
|
||||
|
||||
// TODO returns a non-nil, empty Context. Code should use context.TODO when
|
||||
// it's unclear which Context to use or it is not yet available (because the
|
||||
// surrounding function has not yet been extended to accept a Context
|
||||
// parameter). TODO is recognized by static analysis tools that determine
|
||||
// whether Contexts are propagated correctly in a program.
|
||||
func TODO() Context {
|
||||
return context.TODO()
|
||||
}
|
||||
|
||||
// Background returns a non-nil, empty Context. It is never canceled, has no
|
||||
// values, and has no deadline. It is typically used by the main function,
|
||||
// initialization, and tests, and as the top-level Context for incoming
|
||||
// requests.
|
||||
func Background() Context {
|
||||
return context.Background()
|
||||
}
|
2
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/doc.go
generated
vendored
Normal file
2
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
// Package godo is the DigtalOcean API v2 client for Go
|
||||
package godo
|
330
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/domains.go
generated
vendored
Normal file
330
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/domains.go
generated
vendored
Normal file
|
@ -0,0 +1,330 @@
|
|||
package godo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/digitalocean/godo/context"
|
||||
)
|
||||
|
||||
const domainsBasePath = "v2/domains"
|
||||
|
||||
// DomainsService is an interface for managing DNS with the DigitalOcean API.
|
||||
// See: https://developers.digitalocean.com/documentation/v2#domains and
|
||||
// https://developers.digitalocean.com/documentation/v2#domain-records
|
||||
type DomainsService interface {
|
||||
List(context.Context, *ListOptions) ([]Domain, *Response, error)
|
||||
Get(context.Context, string) (*Domain, *Response, error)
|
||||
Create(context.Context, *DomainCreateRequest) (*Domain, *Response, error)
|
||||
Delete(context.Context, string) (*Response, error)
|
||||
|
||||
Records(context.Context, string, *ListOptions) ([]DomainRecord, *Response, error)
|
||||
Record(context.Context, string, int) (*DomainRecord, *Response, error)
|
||||
DeleteRecord(context.Context, string, int) (*Response, error)
|
||||
EditRecord(context.Context, string, int, *DomainRecordEditRequest) (*DomainRecord, *Response, error)
|
||||
CreateRecord(context.Context, string, *DomainRecordEditRequest) (*DomainRecord, *Response, error)
|
||||
}
|
||||
|
||||
// DomainsServiceOp handles communication with the domain related methods of the
|
||||
// DigitalOcean API.
|
||||
type DomainsServiceOp struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
var _ DomainsService = &DomainsServiceOp{}
|
||||
|
||||
// Domain represents a DigitalOcean domain
|
||||
type Domain struct {
|
||||
Name string `json:"name"`
|
||||
TTL int `json:"ttl"`
|
||||
ZoneFile string `json:"zone_file"`
|
||||
}
|
||||
|
||||
// domainRoot represents a response from the DigitalOcean API
|
||||
type domainRoot struct {
|
||||
Domain *Domain `json:"domain"`
|
||||
}
|
||||
|
||||
type domainsRoot struct {
|
||||
Domains []Domain `json:"domains"`
|
||||
Links *Links `json:"links"`
|
||||
}
|
||||
|
||||
// DomainCreateRequest respresents a request to create a domain.
|
||||
type DomainCreateRequest struct {
|
||||
Name string `json:"name"`
|
||||
IPAddress string `json:"ip_address"`
|
||||
}
|
||||
|
||||
// DomainRecordRoot is the root of an individual Domain Record response
|
||||
type domainRecordRoot struct {
|
||||
DomainRecord *DomainRecord `json:"domain_record"`
|
||||
}
|
||||
|
||||
// DomainRecordsRoot is the root of a group of Domain Record responses
|
||||
type domainRecordsRoot struct {
|
||||
DomainRecords []DomainRecord `json:"domain_records"`
|
||||
Links *Links `json:"links"`
|
||||
}
|
||||
|
||||
// DomainRecord represents a DigitalOcean DomainRecord
|
||||
type DomainRecord struct {
|
||||
ID int `json:"id,float64,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Data string `json:"data,omitempty"`
|
||||
Priority int `json:"priority,omitempty"`
|
||||
Port int `json:"port,omitempty"`
|
||||
TTL int `json:"ttl,omitempty"`
|
||||
Weight int `json:"weight,omitempty"`
|
||||
}
|
||||
|
||||
// DomainRecordEditRequest represents a request to update a domain record.
|
||||
type DomainRecordEditRequest struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Data string `json:"data,omitempty"`
|
||||
Priority int `json:"priority,omitempty"`
|
||||
Port int `json:"port,omitempty"`
|
||||
TTL int `json:"ttl,omitempty"`
|
||||
Weight int `json:"weight,omitempty"`
|
||||
}
|
||||
|
||||
func (d Domain) String() string {
|
||||
return Stringify(d)
|
||||
}
|
||||
|
||||
// List all domains.
|
||||
func (s DomainsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Domain, *Response, error) {
|
||||
path := domainsBasePath
|
||||
path, err := addOptions(path, opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(domainsRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
if l := root.Links; l != nil {
|
||||
resp.Links = l
|
||||
}
|
||||
|
||||
return root.Domains, resp, err
|
||||
}
|
||||
|
||||
// Get individual domain. It requires a non-empty domain name.
|
||||
func (s *DomainsServiceOp) Get(ctx context.Context, name string) (*Domain, *Response, error) {
|
||||
if len(name) < 1 {
|
||||
return nil, nil, NewArgError("name", "cannot be an empty string")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%s", domainsBasePath, name)
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(domainRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Domain, resp, err
|
||||
}
|
||||
|
||||
// Create a new domain
|
||||
func (s *DomainsServiceOp) Create(ctx context.Context, createRequest *DomainCreateRequest) (*Domain, *Response, error) {
|
||||
if createRequest == nil {
|
||||
return nil, nil, NewArgError("createRequest", "cannot be nil")
|
||||
}
|
||||
|
||||
path := domainsBasePath
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodPost, path, createRequest)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(domainRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
return root.Domain, resp, err
|
||||
}
|
||||
|
||||
// Delete domain
|
||||
func (s *DomainsServiceOp) Delete(ctx context.Context, name string) (*Response, error) {
|
||||
if len(name) < 1 {
|
||||
return nil, NewArgError("name", "cannot be an empty string")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%s", domainsBasePath, name)
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodDelete, path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(ctx, req, nil)
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// Converts a DomainRecord to a string.
|
||||
func (d DomainRecord) String() string {
|
||||
return Stringify(d)
|
||||
}
|
||||
|
||||
// Converts a DomainRecordEditRequest to a string.
|
||||
func (d DomainRecordEditRequest) String() string {
|
||||
return Stringify(d)
|
||||
}
|
||||
|
||||
// Records returns a slice of DomainRecords for a domain
|
||||
func (s *DomainsServiceOp) Records(ctx context.Context, domain string, opt *ListOptions) ([]DomainRecord, *Response, error) {
|
||||
if len(domain) < 1 {
|
||||
return nil, nil, NewArgError("domain", "cannot be an empty string")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%s/records", domainsBasePath, domain)
|
||||
path, err := addOptions(path, opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(domainRecordsRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
if l := root.Links; l != nil {
|
||||
resp.Links = l
|
||||
}
|
||||
|
||||
return root.DomainRecords, resp, err
|
||||
}
|
||||
|
||||
// Record returns the record id from a domain
|
||||
func (s *DomainsServiceOp) Record(ctx context.Context, domain string, id int) (*DomainRecord, *Response, error) {
|
||||
if len(domain) < 1 {
|
||||
return nil, nil, NewArgError("domain", "cannot be an empty string")
|
||||
}
|
||||
|
||||
if id < 1 {
|
||||
return nil, nil, NewArgError("id", "cannot be less than 1")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%s/records/%d", domainsBasePath, domain, id)
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
record := new(domainRecordRoot)
|
||||
resp, err := s.client.Do(ctx, req, record)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return record.DomainRecord, resp, err
|
||||
}
|
||||
|
||||
// DeleteRecord deletes a record from a domain identified by id
|
||||
func (s *DomainsServiceOp) DeleteRecord(ctx context.Context, domain string, id int) (*Response, error) {
|
||||
if len(domain) < 1 {
|
||||
return nil, NewArgError("domain", "cannot be an empty string")
|
||||
}
|
||||
|
||||
if id < 1 {
|
||||
return nil, NewArgError("id", "cannot be less than 1")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%s/records/%d", domainsBasePath, domain, id)
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodDelete, path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(ctx, req, nil)
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// EditRecord edits a record using a DomainRecordEditRequest
|
||||
func (s *DomainsServiceOp) EditRecord(ctx context.Context,
|
||||
domain string,
|
||||
id int,
|
||||
editRequest *DomainRecordEditRequest,
|
||||
) (*DomainRecord, *Response, error) {
|
||||
if len(domain) < 1 {
|
||||
return nil, nil, NewArgError("domain", "cannot be an empty string")
|
||||
}
|
||||
|
||||
if id < 1 {
|
||||
return nil, nil, NewArgError("id", "cannot be less than 1")
|
||||
}
|
||||
|
||||
if editRequest == nil {
|
||||
return nil, nil, NewArgError("editRequest", "cannot be nil")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%s/records/%d", domainsBasePath, domain, id)
|
||||
|
||||
req, err := s.client.NewRequest(ctx, "PUT", path, editRequest)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
d := new(DomainRecord)
|
||||
resp, err := s.client.Do(ctx, req, d)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return d, resp, err
|
||||
}
|
||||
|
||||
// CreateRecord creates a record using a DomainRecordEditRequest
|
||||
func (s *DomainsServiceOp) CreateRecord(ctx context.Context,
|
||||
domain string,
|
||||
createRequest *DomainRecordEditRequest) (*DomainRecord, *Response, error) {
|
||||
if len(domain) < 1 {
|
||||
return nil, nil, NewArgError("domain", "cannot be empty string")
|
||||
}
|
||||
|
||||
if createRequest == nil {
|
||||
return nil, nil, NewArgError("createRequest", "cannot be nil")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%s/records", domainsBasePath, domain)
|
||||
req, err := s.client.NewRequest(ctx, http.MethodPost, path, createRequest)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
d := new(domainRecordRoot)
|
||||
resp, err := s.client.Do(ctx, req, d)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return d.DomainRecord, resp, err
|
||||
}
|
337
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/droplet_actions.go
generated
vendored
Normal file
337
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/droplet_actions.go
generated
vendored
Normal file
|
@ -0,0 +1,337 @@
|
|||
package godo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/digitalocean/godo/context"
|
||||
)
|
||||
|
||||
// ActionRequest reprents DigitalOcean Action Request
|
||||
type ActionRequest map[string]interface{}
|
||||
|
||||
// DropletActionsService is an interface for interfacing with the Droplet actions
|
||||
// endpoints of the DigitalOcean API
|
||||
// See: https://developers.digitalocean.com/documentation/v2#droplet-actions
|
||||
type DropletActionsService interface {
|
||||
Shutdown(context.Context, int) (*Action, *Response, error)
|
||||
ShutdownByTag(context.Context, string) ([]Action, *Response, error)
|
||||
PowerOff(context.Context, int) (*Action, *Response, error)
|
||||
PowerOffByTag(context.Context, string) ([]Action, *Response, error)
|
||||
PowerOn(context.Context, int) (*Action, *Response, error)
|
||||
PowerOnByTag(context.Context, string) ([]Action, *Response, error)
|
||||
PowerCycle(context.Context, int) (*Action, *Response, error)
|
||||
PowerCycleByTag(context.Context, string) ([]Action, *Response, error)
|
||||
Reboot(context.Context, int) (*Action, *Response, error)
|
||||
Restore(context.Context, int, int) (*Action, *Response, error)
|
||||
Resize(context.Context, int, string, bool) (*Action, *Response, error)
|
||||
Rename(context.Context, int, string) (*Action, *Response, error)
|
||||
Snapshot(context.Context, int, string) (*Action, *Response, error)
|
||||
SnapshotByTag(context.Context, string, string) ([]Action, *Response, error)
|
||||
EnableBackups(context.Context, int) (*Action, *Response, error)
|
||||
EnableBackupsByTag(context.Context, string) ([]Action, *Response, error)
|
||||
DisableBackups(context.Context, int) (*Action, *Response, error)
|
||||
DisableBackupsByTag(context.Context, string) ([]Action, *Response, error)
|
||||
PasswordReset(context.Context, int) (*Action, *Response, error)
|
||||
RebuildByImageID(context.Context, int, int) (*Action, *Response, error)
|
||||
RebuildByImageSlug(context.Context, int, string) (*Action, *Response, error)
|
||||
ChangeKernel(context.Context, int, int) (*Action, *Response, error)
|
||||
EnableIPv6(context.Context, int) (*Action, *Response, error)
|
||||
EnableIPv6ByTag(context.Context, string) ([]Action, *Response, error)
|
||||
EnablePrivateNetworking(context.Context, int) (*Action, *Response, error)
|
||||
EnablePrivateNetworkingByTag(context.Context, string) ([]Action, *Response, error)
|
||||
Upgrade(context.Context, int) (*Action, *Response, error)
|
||||
Get(context.Context, int, int) (*Action, *Response, error)
|
||||
GetByURI(context.Context, string) (*Action, *Response, error)
|
||||
}
|
||||
|
||||
// DropletActionsServiceOp handles communication with the Droplet action related
|
||||
// methods of the DigitalOcean API.
|
||||
type DropletActionsServiceOp struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
var _ DropletActionsService = &DropletActionsServiceOp{}
|
||||
|
||||
// Shutdown a Droplet
|
||||
func (s *DropletActionsServiceOp) Shutdown(ctx context.Context, id int) (*Action, *Response, error) {
|
||||
request := &ActionRequest{"type": "shutdown"}
|
||||
return s.doAction(ctx, id, request)
|
||||
}
|
||||
|
||||
// ShutdownByTag shuts down Droplets matched by a Tag.
|
||||
func (s *DropletActionsServiceOp) ShutdownByTag(ctx context.Context, tag string) ([]Action, *Response, error) {
|
||||
request := &ActionRequest{"type": "shutdown"}
|
||||
return s.doActionByTag(ctx, tag, request)
|
||||
}
|
||||
|
||||
// PowerOff a Droplet
|
||||
func (s *DropletActionsServiceOp) PowerOff(ctx context.Context, id int) (*Action, *Response, error) {
|
||||
request := &ActionRequest{"type": "power_off"}
|
||||
return s.doAction(ctx, id, request)
|
||||
}
|
||||
|
||||
// PowerOffByTag powers off Droplets matched by a Tag.
|
||||
func (s *DropletActionsServiceOp) PowerOffByTag(ctx context.Context, tag string) ([]Action, *Response, error) {
|
||||
request := &ActionRequest{"type": "power_off"}
|
||||
return s.doActionByTag(ctx, tag, request)
|
||||
}
|
||||
|
||||
// PowerOn a Droplet
|
||||
func (s *DropletActionsServiceOp) PowerOn(ctx context.Context, id int) (*Action, *Response, error) {
|
||||
request := &ActionRequest{"type": "power_on"}
|
||||
return s.doAction(ctx, id, request)
|
||||
}
|
||||
|
||||
// PowerOnByTag powers on Droplets matched by a Tag.
|
||||
func (s *DropletActionsServiceOp) PowerOnByTag(ctx context.Context, tag string) ([]Action, *Response, error) {
|
||||
request := &ActionRequest{"type": "power_on"}
|
||||
return s.doActionByTag(ctx, tag, request)
|
||||
}
|
||||
|
||||
// PowerCycle a Droplet
|
||||
func (s *DropletActionsServiceOp) PowerCycle(ctx context.Context, id int) (*Action, *Response, error) {
|
||||
request := &ActionRequest{"type": "power_cycle"}
|
||||
return s.doAction(ctx, id, request)
|
||||
}
|
||||
|
||||
// PowerCycleByTag power cycles Droplets matched by a Tag.
|
||||
func (s *DropletActionsServiceOp) PowerCycleByTag(ctx context.Context, tag string) ([]Action, *Response, error) {
|
||||
request := &ActionRequest{"type": "power_cycle"}
|
||||
return s.doActionByTag(ctx, tag, request)
|
||||
}
|
||||
|
||||
// Reboot a Droplet
|
||||
func (s *DropletActionsServiceOp) Reboot(ctx context.Context, id int) (*Action, *Response, error) {
|
||||
request := &ActionRequest{"type": "reboot"}
|
||||
return s.doAction(ctx, id, request)
|
||||
}
|
||||
|
||||
// Restore an image to a Droplet
|
||||
func (s *DropletActionsServiceOp) Restore(ctx context.Context, id, imageID int) (*Action, *Response, error) {
|
||||
requestType := "restore"
|
||||
request := &ActionRequest{
|
||||
"type": requestType,
|
||||
"image": float64(imageID),
|
||||
}
|
||||
return s.doAction(ctx, id, request)
|
||||
}
|
||||
|
||||
// Resize a Droplet
|
||||
func (s *DropletActionsServiceOp) Resize(ctx context.Context, id int, sizeSlug string, resizeDisk bool) (*Action, *Response, error) {
|
||||
requestType := "resize"
|
||||
request := &ActionRequest{
|
||||
"type": requestType,
|
||||
"size": sizeSlug,
|
||||
"disk": resizeDisk,
|
||||
}
|
||||
return s.doAction(ctx, id, request)
|
||||
}
|
||||
|
||||
// Rename a Droplet
|
||||
func (s *DropletActionsServiceOp) Rename(ctx context.Context, id int, name string) (*Action, *Response, error) {
|
||||
requestType := "rename"
|
||||
request := &ActionRequest{
|
||||
"type": requestType,
|
||||
"name": name,
|
||||
}
|
||||
return s.doAction(ctx, id, request)
|
||||
}
|
||||
|
||||
// Snapshot a Droplet.
|
||||
func (s *DropletActionsServiceOp) Snapshot(ctx context.Context, id int, name string) (*Action, *Response, error) {
|
||||
requestType := "snapshot"
|
||||
request := &ActionRequest{
|
||||
"type": requestType,
|
||||
"name": name,
|
||||
}
|
||||
return s.doAction(ctx, id, request)
|
||||
}
|
||||
|
||||
// SnapshotByTag snapshots Droplets matched by a Tag.
|
||||
func (s *DropletActionsServiceOp) SnapshotByTag(ctx context.Context, tag string, name string) ([]Action, *Response, error) {
|
||||
requestType := "snapshot"
|
||||
request := &ActionRequest{
|
||||
"type": requestType,
|
||||
"name": name,
|
||||
}
|
||||
return s.doActionByTag(ctx, tag, request)
|
||||
}
|
||||
|
||||
// EnableBackups enables backups for a Droplet.
|
||||
func (s *DropletActionsServiceOp) EnableBackups(ctx context.Context, id int) (*Action, *Response, error) {
|
||||
request := &ActionRequest{"type": "enable_backups"}
|
||||
return s.doAction(ctx, id, request)
|
||||
}
|
||||
|
||||
// EnableBackupsByTag enables backups for Droplets matched by a Tag.
|
||||
func (s *DropletActionsServiceOp) EnableBackupsByTag(ctx context.Context, tag string) ([]Action, *Response, error) {
|
||||
request := &ActionRequest{"type": "enable_backups"}
|
||||
return s.doActionByTag(ctx, tag, request)
|
||||
}
|
||||
|
||||
// DisableBackups disables backups for a Droplet.
|
||||
func (s *DropletActionsServiceOp) DisableBackups(ctx context.Context, id int) (*Action, *Response, error) {
|
||||
request := &ActionRequest{"type": "disable_backups"}
|
||||
return s.doAction(ctx, id, request)
|
||||
}
|
||||
|
||||
// DisableBackupsByTag disables backups for Droplet matched by a Tag.
|
||||
func (s *DropletActionsServiceOp) DisableBackupsByTag(ctx context.Context, tag string) ([]Action, *Response, error) {
|
||||
request := &ActionRequest{"type": "disable_backups"}
|
||||
return s.doActionByTag(ctx, tag, request)
|
||||
}
|
||||
|
||||
// PasswordReset resets the password for a Droplet.
|
||||
func (s *DropletActionsServiceOp) PasswordReset(ctx context.Context, id int) (*Action, *Response, error) {
|
||||
request := &ActionRequest{"type": "password_reset"}
|
||||
return s.doAction(ctx, id, request)
|
||||
}
|
||||
|
||||
// RebuildByImageID rebuilds a Droplet from an image with a given id.
|
||||
func (s *DropletActionsServiceOp) RebuildByImageID(ctx context.Context, id, imageID int) (*Action, *Response, error) {
|
||||
request := &ActionRequest{"type": "rebuild", "image": imageID}
|
||||
return s.doAction(ctx, id, request)
|
||||
}
|
||||
|
||||
// RebuildByImageSlug rebuilds a Droplet from an Image matched by a given Slug.
|
||||
func (s *DropletActionsServiceOp) RebuildByImageSlug(ctx context.Context, id int, slug string) (*Action, *Response, error) {
|
||||
request := &ActionRequest{"type": "rebuild", "image": slug}
|
||||
return s.doAction(ctx, id, request)
|
||||
}
|
||||
|
||||
// ChangeKernel changes the kernel for a Droplet.
|
||||
func (s *DropletActionsServiceOp) ChangeKernel(ctx context.Context, id, kernelID int) (*Action, *Response, error) {
|
||||
request := &ActionRequest{"type": "change_kernel", "kernel": kernelID}
|
||||
return s.doAction(ctx, id, request)
|
||||
}
|
||||
|
||||
// EnableIPv6 enables IPv6 for a Droplet.
|
||||
func (s *DropletActionsServiceOp) EnableIPv6(ctx context.Context, id int) (*Action, *Response, error) {
|
||||
request := &ActionRequest{"type": "enable_ipv6"}
|
||||
return s.doAction(ctx, id, request)
|
||||
}
|
||||
|
||||
// EnableIPv6ByTag enables IPv6 for Droplets matched by a Tag.
|
||||
func (s *DropletActionsServiceOp) EnableIPv6ByTag(ctx context.Context, tag string) ([]Action, *Response, error) {
|
||||
request := &ActionRequest{"type": "enable_ipv6"}
|
||||
return s.doActionByTag(ctx, tag, request)
|
||||
}
|
||||
|
||||
// EnablePrivateNetworking enables private networking for a Droplet.
|
||||
func (s *DropletActionsServiceOp) EnablePrivateNetworking(ctx context.Context, id int) (*Action, *Response, error) {
|
||||
request := &ActionRequest{"type": "enable_private_networking"}
|
||||
return s.doAction(ctx, id, request)
|
||||
}
|
||||
|
||||
// EnablePrivateNetworkingByTag enables private networking for Droplets matched by a Tag.
|
||||
func (s *DropletActionsServiceOp) EnablePrivateNetworkingByTag(ctx context.Context, tag string) ([]Action, *Response, error) {
|
||||
request := &ActionRequest{"type": "enable_private_networking"}
|
||||
return s.doActionByTag(ctx, tag, request)
|
||||
}
|
||||
|
||||
// Upgrade a Droplet.
|
||||
func (s *DropletActionsServiceOp) Upgrade(ctx context.Context, id int) (*Action, *Response, error) {
|
||||
request := &ActionRequest{"type": "upgrade"}
|
||||
return s.doAction(ctx, id, request)
|
||||
}
|
||||
|
||||
func (s *DropletActionsServiceOp) doAction(ctx context.Context, id int, request *ActionRequest) (*Action, *Response, error) {
|
||||
if id < 1 {
|
||||
return nil, nil, NewArgError("id", "cannot be less than 1")
|
||||
}
|
||||
|
||||
if request == nil {
|
||||
return nil, nil, NewArgError("request", "request can't be nil")
|
||||
}
|
||||
|
||||
path := dropletActionPath(id)
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodPost, path, request)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(actionRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Event, resp, err
|
||||
}
|
||||
|
||||
func (s *DropletActionsServiceOp) doActionByTag(ctx context.Context, tag string, request *ActionRequest) ([]Action, *Response, error) {
|
||||
if tag == "" {
|
||||
return nil, nil, NewArgError("tag", "cannot be empty")
|
||||
}
|
||||
|
||||
if request == nil {
|
||||
return nil, nil, NewArgError("request", "request can't be nil")
|
||||
}
|
||||
|
||||
path := dropletActionPathByTag(tag)
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodPost, path, request)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(actionsRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Actions, resp, err
|
||||
}
|
||||
|
||||
// Get an action for a particular Droplet by id.
|
||||
func (s *DropletActionsServiceOp) Get(ctx context.Context, dropletID, actionID int) (*Action, *Response, error) {
|
||||
if dropletID < 1 {
|
||||
return nil, nil, NewArgError("dropletID", "cannot be less than 1")
|
||||
}
|
||||
|
||||
if actionID < 1 {
|
||||
return nil, nil, NewArgError("actionID", "cannot be less than 1")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%d", dropletActionPath(dropletID), actionID)
|
||||
return s.get(ctx, path)
|
||||
}
|
||||
|
||||
// GetByURI gets an action for a particular Droplet by id.
|
||||
func (s *DropletActionsServiceOp) GetByURI(ctx context.Context, rawurl string) (*Action, *Response, error) {
|
||||
u, err := url.Parse(rawurl)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return s.get(ctx, u.Path)
|
||||
|
||||
}
|
||||
|
||||
func (s *DropletActionsServiceOp) get(ctx context.Context, path string) (*Action, *Response, error) {
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(actionRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Event, resp, err
|
||||
|
||||
}
|
||||
|
||||
func dropletActionPath(dropletID int) string {
|
||||
return fmt.Sprintf("v2/droplets/%d/actions", dropletID)
|
||||
}
|
||||
|
||||
func dropletActionPathByTag(tag string) string {
|
||||
return fmt.Sprintf("v2/droplets/actions?tag_name=%s", tag)
|
||||
}
|
567
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/droplets.go
generated
vendored
Normal file
567
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/droplets.go
generated
vendored
Normal file
|
@ -0,0 +1,567 @@
|
|||
package godo
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/digitalocean/godo/context"
|
||||
)
|
||||
|
||||
const dropletBasePath = "v2/droplets"
|
||||
|
||||
var errNoNetworks = errors.New("no networks have been defined")
|
||||
|
||||
// DropletsService is an interface for interfacing with the Droplet
|
||||
// endpoints of the DigitalOcean API
|
||||
// See: https://developers.digitalocean.com/documentation/v2#droplets
|
||||
type DropletsService interface {
|
||||
List(context.Context, *ListOptions) ([]Droplet, *Response, error)
|
||||
ListByTag(context.Context, string, *ListOptions) ([]Droplet, *Response, error)
|
||||
Get(context.Context, int) (*Droplet, *Response, error)
|
||||
Create(context.Context, *DropletCreateRequest) (*Droplet, *Response, error)
|
||||
CreateMultiple(context.Context, *DropletMultiCreateRequest) ([]Droplet, *Response, error)
|
||||
Delete(context.Context, int) (*Response, error)
|
||||
DeleteByTag(context.Context, string) (*Response, error)
|
||||
Kernels(context.Context, int, *ListOptions) ([]Kernel, *Response, error)
|
||||
Snapshots(context.Context, int, *ListOptions) ([]Image, *Response, error)
|
||||
Backups(context.Context, int, *ListOptions) ([]Image, *Response, error)
|
||||
Actions(context.Context, int, *ListOptions) ([]Action, *Response, error)
|
||||
Neighbors(context.Context, int) ([]Droplet, *Response, error)
|
||||
}
|
||||
|
||||
// DropletsServiceOp handles communication with the Droplet related methods of the
|
||||
// DigitalOcean API.
|
||||
type DropletsServiceOp struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
var _ DropletsService = &DropletsServiceOp{}
|
||||
|
||||
// Droplet represents a DigitalOcean Droplet
|
||||
type Droplet struct {
|
||||
ID int `json:"id,float64,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Memory int `json:"memory,omitempty"`
|
||||
Vcpus int `json:"vcpus,omitempty"`
|
||||
Disk int `json:"disk,omitempty"`
|
||||
Region *Region `json:"region,omitempty"`
|
||||
Image *Image `json:"image,omitempty"`
|
||||
Size *Size `json:"size,omitempty"`
|
||||
SizeSlug string `json:"size_slug,omitempty"`
|
||||
BackupIDs []int `json:"backup_ids,omitempty"`
|
||||
NextBackupWindow *BackupWindow `json:"next_backup_window,omitempty"`
|
||||
SnapshotIDs []int `json:"snapshot_ids,omitempty"`
|
||||
Features []string `json:"features,omitempty"`
|
||||
Locked bool `json:"locked,bool,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
Networks *Networks `json:"networks,omitempty"`
|
||||
Created string `json:"created_at,omitempty"`
|
||||
Kernel *Kernel `json:"kernel,omitempty"`
|
||||
Tags []string `json:"tags,omitempty"`
|
||||
VolumeIDs []string `json:"volume_ids"`
|
||||
}
|
||||
|
||||
// PublicIPv4 returns the public IPv4 address for the Droplet.
|
||||
func (d *Droplet) PublicIPv4() (string, error) {
|
||||
if d.Networks == nil {
|
||||
return "", errNoNetworks
|
||||
}
|
||||
|
||||
for _, v4 := range d.Networks.V4 {
|
||||
if v4.Type == "public" {
|
||||
return v4.IPAddress, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// PrivateIPv4 returns the private IPv4 address for the Droplet.
|
||||
func (d *Droplet) PrivateIPv4() (string, error) {
|
||||
if d.Networks == nil {
|
||||
return "", errNoNetworks
|
||||
}
|
||||
|
||||
for _, v4 := range d.Networks.V4 {
|
||||
if v4.Type == "private" {
|
||||
return v4.IPAddress, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// PublicIPv6 returns the public IPv6 address for the Droplet.
|
||||
func (d *Droplet) PublicIPv6() (string, error) {
|
||||
if d.Networks == nil {
|
||||
return "", errNoNetworks
|
||||
}
|
||||
|
||||
for _, v6 := range d.Networks.V6 {
|
||||
if v6.Type == "public" {
|
||||
return v6.IPAddress, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Kernel object
|
||||
type Kernel struct {
|
||||
ID int `json:"id,float64,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
}
|
||||
|
||||
// BackupWindow object
|
||||
type BackupWindow struct {
|
||||
Start *Timestamp `json:"start,omitempty"`
|
||||
End *Timestamp `json:"end,omitempty"`
|
||||
}
|
||||
|
||||
// Convert Droplet to a string
|
||||
func (d Droplet) String() string {
|
||||
return Stringify(d)
|
||||
}
|
||||
|
||||
// DropletRoot represents a Droplet root
|
||||
type dropletRoot struct {
|
||||
Droplet *Droplet `json:"droplet"`
|
||||
Links *Links `json:"links,omitempty"`
|
||||
}
|
||||
|
||||
type dropletsRoot struct {
|
||||
Droplets []Droplet `json:"droplets"`
|
||||
Links *Links `json:"links"`
|
||||
}
|
||||
|
||||
type kernelsRoot struct {
|
||||
Kernels []Kernel `json:"kernels,omitempty"`
|
||||
Links *Links `json:"links"`
|
||||
}
|
||||
|
||||
type dropletSnapshotsRoot struct {
|
||||
Snapshots []Image `json:"snapshots,omitempty"`
|
||||
Links *Links `json:"links"`
|
||||
}
|
||||
|
||||
type backupsRoot struct {
|
||||
Backups []Image `json:"backups,omitempty"`
|
||||
Links *Links `json:"links"`
|
||||
}
|
||||
|
||||
// DropletCreateImage identifies an image for the create request. It prefers slug over ID.
|
||||
type DropletCreateImage struct {
|
||||
ID int
|
||||
Slug string
|
||||
}
|
||||
|
||||
// MarshalJSON returns either the slug or id of the image. It returns the id
|
||||
// if the slug is empty.
|
||||
func (d DropletCreateImage) MarshalJSON() ([]byte, error) {
|
||||
if d.Slug != "" {
|
||||
return json.Marshal(d.Slug)
|
||||
}
|
||||
|
||||
return json.Marshal(d.ID)
|
||||
}
|
||||
|
||||
// DropletCreateVolume identifies a volume to attach for the create request. It
|
||||
// prefers Name over ID,
|
||||
type DropletCreateVolume struct {
|
||||
ID string
|
||||
Name string
|
||||
}
|
||||
|
||||
// MarshalJSON returns an object with either the name or id of the volume. It
|
||||
// returns the id if the name is empty.
|
||||
func (d DropletCreateVolume) MarshalJSON() ([]byte, error) {
|
||||
if d.Name != "" {
|
||||
return json.Marshal(struct {
|
||||
Name string `json:"name"`
|
||||
}{Name: d.Name})
|
||||
}
|
||||
|
||||
return json.Marshal(struct {
|
||||
ID string `json:"id"`
|
||||
}{ID: d.ID})
|
||||
}
|
||||
|
||||
// DropletCreateSSHKey identifies a SSH Key for the create request. It prefers fingerprint over ID.
|
||||
type DropletCreateSSHKey struct {
|
||||
ID int
|
||||
Fingerprint string
|
||||
}
|
||||
|
||||
// MarshalJSON returns either the fingerprint or id of the ssh key. It returns
|
||||
// the id if the fingerprint is empty.
|
||||
func (d DropletCreateSSHKey) MarshalJSON() ([]byte, error) {
|
||||
if d.Fingerprint != "" {
|
||||
return json.Marshal(d.Fingerprint)
|
||||
}
|
||||
|
||||
return json.Marshal(d.ID)
|
||||
}
|
||||
|
||||
// DropletCreateRequest represents a request to create a Droplet.
|
||||
type DropletCreateRequest struct {
|
||||
Name string `json:"name"`
|
||||
Region string `json:"region"`
|
||||
Size string `json:"size"`
|
||||
Image DropletCreateImage `json:"image"`
|
||||
SSHKeys []DropletCreateSSHKey `json:"ssh_keys"`
|
||||
Backups bool `json:"backups"`
|
||||
IPv6 bool `json:"ipv6"`
|
||||
PrivateNetworking bool `json:"private_networking"`
|
||||
Monitoring bool `json:"monitoring"`
|
||||
UserData string `json:"user_data,omitempty"`
|
||||
Volumes []DropletCreateVolume `json:"volumes,omitempty"`
|
||||
Tags []string `json:"tags"`
|
||||
}
|
||||
|
||||
// DropletMultiCreateRequest is a request to create multiple Droplets.
|
||||
type DropletMultiCreateRequest struct {
|
||||
Names []string `json:"names"`
|
||||
Region string `json:"region"`
|
||||
Size string `json:"size"`
|
||||
Image DropletCreateImage `json:"image"`
|
||||
SSHKeys []DropletCreateSSHKey `json:"ssh_keys"`
|
||||
Backups bool `json:"backups"`
|
||||
IPv6 bool `json:"ipv6"`
|
||||
PrivateNetworking bool `json:"private_networking"`
|
||||
Monitoring bool `json:"monitoring"`
|
||||
UserData string `json:"user_data,omitempty"`
|
||||
Tags []string `json:"tags"`
|
||||
}
|
||||
|
||||
func (d DropletCreateRequest) String() string {
|
||||
return Stringify(d)
|
||||
}
|
||||
|
||||
func (d DropletMultiCreateRequest) String() string {
|
||||
return Stringify(d)
|
||||
}
|
||||
|
||||
// Networks represents the Droplet's Networks.
|
||||
type Networks struct {
|
||||
V4 []NetworkV4 `json:"v4,omitempty"`
|
||||
V6 []NetworkV6 `json:"v6,omitempty"`
|
||||
}
|
||||
|
||||
// NetworkV4 represents a DigitalOcean IPv4 Network.
|
||||
type NetworkV4 struct {
|
||||
IPAddress string `json:"ip_address,omitempty"`
|
||||
Netmask string `json:"netmask,omitempty"`
|
||||
Gateway string `json:"gateway,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
func (n NetworkV4) String() string {
|
||||
return Stringify(n)
|
||||
}
|
||||
|
||||
// NetworkV6 represents a DigitalOcean IPv6 network.
|
||||
type NetworkV6 struct {
|
||||
IPAddress string `json:"ip_address,omitempty"`
|
||||
Netmask int `json:"netmask,omitempty"`
|
||||
Gateway string `json:"gateway,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
func (n NetworkV6) String() string {
|
||||
return Stringify(n)
|
||||
}
|
||||
|
||||
// Performs a list request given a path.
|
||||
func (s *DropletsServiceOp) list(ctx context.Context, path string) ([]Droplet, *Response, error) {
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(dropletsRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
if l := root.Links; l != nil {
|
||||
resp.Links = l
|
||||
}
|
||||
|
||||
return root.Droplets, resp, err
|
||||
}
|
||||
|
||||
// List all Droplets.
|
||||
func (s *DropletsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Droplet, *Response, error) {
|
||||
path := dropletBasePath
|
||||
path, err := addOptions(path, opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return s.list(ctx, path)
|
||||
}
|
||||
|
||||
// ListByTag lists all Droplets matched by a Tag.
|
||||
func (s *DropletsServiceOp) ListByTag(ctx context.Context, tag string, opt *ListOptions) ([]Droplet, *Response, error) {
|
||||
path := fmt.Sprintf("%s?tag_name=%s", dropletBasePath, tag)
|
||||
path, err := addOptions(path, opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return s.list(ctx, path)
|
||||
}
|
||||
|
||||
// Get individual Droplet.
|
||||
func (s *DropletsServiceOp) Get(ctx context.Context, dropletID int) (*Droplet, *Response, error) {
|
||||
if dropletID < 1 {
|
||||
return nil, nil, NewArgError("dropletID", "cannot be less than 1")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%d", dropletBasePath, dropletID)
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(dropletRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Droplet, resp, err
|
||||
}
|
||||
|
||||
// Create Droplet
|
||||
func (s *DropletsServiceOp) Create(ctx context.Context, createRequest *DropletCreateRequest) (*Droplet, *Response, error) {
|
||||
if createRequest == nil {
|
||||
return nil, nil, NewArgError("createRequest", "cannot be nil")
|
||||
}
|
||||
|
||||
path := dropletBasePath
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodPost, path, createRequest)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(dropletRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
if l := root.Links; l != nil {
|
||||
resp.Links = l
|
||||
}
|
||||
|
||||
return root.Droplet, resp, err
|
||||
}
|
||||
|
||||
// CreateMultiple creates multiple Droplets.
|
||||
func (s *DropletsServiceOp) CreateMultiple(ctx context.Context, createRequest *DropletMultiCreateRequest) ([]Droplet, *Response, error) {
|
||||
if createRequest == nil {
|
||||
return nil, nil, NewArgError("createRequest", "cannot be nil")
|
||||
}
|
||||
|
||||
path := dropletBasePath
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodPost, path, createRequest)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(dropletsRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
if l := root.Links; l != nil {
|
||||
resp.Links = l
|
||||
}
|
||||
|
||||
return root.Droplets, resp, err
|
||||
}
|
||||
|
||||
// Performs a delete request given a path
|
||||
func (s *DropletsServiceOp) delete(ctx context.Context, path string) (*Response, error) {
|
||||
req, err := s.client.NewRequest(ctx, http.MethodDelete, path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(ctx, req, nil)
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// Delete Droplet.
|
||||
func (s *DropletsServiceOp) Delete(ctx context.Context, dropletID int) (*Response, error) {
|
||||
if dropletID < 1 {
|
||||
return nil, NewArgError("dropletID", "cannot be less than 1")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%d", dropletBasePath, dropletID)
|
||||
|
||||
return s.delete(ctx, path)
|
||||
}
|
||||
|
||||
// DeleteByTag deletes Droplets matched by a Tag.
|
||||
func (s *DropletsServiceOp) DeleteByTag(ctx context.Context, tag string) (*Response, error) {
|
||||
if tag == "" {
|
||||
return nil, NewArgError("tag", "cannot be empty")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s?tag_name=%s", dropletBasePath, tag)
|
||||
|
||||
return s.delete(ctx, path)
|
||||
}
|
||||
|
||||
// Kernels lists kernels available for a Droplet.
|
||||
func (s *DropletsServiceOp) Kernels(ctx context.Context, dropletID int, opt *ListOptions) ([]Kernel, *Response, error) {
|
||||
if dropletID < 1 {
|
||||
return nil, nil, NewArgError("dropletID", "cannot be less than 1")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%d/kernels", dropletBasePath, dropletID)
|
||||
path, err := addOptions(path, opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(kernelsRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if l := root.Links; l != nil {
|
||||
resp.Links = l
|
||||
}
|
||||
|
||||
return root.Kernels, resp, err
|
||||
}
|
||||
|
||||
// Actions lists the actions for a Droplet.
|
||||
func (s *DropletsServiceOp) Actions(ctx context.Context, dropletID int, opt *ListOptions) ([]Action, *Response, error) {
|
||||
if dropletID < 1 {
|
||||
return nil, nil, NewArgError("dropletID", "cannot be less than 1")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%d/actions", dropletBasePath, dropletID)
|
||||
path, err := addOptions(path, opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(actionsRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
if l := root.Links; l != nil {
|
||||
resp.Links = l
|
||||
}
|
||||
|
||||
return root.Actions, resp, err
|
||||
}
|
||||
|
||||
// Backups lists the backups for a Droplet.
|
||||
func (s *DropletsServiceOp) Backups(ctx context.Context, dropletID int, opt *ListOptions) ([]Image, *Response, error) {
|
||||
if dropletID < 1 {
|
||||
return nil, nil, NewArgError("dropletID", "cannot be less than 1")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%d/backups", dropletBasePath, dropletID)
|
||||
path, err := addOptions(path, opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(backupsRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
if l := root.Links; l != nil {
|
||||
resp.Links = l
|
||||
}
|
||||
|
||||
return root.Backups, resp, err
|
||||
}
|
||||
|
||||
// Snapshots lists the snapshots available for a Droplet.
|
||||
func (s *DropletsServiceOp) Snapshots(ctx context.Context, dropletID int, opt *ListOptions) ([]Image, *Response, error) {
|
||||
if dropletID < 1 {
|
||||
return nil, nil, NewArgError("dropletID", "cannot be less than 1")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%d/snapshots", dropletBasePath, dropletID)
|
||||
path, err := addOptions(path, opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(dropletSnapshotsRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
if l := root.Links; l != nil {
|
||||
resp.Links = l
|
||||
}
|
||||
|
||||
return root.Snapshots, resp, err
|
||||
}
|
||||
|
||||
// Neighbors lists the neighbors for a Droplet.
|
||||
func (s *DropletsServiceOp) Neighbors(ctx context.Context, dropletID int) ([]Droplet, *Response, error) {
|
||||
if dropletID < 1 {
|
||||
return nil, nil, NewArgError("dropletID", "cannot be less than 1")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%d/neighbors", dropletBasePath, dropletID)
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(dropletsRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Droplets, resp, err
|
||||
}
|
||||
|
||||
func (s *DropletsServiceOp) dropletActionStatus(ctx context.Context, uri string) (string, error) {
|
||||
action, _, err := s.client.DropletActions.GetByURI(ctx, uri)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return action.Status, nil
|
||||
}
|
24
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/errors.go
generated
vendored
Normal file
24
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/errors.go
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
package godo
|
||||
|
||||
import "fmt"
|
||||
|
||||
// ArgError is an error that represents an error with an input to godo. It
|
||||
// identifies the argument and the cause (if possible).
|
||||
type ArgError struct {
|
||||
arg string
|
||||
reason string
|
||||
}
|
||||
|
||||
var _ error = &ArgError{}
|
||||
|
||||
// NewArgError creates an InputError.
|
||||
func NewArgError(arg, reason string) *ArgError {
|
||||
return &ArgError{
|
||||
arg: arg,
|
||||
reason: reason,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *ArgError) Error() string {
|
||||
return fmt.Sprintf("%s is invalid because %s", e.arg, e.reason)
|
||||
}
|
264
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/firewalls.go
generated
vendored
Normal file
264
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/firewalls.go
generated
vendored
Normal file
|
@ -0,0 +1,264 @@
|
|||
package godo
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"path"
|
||||
"strconv"
|
||||
|
||||
"github.com/digitalocean/godo/context"
|
||||
)
|
||||
|
||||
const firewallsBasePath = "/v2/firewalls"
|
||||
|
||||
// FirewallsService is an interface for managing Firewalls with the DigitalOcean API.
|
||||
// See: https://developers.digitalocean.com/documentation/documentation/v2/#firewalls
|
||||
type FirewallsService interface {
|
||||
Get(context.Context, string) (*Firewall, *Response, error)
|
||||
Create(context.Context, *FirewallRequest) (*Firewall, *Response, error)
|
||||
Update(context.Context, string, *FirewallRequest) (*Firewall, *Response, error)
|
||||
Delete(context.Context, string) (*Response, error)
|
||||
List(context.Context, *ListOptions) ([]Firewall, *Response, error)
|
||||
ListByDroplet(context.Context, int, *ListOptions) ([]Firewall, *Response, error)
|
||||
AddDroplets(context.Context, string, ...int) (*Response, error)
|
||||
RemoveDroplets(context.Context, string, ...int) (*Response, error)
|
||||
AddTags(context.Context, string, ...string) (*Response, error)
|
||||
RemoveTags(context.Context, string, ...string) (*Response, error)
|
||||
AddRules(context.Context, string, *FirewallRulesRequest) (*Response, error)
|
||||
RemoveRules(context.Context, string, *FirewallRulesRequest) (*Response, error)
|
||||
}
|
||||
|
||||
// FirewallsServiceOp handles communication with Firewalls methods of the DigitalOcean API.
|
||||
type FirewallsServiceOp struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Firewall represents a DigitalOcean Firewall configuration.
|
||||
type Firewall struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Status string `json:"status"`
|
||||
InboundRules []InboundRule `json:"inbound_rules"`
|
||||
OutboundRules []OutboundRule `json:"outbound_rules"`
|
||||
DropletIDs []int `json:"droplet_ids"`
|
||||
Tags []string `json:"tags"`
|
||||
Created string `json:"created_at"`
|
||||
PendingChanges []PendingChange `json:"pending_changes"`
|
||||
}
|
||||
|
||||
// String creates a human-readable description of a Firewall.
|
||||
func (fw Firewall) String() string {
|
||||
return Stringify(fw)
|
||||
}
|
||||
|
||||
// FirewallRequest represents the configuration to be applied to an existing or a new Firewall.
|
||||
type FirewallRequest struct {
|
||||
Name string `json:"name"`
|
||||
InboundRules []InboundRule `json:"inbound_rules"`
|
||||
OutboundRules []OutboundRule `json:"outbound_rules"`
|
||||
DropletIDs []int `json:"droplet_ids"`
|
||||
Tags []string `json:"tags"`
|
||||
}
|
||||
|
||||
// FirewallRulesRequest represents rules configuration to be applied to an existing Firewall.
|
||||
type FirewallRulesRequest struct {
|
||||
InboundRules []InboundRule `json:"inbound_rules"`
|
||||
OutboundRules []OutboundRule `json:"outbound_rules"`
|
||||
}
|
||||
|
||||
// InboundRule represents a DigitalOcean Firewall inbound rule.
|
||||
type InboundRule struct {
|
||||
Protocol string `json:"protocol,omitempty"`
|
||||
PortRange string `json:"ports,omitempty"`
|
||||
Sources *Sources `json:"sources"`
|
||||
}
|
||||
|
||||
// OutboundRule represents a DigitalOcean Firewall outbound rule.
|
||||
type OutboundRule struct {
|
||||
Protocol string `json:"protocol,omitempty"`
|
||||
PortRange string `json:"ports,omitempty"`
|
||||
Destinations *Destinations `json:"destinations"`
|
||||
}
|
||||
|
||||
// Sources represents a DigitalOcean Firewall InboundRule sources.
|
||||
type Sources struct {
|
||||
Addresses []string `json:"addresses,omitempty"`
|
||||
Tags []string `json:"tags,omitempty"`
|
||||
DropletIDs []int `json:"droplet_ids,omitempty"`
|
||||
LoadBalancerUIDs []string `json:"load_balancer_uids,omitempty"`
|
||||
}
|
||||
|
||||
// PendingChange represents a DigitalOcean Firewall status details.
|
||||
type PendingChange struct {
|
||||
DropletID int `json:"droplet_id,omitempty"`
|
||||
Removing bool `json:"removing,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// Destinations represents a DigitalOcean Firewall OutboundRule destinations.
|
||||
type Destinations struct {
|
||||
Addresses []string `json:"addresses,omitempty"`
|
||||
Tags []string `json:"tags,omitempty"`
|
||||
DropletIDs []int `json:"droplet_ids,omitempty"`
|
||||
LoadBalancerUIDs []string `json:"load_balancer_uids,omitempty"`
|
||||
}
|
||||
|
||||
var _ FirewallsService = &FirewallsServiceOp{}
|
||||
|
||||
// Get an existing Firewall by its identifier.
|
||||
func (fw *FirewallsServiceOp) Get(ctx context.Context, fID string) (*Firewall, *Response, error) {
|
||||
path := path.Join(firewallsBasePath, fID)
|
||||
|
||||
req, err := fw.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(firewallRoot)
|
||||
resp, err := fw.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Firewall, resp, err
|
||||
}
|
||||
|
||||
// Create a new Firewall with a given configuration.
|
||||
func (fw *FirewallsServiceOp) Create(ctx context.Context, fr *FirewallRequest) (*Firewall, *Response, error) {
|
||||
req, err := fw.client.NewRequest(ctx, http.MethodPost, firewallsBasePath, fr)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(firewallRoot)
|
||||
resp, err := fw.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Firewall, resp, err
|
||||
}
|
||||
|
||||
// Update an existing Firewall with new configuration.
|
||||
func (fw *FirewallsServiceOp) Update(ctx context.Context, fID string, fr *FirewallRequest) (*Firewall, *Response, error) {
|
||||
path := path.Join(firewallsBasePath, fID)
|
||||
|
||||
req, err := fw.client.NewRequest(ctx, "PUT", path, fr)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(firewallRoot)
|
||||
resp, err := fw.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Firewall, resp, err
|
||||
}
|
||||
|
||||
// Delete a Firewall by its identifier.
|
||||
func (fw *FirewallsServiceOp) Delete(ctx context.Context, fID string) (*Response, error) {
|
||||
path := path.Join(firewallsBasePath, fID)
|
||||
return fw.createAndDoReq(ctx, http.MethodDelete, path, nil)
|
||||
}
|
||||
|
||||
// List Firewalls.
|
||||
func (fw *FirewallsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Firewall, *Response, error) {
|
||||
path, err := addOptions(firewallsBasePath, opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return fw.listHelper(ctx, path)
|
||||
}
|
||||
|
||||
// ListByDroplet Firewalls.
|
||||
func (fw *FirewallsServiceOp) ListByDroplet(ctx context.Context, dID int, opt *ListOptions) ([]Firewall, *Response, error) {
|
||||
basePath := path.Join(dropletBasePath, strconv.Itoa(dID), "firewalls")
|
||||
path, err := addOptions(basePath, opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return fw.listHelper(ctx, path)
|
||||
}
|
||||
|
||||
// AddDroplets to a Firewall.
|
||||
func (fw *FirewallsServiceOp) AddDroplets(ctx context.Context, fID string, dropletIDs ...int) (*Response, error) {
|
||||
path := path.Join(firewallsBasePath, fID, "droplets")
|
||||
return fw.createAndDoReq(ctx, http.MethodPost, path, &dropletsRequest{IDs: dropletIDs})
|
||||
}
|
||||
|
||||
// RemoveDroplets from a Firewall.
|
||||
func (fw *FirewallsServiceOp) RemoveDroplets(ctx context.Context, fID string, dropletIDs ...int) (*Response, error) {
|
||||
path := path.Join(firewallsBasePath, fID, "droplets")
|
||||
return fw.createAndDoReq(ctx, http.MethodDelete, path, &dropletsRequest{IDs: dropletIDs})
|
||||
}
|
||||
|
||||
// AddTags to a Firewall.
|
||||
func (fw *FirewallsServiceOp) AddTags(ctx context.Context, fID string, tags ...string) (*Response, error) {
|
||||
path := path.Join(firewallsBasePath, fID, "tags")
|
||||
return fw.createAndDoReq(ctx, http.MethodPost, path, &tagsRequest{Tags: tags})
|
||||
}
|
||||
|
||||
// RemoveTags from a Firewall.
|
||||
func (fw *FirewallsServiceOp) RemoveTags(ctx context.Context, fID string, tags ...string) (*Response, error) {
|
||||
path := path.Join(firewallsBasePath, fID, "tags")
|
||||
return fw.createAndDoReq(ctx, http.MethodDelete, path, &tagsRequest{Tags: tags})
|
||||
}
|
||||
|
||||
// AddRules to a Firewall.
|
||||
func (fw *FirewallsServiceOp) AddRules(ctx context.Context, fID string, rr *FirewallRulesRequest) (*Response, error) {
|
||||
path := path.Join(firewallsBasePath, fID, "rules")
|
||||
return fw.createAndDoReq(ctx, http.MethodPost, path, rr)
|
||||
}
|
||||
|
||||
// RemoveRules from a Firewall.
|
||||
func (fw *FirewallsServiceOp) RemoveRules(ctx context.Context, fID string, rr *FirewallRulesRequest) (*Response, error) {
|
||||
path := path.Join(firewallsBasePath, fID, "rules")
|
||||
return fw.createAndDoReq(ctx, http.MethodDelete, path, rr)
|
||||
}
|
||||
|
||||
type dropletsRequest struct {
|
||||
IDs []int `json:"droplet_ids"`
|
||||
}
|
||||
|
||||
type tagsRequest struct {
|
||||
Tags []string `json:"tags"`
|
||||
}
|
||||
|
||||
type firewallRoot struct {
|
||||
Firewall *Firewall `json:"firewall"`
|
||||
}
|
||||
|
||||
type firewallsRoot struct {
|
||||
Firewalls []Firewall `json:"firewalls"`
|
||||
Links *Links `json:"links"`
|
||||
}
|
||||
|
||||
func (fw *FirewallsServiceOp) createAndDoReq(ctx context.Context, method, path string, v interface{}) (*Response, error) {
|
||||
req, err := fw.client.NewRequest(ctx, method, path, v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return fw.client.Do(ctx, req, nil)
|
||||
}
|
||||
|
||||
func (fw *FirewallsServiceOp) listHelper(ctx context.Context, path string) ([]Firewall, *Response, error) {
|
||||
req, err := fw.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(firewallsRoot)
|
||||
resp, err := fw.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
if l := root.Links; l != nil {
|
||||
resp.Links = l
|
||||
}
|
||||
|
||||
return root.Firewalls, resp, err
|
||||
}
|
136
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/floating_ips.go
generated
vendored
Normal file
136
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/floating_ips.go
generated
vendored
Normal file
|
@ -0,0 +1,136 @@
|
|||
package godo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/digitalocean/godo/context"
|
||||
)
|
||||
|
||||
const floatingBasePath = "v2/floating_ips"
|
||||
|
||||
// FloatingIPsService is an interface for interfacing with the floating IPs
|
||||
// endpoints of the Digital Ocean API.
|
||||
// See: https://developers.digitalocean.com/documentation/v2#floating-ips
|
||||
type FloatingIPsService interface {
|
||||
List(context.Context, *ListOptions) ([]FloatingIP, *Response, error)
|
||||
Get(context.Context, string) (*FloatingIP, *Response, error)
|
||||
Create(context.Context, *FloatingIPCreateRequest) (*FloatingIP, *Response, error)
|
||||
Delete(context.Context, string) (*Response, error)
|
||||
}
|
||||
|
||||
// FloatingIPsServiceOp handles communication with the floating IPs related methods of the
|
||||
// DigitalOcean API.
|
||||
type FloatingIPsServiceOp struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
var _ FloatingIPsService = &FloatingIPsServiceOp{}
|
||||
|
||||
// FloatingIP represents a Digital Ocean floating IP.
|
||||
type FloatingIP struct {
|
||||
Region *Region `json:"region"`
|
||||
Droplet *Droplet `json:"droplet"`
|
||||
IP string `json:"ip"`
|
||||
}
|
||||
|
||||
func (f FloatingIP) String() string {
|
||||
return Stringify(f)
|
||||
}
|
||||
|
||||
type floatingIPsRoot struct {
|
||||
FloatingIPs []FloatingIP `json:"floating_ips"`
|
||||
Links *Links `json:"links"`
|
||||
}
|
||||
|
||||
type floatingIPRoot struct {
|
||||
FloatingIP *FloatingIP `json:"floating_ip"`
|
||||
Links *Links `json:"links,omitempty"`
|
||||
}
|
||||
|
||||
// FloatingIPCreateRequest represents a request to create a floating IP.
|
||||
// If DropletID is not empty, the floating IP will be assigned to the
|
||||
// droplet.
|
||||
type FloatingIPCreateRequest struct {
|
||||
Region string `json:"region"`
|
||||
DropletID int `json:"droplet_id,omitempty"`
|
||||
}
|
||||
|
||||
// List all floating IPs.
|
||||
func (f *FloatingIPsServiceOp) List(ctx context.Context, opt *ListOptions) ([]FloatingIP, *Response, error) {
|
||||
path := floatingBasePath
|
||||
path, err := addOptions(path, opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
req, err := f.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(floatingIPsRoot)
|
||||
resp, err := f.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
if l := root.Links; l != nil {
|
||||
resp.Links = l
|
||||
}
|
||||
|
||||
return root.FloatingIPs, resp, err
|
||||
}
|
||||
|
||||
// Get an individual floating IP.
|
||||
func (f *FloatingIPsServiceOp) Get(ctx context.Context, ip string) (*FloatingIP, *Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", floatingBasePath, ip)
|
||||
|
||||
req, err := f.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(floatingIPRoot)
|
||||
resp, err := f.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.FloatingIP, resp, err
|
||||
}
|
||||
|
||||
// Create a floating IP. If the DropletID field of the request is not empty,
|
||||
// the floating IP will also be assigned to the droplet.
|
||||
func (f *FloatingIPsServiceOp) Create(ctx context.Context, createRequest *FloatingIPCreateRequest) (*FloatingIP, *Response, error) {
|
||||
path := floatingBasePath
|
||||
|
||||
req, err := f.client.NewRequest(ctx, http.MethodPost, path, createRequest)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(floatingIPRoot)
|
||||
resp, err := f.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
if l := root.Links; l != nil {
|
||||
resp.Links = l
|
||||
}
|
||||
|
||||
return root.FloatingIP, resp, err
|
||||
}
|
||||
|
||||
// Delete a floating IP.
|
||||
func (f *FloatingIPsServiceOp) Delete(ctx context.Context, ip string) (*Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", floatingBasePath, ip)
|
||||
|
||||
req, err := f.client.NewRequest(ctx, http.MethodDelete, path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := f.client.Do(ctx, req, nil)
|
||||
|
||||
return resp, err
|
||||
}
|
110
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/floating_ips_actions.go
generated
vendored
Normal file
110
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/floating_ips_actions.go
generated
vendored
Normal file
|
@ -0,0 +1,110 @@
|
|||
package godo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/digitalocean/godo/context"
|
||||
)
|
||||
|
||||
// FloatingIPActionsService is an interface for interfacing with the
|
||||
// floating IPs actions endpoints of the Digital Ocean API.
|
||||
// See: https://developers.digitalocean.com/documentation/v2#floating-ips-action
|
||||
type FloatingIPActionsService interface {
|
||||
Assign(ctx context.Context, ip string, dropletID int) (*Action, *Response, error)
|
||||
Unassign(ctx context.Context, ip string) (*Action, *Response, error)
|
||||
Get(ctx context.Context, ip string, actionID int) (*Action, *Response, error)
|
||||
List(ctx context.Context, ip string, opt *ListOptions) ([]Action, *Response, error)
|
||||
}
|
||||
|
||||
// FloatingIPActionsServiceOp handles communication with the floating IPs
|
||||
// action related methods of the DigitalOcean API.
|
||||
type FloatingIPActionsServiceOp struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Assign a floating IP to a droplet.
|
||||
func (s *FloatingIPActionsServiceOp) Assign(ctx context.Context, ip string, dropletID int) (*Action, *Response, error) {
|
||||
request := &ActionRequest{
|
||||
"type": "assign",
|
||||
"droplet_id": dropletID,
|
||||
}
|
||||
return s.doAction(ctx, ip, request)
|
||||
}
|
||||
|
||||
// Unassign a floating IP from the droplet it is currently assigned to.
|
||||
func (s *FloatingIPActionsServiceOp) Unassign(ctx context.Context, ip string) (*Action, *Response, error) {
|
||||
request := &ActionRequest{"type": "unassign"}
|
||||
return s.doAction(ctx, ip, request)
|
||||
}
|
||||
|
||||
// Get an action for a particular floating IP by id.
|
||||
func (s *FloatingIPActionsServiceOp) Get(ctx context.Context, ip string, actionID int) (*Action, *Response, error) {
|
||||
path := fmt.Sprintf("%s/%d", floatingIPActionPath(ip), actionID)
|
||||
return s.get(ctx, path)
|
||||
}
|
||||
|
||||
// List the actions for a particular floating IP.
|
||||
func (s *FloatingIPActionsServiceOp) List(ctx context.Context, ip string, opt *ListOptions) ([]Action, *Response, error) {
|
||||
path := floatingIPActionPath(ip)
|
||||
path, err := addOptions(path, opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return s.list(ctx, path)
|
||||
}
|
||||
|
||||
func (s *FloatingIPActionsServiceOp) doAction(ctx context.Context, ip string, request *ActionRequest) (*Action, *Response, error) {
|
||||
path := floatingIPActionPath(ip)
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodPost, path, request)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(actionRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Event, resp, err
|
||||
}
|
||||
|
||||
func (s *FloatingIPActionsServiceOp) get(ctx context.Context, path string) (*Action, *Response, error) {
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(actionRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Event, resp, err
|
||||
}
|
||||
|
||||
func (s *FloatingIPActionsServiceOp) list(ctx context.Context, path string) ([]Action, *Response, error) {
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(actionsRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
if l := root.Links; l != nil {
|
||||
resp.Links = l
|
||||
}
|
||||
|
||||
return root.Actions, resp, err
|
||||
}
|
||||
|
||||
func floatingIPActionPath(ip string) string {
|
||||
return fmt.Sprintf("%s/%s/actions", floatingBasePath, ip)
|
||||
}
|
400
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/godo.go
generated
vendored
Normal file
400
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/godo.go
generated
vendored
Normal file
|
@ -0,0 +1,400 @@
|
|||
package godo
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-querystring/query"
|
||||
headerLink "github.com/tent/http-link-go"
|
||||
|
||||
"github.com/digitalocean/godo/context"
|
||||
)
|
||||
|
||||
const (
|
||||
libraryVersion = "1.1.0"
|
||||
defaultBaseURL = "https://api.digitalocean.com/"
|
||||
userAgent = "godo/" + libraryVersion
|
||||
mediaType = "application/json"
|
||||
|
||||
headerRateLimit = "RateLimit-Limit"
|
||||
headerRateRemaining = "RateLimit-Remaining"
|
||||
headerRateReset = "RateLimit-Reset"
|
||||
)
|
||||
|
||||
// Client manages communication with DigitalOcean V2 API.
|
||||
type Client struct {
|
||||
// HTTP client used to communicate with the DO API.
|
||||
client *http.Client
|
||||
|
||||
// Base URL for API requests.
|
||||
BaseURL *url.URL
|
||||
|
||||
// User agent for client
|
||||
UserAgent string
|
||||
|
||||
// Rate contains the current rate limit for the client as determined by the most recent
|
||||
// API call.
|
||||
Rate Rate
|
||||
|
||||
// Services used for communicating with the API
|
||||
Account AccountService
|
||||
Actions ActionsService
|
||||
Domains DomainsService
|
||||
Droplets DropletsService
|
||||
DropletActions DropletActionsService
|
||||
Images ImagesService
|
||||
ImageActions ImageActionsService
|
||||
Keys KeysService
|
||||
Regions RegionsService
|
||||
Sizes SizesService
|
||||
FloatingIPs FloatingIPsService
|
||||
FloatingIPActions FloatingIPActionsService
|
||||
Snapshots SnapshotsService
|
||||
Storage StorageService
|
||||
StorageActions StorageActionsService
|
||||
Tags TagsService
|
||||
LoadBalancers LoadBalancersService
|
||||
Certificates CertificatesService
|
||||
Firewalls FirewallsService
|
||||
|
||||
// Optional function called after every successful request made to the DO APIs
|
||||
onRequestCompleted RequestCompletionCallback
|
||||
}
|
||||
|
||||
// RequestCompletionCallback defines the type of the request callback function
|
||||
type RequestCompletionCallback func(*http.Request, *http.Response)
|
||||
|
||||
// ListOptions specifies the optional parameters to various List methods that
|
||||
// support pagination.
|
||||
type ListOptions struct {
|
||||
// For paginated result sets, page of results to retrieve.
|
||||
Page int `url:"page,omitempty"`
|
||||
|
||||
// For paginated result sets, the number of results to include per page.
|
||||
PerPage int `url:"per_page,omitempty"`
|
||||
}
|
||||
|
||||
// Response is a DigitalOcean response. This wraps the standard http.Response returned from DigitalOcean.
|
||||
type Response struct {
|
||||
*http.Response
|
||||
|
||||
// Links that were returned with the response. These are parsed from
|
||||
// request body and not the header.
|
||||
Links *Links
|
||||
|
||||
// Monitoring URI
|
||||
Monitor string
|
||||
|
||||
Rate
|
||||
}
|
||||
|
||||
// An ErrorResponse reports the error caused by an API request
|
||||
type ErrorResponse struct {
|
||||
// HTTP response that caused this error
|
||||
Response *http.Response
|
||||
|
||||
// Error message
|
||||
Message string `json:"message"`
|
||||
|
||||
// RequestID returned from the API, useful to contact support.
|
||||
RequestID string `json:"request_id"`
|
||||
}
|
||||
|
||||
// Rate contains the rate limit for the current client.
|
||||
type Rate struct {
|
||||
// The number of request per hour the client is currently limited to.
|
||||
Limit int `json:"limit"`
|
||||
|
||||
// The number of remaining requests the client can make this hour.
|
||||
Remaining int `json:"remaining"`
|
||||
|
||||
// The time at which the current rate limit will reset.
|
||||
Reset Timestamp `json:"reset"`
|
||||
}
|
||||
|
||||
func addOptions(s string, opt interface{}) (string, error) {
|
||||
v := reflect.ValueOf(opt)
|
||||
|
||||
if v.Kind() == reflect.Ptr && v.IsNil() {
|
||||
return s, nil
|
||||
}
|
||||
|
||||
origURL, err := url.Parse(s)
|
||||
if err != nil {
|
||||
return s, err
|
||||
}
|
||||
|
||||
origValues := origURL.Query()
|
||||
|
||||
newValues, err := query.Values(opt)
|
||||
if err != nil {
|
||||
return s, err
|
||||
}
|
||||
|
||||
for k, v := range newValues {
|
||||
origValues[k] = v
|
||||
}
|
||||
|
||||
origURL.RawQuery = origValues.Encode()
|
||||
return origURL.String(), nil
|
||||
}
|
||||
|
||||
// NewClient returns a new DigitalOcean API client.
|
||||
func NewClient(httpClient *http.Client) *Client {
|
||||
if httpClient == nil {
|
||||
httpClient = http.DefaultClient
|
||||
}
|
||||
|
||||
baseURL, _ := url.Parse(defaultBaseURL)
|
||||
|
||||
c := &Client{client: httpClient, BaseURL: baseURL, UserAgent: userAgent}
|
||||
c.Account = &AccountServiceOp{client: c}
|
||||
c.Actions = &ActionsServiceOp{client: c}
|
||||
c.Domains = &DomainsServiceOp{client: c}
|
||||
c.Droplets = &DropletsServiceOp{client: c}
|
||||
c.DropletActions = &DropletActionsServiceOp{client: c}
|
||||
c.FloatingIPs = &FloatingIPsServiceOp{client: c}
|
||||
c.FloatingIPActions = &FloatingIPActionsServiceOp{client: c}
|
||||
c.Images = &ImagesServiceOp{client: c}
|
||||
c.ImageActions = &ImageActionsServiceOp{client: c}
|
||||
c.Keys = &KeysServiceOp{client: c}
|
||||
c.Regions = &RegionsServiceOp{client: c}
|
||||
c.Snapshots = &SnapshotsServiceOp{client: c}
|
||||
c.Sizes = &SizesServiceOp{client: c}
|
||||
c.Storage = &StorageServiceOp{client: c}
|
||||
c.StorageActions = &StorageActionsServiceOp{client: c}
|
||||
c.Tags = &TagsServiceOp{client: c}
|
||||
c.LoadBalancers = &LoadBalancersServiceOp{client: c}
|
||||
c.Certificates = &CertificatesServiceOp{client: c}
|
||||
c.Firewalls = &FirewallsServiceOp{client: c}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
// ClientOpt are options for New.
|
||||
type ClientOpt func(*Client) error
|
||||
|
||||
// New returns a new DIgitalOcean API client instance.
|
||||
func New(httpClient *http.Client, opts ...ClientOpt) (*Client, error) {
|
||||
c := NewClient(httpClient)
|
||||
for _, opt := range opts {
|
||||
if err := opt(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// SetBaseURL is a client option for setting the base URL.
|
||||
func SetBaseURL(bu string) ClientOpt {
|
||||
return func(c *Client) error {
|
||||
u, err := url.Parse(bu)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.BaseURL = u
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// SetUserAgent is a client option for setting the user agent.
|
||||
func SetUserAgent(ua string) ClientOpt {
|
||||
return func(c *Client) error {
|
||||
c.UserAgent = fmt.Sprintf("%s+%s", ua, c.UserAgent)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// NewRequest creates an API request. A relative URL can be provided in urlStr, which will be resolved to the
|
||||
// BaseURL of the Client. Relative URLS should always be specified without a preceding slash. If specified, the
|
||||
// value pointed to by body is JSON encoded and included in as the request body.
|
||||
func (c *Client) NewRequest(ctx context.Context, method, urlStr string, body interface{}) (*http.Request, error) {
|
||||
rel, err := url.Parse(urlStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
u := c.BaseURL.ResolveReference(rel)
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
if body != nil {
|
||||
err = json.NewEncoder(buf).Encode(body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(method, u.String(), buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.Header.Add("Content-Type", mediaType)
|
||||
req.Header.Add("Accept", mediaType)
|
||||
req.Header.Add("User-Agent", c.UserAgent)
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// OnRequestCompleted sets the DO API request completion callback
|
||||
func (c *Client) OnRequestCompleted(rc RequestCompletionCallback) {
|
||||
c.onRequestCompleted = rc
|
||||
}
|
||||
|
||||
// newResponse creates a new Response for the provided http.Response
|
||||
func newResponse(r *http.Response) *Response {
|
||||
response := Response{Response: r}
|
||||
response.populateRate()
|
||||
|
||||
return &response
|
||||
}
|
||||
|
||||
func (r *Response) links() (map[string]headerLink.Link, error) {
|
||||
if linkText, ok := r.Response.Header["Link"]; ok {
|
||||
links, err := headerLink.Parse(linkText[0])
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
linkMap := map[string]headerLink.Link{}
|
||||
for _, link := range links {
|
||||
linkMap[link.Rel] = link
|
||||
}
|
||||
|
||||
return linkMap, nil
|
||||
}
|
||||
|
||||
return map[string]headerLink.Link{}, nil
|
||||
}
|
||||
|
||||
// populateRate parses the rate related headers and populates the response Rate.
|
||||
func (r *Response) populateRate() {
|
||||
if limit := r.Header.Get(headerRateLimit); limit != "" {
|
||||
r.Rate.Limit, _ = strconv.Atoi(limit)
|
||||
}
|
||||
if remaining := r.Header.Get(headerRateRemaining); remaining != "" {
|
||||
r.Rate.Remaining, _ = strconv.Atoi(remaining)
|
||||
}
|
||||
if reset := r.Header.Get(headerRateReset); reset != "" {
|
||||
if v, _ := strconv.ParseInt(reset, 10, 64); v != 0 {
|
||||
r.Rate.Reset = Timestamp{time.Unix(v, 0)}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do sends an API request and returns the API response. The API response is JSON decoded and stored in the value
|
||||
// pointed to by v, or returned as an error if an API error has occurred. If v implements the io.Writer interface,
|
||||
// the raw response will be written to v, without attempting to decode it.
|
||||
func (c *Client) Do(ctx context.Context, req *http.Request, v interface{}) (*Response, error) {
|
||||
resp, err := context.DoRequestWithClient(ctx, c.client, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if c.onRequestCompleted != nil {
|
||||
c.onRequestCompleted(req, resp)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if rerr := resp.Body.Close(); err == nil {
|
||||
err = rerr
|
||||
}
|
||||
}()
|
||||
|
||||
response := newResponse(resp)
|
||||
c.Rate = response.Rate
|
||||
|
||||
err = CheckResponse(resp)
|
||||
if err != nil {
|
||||
return response, err
|
||||
}
|
||||
|
||||
if v != nil {
|
||||
if w, ok := v.(io.Writer); ok {
|
||||
_, err = io.Copy(w, resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
err = json.NewDecoder(resp.Body).Decode(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return response, err
|
||||
}
|
||||
func (r *ErrorResponse) Error() string {
|
||||
if r.RequestID != "" {
|
||||
return fmt.Sprintf("%v %v: %d (request %q) %v",
|
||||
r.Response.Request.Method, r.Response.Request.URL, r.Response.StatusCode, r.RequestID, r.Message)
|
||||
}
|
||||
return fmt.Sprintf("%v %v: %d %v",
|
||||
r.Response.Request.Method, r.Response.Request.URL, r.Response.StatusCode, r.Message)
|
||||
}
|
||||
|
||||
// CheckResponse checks the API response for errors, and returns them if present. A response is considered an
|
||||
// error if it has a status code outside the 200 range. API error responses are expected to have either no response
|
||||
// body, or a JSON response body that maps to ErrorResponse. Any other response body will be silently ignored.
|
||||
func CheckResponse(r *http.Response) error {
|
||||
if c := r.StatusCode; c >= 200 && c <= 299 {
|
||||
return nil
|
||||
}
|
||||
|
||||
errorResponse := &ErrorResponse{Response: r}
|
||||
data, err := ioutil.ReadAll(r.Body)
|
||||
if err == nil && len(data) > 0 {
|
||||
err := json.Unmarshal(data, errorResponse)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return errorResponse
|
||||
}
|
||||
|
||||
func (r Rate) String() string {
|
||||
return Stringify(r)
|
||||
}
|
||||
|
||||
// String is a helper routine that allocates a new string value
|
||||
// to store v and returns a pointer to it.
|
||||
func String(v string) *string {
|
||||
p := new(string)
|
||||
*p = v
|
||||
return p
|
||||
}
|
||||
|
||||
// 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.
|
||||
func Int(v int) *int {
|
||||
p := new(int)
|
||||
*p = v
|
||||
return p
|
||||
}
|
||||
|
||||
// Bool is a helper routine that allocates a new bool value
|
||||
// to store v and returns a pointer to it.
|
||||
func Bool(v bool) *bool {
|
||||
p := new(bool)
|
||||
*p = v
|
||||
return p
|
||||
}
|
||||
|
||||
// StreamToString converts a reader to a string
|
||||
func StreamToString(stream io.Reader) string {
|
||||
buf := new(bytes.Buffer)
|
||||
_, _ = buf.ReadFrom(stream)
|
||||
return buf.String()
|
||||
}
|
103
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/image_actions.go
generated
vendored
Normal file
103
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/image_actions.go
generated
vendored
Normal file
|
@ -0,0 +1,103 @@
|
|||
package godo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/digitalocean/godo/context"
|
||||
)
|
||||
|
||||
// ImageActionsService is an interface for interfacing with the image actions
|
||||
// endpoints of the DigitalOcean API
|
||||
// See: https://developers.digitalocean.com/documentation/v2#image-actions
|
||||
type ImageActionsService interface {
|
||||
Get(context.Context, int, int) (*Action, *Response, error)
|
||||
Transfer(context.Context, int, *ActionRequest) (*Action, *Response, error)
|
||||
Convert(context.Context, int) (*Action, *Response, error)
|
||||
}
|
||||
|
||||
// ImageActionsServiceOp handles communition with the image action related methods of the
|
||||
// DigitalOcean API.
|
||||
type ImageActionsServiceOp struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
var _ ImageActionsService = &ImageActionsServiceOp{}
|
||||
|
||||
// Transfer an image
|
||||
func (i *ImageActionsServiceOp) Transfer(ctx context.Context, imageID int, transferRequest *ActionRequest) (*Action, *Response, error) {
|
||||
if imageID < 1 {
|
||||
return nil, nil, NewArgError("imageID", "cannot be less than 1")
|
||||
}
|
||||
|
||||
if transferRequest == nil {
|
||||
return nil, nil, NewArgError("transferRequest", "cannot be nil")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("v2/images/%d/actions", imageID)
|
||||
|
||||
req, err := i.client.NewRequest(ctx, http.MethodPost, path, transferRequest)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(actionRoot)
|
||||
resp, err := i.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Event, resp, err
|
||||
}
|
||||
|
||||
// Convert an image to a snapshot
|
||||
func (i *ImageActionsServiceOp) Convert(ctx context.Context, imageID int) (*Action, *Response, error) {
|
||||
if imageID < 1 {
|
||||
return nil, nil, NewArgError("imageID", "cannont be less than 1")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("v2/images/%d/actions", imageID)
|
||||
|
||||
convertRequest := &ActionRequest{
|
||||
"type": "convert",
|
||||
}
|
||||
|
||||
req, err := i.client.NewRequest(ctx, http.MethodPost, path, convertRequest)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(actionRoot)
|
||||
resp, err := i.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Event, resp, err
|
||||
}
|
||||
|
||||
// Get an action for a particular image by id.
|
||||
func (i *ImageActionsServiceOp) Get(ctx context.Context, imageID, actionID int) (*Action, *Response, error) {
|
||||
if imageID < 1 {
|
||||
return nil, nil, NewArgError("imageID", "cannot be less than 1")
|
||||
}
|
||||
|
||||
if actionID < 1 {
|
||||
return nil, nil, NewArgError("actionID", "cannot be less than 1")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("v2/images/%d/actions/%d", imageID, actionID)
|
||||
|
||||
req, err := i.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(actionRoot)
|
||||
resp, err := i.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Event, resp, err
|
||||
}
|
199
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/images.go
generated
vendored
Normal file
199
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/images.go
generated
vendored
Normal file
|
@ -0,0 +1,199 @@
|
|||
package godo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/digitalocean/godo/context"
|
||||
)
|
||||
|
||||
const imageBasePath = "v2/images"
|
||||
|
||||
// ImagesService is an interface for interfacing with the images
|
||||
// endpoints of the DigitalOcean API
|
||||
// See: https://developers.digitalocean.com/documentation/v2#images
|
||||
type ImagesService interface {
|
||||
List(context.Context, *ListOptions) ([]Image, *Response, error)
|
||||
ListDistribution(ctx context.Context, opt *ListOptions) ([]Image, *Response, error)
|
||||
ListApplication(ctx context.Context, opt *ListOptions) ([]Image, *Response, error)
|
||||
ListUser(ctx context.Context, opt *ListOptions) ([]Image, *Response, error)
|
||||
GetByID(context.Context, int) (*Image, *Response, error)
|
||||
GetBySlug(context.Context, string) (*Image, *Response, error)
|
||||
Update(context.Context, int, *ImageUpdateRequest) (*Image, *Response, error)
|
||||
Delete(context.Context, int) (*Response, error)
|
||||
}
|
||||
|
||||
// ImagesServiceOp handles communication with the image related methods of the
|
||||
// DigitalOcean API.
|
||||
type ImagesServiceOp struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
var _ ImagesService = &ImagesServiceOp{}
|
||||
|
||||
// Image represents a DigitalOcean Image
|
||||
type Image struct {
|
||||
ID int `json:"id,float64,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Distribution string `json:"distribution,omitempty"`
|
||||
Slug string `json:"slug,omitempty"`
|
||||
Public bool `json:"public,omitempty"`
|
||||
Regions []string `json:"regions,omitempty"`
|
||||
MinDiskSize int `json:"min_disk_size,omitempty"`
|
||||
Created string `json:"created_at,omitempty"`
|
||||
}
|
||||
|
||||
// ImageUpdateRequest represents a request to update an image.
|
||||
type ImageUpdateRequest struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type imageRoot struct {
|
||||
Image *Image
|
||||
}
|
||||
|
||||
type imagesRoot struct {
|
||||
Images []Image
|
||||
Links *Links `json:"links"`
|
||||
}
|
||||
|
||||
type listImageOptions struct {
|
||||
Private bool `url:"private,omitempty"`
|
||||
Type string `url:"type,omitempty"`
|
||||
}
|
||||
|
||||
func (i Image) String() string {
|
||||
return Stringify(i)
|
||||
}
|
||||
|
||||
// List lists all the images available.
|
||||
func (s *ImagesServiceOp) List(ctx context.Context, opt *ListOptions) ([]Image, *Response, error) {
|
||||
return s.list(ctx, opt, nil)
|
||||
}
|
||||
|
||||
// ListDistribution lists all the distribution images.
|
||||
func (s *ImagesServiceOp) ListDistribution(ctx context.Context, opt *ListOptions) ([]Image, *Response, error) {
|
||||
listOpt := listImageOptions{Type: "distribution"}
|
||||
return s.list(ctx, opt, &listOpt)
|
||||
}
|
||||
|
||||
// ListApplication lists all the application images.
|
||||
func (s *ImagesServiceOp) ListApplication(ctx context.Context, opt *ListOptions) ([]Image, *Response, error) {
|
||||
listOpt := listImageOptions{Type: "application"}
|
||||
return s.list(ctx, opt, &listOpt)
|
||||
}
|
||||
|
||||
// ListUser lists all the user images.
|
||||
func (s *ImagesServiceOp) ListUser(ctx context.Context, opt *ListOptions) ([]Image, *Response, error) {
|
||||
listOpt := listImageOptions{Private: true}
|
||||
return s.list(ctx, opt, &listOpt)
|
||||
}
|
||||
|
||||
// GetByID retrieves an image by id.
|
||||
func (s *ImagesServiceOp) GetByID(ctx context.Context, imageID int) (*Image, *Response, error) {
|
||||
if imageID < 1 {
|
||||
return nil, nil, NewArgError("imageID", "cannot be less than 1")
|
||||
}
|
||||
|
||||
return s.get(ctx, interface{}(imageID))
|
||||
}
|
||||
|
||||
// GetBySlug retrieves an image by slug.
|
||||
func (s *ImagesServiceOp) GetBySlug(ctx context.Context, slug string) (*Image, *Response, error) {
|
||||
if len(slug) < 1 {
|
||||
return nil, nil, NewArgError("slug", "cannot be blank")
|
||||
}
|
||||
|
||||
return s.get(ctx, interface{}(slug))
|
||||
}
|
||||
|
||||
// Update an image name.
|
||||
func (s *ImagesServiceOp) Update(ctx context.Context, imageID int, updateRequest *ImageUpdateRequest) (*Image, *Response, error) {
|
||||
if imageID < 1 {
|
||||
return nil, nil, NewArgError("imageID", "cannot be less than 1")
|
||||
}
|
||||
|
||||
if updateRequest == nil {
|
||||
return nil, nil, NewArgError("updateRequest", "cannot be nil")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%d", imageBasePath, imageID)
|
||||
req, err := s.client.NewRequest(ctx, "PUT", path, updateRequest)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(imageRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Image, resp, err
|
||||
}
|
||||
|
||||
// Delete an image.
|
||||
func (s *ImagesServiceOp) Delete(ctx context.Context, imageID int) (*Response, error) {
|
||||
if imageID < 1 {
|
||||
return nil, NewArgError("imageID", "cannot be less than 1")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%d", imageBasePath, imageID)
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodDelete, path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(ctx, req, nil)
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// Helper method for getting an individual image
|
||||
func (s *ImagesServiceOp) get(ctx context.Context, ID interface{}) (*Image, *Response, error) {
|
||||
path := fmt.Sprintf("%s/%v", imageBasePath, ID)
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(imageRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Image, resp, err
|
||||
}
|
||||
|
||||
// Helper method for listing images
|
||||
func (s *ImagesServiceOp) list(ctx context.Context, opt *ListOptions, listOpt *listImageOptions) ([]Image, *Response, error) {
|
||||
path := imageBasePath
|
||||
path, err := addOptions(path, opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
path, err = addOptions(path, listOpt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(imagesRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
if l := root.Links; l != nil {
|
||||
resp.Links = l
|
||||
}
|
||||
|
||||
return root.Images, resp, err
|
||||
}
|
227
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/keys.go
generated
vendored
Normal file
227
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/keys.go
generated
vendored
Normal file
|
@ -0,0 +1,227 @@
|
|||
package godo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/digitalocean/godo/context"
|
||||
)
|
||||
|
||||
const keysBasePath = "v2/account/keys"
|
||||
|
||||
// KeysService is an interface for interfacing with the keys
|
||||
// endpoints of the DigitalOcean API
|
||||
// See: https://developers.digitalocean.com/documentation/v2#keys
|
||||
type KeysService interface {
|
||||
List(context.Context, *ListOptions) ([]Key, *Response, error)
|
||||
GetByID(context.Context, int) (*Key, *Response, error)
|
||||
GetByFingerprint(context.Context, string) (*Key, *Response, error)
|
||||
Create(context.Context, *KeyCreateRequest) (*Key, *Response, error)
|
||||
UpdateByID(context.Context, int, *KeyUpdateRequest) (*Key, *Response, error)
|
||||
UpdateByFingerprint(context.Context, string, *KeyUpdateRequest) (*Key, *Response, error)
|
||||
DeleteByID(context.Context, int) (*Response, error)
|
||||
DeleteByFingerprint(context.Context, string) (*Response, error)
|
||||
}
|
||||
|
||||
// KeysServiceOp handles communication with key related method of the
|
||||
// DigitalOcean API.
|
||||
type KeysServiceOp struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
var _ KeysService = &KeysServiceOp{}
|
||||
|
||||
// Key represents a DigitalOcean Key.
|
||||
type Key struct {
|
||||
ID int `json:"id,float64,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Fingerprint string `json:"fingerprint,omitempty"`
|
||||
PublicKey string `json:"public_key,omitempty"`
|
||||
}
|
||||
|
||||
// KeyUpdateRequest represents a request to update a DigitalOcean key.
|
||||
type KeyUpdateRequest struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type keysRoot struct {
|
||||
SSHKeys []Key `json:"ssh_keys"`
|
||||
Links *Links `json:"links"`
|
||||
}
|
||||
|
||||
type keyRoot struct {
|
||||
SSHKey *Key `json:"ssh_key"`
|
||||
}
|
||||
|
||||
func (s Key) String() string {
|
||||
return Stringify(s)
|
||||
}
|
||||
|
||||
// KeyCreateRequest represents a request to create a new key.
|
||||
type KeyCreateRequest struct {
|
||||
Name string `json:"name"`
|
||||
PublicKey string `json:"public_key"`
|
||||
}
|
||||
|
||||
// List all keys
|
||||
func (s *KeysServiceOp) List(ctx context.Context, opt *ListOptions) ([]Key, *Response, error) {
|
||||
path := keysBasePath
|
||||
path, err := addOptions(path, opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(keysRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
if l := root.Links; l != nil {
|
||||
resp.Links = l
|
||||
}
|
||||
|
||||
return root.SSHKeys, resp, err
|
||||
}
|
||||
|
||||
// Performs a get given a path
|
||||
func (s *KeysServiceOp) get(ctx context.Context, path string) (*Key, *Response, error) {
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(keyRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.SSHKey, resp, err
|
||||
}
|
||||
|
||||
// GetByID gets a Key by id
|
||||
func (s *KeysServiceOp) GetByID(ctx context.Context, keyID int) (*Key, *Response, error) {
|
||||
if keyID < 1 {
|
||||
return nil, nil, NewArgError("keyID", "cannot be less than 1")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%d", keysBasePath, keyID)
|
||||
return s.get(ctx, path)
|
||||
}
|
||||
|
||||
// GetByFingerprint gets a Key by by fingerprint
|
||||
func (s *KeysServiceOp) GetByFingerprint(ctx context.Context, fingerprint string) (*Key, *Response, error) {
|
||||
if len(fingerprint) < 1 {
|
||||
return nil, nil, NewArgError("fingerprint", "cannot not be empty")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%s", keysBasePath, fingerprint)
|
||||
return s.get(ctx, path)
|
||||
}
|
||||
|
||||
// Create a key using a KeyCreateRequest
|
||||
func (s *KeysServiceOp) Create(ctx context.Context, createRequest *KeyCreateRequest) (*Key, *Response, error) {
|
||||
if createRequest == nil {
|
||||
return nil, nil, NewArgError("createRequest", "cannot be nil")
|
||||
}
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodPost, keysBasePath, createRequest)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(keyRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.SSHKey, resp, err
|
||||
}
|
||||
|
||||
// UpdateByID updates a key name by ID.
|
||||
func (s *KeysServiceOp) UpdateByID(ctx context.Context, keyID int, updateRequest *KeyUpdateRequest) (*Key, *Response, error) {
|
||||
if keyID < 1 {
|
||||
return nil, nil, NewArgError("keyID", "cannot be less than 1")
|
||||
}
|
||||
|
||||
if updateRequest == nil {
|
||||
return nil, nil, NewArgError("updateRequest", "cannot be nil")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%d", keysBasePath, keyID)
|
||||
req, err := s.client.NewRequest(ctx, "PUT", path, updateRequest)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(keyRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.SSHKey, resp, err
|
||||
}
|
||||
|
||||
// UpdateByFingerprint updates a key name by fingerprint.
|
||||
func (s *KeysServiceOp) UpdateByFingerprint(ctx context.Context, fingerprint string, updateRequest *KeyUpdateRequest) (*Key, *Response, error) {
|
||||
if len(fingerprint) < 1 {
|
||||
return nil, nil, NewArgError("fingerprint", "cannot be empty")
|
||||
}
|
||||
|
||||
if updateRequest == nil {
|
||||
return nil, nil, NewArgError("updateRequest", "cannot be nil")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%s", keysBasePath, fingerprint)
|
||||
req, err := s.client.NewRequest(ctx, "PUT", path, updateRequest)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(keyRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.SSHKey, resp, err
|
||||
}
|
||||
|
||||
// Delete key using a path
|
||||
func (s *KeysServiceOp) delete(ctx context.Context, path string) (*Response, error) {
|
||||
req, err := s.client.NewRequest(ctx, http.MethodDelete, path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(ctx, req, nil)
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// DeleteByID deletes a key by its id
|
||||
func (s *KeysServiceOp) DeleteByID(ctx context.Context, keyID int) (*Response, error) {
|
||||
if keyID < 1 {
|
||||
return nil, NewArgError("keyID", "cannot be less than 1")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%d", keysBasePath, keyID)
|
||||
return s.delete(ctx, path)
|
||||
}
|
||||
|
||||
// DeleteByFingerprint deletes a key by its fingerprint
|
||||
func (s *KeysServiceOp) DeleteByFingerprint(ctx context.Context, fingerprint string) (*Response, error) {
|
||||
if len(fingerprint) < 1 {
|
||||
return nil, NewArgError("fingerprint", "cannot be empty")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%s", keysBasePath, fingerprint)
|
||||
return s.delete(ctx, path)
|
||||
}
|
84
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/links.go
generated
vendored
Normal file
84
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/links.go
generated
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
package godo
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/digitalocean/godo/context"
|
||||
)
|
||||
|
||||
// Links manages links that are returned along with a List
|
||||
type Links struct {
|
||||
Pages *Pages `json:"pages,omitempty"`
|
||||
Actions []LinkAction `json:"actions,omitempty"`
|
||||
}
|
||||
|
||||
// Pages are pages specified in Links
|
||||
type Pages struct {
|
||||
First string `json:"first,omitempty"`
|
||||
Prev string `json:"prev,omitempty"`
|
||||
Last string `json:"last,omitempty"`
|
||||
Next string `json:"next,omitempty"`
|
||||
}
|
||||
|
||||
// LinkAction is a pointer to an action
|
||||
type LinkAction struct {
|
||||
ID int `json:"id,omitempty"`
|
||||
Rel string `json:"rel,omitempty"`
|
||||
HREF string `json:"href,omitempty"`
|
||||
}
|
||||
|
||||
// CurrentPage is current page of the list
|
||||
func (l *Links) CurrentPage() (int, error) {
|
||||
return l.Pages.current()
|
||||
}
|
||||
|
||||
func (p *Pages) current() (int, error) {
|
||||
switch {
|
||||
case p == nil:
|
||||
return 1, nil
|
||||
case p.Prev == "" && p.Next != "":
|
||||
return 1, nil
|
||||
case p.Prev != "":
|
||||
prevPage, err := pageForURL(p.Prev)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return prevPage + 1, nil
|
||||
}
|
||||
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// IsLastPage returns true if the current page is the last
|
||||
func (l *Links) IsLastPage() bool {
|
||||
if l.Pages == nil {
|
||||
return true
|
||||
}
|
||||
return l.Pages.isLast()
|
||||
}
|
||||
|
||||
func (p *Pages) isLast() bool {
|
||||
return p.Last == ""
|
||||
}
|
||||
|
||||
func pageForURL(urlText string) (int, error) {
|
||||
u, err := url.ParseRequestURI(urlText)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
pageStr := u.Query().Get("page")
|
||||
page, err := strconv.Atoi(pageStr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return page, nil
|
||||
}
|
||||
|
||||
// Get a link action by id.
|
||||
func (la *LinkAction) Get(ctx context.Context, client *Client) (*Action, *Response, error) {
|
||||
return client.Actions.Get(ctx, la.ID)
|
||||
}
|
278
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/load_balancers.go
generated
vendored
Normal file
278
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/load_balancers.go
generated
vendored
Normal file
|
@ -0,0 +1,278 @@
|
|||
package godo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/digitalocean/godo/context"
|
||||
)
|
||||
|
||||
const loadBalancersBasePath = "/v2/load_balancers"
|
||||
const forwardingRulesPath = "forwarding_rules"
|
||||
|
||||
const dropletsPath = "droplets"
|
||||
|
||||
// LoadBalancersService is an interface for managing load balancers with the DigitalOcean API.
|
||||
// See: https://developers.digitalocean.com/documentation/v2#load-balancers
|
||||
type LoadBalancersService interface {
|
||||
Get(context.Context, string) (*LoadBalancer, *Response, error)
|
||||
List(context.Context, *ListOptions) ([]LoadBalancer, *Response, error)
|
||||
Create(context.Context, *LoadBalancerRequest) (*LoadBalancer, *Response, error)
|
||||
Update(ctx context.Context, lbID string, lbr *LoadBalancerRequest) (*LoadBalancer, *Response, error)
|
||||
Delete(ctx context.Context, lbID string) (*Response, error)
|
||||
AddDroplets(ctx context.Context, lbID string, dropletIDs ...int) (*Response, error)
|
||||
RemoveDroplets(ctx context.Context, lbID string, dropletIDs ...int) (*Response, error)
|
||||
AddForwardingRules(ctx context.Context, lbID string, rules ...ForwardingRule) (*Response, error)
|
||||
RemoveForwardingRules(ctx context.Context, lbID string, rules ...ForwardingRule) (*Response, error)
|
||||
}
|
||||
|
||||
// LoadBalancer represents a DigitalOcean load balancer configuration.
|
||||
type LoadBalancer struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
IP string `json:"ip,omitempty"`
|
||||
Algorithm string `json:"algorithm,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
Created string `json:"created_at,omitempty"`
|
||||
ForwardingRules []ForwardingRule `json:"forwarding_rules,omitempty"`
|
||||
HealthCheck *HealthCheck `json:"health_check,omitempty"`
|
||||
StickySessions *StickySessions `json:"sticky_sessions,omitempty"`
|
||||
Region *Region `json:"region,omitempty"`
|
||||
DropletIDs []int `json:"droplet_ids,omitempty"`
|
||||
Tag string `json:"tag,omitempty"`
|
||||
RedirectHttpToHttps bool `json:"redirect_http_to_https,omitempty"`
|
||||
}
|
||||
|
||||
// String creates a human-readable description of a LoadBalancer.
|
||||
func (l LoadBalancer) String() string {
|
||||
return Stringify(l)
|
||||
}
|
||||
|
||||
// ForwardingRule represents load balancer forwarding rules.
|
||||
type ForwardingRule struct {
|
||||
EntryProtocol string `json:"entry_protocol,omitempty"`
|
||||
EntryPort int `json:"entry_port,omitempty"`
|
||||
TargetProtocol string `json:"target_protocol,omitempty"`
|
||||
TargetPort int `json:"target_port,omitempty"`
|
||||
CertificateID string `json:"certificate_id,omitempty"`
|
||||
TlsPassthrough bool `json:"tls_passthrough,omitempty"`
|
||||
}
|
||||
|
||||
// String creates a human-readable description of a ForwardingRule.
|
||||
func (f ForwardingRule) String() string {
|
||||
return Stringify(f)
|
||||
}
|
||||
|
||||
// HealthCheck represents optional load balancer health check rules.
|
||||
type HealthCheck struct {
|
||||
Protocol string `json:"protocol,omitempty"`
|
||||
Port int `json:"port,omitempty"`
|
||||
Path string `json:"path,omitempty"`
|
||||
CheckIntervalSeconds int `json:"check_interval_seconds,omitempty"`
|
||||
ResponseTimeoutSeconds int `json:"response_timeout_seconds,omitempty"`
|
||||
HealthyThreshold int `json:"healthy_threshold,omitempty"`
|
||||
UnhealthyThreshold int `json:"unhealthy_threshold,omitempty"`
|
||||
}
|
||||
|
||||
// String creates a human-readable description of a HealthCheck.
|
||||
func (h HealthCheck) String() string {
|
||||
return Stringify(h)
|
||||
}
|
||||
|
||||
// StickySessions represents optional load balancer session affinity rules.
|
||||
type StickySessions struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
CookieName string `json:"cookie_name,omitempty"`
|
||||
CookieTtlSeconds int `json:"cookie_ttl_seconds,omitempty"`
|
||||
}
|
||||
|
||||
// String creates a human-readable description of a StickySessions instance.
|
||||
func (s StickySessions) String() string {
|
||||
return Stringify(s)
|
||||
}
|
||||
|
||||
// LoadBalancerRequest represents the configuration to be applied to an existing or a new load balancer.
|
||||
type LoadBalancerRequest struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Algorithm string `json:"algorithm,omitempty"`
|
||||
Region string `json:"region,omitempty"`
|
||||
ForwardingRules []ForwardingRule `json:"forwarding_rules,omitempty"`
|
||||
HealthCheck *HealthCheck `json:"health_check,omitempty"`
|
||||
StickySessions *StickySessions `json:"sticky_sessions,omitempty"`
|
||||
DropletIDs []int `json:"droplet_ids,omitempty"`
|
||||
Tag string `json:"tag,omitempty"`
|
||||
RedirectHttpToHttps bool `json:"redirect_http_to_https,omitempty"`
|
||||
}
|
||||
|
||||
// String creates a human-readable description of a LoadBalancerRequest.
|
||||
func (l LoadBalancerRequest) String() string {
|
||||
return Stringify(l)
|
||||
}
|
||||
|
||||
type forwardingRulesRequest struct {
|
||||
Rules []ForwardingRule `json:"forwarding_rules,omitempty"`
|
||||
}
|
||||
|
||||
func (l forwardingRulesRequest) String() string {
|
||||
return Stringify(l)
|
||||
}
|
||||
|
||||
type dropletIDsRequest struct {
|
||||
IDs []int `json:"droplet_ids,omitempty"`
|
||||
}
|
||||
|
||||
func (l dropletIDsRequest) String() string {
|
||||
return Stringify(l)
|
||||
}
|
||||
|
||||
type loadBalancersRoot struct {
|
||||
LoadBalancers []LoadBalancer `json:"load_balancers"`
|
||||
Links *Links `json:"links"`
|
||||
}
|
||||
|
||||
type loadBalancerRoot struct {
|
||||
LoadBalancer *LoadBalancer `json:"load_balancer"`
|
||||
}
|
||||
|
||||
// LoadBalancersServiceOp handles communication with load balancer-related methods of the DigitalOcean API.
|
||||
type LoadBalancersServiceOp struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
var _ LoadBalancersService = &LoadBalancersServiceOp{}
|
||||
|
||||
// Get an existing load balancer by its identifier.
|
||||
func (l *LoadBalancersServiceOp) Get(ctx context.Context, lbID string) (*LoadBalancer, *Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", loadBalancersBasePath, lbID)
|
||||
|
||||
req, err := l.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(loadBalancerRoot)
|
||||
resp, err := l.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.LoadBalancer, resp, err
|
||||
}
|
||||
|
||||
// List load balancers, with optional pagination.
|
||||
func (l *LoadBalancersServiceOp) List(ctx context.Context, opt *ListOptions) ([]LoadBalancer, *Response, error) {
|
||||
path, err := addOptions(loadBalancersBasePath, opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
req, err := l.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(loadBalancersRoot)
|
||||
resp, err := l.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
if l := root.Links; l != nil {
|
||||
resp.Links = l
|
||||
}
|
||||
|
||||
return root.LoadBalancers, resp, err
|
||||
}
|
||||
|
||||
// Create a new load balancer with a given configuration.
|
||||
func (l *LoadBalancersServiceOp) Create(ctx context.Context, lbr *LoadBalancerRequest) (*LoadBalancer, *Response, error) {
|
||||
req, err := l.client.NewRequest(ctx, http.MethodPost, loadBalancersBasePath, lbr)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(loadBalancerRoot)
|
||||
resp, err := l.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.LoadBalancer, resp, err
|
||||
}
|
||||
|
||||
// Update an existing load balancer with new configuration.
|
||||
func (l *LoadBalancersServiceOp) Update(ctx context.Context, lbID string, lbr *LoadBalancerRequest) (*LoadBalancer, *Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", loadBalancersBasePath, lbID)
|
||||
|
||||
req, err := l.client.NewRequest(ctx, "PUT", path, lbr)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(loadBalancerRoot)
|
||||
resp, err := l.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.LoadBalancer, resp, err
|
||||
}
|
||||
|
||||
// Delete a load balancer by its identifier.
|
||||
func (l *LoadBalancersServiceOp) Delete(ctx context.Context, ldID string) (*Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", loadBalancersBasePath, ldID)
|
||||
|
||||
req, err := l.client.NewRequest(ctx, http.MethodDelete, path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return l.client.Do(ctx, req, nil)
|
||||
}
|
||||
|
||||
// AddDroplets adds droplets to a load balancer.
|
||||
func (l *LoadBalancersServiceOp) AddDroplets(ctx context.Context, lbID string, dropletIDs ...int) (*Response, error) {
|
||||
path := fmt.Sprintf("%s/%s/%s", loadBalancersBasePath, lbID, dropletsPath)
|
||||
|
||||
req, err := l.client.NewRequest(ctx, http.MethodPost, path, &dropletIDsRequest{IDs: dropletIDs})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return l.client.Do(ctx, req, nil)
|
||||
}
|
||||
|
||||
// RemoveDroplets removes droplets from a load balancer.
|
||||
func (l *LoadBalancersServiceOp) RemoveDroplets(ctx context.Context, lbID string, dropletIDs ...int) (*Response, error) {
|
||||
path := fmt.Sprintf("%s/%s/%s", loadBalancersBasePath, lbID, dropletsPath)
|
||||
|
||||
req, err := l.client.NewRequest(ctx, http.MethodDelete, path, &dropletIDsRequest{IDs: dropletIDs})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return l.client.Do(ctx, req, nil)
|
||||
}
|
||||
|
||||
// AddForwardingRules adds forwarding rules to a load balancer.
|
||||
func (l *LoadBalancersServiceOp) AddForwardingRules(ctx context.Context, lbID string, rules ...ForwardingRule) (*Response, error) {
|
||||
path := fmt.Sprintf("%s/%s/%s", loadBalancersBasePath, lbID, forwardingRulesPath)
|
||||
|
||||
req, err := l.client.NewRequest(ctx, http.MethodPost, path, &forwardingRulesRequest{Rules: rules})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return l.client.Do(ctx, req, nil)
|
||||
}
|
||||
|
||||
// RemoveForwardingRules removes forwarding rules from a load balancer.
|
||||
func (l *LoadBalancersServiceOp) RemoveForwardingRules(ctx context.Context, lbID string, rules ...ForwardingRule) (*Response, error) {
|
||||
path := fmt.Sprintf("%s/%s/%s", loadBalancersBasePath, lbID, forwardingRulesPath)
|
||||
|
||||
req, err := l.client.NewRequest(ctx, http.MethodDelete, path, &forwardingRulesRequest{Rules: rules})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return l.client.Do(ctx, req, nil)
|
||||
}
|
65
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/regions.go
generated
vendored
Normal file
65
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/regions.go
generated
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
package godo
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/digitalocean/godo/context"
|
||||
)
|
||||
|
||||
// RegionsService is an interface for interfacing with the regions
|
||||
// endpoints of the DigitalOcean API
|
||||
// See: https://developers.digitalocean.com/documentation/v2#regions
|
||||
type RegionsService interface {
|
||||
List(context.Context, *ListOptions) ([]Region, *Response, error)
|
||||
}
|
||||
|
||||
// RegionsServiceOp handles communication with the region related methods of the
|
||||
// DigitalOcean API.
|
||||
type RegionsServiceOp struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
var _ RegionsService = &RegionsServiceOp{}
|
||||
|
||||
// Region represents a DigitalOcean Region
|
||||
type Region struct {
|
||||
Slug string `json:"slug,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Sizes []string `json:"sizes,omitempty"`
|
||||
Available bool `json:"available,omitempty"`
|
||||
Features []string `json:"features,omitempty"`
|
||||
}
|
||||
|
||||
type regionsRoot struct {
|
||||
Regions []Region
|
||||
Links *Links `json:"links"`
|
||||
}
|
||||
|
||||
func (r Region) String() string {
|
||||
return Stringify(r)
|
||||
}
|
||||
|
||||
// List all regions
|
||||
func (s *RegionsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Region, *Response, error) {
|
||||
path := "v2/regions"
|
||||
path, err := addOptions(path, opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(regionsRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
if l := root.Links; l != nil {
|
||||
resp.Links = l
|
||||
}
|
||||
|
||||
return root.Regions, resp, err
|
||||
}
|
69
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/sizes.go
generated
vendored
Normal file
69
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/sizes.go
generated
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
package godo
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/digitalocean/godo/context"
|
||||
)
|
||||
|
||||
// SizesService is an interface for interfacing with the size
|
||||
// endpoints of the DigitalOcean API
|
||||
// See: https://developers.digitalocean.com/documentation/v2#sizes
|
||||
type SizesService interface {
|
||||
List(context.Context, *ListOptions) ([]Size, *Response, error)
|
||||
}
|
||||
|
||||
// SizesServiceOp handles communication with the size related methods of the
|
||||
// DigitalOcean API.
|
||||
type SizesServiceOp struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
var _ SizesService = &SizesServiceOp{}
|
||||
|
||||
// Size represents a DigitalOcean Size
|
||||
type Size struct {
|
||||
Slug string `json:"slug,omitempty"`
|
||||
Memory int `json:"memory,omitempty"`
|
||||
Vcpus int `json:"vcpus,omitempty"`
|
||||
Disk int `json:"disk,omitempty"`
|
||||
PriceMonthly float64 `json:"price_monthly,omitempty"`
|
||||
PriceHourly float64 `json:"price_hourly,omitempty"`
|
||||
Regions []string `json:"regions,omitempty"`
|
||||
Available bool `json:"available,omitempty"`
|
||||
Transfer float64 `json:"transfer,omitempty"`
|
||||
}
|
||||
|
||||
func (s Size) String() string {
|
||||
return Stringify(s)
|
||||
}
|
||||
|
||||
type sizesRoot struct {
|
||||
Sizes []Size
|
||||
Links *Links `json:"links"`
|
||||
}
|
||||
|
||||
// List all images
|
||||
func (s *SizesServiceOp) List(ctx context.Context, opt *ListOptions) ([]Size, *Response, error) {
|
||||
path := "v2/sizes"
|
||||
path, err := addOptions(path, opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(sizesRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
if l := root.Links; l != nil {
|
||||
resp.Links = l
|
||||
}
|
||||
|
||||
return root.Sizes, resp, err
|
||||
}
|
141
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/snapshots.go
generated
vendored
Normal file
141
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/snapshots.go
generated
vendored
Normal file
|
@ -0,0 +1,141 @@
|
|||
package godo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/digitalocean/godo/context"
|
||||
)
|
||||
|
||||
const snapshotBasePath = "v2/snapshots"
|
||||
|
||||
// SnapshotsService is an interface for interfacing with the snapshots
|
||||
// endpoints of the DigitalOcean API
|
||||
// See: https://developers.digitalocean.com/documentation/v2#snapshots
|
||||
type SnapshotsService interface {
|
||||
List(context.Context, *ListOptions) ([]Snapshot, *Response, error)
|
||||
ListVolume(context.Context, *ListOptions) ([]Snapshot, *Response, error)
|
||||
ListDroplet(context.Context, *ListOptions) ([]Snapshot, *Response, error)
|
||||
Get(context.Context, string) (*Snapshot, *Response, error)
|
||||
Delete(context.Context, string) (*Response, error)
|
||||
}
|
||||
|
||||
// SnapshotsServiceOp handles communication with the snapshot related methods of the
|
||||
// DigitalOcean API.
|
||||
type SnapshotsServiceOp struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
var _ SnapshotsService = &SnapshotsServiceOp{}
|
||||
|
||||
// Snapshot represents a DigitalOcean Snapshot
|
||||
type Snapshot struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
ResourceID string `json:"resource_id,omitempty"`
|
||||
ResourceType string `json:"resource_type,omitempty"`
|
||||
Regions []string `json:"regions,omitempty"`
|
||||
MinDiskSize int `json:"min_disk_size,omitempty"`
|
||||
SizeGigaBytes float64 `json:"size_gigabytes,omitempty"`
|
||||
Created string `json:"created_at,omitempty"`
|
||||
}
|
||||
|
||||
type snapshotRoot struct {
|
||||
Snapshot *Snapshot `json:"snapshot"`
|
||||
}
|
||||
|
||||
type snapshotsRoot struct {
|
||||
Snapshots []Snapshot `json:"snapshots"`
|
||||
Links *Links `json:"links,omitempty"`
|
||||
}
|
||||
|
||||
type listSnapshotOptions struct {
|
||||
ResourceType string `url:"resource_type,omitempty"`
|
||||
}
|
||||
|
||||
func (s Snapshot) String() string {
|
||||
return Stringify(s)
|
||||
}
|
||||
|
||||
// List lists all the snapshots available.
|
||||
func (s *SnapshotsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Snapshot, *Response, error) {
|
||||
return s.list(ctx, opt, nil)
|
||||
}
|
||||
|
||||
// ListDroplet lists all the Droplet snapshots.
|
||||
func (s *SnapshotsServiceOp) ListDroplet(ctx context.Context, opt *ListOptions) ([]Snapshot, *Response, error) {
|
||||
listOpt := listSnapshotOptions{ResourceType: "droplet"}
|
||||
return s.list(ctx, opt, &listOpt)
|
||||
}
|
||||
|
||||
// ListVolume lists all the volume snapshots.
|
||||
func (s *SnapshotsServiceOp) ListVolume(ctx context.Context, opt *ListOptions) ([]Snapshot, *Response, error) {
|
||||
listOpt := listSnapshotOptions{ResourceType: "volume"}
|
||||
return s.list(ctx, opt, &listOpt)
|
||||
}
|
||||
|
||||
// Get retrieves an snapshot by id.
|
||||
func (s *SnapshotsServiceOp) Get(ctx context.Context, snapshotID string) (*Snapshot, *Response, error) {
|
||||
return s.get(ctx, snapshotID)
|
||||
}
|
||||
|
||||
// Delete an snapshot.
|
||||
func (s *SnapshotsServiceOp) Delete(ctx context.Context, snapshotID string) (*Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", snapshotBasePath, snapshotID)
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodDelete, path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(ctx, req, nil)
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// Helper method for getting an individual snapshot
|
||||
func (s *SnapshotsServiceOp) get(ctx context.Context, ID string) (*Snapshot, *Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", snapshotBasePath, ID)
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(snapshotRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Snapshot, resp, err
|
||||
}
|
||||
|
||||
// Helper method for listing snapshots
|
||||
func (s *SnapshotsServiceOp) list(ctx context.Context, opt *ListOptions, listOpt *listSnapshotOptions) ([]Snapshot, *Response, error) {
|
||||
path := snapshotBasePath
|
||||
path, err := addOptions(path, opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
path, err = addOptions(path, listOpt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(snapshotsRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
if l := root.Links; l != nil {
|
||||
resp.Links = l
|
||||
}
|
||||
|
||||
return root.Snapshots, resp, err
|
||||
}
|
241
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/storage.go
generated
vendored
Normal file
241
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/storage.go
generated
vendored
Normal file
|
@ -0,0 +1,241 @@
|
|||
package godo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"net/http"
|
||||
|
||||
"github.com/digitalocean/godo/context"
|
||||
)
|
||||
|
||||
const (
|
||||
storageBasePath = "v2"
|
||||
storageAllocPath = storageBasePath + "/volumes"
|
||||
storageSnapPath = storageBasePath + "/snapshots"
|
||||
)
|
||||
|
||||
// StorageService is an interface for interfacing with the storage
|
||||
// endpoints of the Digital Ocean API.
|
||||
// See: https://developers.digitalocean.com/documentation/v2#storage
|
||||
type StorageService interface {
|
||||
ListVolumes(context.Context, *ListVolumeParams) ([]Volume, *Response, error)
|
||||
GetVolume(context.Context, string) (*Volume, *Response, error)
|
||||
CreateVolume(context.Context, *VolumeCreateRequest) (*Volume, *Response, error)
|
||||
DeleteVolume(context.Context, string) (*Response, error)
|
||||
ListSnapshots(ctx context.Context, volumeID string, opts *ListOptions) ([]Snapshot, *Response, error)
|
||||
GetSnapshot(context.Context, string) (*Snapshot, *Response, error)
|
||||
CreateSnapshot(context.Context, *SnapshotCreateRequest) (*Snapshot, *Response, error)
|
||||
DeleteSnapshot(context.Context, string) (*Response, error)
|
||||
}
|
||||
|
||||
// StorageServiceOp handles communication with the storage volumes related methods of the
|
||||
// DigitalOcean API.
|
||||
type StorageServiceOp struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// ListVolumeParams stores the options you can set for a ListVolumeCall
|
||||
type ListVolumeParams struct {
|
||||
Region string `json:"region"`
|
||||
Name string `json:"name"`
|
||||
ListOptions *ListOptions `json:"list_options,omitempty"`
|
||||
}
|
||||
|
||||
var _ StorageService = &StorageServiceOp{}
|
||||
|
||||
// Volume represents a Digital Ocean block store volume.
|
||||
type Volume struct {
|
||||
ID string `json:"id"`
|
||||
Region *Region `json:"region"`
|
||||
Name string `json:"name"`
|
||||
SizeGigaBytes int64 `json:"size_gigabytes"`
|
||||
Description string `json:"description"`
|
||||
DropletIDs []int `json:"droplet_ids"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
func (f Volume) String() string {
|
||||
return Stringify(f)
|
||||
}
|
||||
|
||||
type storageVolumesRoot struct {
|
||||
Volumes []Volume `json:"volumes"`
|
||||
Links *Links `json:"links"`
|
||||
}
|
||||
|
||||
type storageVolumeRoot struct {
|
||||
Volume *Volume `json:"volume"`
|
||||
Links *Links `json:"links,omitempty"`
|
||||
}
|
||||
|
||||
// VolumeCreateRequest represents a request to create a block store
|
||||
// volume.
|
||||
type VolumeCreateRequest struct {
|
||||
Region string `json:"region"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
SizeGigaBytes int64 `json:"size_gigabytes"`
|
||||
SnapshotID string `json:"snapshot_id"`
|
||||
}
|
||||
|
||||
// ListVolumes lists all storage volumes.
|
||||
func (svc *StorageServiceOp) ListVolumes(ctx context.Context, params *ListVolumeParams) ([]Volume, *Response, error) {
|
||||
path := storageAllocPath
|
||||
if params != nil {
|
||||
if params.Region != "" && params.Name != "" {
|
||||
path = fmt.Sprintf("%s?name=%s®ion=%s", path, params.Name, params.Region)
|
||||
}
|
||||
|
||||
if params.ListOptions != nil {
|
||||
var err error
|
||||
path, err = addOptions(path, params.ListOptions)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
req, err := svc.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(storageVolumesRoot)
|
||||
resp, err := svc.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
if l := root.Links; l != nil {
|
||||
resp.Links = l
|
||||
}
|
||||
|
||||
return root.Volumes, resp, nil
|
||||
}
|
||||
|
||||
// CreateVolume creates a storage volume. The name must be unique.
|
||||
func (svc *StorageServiceOp) CreateVolume(ctx context.Context, createRequest *VolumeCreateRequest) (*Volume, *Response, error) {
|
||||
path := storageAllocPath
|
||||
|
||||
req, err := svc.client.NewRequest(ctx, http.MethodPost, path, createRequest)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(storageVolumeRoot)
|
||||
resp, err := svc.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
return root.Volume, resp, nil
|
||||
}
|
||||
|
||||
// GetVolume retrieves an individual storage volume.
|
||||
func (svc *StorageServiceOp) GetVolume(ctx context.Context, id string) (*Volume, *Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", storageAllocPath, id)
|
||||
|
||||
req, err := svc.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(storageVolumeRoot)
|
||||
resp, err := svc.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Volume, resp, nil
|
||||
}
|
||||
|
||||
// DeleteVolume deletes a storage volume.
|
||||
func (svc *StorageServiceOp) DeleteVolume(ctx context.Context, id string) (*Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", storageAllocPath, id)
|
||||
|
||||
req, err := svc.client.NewRequest(ctx, http.MethodDelete, path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return svc.client.Do(ctx, req, nil)
|
||||
}
|
||||
|
||||
// SnapshotCreateRequest represents a request to create a block store
|
||||
// volume.
|
||||
type SnapshotCreateRequest struct {
|
||||
VolumeID string `json:"volume_id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
// ListSnapshots lists all snapshots related to a storage volume.
|
||||
func (svc *StorageServiceOp) ListSnapshots(ctx context.Context, volumeID string, opt *ListOptions) ([]Snapshot, *Response, error) {
|
||||
path := fmt.Sprintf("%s/%s/snapshots", storageAllocPath, volumeID)
|
||||
path, err := addOptions(path, opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
req, err := svc.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(snapshotsRoot)
|
||||
resp, err := svc.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
if l := root.Links; l != nil {
|
||||
resp.Links = l
|
||||
}
|
||||
|
||||
return root.Snapshots, resp, nil
|
||||
}
|
||||
|
||||
// CreateSnapshot creates a snapshot of a storage volume.
|
||||
func (svc *StorageServiceOp) CreateSnapshot(ctx context.Context, createRequest *SnapshotCreateRequest) (*Snapshot, *Response, error) {
|
||||
path := fmt.Sprintf("%s/%s/snapshots", storageAllocPath, createRequest.VolumeID)
|
||||
|
||||
req, err := svc.client.NewRequest(ctx, http.MethodPost, path, createRequest)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(snapshotRoot)
|
||||
resp, err := svc.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
return root.Snapshot, resp, nil
|
||||
}
|
||||
|
||||
// GetSnapshot retrieves an individual snapshot.
|
||||
func (svc *StorageServiceOp) GetSnapshot(ctx context.Context, id string) (*Snapshot, *Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", storageSnapPath, id)
|
||||
|
||||
req, err := svc.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(snapshotRoot)
|
||||
resp, err := svc.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Snapshot, resp, nil
|
||||
}
|
||||
|
||||
// DeleteSnapshot deletes a snapshot.
|
||||
func (svc *StorageServiceOp) DeleteSnapshot(ctx context.Context, id string) (*Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", storageSnapPath, id)
|
||||
|
||||
req, err := svc.client.NewRequest(ctx, http.MethodDelete, path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return svc.client.Do(ctx, req, nil)
|
||||
}
|
130
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/storage_actions.go
generated
vendored
Normal file
130
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/storage_actions.go
generated
vendored
Normal file
|
@ -0,0 +1,130 @@
|
|||
package godo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/digitalocean/godo/context"
|
||||
)
|
||||
|
||||
// StorageActionsService is an interface for interfacing with the
|
||||
// storage actions endpoints of the Digital Ocean API.
|
||||
// See: https://developers.digitalocean.com/documentation/v2#storage-actions
|
||||
type StorageActionsService interface {
|
||||
Attach(ctx context.Context, volumeID string, dropletID int) (*Action, *Response, error)
|
||||
DetachByDropletID(ctx context.Context, volumeID string, dropletID int) (*Action, *Response, error)
|
||||
Get(ctx context.Context, volumeID string, actionID int) (*Action, *Response, error)
|
||||
List(ctx context.Context, volumeID string, opt *ListOptions) ([]Action, *Response, error)
|
||||
Resize(ctx context.Context, volumeID string, sizeGigabytes int, regionSlug string) (*Action, *Response, error)
|
||||
}
|
||||
|
||||
// StorageActionsServiceOp handles communication with the storage volumes
|
||||
// action related methods of the DigitalOcean API.
|
||||
type StorageActionsServiceOp struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// StorageAttachment represents the attachement of a block storage
|
||||
// volume to a specific Droplet under the device name.
|
||||
type StorageAttachment struct {
|
||||
DropletID int `json:"droplet_id"`
|
||||
}
|
||||
|
||||
// Attach a storage volume to a Droplet.
|
||||
func (s *StorageActionsServiceOp) Attach(ctx context.Context, volumeID string, dropletID int) (*Action, *Response, error) {
|
||||
request := &ActionRequest{
|
||||
"type": "attach",
|
||||
"droplet_id": dropletID,
|
||||
}
|
||||
return s.doAction(ctx, volumeID, request)
|
||||
}
|
||||
|
||||
// DetachByDropletID a storage volume from a Droplet by Droplet ID.
|
||||
func (s *StorageActionsServiceOp) DetachByDropletID(ctx context.Context, volumeID string, dropletID int) (*Action, *Response, error) {
|
||||
request := &ActionRequest{
|
||||
"type": "detach",
|
||||
"droplet_id": dropletID,
|
||||
}
|
||||
return s.doAction(ctx, volumeID, request)
|
||||
}
|
||||
|
||||
// Get an action for a particular storage volume by id.
|
||||
func (s *StorageActionsServiceOp) Get(ctx context.Context, volumeID string, actionID int) (*Action, *Response, error) {
|
||||
path := fmt.Sprintf("%s/%d", storageAllocationActionPath(volumeID), actionID)
|
||||
return s.get(ctx, path)
|
||||
}
|
||||
|
||||
// List the actions for a particular storage volume.
|
||||
func (s *StorageActionsServiceOp) List(ctx context.Context, volumeID string, opt *ListOptions) ([]Action, *Response, error) {
|
||||
path := storageAllocationActionPath(volumeID)
|
||||
path, err := addOptions(path, opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return s.list(ctx, path)
|
||||
}
|
||||
|
||||
// Resize a storage volume.
|
||||
func (s *StorageActionsServiceOp) Resize(ctx context.Context, volumeID string, sizeGigabytes int, regionSlug string) (*Action, *Response, error) {
|
||||
request := &ActionRequest{
|
||||
"type": "resize",
|
||||
"size_gigabytes": sizeGigabytes,
|
||||
"region": regionSlug,
|
||||
}
|
||||
return s.doAction(ctx, volumeID, request)
|
||||
}
|
||||
|
||||
func (s *StorageActionsServiceOp) doAction(ctx context.Context, volumeID string, request *ActionRequest) (*Action, *Response, error) {
|
||||
path := storageAllocationActionPath(volumeID)
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodPost, path, request)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(actionRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Event, resp, err
|
||||
}
|
||||
|
||||
func (s *StorageActionsServiceOp) get(ctx context.Context, path string) (*Action, *Response, error) {
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(actionRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Event, resp, err
|
||||
}
|
||||
|
||||
func (s *StorageActionsServiceOp) list(ctx context.Context, path string) ([]Action, *Response, error) {
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(actionsRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
if l := root.Links; l != nil {
|
||||
resp.Links = l
|
||||
}
|
||||
|
||||
return root.Actions, resp, err
|
||||
}
|
||||
|
||||
func storageAllocationActionPath(volumeID string) string {
|
||||
return fmt.Sprintf("%s/%s/actions", storageAllocPath, volumeID)
|
||||
}
|
92
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/strings.go
generated
vendored
Normal file
92
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/strings.go
generated
vendored
Normal file
|
@ -0,0 +1,92 @@
|
|||
package godo
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
var timestampType = reflect.TypeOf(Timestamp{})
|
||||
|
||||
// Stringify attempts to create a string representation of DigitalOcean types
|
||||
func Stringify(message interface{}) string {
|
||||
var buf bytes.Buffer
|
||||
v := reflect.ValueOf(message)
|
||||
stringifyValue(&buf, v)
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// stringifyValue was graciously cargoculted from the goprotubuf library
|
||||
func stringifyValue(w io.Writer, val reflect.Value) {
|
||||
if val.Kind() == reflect.Ptr && val.IsNil() {
|
||||
_, _ = w.Write([]byte("<nil>"))
|
||||
return
|
||||
}
|
||||
|
||||
v := reflect.Indirect(val)
|
||||
|
||||
switch v.Kind() {
|
||||
case reflect.String:
|
||||
fmt.Fprintf(w, `"%s"`, v)
|
||||
case reflect.Slice:
|
||||
stringifySlice(w, v)
|
||||
return
|
||||
case reflect.Struct:
|
||||
stringifyStruct(w, v)
|
||||
default:
|
||||
if v.CanInterface() {
|
||||
fmt.Fprint(w, v.Interface())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func stringifySlice(w io.Writer, v reflect.Value) {
|
||||
_, _ = w.Write([]byte{'['})
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
if i > 0 {
|
||||
_, _ = w.Write([]byte{' '})
|
||||
}
|
||||
|
||||
stringifyValue(w, v.Index(i))
|
||||
}
|
||||
|
||||
_, _ = w.Write([]byte{']'})
|
||||
}
|
||||
|
||||
func stringifyStruct(w io.Writer, v reflect.Value) {
|
||||
if v.Type().Name() != "" {
|
||||
_, _ = w.Write([]byte(v.Type().String()))
|
||||
}
|
||||
|
||||
// special handling of Timestamp values
|
||||
if v.Type() == timestampType {
|
||||
fmt.Fprintf(w, "{%s}", v.Interface())
|
||||
return
|
||||
}
|
||||
|
||||
_, _ = w.Write([]byte{'{'})
|
||||
|
||||
var sep bool
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
fv := v.Field(i)
|
||||
if fv.Kind() == reflect.Ptr && fv.IsNil() {
|
||||
continue
|
||||
}
|
||||
if fv.Kind() == reflect.Slice && fv.IsNil() {
|
||||
continue
|
||||
}
|
||||
|
||||
if sep {
|
||||
_, _ = w.Write([]byte(", "))
|
||||
} else {
|
||||
sep = true
|
||||
}
|
||||
|
||||
_, _ = w.Write([]byte(v.Type().Field(i).Name))
|
||||
_, _ = w.Write([]byte{':'})
|
||||
stringifyValue(w, fv)
|
||||
}
|
||||
|
||||
_, _ = w.Write([]byte{'}'})
|
||||
}
|
209
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/tags.go
generated
vendored
Normal file
209
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/tags.go
generated
vendored
Normal file
|
@ -0,0 +1,209 @@
|
|||
package godo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/digitalocean/godo/context"
|
||||
)
|
||||
|
||||
const tagsBasePath = "v2/tags"
|
||||
|
||||
// TagsService is an interface for interfacing with the tags
|
||||
// endpoints of the DigitalOcean API
|
||||
// See: https://developers.digitalocean.com/documentation/v2#tags
|
||||
type TagsService interface {
|
||||
List(context.Context, *ListOptions) ([]Tag, *Response, error)
|
||||
Get(context.Context, string) (*Tag, *Response, error)
|
||||
Create(context.Context, *TagCreateRequest) (*Tag, *Response, error)
|
||||
Delete(context.Context, string) (*Response, error)
|
||||
|
||||
TagResources(context.Context, string, *TagResourcesRequest) (*Response, error)
|
||||
UntagResources(context.Context, string, *UntagResourcesRequest) (*Response, error)
|
||||
}
|
||||
|
||||
// TagsServiceOp handles communication with tag related method of the
|
||||
// DigitalOcean API.
|
||||
type TagsServiceOp struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
var _ TagsService = &TagsServiceOp{}
|
||||
|
||||
// ResourceType represents a class of resource, currently only droplet are supported
|
||||
type ResourceType string
|
||||
|
||||
const (
|
||||
//DropletResourceType holds the string representing our ResourceType of Droplet.
|
||||
DropletResourceType ResourceType = "droplet"
|
||||
)
|
||||
|
||||
// Resource represent a single resource for associating/disassociating with tags
|
||||
type Resource struct {
|
||||
ID string `json:"resource_id,omit_empty"`
|
||||
Type ResourceType `json:"resource_type,omit_empty"`
|
||||
}
|
||||
|
||||
// TaggedResources represent the set of resources a tag is attached to
|
||||
type TaggedResources struct {
|
||||
Droplets *TaggedDropletsResources `json:"droplets,omitempty"`
|
||||
}
|
||||
|
||||
// TaggedDropletsResources represent the droplet resources a tag is attached to
|
||||
type TaggedDropletsResources struct {
|
||||
Count int `json:"count,float64,omitempty"`
|
||||
LastTagged *Droplet `json:"last_tagged,omitempty"`
|
||||
}
|
||||
|
||||
// Tag represent DigitalOcean tag
|
||||
type Tag struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Resources *TaggedResources `json:"resources,omitempty"`
|
||||
}
|
||||
|
||||
//TagCreateRequest represents the JSON structure of a request of that type.
|
||||
type TagCreateRequest struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// TagResourcesRequest represents the JSON structure of a request of that type.
|
||||
type TagResourcesRequest struct {
|
||||
Resources []Resource `json:"resources"`
|
||||
}
|
||||
|
||||
// UntagResourcesRequest represents the JSON structure of a request of that type.
|
||||
type UntagResourcesRequest struct {
|
||||
Resources []Resource `json:"resources"`
|
||||
}
|
||||
|
||||
type tagsRoot struct {
|
||||
Tags []Tag `json:"tags"`
|
||||
Links *Links `json:"links"`
|
||||
}
|
||||
|
||||
type tagRoot struct {
|
||||
Tag *Tag `json:"tag"`
|
||||
}
|
||||
|
||||
// List all tags
|
||||
func (s *TagsServiceOp) List(ctx context.Context, opt *ListOptions) ([]Tag, *Response, error) {
|
||||
path := tagsBasePath
|
||||
path, err := addOptions(path, opt)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(tagsRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
if l := root.Links; l != nil {
|
||||
resp.Links = l
|
||||
}
|
||||
|
||||
return root.Tags, resp, err
|
||||
}
|
||||
|
||||
// Get a single tag
|
||||
func (s *TagsServiceOp) Get(ctx context.Context, name string) (*Tag, *Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", tagsBasePath, name)
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(tagRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Tag, resp, err
|
||||
}
|
||||
|
||||
// Create a new tag
|
||||
func (s *TagsServiceOp) Create(ctx context.Context, createRequest *TagCreateRequest) (*Tag, *Response, error) {
|
||||
if createRequest == nil {
|
||||
return nil, nil, NewArgError("createRequest", "cannot be nil")
|
||||
}
|
||||
|
||||
req, err := s.client.NewRequest(ctx, http.MethodPost, tagsBasePath, createRequest)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
root := new(tagRoot)
|
||||
resp, err := s.client.Do(ctx, req, root)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return root.Tag, resp, err
|
||||
}
|
||||
|
||||
// Delete an existing tag
|
||||
func (s *TagsServiceOp) Delete(ctx context.Context, name string) (*Response, error) {
|
||||
if name == "" {
|
||||
return nil, NewArgError("name", "cannot be empty")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%s", tagsBasePath, name)
|
||||
req, err := s.client.NewRequest(ctx, http.MethodDelete, path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(ctx, req, nil)
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// TagResources associates resources with a given Tag.
|
||||
func (s *TagsServiceOp) TagResources(ctx context.Context, name string, tagRequest *TagResourcesRequest) (*Response, error) {
|
||||
if name == "" {
|
||||
return nil, NewArgError("name", "cannot be empty")
|
||||
}
|
||||
|
||||
if tagRequest == nil {
|
||||
return nil, NewArgError("tagRequest", "cannot be nil")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%s/resources", tagsBasePath, name)
|
||||
req, err := s.client.NewRequest(ctx, http.MethodPost, path, tagRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(ctx, req, nil)
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// UntagResources dissociates resources with a given Tag.
|
||||
func (s *TagsServiceOp) UntagResources(ctx context.Context, name string, untagRequest *UntagResourcesRequest) (*Response, error) {
|
||||
if name == "" {
|
||||
return nil, NewArgError("name", "cannot be empty")
|
||||
}
|
||||
|
||||
if untagRequest == nil {
|
||||
return nil, NewArgError("tagRequest", "cannot be nil")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%s/resources", tagsBasePath, name)
|
||||
req, err := s.client.NewRequest(ctx, http.MethodDelete, path, untagRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(ctx, req, nil)
|
||||
|
||||
return resp, err
|
||||
}
|
35
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/timestamp.go
generated
vendored
Normal file
35
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/digitalocean/godo/timestamp.go
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
package godo
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Timestamp represents a time that can be unmarshalled from a JSON string
|
||||
// formatted as either an RFC3339 or Unix timestamp. All
|
||||
// exported methods of time.Time can be called on Timestamp.
|
||||
type Timestamp struct {
|
||||
time.Time
|
||||
}
|
||||
|
||||
func (t Timestamp) String() string {
|
||||
return t.Time.String()
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||
// Time is expected in RFC3339 or Unix format.
|
||||
func (t *Timestamp) UnmarshalJSON(data []byte) error {
|
||||
str := string(data)
|
||||
i, err := strconv.ParseInt(str, 10, 64)
|
||||
if err == nil {
|
||||
t.Time = time.Unix(i, 0)
|
||||
} else {
|
||||
t.Time, err = time.Parse(`"`+time.RFC3339+`"`, str)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Equal reports whether t and u are equal based on time.Equal
|
||||
func (t Timestamp) Equal(u Timestamp) bool {
|
||||
return t.Time.Equal(u.Time)
|
||||
}
|
31
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/LICENSE
generated
vendored
Normal file
31
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
Go support for Protocol Buffers - Google's data interchange format
|
||||
|
||||
Copyright 2010 The Go Authors. All rights reserved.
|
||||
https://github.com/golang/protobuf
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
43
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/Makefile
generated
vendored
Normal file
43
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/Makefile
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
# Go support for Protocol Buffers - Google's data interchange format
|
||||
#
|
||||
# Copyright 2010 The Go Authors. All rights reserved.
|
||||
# https://github.com/golang/protobuf
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
install:
|
||||
go install
|
||||
|
||||
test: install generate-test-pbs
|
||||
go test
|
||||
|
||||
|
||||
generate-test-pbs:
|
||||
make install
|
||||
make -C testdata
|
||||
protoc --go_out=Mtestdata/test.proto=github.com/golang/protobuf/proto/testdata,Mgoogle/protobuf/any.proto=github.com/golang/protobuf/ptypes/any:. proto3_proto/proto3.proto
|
||||
make
|
229
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/clone.go
generated
vendored
Normal file
229
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/clone.go
generated
vendored
Normal file
|
@ -0,0 +1,229 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Protocol buffer deep copy and merge.
|
||||
// TODO: RawMessage.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"log"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Clone returns a deep copy of a protocol buffer.
|
||||
func Clone(pb Message) Message {
|
||||
in := reflect.ValueOf(pb)
|
||||
if in.IsNil() {
|
||||
return pb
|
||||
}
|
||||
|
||||
out := reflect.New(in.Type().Elem())
|
||||
// out is empty so a merge is a deep copy.
|
||||
mergeStruct(out.Elem(), in.Elem())
|
||||
return out.Interface().(Message)
|
||||
}
|
||||
|
||||
// Merge merges src into dst.
|
||||
// Required and optional fields that are set in src will be set to that value in dst.
|
||||
// Elements of repeated fields will be appended.
|
||||
// Merge panics if src and dst are not the same type, or if dst is nil.
|
||||
func Merge(dst, src Message) {
|
||||
in := reflect.ValueOf(src)
|
||||
out := reflect.ValueOf(dst)
|
||||
if out.IsNil() {
|
||||
panic("proto: nil destination")
|
||||
}
|
||||
if in.Type() != out.Type() {
|
||||
// Explicit test prior to mergeStruct so that mistyped nils will fail
|
||||
panic("proto: type mismatch")
|
||||
}
|
||||
if in.IsNil() {
|
||||
// Merging nil into non-nil is a quiet no-op
|
||||
return
|
||||
}
|
||||
mergeStruct(out.Elem(), in.Elem())
|
||||
}
|
||||
|
||||
func mergeStruct(out, in reflect.Value) {
|
||||
sprop := GetProperties(in.Type())
|
||||
for i := 0; i < in.NumField(); i++ {
|
||||
f := in.Type().Field(i)
|
||||
if strings.HasPrefix(f.Name, "XXX_") {
|
||||
continue
|
||||
}
|
||||
mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i])
|
||||
}
|
||||
|
||||
if emIn, ok := extendable(in.Addr().Interface()); ok {
|
||||
emOut, _ := extendable(out.Addr().Interface())
|
||||
mIn, muIn := emIn.extensionsRead()
|
||||
if mIn != nil {
|
||||
mOut := emOut.extensionsWrite()
|
||||
muIn.Lock()
|
||||
mergeExtension(mOut, mIn)
|
||||
muIn.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
uf := in.FieldByName("XXX_unrecognized")
|
||||
if !uf.IsValid() {
|
||||
return
|
||||
}
|
||||
uin := uf.Bytes()
|
||||
if len(uin) > 0 {
|
||||
out.FieldByName("XXX_unrecognized").SetBytes(append([]byte(nil), uin...))
|
||||
}
|
||||
}
|
||||
|
||||
// mergeAny performs a merge between two values of the same type.
|
||||
// viaPtr indicates whether the values were indirected through a pointer (implying proto2).
|
||||
// prop is set if this is a struct field (it may be nil).
|
||||
func mergeAny(out, in reflect.Value, viaPtr bool, prop *Properties) {
|
||||
if in.Type() == protoMessageType {
|
||||
if !in.IsNil() {
|
||||
if out.IsNil() {
|
||||
out.Set(reflect.ValueOf(Clone(in.Interface().(Message))))
|
||||
} else {
|
||||
Merge(out.Interface().(Message), in.Interface().(Message))
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
switch in.Kind() {
|
||||
case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
|
||||
reflect.String, reflect.Uint32, reflect.Uint64:
|
||||
if !viaPtr && isProto3Zero(in) {
|
||||
return
|
||||
}
|
||||
out.Set(in)
|
||||
case reflect.Interface:
|
||||
// Probably a oneof field; copy non-nil values.
|
||||
if in.IsNil() {
|
||||
return
|
||||
}
|
||||
// Allocate destination if it is not set, or set to a different type.
|
||||
// Otherwise we will merge as normal.
|
||||
if out.IsNil() || out.Elem().Type() != in.Elem().Type() {
|
||||
out.Set(reflect.New(in.Elem().Elem().Type())) // interface -> *T -> T -> new(T)
|
||||
}
|
||||
mergeAny(out.Elem(), in.Elem(), false, nil)
|
||||
case reflect.Map:
|
||||
if in.Len() == 0 {
|
||||
return
|
||||
}
|
||||
if out.IsNil() {
|
||||
out.Set(reflect.MakeMap(in.Type()))
|
||||
}
|
||||
// For maps with value types of *T or []byte we need to deep copy each value.
|
||||
elemKind := in.Type().Elem().Kind()
|
||||
for _, key := range in.MapKeys() {
|
||||
var val reflect.Value
|
||||
switch elemKind {
|
||||
case reflect.Ptr:
|
||||
val = reflect.New(in.Type().Elem().Elem())
|
||||
mergeAny(val, in.MapIndex(key), false, nil)
|
||||
case reflect.Slice:
|
||||
val = in.MapIndex(key)
|
||||
val = reflect.ValueOf(append([]byte{}, val.Bytes()...))
|
||||
default:
|
||||
val = in.MapIndex(key)
|
||||
}
|
||||
out.SetMapIndex(key, val)
|
||||
}
|
||||
case reflect.Ptr:
|
||||
if in.IsNil() {
|
||||
return
|
||||
}
|
||||
if out.IsNil() {
|
||||
out.Set(reflect.New(in.Elem().Type()))
|
||||
}
|
||||
mergeAny(out.Elem(), in.Elem(), true, nil)
|
||||
case reflect.Slice:
|
||||
if in.IsNil() {
|
||||
return
|
||||
}
|
||||
if in.Type().Elem().Kind() == reflect.Uint8 {
|
||||
// []byte is a scalar bytes field, not a repeated field.
|
||||
|
||||
// Edge case: if this is in a proto3 message, a zero length
|
||||
// bytes field is considered the zero value, and should not
|
||||
// be merged.
|
||||
if prop != nil && prop.proto3 && in.Len() == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Make a deep copy.
|
||||
// Append to []byte{} instead of []byte(nil) so that we never end up
|
||||
// with a nil result.
|
||||
out.SetBytes(append([]byte{}, in.Bytes()...))
|
||||
return
|
||||
}
|
||||
n := in.Len()
|
||||
if out.IsNil() {
|
||||
out.Set(reflect.MakeSlice(in.Type(), 0, n))
|
||||
}
|
||||
switch in.Type().Elem().Kind() {
|
||||
case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
|
||||
reflect.String, reflect.Uint32, reflect.Uint64:
|
||||
out.Set(reflect.AppendSlice(out, in))
|
||||
default:
|
||||
for i := 0; i < n; i++ {
|
||||
x := reflect.Indirect(reflect.New(in.Type().Elem()))
|
||||
mergeAny(x, in.Index(i), false, nil)
|
||||
out.Set(reflect.Append(out, x))
|
||||
}
|
||||
}
|
||||
case reflect.Struct:
|
||||
mergeStruct(out, in)
|
||||
default:
|
||||
// unknown type, so not a protocol buffer
|
||||
log.Printf("proto: don't know how to copy %v", in)
|
||||
}
|
||||
}
|
||||
|
||||
func mergeExtension(out, in map[int32]Extension) {
|
||||
for extNum, eIn := range in {
|
||||
eOut := Extension{desc: eIn.desc}
|
||||
if eIn.value != nil {
|
||||
v := reflect.New(reflect.TypeOf(eIn.value)).Elem()
|
||||
mergeAny(v, reflect.ValueOf(eIn.value), false, nil)
|
||||
eOut.value = v.Interface()
|
||||
}
|
||||
if eIn.enc != nil {
|
||||
eOut.enc = make([]byte, len(eIn.enc))
|
||||
copy(eOut.enc, eIn.enc)
|
||||
}
|
||||
|
||||
out[extNum] = eOut
|
||||
}
|
||||
}
|
970
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/decode.go
generated
vendored
Normal file
970
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/decode.go
generated
vendored
Normal file
|
@ -0,0 +1,970 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
/*
|
||||
* Routines for decoding protocol buffer data to construct in-memory representations.
|
||||
*/
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// errOverflow is returned when an integer is too large to be represented.
|
||||
var errOverflow = errors.New("proto: integer overflow")
|
||||
|
||||
// ErrInternalBadWireType is returned by generated code when an incorrect
|
||||
// wire type is encountered. It does not get returned to user code.
|
||||
var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof")
|
||||
|
||||
// The fundamental decoders that interpret bytes on the wire.
|
||||
// Those that take integer types all return uint64 and are
|
||||
// therefore of type valueDecoder.
|
||||
|
||||
// DecodeVarint reads a varint-encoded integer from the slice.
|
||||
// It returns the integer and the number of bytes consumed, or
|
||||
// zero if there is not enough.
|
||||
// This is the format for the
|
||||
// int32, int64, uint32, uint64, bool, and enum
|
||||
// protocol buffer types.
|
||||
func DecodeVarint(buf []byte) (x uint64, n int) {
|
||||
for shift := uint(0); shift < 64; shift += 7 {
|
||||
if n >= len(buf) {
|
||||
return 0, 0
|
||||
}
|
||||
b := uint64(buf[n])
|
||||
n++
|
||||
x |= (b & 0x7F) << shift
|
||||
if (b & 0x80) == 0 {
|
||||
return x, n
|
||||
}
|
||||
}
|
||||
|
||||
// The number is too large to represent in a 64-bit value.
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
func (p *Buffer) decodeVarintSlow() (x uint64, err error) {
|
||||
i := p.index
|
||||
l := len(p.buf)
|
||||
|
||||
for shift := uint(0); shift < 64; shift += 7 {
|
||||
if i >= l {
|
||||
err = io.ErrUnexpectedEOF
|
||||
return
|
||||
}
|
||||
b := p.buf[i]
|
||||
i++
|
||||
x |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
p.index = i
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// The number is too large to represent in a 64-bit value.
|
||||
err = errOverflow
|
||||
return
|
||||
}
|
||||
|
||||
// DecodeVarint reads a varint-encoded integer from the Buffer.
|
||||
// This is the format for the
|
||||
// int32, int64, uint32, uint64, bool, and enum
|
||||
// protocol buffer types.
|
||||
func (p *Buffer) DecodeVarint() (x uint64, err error) {
|
||||
i := p.index
|
||||
buf := p.buf
|
||||
|
||||
if i >= len(buf) {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
} else if buf[i] < 0x80 {
|
||||
p.index++
|
||||
return uint64(buf[i]), nil
|
||||
} else if len(buf)-i < 10 {
|
||||
return p.decodeVarintSlow()
|
||||
}
|
||||
|
||||
var b uint64
|
||||
// we already checked the first byte
|
||||
x = uint64(buf[i]) - 0x80
|
||||
i++
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 7
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
x -= 0x80 << 7
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 14
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
x -= 0x80 << 14
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 21
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
x -= 0x80 << 21
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 28
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
x -= 0x80 << 28
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 35
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
x -= 0x80 << 35
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 42
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
x -= 0x80 << 42
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 49
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
x -= 0x80 << 49
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 56
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
x -= 0x80 << 56
|
||||
|
||||
b = uint64(buf[i])
|
||||
i++
|
||||
x += b << 63
|
||||
if b&0x80 == 0 {
|
||||
goto done
|
||||
}
|
||||
// x -= 0x80 << 63 // Always zero.
|
||||
|
||||
return 0, errOverflow
|
||||
|
||||
done:
|
||||
p.index = i
|
||||
return x, nil
|
||||
}
|
||||
|
||||
// DecodeFixed64 reads a 64-bit integer from the Buffer.
|
||||
// This is the format for the
|
||||
// fixed64, sfixed64, and double protocol buffer types.
|
||||
func (p *Buffer) DecodeFixed64() (x uint64, err error) {
|
||||
// x, err already 0
|
||||
i := p.index + 8
|
||||
if i < 0 || i > len(p.buf) {
|
||||
err = io.ErrUnexpectedEOF
|
||||
return
|
||||
}
|
||||
p.index = i
|
||||
|
||||
x = uint64(p.buf[i-8])
|
||||
x |= uint64(p.buf[i-7]) << 8
|
||||
x |= uint64(p.buf[i-6]) << 16
|
||||
x |= uint64(p.buf[i-5]) << 24
|
||||
x |= uint64(p.buf[i-4]) << 32
|
||||
x |= uint64(p.buf[i-3]) << 40
|
||||
x |= uint64(p.buf[i-2]) << 48
|
||||
x |= uint64(p.buf[i-1]) << 56
|
||||
return
|
||||
}
|
||||
|
||||
// DecodeFixed32 reads a 32-bit integer from the Buffer.
|
||||
// This is the format for the
|
||||
// fixed32, sfixed32, and float protocol buffer types.
|
||||
func (p *Buffer) DecodeFixed32() (x uint64, err error) {
|
||||
// x, err already 0
|
||||
i := p.index + 4
|
||||
if i < 0 || i > len(p.buf) {
|
||||
err = io.ErrUnexpectedEOF
|
||||
return
|
||||
}
|
||||
p.index = i
|
||||
|
||||
x = uint64(p.buf[i-4])
|
||||
x |= uint64(p.buf[i-3]) << 8
|
||||
x |= uint64(p.buf[i-2]) << 16
|
||||
x |= uint64(p.buf[i-1]) << 24
|
||||
return
|
||||
}
|
||||
|
||||
// DecodeZigzag64 reads a zigzag-encoded 64-bit integer
|
||||
// from the Buffer.
|
||||
// This is the format used for the sint64 protocol buffer type.
|
||||
func (p *Buffer) DecodeZigzag64() (x uint64, err error) {
|
||||
x, err = p.DecodeVarint()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63)
|
||||
return
|
||||
}
|
||||
|
||||
// DecodeZigzag32 reads a zigzag-encoded 32-bit integer
|
||||
// from the Buffer.
|
||||
// This is the format used for the sint32 protocol buffer type.
|
||||
func (p *Buffer) DecodeZigzag32() (x uint64, err error) {
|
||||
x, err = p.DecodeVarint()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31))
|
||||
return
|
||||
}
|
||||
|
||||
// These are not ValueDecoders: they produce an array of bytes or a string.
|
||||
// bytes, embedded messages
|
||||
|
||||
// DecodeRawBytes reads a count-delimited byte buffer from the Buffer.
|
||||
// This is the format used for the bytes protocol buffer
|
||||
// type and for embedded messages.
|
||||
func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) {
|
||||
n, err := p.DecodeVarint()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nb := int(n)
|
||||
if nb < 0 {
|
||||
return nil, fmt.Errorf("proto: bad byte length %d", nb)
|
||||
}
|
||||
end := p.index + nb
|
||||
if end < p.index || end > len(p.buf) {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
if !alloc {
|
||||
// todo: check if can get more uses of alloc=false
|
||||
buf = p.buf[p.index:end]
|
||||
p.index += nb
|
||||
return
|
||||
}
|
||||
|
||||
buf = make([]byte, nb)
|
||||
copy(buf, p.buf[p.index:])
|
||||
p.index += nb
|
||||
return
|
||||
}
|
||||
|
||||
// DecodeStringBytes reads an encoded string from the Buffer.
|
||||
// This is the format used for the proto2 string type.
|
||||
func (p *Buffer) DecodeStringBytes() (s string, err error) {
|
||||
buf, err := p.DecodeRawBytes(false)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return string(buf), nil
|
||||
}
|
||||
|
||||
// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
|
||||
// If the protocol buffer has extensions, and the field matches, add it as an extension.
|
||||
// Otherwise, if the XXX_unrecognized field exists, append the skipped data there.
|
||||
func (o *Buffer) skipAndSave(t reflect.Type, tag, wire int, base structPointer, unrecField field) error {
|
||||
oi := o.index
|
||||
|
||||
err := o.skip(t, tag, wire)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !unrecField.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
ptr := structPointer_Bytes(base, unrecField)
|
||||
|
||||
// Add the skipped field to struct field
|
||||
obuf := o.buf
|
||||
|
||||
o.buf = *ptr
|
||||
o.EncodeVarint(uint64(tag<<3 | wire))
|
||||
*ptr = append(o.buf, obuf[oi:o.index]...)
|
||||
|
||||
o.buf = obuf
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
|
||||
func (o *Buffer) skip(t reflect.Type, tag, wire int) error {
|
||||
|
||||
var u uint64
|
||||
var err error
|
||||
|
||||
switch wire {
|
||||
case WireVarint:
|
||||
_, err = o.DecodeVarint()
|
||||
case WireFixed64:
|
||||
_, err = o.DecodeFixed64()
|
||||
case WireBytes:
|
||||
_, err = o.DecodeRawBytes(false)
|
||||
case WireFixed32:
|
||||
_, err = o.DecodeFixed32()
|
||||
case WireStartGroup:
|
||||
for {
|
||||
u, err = o.DecodeVarint()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
fwire := int(u & 0x7)
|
||||
if fwire == WireEndGroup {
|
||||
break
|
||||
}
|
||||
ftag := int(u >> 3)
|
||||
err = o.skip(t, ftag, fwire)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
default:
|
||||
err = fmt.Errorf("proto: can't skip unknown wire type %d for %s", wire, t)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Unmarshaler is the interface representing objects that can
|
||||
// unmarshal themselves. The method should reset the receiver before
|
||||
// decoding starts. The argument points to data that may be
|
||||
// overwritten, so implementations should not keep references to the
|
||||
// buffer.
|
||||
type Unmarshaler interface {
|
||||
Unmarshal([]byte) error
|
||||
}
|
||||
|
||||
// Unmarshal parses the protocol buffer representation in buf and places the
|
||||
// decoded result in pb. If the struct underlying pb does not match
|
||||
// the data in buf, the results can be unpredictable.
|
||||
//
|
||||
// Unmarshal resets pb before starting to unmarshal, so any
|
||||
// existing data in pb is always removed. Use UnmarshalMerge
|
||||
// to preserve and append to existing data.
|
||||
func Unmarshal(buf []byte, pb Message) error {
|
||||
pb.Reset()
|
||||
return UnmarshalMerge(buf, pb)
|
||||
}
|
||||
|
||||
// UnmarshalMerge parses the protocol buffer representation in buf and
|
||||
// writes the decoded result to pb. If the struct underlying pb does not match
|
||||
// the data in buf, the results can be unpredictable.
|
||||
//
|
||||
// UnmarshalMerge merges into existing data in pb.
|
||||
// Most code should use Unmarshal instead.
|
||||
func UnmarshalMerge(buf []byte, pb Message) error {
|
||||
// If the object can unmarshal itself, let it.
|
||||
if u, ok := pb.(Unmarshaler); ok {
|
||||
return u.Unmarshal(buf)
|
||||
}
|
||||
return NewBuffer(buf).Unmarshal(pb)
|
||||
}
|
||||
|
||||
// DecodeMessage reads a count-delimited message from the Buffer.
|
||||
func (p *Buffer) DecodeMessage(pb Message) error {
|
||||
enc, err := p.DecodeRawBytes(false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return NewBuffer(enc).Unmarshal(pb)
|
||||
}
|
||||
|
||||
// DecodeGroup reads a tag-delimited group from the Buffer.
|
||||
func (p *Buffer) DecodeGroup(pb Message) error {
|
||||
typ, base, err := getbase(pb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), true, base)
|
||||
}
|
||||
|
||||
// Unmarshal parses the protocol buffer representation in the
|
||||
// Buffer and places the decoded result in pb. If the struct
|
||||
// underlying pb does not match the data in the buffer, the results can be
|
||||
// unpredictable.
|
||||
//
|
||||
// Unlike proto.Unmarshal, this does not reset pb before starting to unmarshal.
|
||||
func (p *Buffer) Unmarshal(pb Message) error {
|
||||
// If the object can unmarshal itself, let it.
|
||||
if u, ok := pb.(Unmarshaler); ok {
|
||||
err := u.Unmarshal(p.buf[p.index:])
|
||||
p.index = len(p.buf)
|
||||
return err
|
||||
}
|
||||
|
||||
typ, base, err := getbase(pb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), false, base)
|
||||
|
||||
if collectStats {
|
||||
stats.Decode++
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// unmarshalType does the work of unmarshaling a structure.
|
||||
func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group bool, base structPointer) error {
|
||||
var state errorState
|
||||
required, reqFields := prop.reqCount, uint64(0)
|
||||
|
||||
var err error
|
||||
for err == nil && o.index < len(o.buf) {
|
||||
oi := o.index
|
||||
var u uint64
|
||||
u, err = o.DecodeVarint()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
wire := int(u & 0x7)
|
||||
if wire == WireEndGroup {
|
||||
if is_group {
|
||||
if required > 0 {
|
||||
// Not enough information to determine the exact field.
|
||||
// (See below.)
|
||||
return &RequiredNotSetError{"{Unknown}"}
|
||||
}
|
||||
return nil // input is satisfied
|
||||
}
|
||||
return fmt.Errorf("proto: %s: wiretype end group for non-group", st)
|
||||
}
|
||||
tag := int(u >> 3)
|
||||
if tag <= 0 {
|
||||
return fmt.Errorf("proto: %s: illegal tag %d (wire type %d)", st, tag, wire)
|
||||
}
|
||||
fieldnum, ok := prop.decoderTags.get(tag)
|
||||
if !ok {
|
||||
// Maybe it's an extension?
|
||||
if prop.extendable {
|
||||
if e, _ := extendable(structPointer_Interface(base, st)); isExtensionField(e, int32(tag)) {
|
||||
if err = o.skip(st, tag, wire); err == nil {
|
||||
extmap := e.extensionsWrite()
|
||||
ext := extmap[int32(tag)] // may be missing
|
||||
ext.enc = append(ext.enc, o.buf[oi:o.index]...)
|
||||
extmap[int32(tag)] = ext
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
// Maybe it's a oneof?
|
||||
if prop.oneofUnmarshaler != nil {
|
||||
m := structPointer_Interface(base, st).(Message)
|
||||
// First return value indicates whether tag is a oneof field.
|
||||
ok, err = prop.oneofUnmarshaler(m, tag, wire, o)
|
||||
if err == ErrInternalBadWireType {
|
||||
// Map the error to something more descriptive.
|
||||
// Do the formatting here to save generated code space.
|
||||
err = fmt.Errorf("bad wiretype for oneof field in %T", m)
|
||||
}
|
||||
if ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
err = o.skipAndSave(st, tag, wire, base, prop.unrecField)
|
||||
continue
|
||||
}
|
||||
p := prop.Prop[fieldnum]
|
||||
|
||||
if p.dec == nil {
|
||||
fmt.Fprintf(os.Stderr, "proto: no protobuf decoder for %s.%s\n", st, st.Field(fieldnum).Name)
|
||||
continue
|
||||
}
|
||||
dec := p.dec
|
||||
if wire != WireStartGroup && wire != p.WireType {
|
||||
if wire == WireBytes && p.packedDec != nil {
|
||||
// a packable field
|
||||
dec = p.packedDec
|
||||
} else {
|
||||
err = fmt.Errorf("proto: bad wiretype for field %s.%s: got wiretype %d, want %d", st, st.Field(fieldnum).Name, wire, p.WireType)
|
||||
continue
|
||||
}
|
||||
}
|
||||
decErr := dec(o, p, base)
|
||||
if decErr != nil && !state.shouldContinue(decErr, p) {
|
||||
err = decErr
|
||||
}
|
||||
if err == nil && p.Required {
|
||||
// Successfully decoded a required field.
|
||||
if tag <= 64 {
|
||||
// use bitmap for fields 1-64 to catch field reuse.
|
||||
var mask uint64 = 1 << uint64(tag-1)
|
||||
if reqFields&mask == 0 {
|
||||
// new required field
|
||||
reqFields |= mask
|
||||
required--
|
||||
}
|
||||
} else {
|
||||
// This is imprecise. It can be fooled by a required field
|
||||
// with a tag > 64 that is encoded twice; that's very rare.
|
||||
// A fully correct implementation would require allocating
|
||||
// a data structure, which we would like to avoid.
|
||||
required--
|
||||
}
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
if is_group {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if state.err != nil {
|
||||
return state.err
|
||||
}
|
||||
if required > 0 {
|
||||
// Not enough information to determine the exact field. If we use extra
|
||||
// CPU, we could determine the field only if the missing required field
|
||||
// has a tag <= 64 and we check reqFields.
|
||||
return &RequiredNotSetError{"{Unknown}"}
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Individual type decoders
|
||||
// For each,
|
||||
// u is the decoded value,
|
||||
// v is a pointer to the field (pointer) in the struct
|
||||
|
||||
// Sizes of the pools to allocate inside the Buffer.
|
||||
// The goal is modest amortization and allocation
|
||||
// on at least 16-byte boundaries.
|
||||
const (
|
||||
boolPoolSize = 16
|
||||
uint32PoolSize = 8
|
||||
uint64PoolSize = 4
|
||||
)
|
||||
|
||||
// Decode a bool.
|
||||
func (o *Buffer) dec_bool(p *Properties, base structPointer) error {
|
||||
u, err := p.valDec(o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(o.bools) == 0 {
|
||||
o.bools = make([]bool, boolPoolSize)
|
||||
}
|
||||
o.bools[0] = u != 0
|
||||
*structPointer_Bool(base, p.field) = &o.bools[0]
|
||||
o.bools = o.bools[1:]
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Buffer) dec_proto3_bool(p *Properties, base structPointer) error {
|
||||
u, err := p.valDec(o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*structPointer_BoolVal(base, p.field) = u != 0
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decode an int32.
|
||||
func (o *Buffer) dec_int32(p *Properties, base structPointer) error {
|
||||
u, err := p.valDec(o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
word32_Set(structPointer_Word32(base, p.field), o, uint32(u))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Buffer) dec_proto3_int32(p *Properties, base structPointer) error {
|
||||
u, err := p.valDec(o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
word32Val_Set(structPointer_Word32Val(base, p.field), uint32(u))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decode an int64.
|
||||
func (o *Buffer) dec_int64(p *Properties, base structPointer) error {
|
||||
u, err := p.valDec(o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
word64_Set(structPointer_Word64(base, p.field), o, u)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Buffer) dec_proto3_int64(p *Properties, base structPointer) error {
|
||||
u, err := p.valDec(o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
word64Val_Set(structPointer_Word64Val(base, p.field), o, u)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decode a string.
|
||||
func (o *Buffer) dec_string(p *Properties, base structPointer) error {
|
||||
s, err := o.DecodeStringBytes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*structPointer_String(base, p.field) = &s
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Buffer) dec_proto3_string(p *Properties, base structPointer) error {
|
||||
s, err := o.DecodeStringBytes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*structPointer_StringVal(base, p.field) = s
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decode a slice of bytes ([]byte).
|
||||
func (o *Buffer) dec_slice_byte(p *Properties, base structPointer) error {
|
||||
b, err := o.DecodeRawBytes(true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*structPointer_Bytes(base, p.field) = b
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decode a slice of bools ([]bool).
|
||||
func (o *Buffer) dec_slice_bool(p *Properties, base structPointer) error {
|
||||
u, err := p.valDec(o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v := structPointer_BoolSlice(base, p.field)
|
||||
*v = append(*v, u != 0)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decode a slice of bools ([]bool) in packed format.
|
||||
func (o *Buffer) dec_slice_packed_bool(p *Properties, base structPointer) error {
|
||||
v := structPointer_BoolSlice(base, p.field)
|
||||
|
||||
nn, err := o.DecodeVarint()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nb := int(nn) // number of bytes of encoded bools
|
||||
fin := o.index + nb
|
||||
if fin < o.index {
|
||||
return errOverflow
|
||||
}
|
||||
|
||||
y := *v
|
||||
for o.index < fin {
|
||||
u, err := p.valDec(o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
y = append(y, u != 0)
|
||||
}
|
||||
|
||||
*v = y
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decode a slice of int32s ([]int32).
|
||||
func (o *Buffer) dec_slice_int32(p *Properties, base structPointer) error {
|
||||
u, err := p.valDec(o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
structPointer_Word32Slice(base, p.field).Append(uint32(u))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decode a slice of int32s ([]int32) in packed format.
|
||||
func (o *Buffer) dec_slice_packed_int32(p *Properties, base structPointer) error {
|
||||
v := structPointer_Word32Slice(base, p.field)
|
||||
|
||||
nn, err := o.DecodeVarint()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nb := int(nn) // number of bytes of encoded int32s
|
||||
|
||||
fin := o.index + nb
|
||||
if fin < o.index {
|
||||
return errOverflow
|
||||
}
|
||||
for o.index < fin {
|
||||
u, err := p.valDec(o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.Append(uint32(u))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decode a slice of int64s ([]int64).
|
||||
func (o *Buffer) dec_slice_int64(p *Properties, base structPointer) error {
|
||||
u, err := p.valDec(o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
structPointer_Word64Slice(base, p.field).Append(u)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decode a slice of int64s ([]int64) in packed format.
|
||||
func (o *Buffer) dec_slice_packed_int64(p *Properties, base structPointer) error {
|
||||
v := structPointer_Word64Slice(base, p.field)
|
||||
|
||||
nn, err := o.DecodeVarint()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nb := int(nn) // number of bytes of encoded int64s
|
||||
|
||||
fin := o.index + nb
|
||||
if fin < o.index {
|
||||
return errOverflow
|
||||
}
|
||||
for o.index < fin {
|
||||
u, err := p.valDec(o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.Append(u)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decode a slice of strings ([]string).
|
||||
func (o *Buffer) dec_slice_string(p *Properties, base structPointer) error {
|
||||
s, err := o.DecodeStringBytes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v := structPointer_StringSlice(base, p.field)
|
||||
*v = append(*v, s)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decode a slice of slice of bytes ([][]byte).
|
||||
func (o *Buffer) dec_slice_slice_byte(p *Properties, base structPointer) error {
|
||||
b, err := o.DecodeRawBytes(true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v := structPointer_BytesSlice(base, p.field)
|
||||
*v = append(*v, b)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decode a map field.
|
||||
func (o *Buffer) dec_new_map(p *Properties, base structPointer) error {
|
||||
raw, err := o.DecodeRawBytes(false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
oi := o.index // index at the end of this map entry
|
||||
o.index -= len(raw) // move buffer back to start of map entry
|
||||
|
||||
mptr := structPointer_NewAt(base, p.field, p.mtype) // *map[K]V
|
||||
if mptr.Elem().IsNil() {
|
||||
mptr.Elem().Set(reflect.MakeMap(mptr.Type().Elem()))
|
||||
}
|
||||
v := mptr.Elem() // map[K]V
|
||||
|
||||
// Prepare addressable doubly-indirect placeholders for the key and value types.
|
||||
// See enc_new_map for why.
|
||||
keyptr := reflect.New(reflect.PtrTo(p.mtype.Key())).Elem() // addressable *K
|
||||
keybase := toStructPointer(keyptr.Addr()) // **K
|
||||
|
||||
var valbase structPointer
|
||||
var valptr reflect.Value
|
||||
switch p.mtype.Elem().Kind() {
|
||||
case reflect.Slice:
|
||||
// []byte
|
||||
var dummy []byte
|
||||
valptr = reflect.ValueOf(&dummy) // *[]byte
|
||||
valbase = toStructPointer(valptr) // *[]byte
|
||||
case reflect.Ptr:
|
||||
// message; valptr is **Msg; need to allocate the intermediate pointer
|
||||
valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
|
||||
valptr.Set(reflect.New(valptr.Type().Elem()))
|
||||
valbase = toStructPointer(valptr)
|
||||
default:
|
||||
// everything else
|
||||
valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
|
||||
valbase = toStructPointer(valptr.Addr()) // **V
|
||||
}
|
||||
|
||||
// Decode.
|
||||
// This parses a restricted wire format, namely the encoding of a message
|
||||
// with two fields. See enc_new_map for the format.
|
||||
for o.index < oi {
|
||||
// tagcode for key and value properties are always a single byte
|
||||
// because they have tags 1 and 2.
|
||||
tagcode := o.buf[o.index]
|
||||
o.index++
|
||||
switch tagcode {
|
||||
case p.mkeyprop.tagcode[0]:
|
||||
if err := p.mkeyprop.dec(o, p.mkeyprop, keybase); err != nil {
|
||||
return err
|
||||
}
|
||||
case p.mvalprop.tagcode[0]:
|
||||
if err := p.mvalprop.dec(o, p.mvalprop, valbase); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
// TODO: Should we silently skip this instead?
|
||||
return fmt.Errorf("proto: bad map data tag %d", raw[0])
|
||||
}
|
||||
}
|
||||
keyelem, valelem := keyptr.Elem(), valptr.Elem()
|
||||
if !keyelem.IsValid() {
|
||||
keyelem = reflect.Zero(p.mtype.Key())
|
||||
}
|
||||
if !valelem.IsValid() {
|
||||
valelem = reflect.Zero(p.mtype.Elem())
|
||||
}
|
||||
|
||||
v.SetMapIndex(keyelem, valelem)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decode a group.
|
||||
func (o *Buffer) dec_struct_group(p *Properties, base structPointer) error {
|
||||
bas := structPointer_GetStructPointer(base, p.field)
|
||||
if structPointer_IsNil(bas) {
|
||||
// allocate new nested message
|
||||
bas = toStructPointer(reflect.New(p.stype))
|
||||
structPointer_SetStructPointer(base, p.field, bas)
|
||||
}
|
||||
return o.unmarshalType(p.stype, p.sprop, true, bas)
|
||||
}
|
||||
|
||||
// Decode an embedded message.
|
||||
func (o *Buffer) dec_struct_message(p *Properties, base structPointer) (err error) {
|
||||
raw, e := o.DecodeRawBytes(false)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
bas := structPointer_GetStructPointer(base, p.field)
|
||||
if structPointer_IsNil(bas) {
|
||||
// allocate new nested message
|
||||
bas = toStructPointer(reflect.New(p.stype))
|
||||
structPointer_SetStructPointer(base, p.field, bas)
|
||||
}
|
||||
|
||||
// If the object can unmarshal itself, let it.
|
||||
if p.isUnmarshaler {
|
||||
iv := structPointer_Interface(bas, p.stype)
|
||||
return iv.(Unmarshaler).Unmarshal(raw)
|
||||
}
|
||||
|
||||
obuf := o.buf
|
||||
oi := o.index
|
||||
o.buf = raw
|
||||
o.index = 0
|
||||
|
||||
err = o.unmarshalType(p.stype, p.sprop, false, bas)
|
||||
o.buf = obuf
|
||||
o.index = oi
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Decode a slice of embedded messages.
|
||||
func (o *Buffer) dec_slice_struct_message(p *Properties, base structPointer) error {
|
||||
return o.dec_slice_struct(p, false, base)
|
||||
}
|
||||
|
||||
// Decode a slice of embedded groups.
|
||||
func (o *Buffer) dec_slice_struct_group(p *Properties, base structPointer) error {
|
||||
return o.dec_slice_struct(p, true, base)
|
||||
}
|
||||
|
||||
// Decode a slice of structs ([]*struct).
|
||||
func (o *Buffer) dec_slice_struct(p *Properties, is_group bool, base structPointer) error {
|
||||
v := reflect.New(p.stype)
|
||||
bas := toStructPointer(v)
|
||||
structPointer_StructPointerSlice(base, p.field).Append(bas)
|
||||
|
||||
if is_group {
|
||||
err := o.unmarshalType(p.stype, p.sprop, is_group, bas)
|
||||
return err
|
||||
}
|
||||
|
||||
raw, err := o.DecodeRawBytes(false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If the object can unmarshal itself, let it.
|
||||
if p.isUnmarshaler {
|
||||
iv := v.Interface()
|
||||
return iv.(Unmarshaler).Unmarshal(raw)
|
||||
}
|
||||
|
||||
obuf := o.buf
|
||||
oi := o.index
|
||||
o.buf = raw
|
||||
o.index = 0
|
||||
|
||||
err = o.unmarshalType(p.stype, p.sprop, is_group, bas)
|
||||
|
||||
o.buf = obuf
|
||||
o.index = oi
|
||||
|
||||
return err
|
||||
}
|
1362
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/encode.go
generated
vendored
Normal file
1362
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/encode.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
300
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/equal.go
generated
vendored
Normal file
300
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/equal.go
generated
vendored
Normal file
|
@ -0,0 +1,300 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Protocol buffer comparison.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"log"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
/*
|
||||
Equal returns true iff protocol buffers a and b are equal.
|
||||
The arguments must both be pointers to protocol buffer structs.
|
||||
|
||||
Equality is defined in this way:
|
||||
- Two messages are equal iff they are the same type,
|
||||
corresponding fields are equal, unknown field sets
|
||||
are equal, and extensions sets are equal.
|
||||
- Two set scalar fields are equal iff their values are equal.
|
||||
If the fields are of a floating-point type, remember that
|
||||
NaN != x for all x, including NaN. If the message is defined
|
||||
in a proto3 .proto file, fields are not "set"; specifically,
|
||||
zero length proto3 "bytes" fields are equal (nil == {}).
|
||||
- Two repeated fields are equal iff their lengths are the same,
|
||||
and their corresponding elements are equal. Note a "bytes" field,
|
||||
although represented by []byte, is not a repeated field and the
|
||||
rule for the scalar fields described above applies.
|
||||
- Two unset fields are equal.
|
||||
- Two unknown field sets are equal if their current
|
||||
encoded state is equal.
|
||||
- Two extension sets are equal iff they have corresponding
|
||||
elements that are pairwise equal.
|
||||
- Two map fields are equal iff their lengths are the same,
|
||||
and they contain the same set of elements. Zero-length map
|
||||
fields are equal.
|
||||
- Every other combination of things are not equal.
|
||||
|
||||
The return value is undefined if a and b are not protocol buffers.
|
||||
*/
|
||||
func Equal(a, b Message) bool {
|
||||
if a == nil || b == nil {
|
||||
return a == b
|
||||
}
|
||||
v1, v2 := reflect.ValueOf(a), reflect.ValueOf(b)
|
||||
if v1.Type() != v2.Type() {
|
||||
return false
|
||||
}
|
||||
if v1.Kind() == reflect.Ptr {
|
||||
if v1.IsNil() {
|
||||
return v2.IsNil()
|
||||
}
|
||||
if v2.IsNil() {
|
||||
return false
|
||||
}
|
||||
v1, v2 = v1.Elem(), v2.Elem()
|
||||
}
|
||||
if v1.Kind() != reflect.Struct {
|
||||
return false
|
||||
}
|
||||
return equalStruct(v1, v2)
|
||||
}
|
||||
|
||||
// v1 and v2 are known to have the same type.
|
||||
func equalStruct(v1, v2 reflect.Value) bool {
|
||||
sprop := GetProperties(v1.Type())
|
||||
for i := 0; i < v1.NumField(); i++ {
|
||||
f := v1.Type().Field(i)
|
||||
if strings.HasPrefix(f.Name, "XXX_") {
|
||||
continue
|
||||
}
|
||||
f1, f2 := v1.Field(i), v2.Field(i)
|
||||
if f.Type.Kind() == reflect.Ptr {
|
||||
if n1, n2 := f1.IsNil(), f2.IsNil(); n1 && n2 {
|
||||
// both unset
|
||||
continue
|
||||
} else if n1 != n2 {
|
||||
// set/unset mismatch
|
||||
return false
|
||||
}
|
||||
b1, ok := f1.Interface().(raw)
|
||||
if ok {
|
||||
b2 := f2.Interface().(raw)
|
||||
// RawMessage
|
||||
if !bytes.Equal(b1.Bytes(), b2.Bytes()) {
|
||||
return false
|
||||
}
|
||||
continue
|
||||
}
|
||||
f1, f2 = f1.Elem(), f2.Elem()
|
||||
}
|
||||
if !equalAny(f1, f2, sprop.Prop[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if em1 := v1.FieldByName("XXX_InternalExtensions"); em1.IsValid() {
|
||||
em2 := v2.FieldByName("XXX_InternalExtensions")
|
||||
if !equalExtensions(v1.Type(), em1.Interface().(XXX_InternalExtensions), em2.Interface().(XXX_InternalExtensions)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() {
|
||||
em2 := v2.FieldByName("XXX_extensions")
|
||||
if !equalExtMap(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
uf := v1.FieldByName("XXX_unrecognized")
|
||||
if !uf.IsValid() {
|
||||
return true
|
||||
}
|
||||
|
||||
u1 := uf.Bytes()
|
||||
u2 := v2.FieldByName("XXX_unrecognized").Bytes()
|
||||
if !bytes.Equal(u1, u2) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// v1 and v2 are known to have the same type.
|
||||
// prop may be nil.
|
||||
func equalAny(v1, v2 reflect.Value, prop *Properties) bool {
|
||||
if v1.Type() == protoMessageType {
|
||||
m1, _ := v1.Interface().(Message)
|
||||
m2, _ := v2.Interface().(Message)
|
||||
return Equal(m1, m2)
|
||||
}
|
||||
switch v1.Kind() {
|
||||
case reflect.Bool:
|
||||
return v1.Bool() == v2.Bool()
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return v1.Float() == v2.Float()
|
||||
case reflect.Int32, reflect.Int64:
|
||||
return v1.Int() == v2.Int()
|
||||
case reflect.Interface:
|
||||
// Probably a oneof field; compare the inner values.
|
||||
n1, n2 := v1.IsNil(), v2.IsNil()
|
||||
if n1 || n2 {
|
||||
return n1 == n2
|
||||
}
|
||||
e1, e2 := v1.Elem(), v2.Elem()
|
||||
if e1.Type() != e2.Type() {
|
||||
return false
|
||||
}
|
||||
return equalAny(e1, e2, nil)
|
||||
case reflect.Map:
|
||||
if v1.Len() != v2.Len() {
|
||||
return false
|
||||
}
|
||||
for _, key := range v1.MapKeys() {
|
||||
val2 := v2.MapIndex(key)
|
||||
if !val2.IsValid() {
|
||||
// This key was not found in the second map.
|
||||
return false
|
||||
}
|
||||
if !equalAny(v1.MapIndex(key), val2, nil) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
case reflect.Ptr:
|
||||
// Maps may have nil values in them, so check for nil.
|
||||
if v1.IsNil() && v2.IsNil() {
|
||||
return true
|
||||
}
|
||||
if v1.IsNil() != v2.IsNil() {
|
||||
return false
|
||||
}
|
||||
return equalAny(v1.Elem(), v2.Elem(), prop)
|
||||
case reflect.Slice:
|
||||
if v1.Type().Elem().Kind() == reflect.Uint8 {
|
||||
// short circuit: []byte
|
||||
|
||||
// Edge case: if this is in a proto3 message, a zero length
|
||||
// bytes field is considered the zero value.
|
||||
if prop != nil && prop.proto3 && v1.Len() == 0 && v2.Len() == 0 {
|
||||
return true
|
||||
}
|
||||
if v1.IsNil() != v2.IsNil() {
|
||||
return false
|
||||
}
|
||||
return bytes.Equal(v1.Interface().([]byte), v2.Interface().([]byte))
|
||||
}
|
||||
|
||||
if v1.Len() != v2.Len() {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < v1.Len(); i++ {
|
||||
if !equalAny(v1.Index(i), v2.Index(i), prop) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
case reflect.String:
|
||||
return v1.Interface().(string) == v2.Interface().(string)
|
||||
case reflect.Struct:
|
||||
return equalStruct(v1, v2)
|
||||
case reflect.Uint32, reflect.Uint64:
|
||||
return v1.Uint() == v2.Uint()
|
||||
}
|
||||
|
||||
// unknown type, so not a protocol buffer
|
||||
log.Printf("proto: don't know how to compare %v", v1)
|
||||
return false
|
||||
}
|
||||
|
||||
// base is the struct type that the extensions are based on.
|
||||
// x1 and x2 are InternalExtensions.
|
||||
func equalExtensions(base reflect.Type, x1, x2 XXX_InternalExtensions) bool {
|
||||
em1, _ := x1.extensionsRead()
|
||||
em2, _ := x2.extensionsRead()
|
||||
return equalExtMap(base, em1, em2)
|
||||
}
|
||||
|
||||
func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool {
|
||||
if len(em1) != len(em2) {
|
||||
return false
|
||||
}
|
||||
|
||||
for extNum, e1 := range em1 {
|
||||
e2, ok := em2[extNum]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
m1, m2 := e1.value, e2.value
|
||||
|
||||
if m1 != nil && m2 != nil {
|
||||
// Both are unencoded.
|
||||
if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) {
|
||||
return false
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// At least one is encoded. To do a semantically correct comparison
|
||||
// we need to unmarshal them first.
|
||||
var desc *ExtensionDesc
|
||||
if m := extensionMaps[base]; m != nil {
|
||||
desc = m[extNum]
|
||||
}
|
||||
if desc == nil {
|
||||
log.Printf("proto: don't know how to compare extension %d of %v", extNum, base)
|
||||
continue
|
||||
}
|
||||
var err error
|
||||
if m1 == nil {
|
||||
m1, err = decodeExtension(e1.enc, desc)
|
||||
}
|
||||
if m2 == nil && err == nil {
|
||||
m2, err = decodeExtension(e2.enc, desc)
|
||||
}
|
||||
if err != nil {
|
||||
// The encoded form is invalid.
|
||||
log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err)
|
||||
return false
|
||||
}
|
||||
if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
587
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/extensions.go
generated
vendored
Normal file
587
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/extensions.go
generated
vendored
Normal file
|
@ -0,0 +1,587 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
/*
|
||||
* Types and routines for supporting protocol buffer extensions.
|
||||
*/
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message.
|
||||
var ErrMissingExtension = errors.New("proto: missing extension")
|
||||
|
||||
// ExtensionRange represents a range of message extensions for a protocol buffer.
|
||||
// Used in code generated by the protocol compiler.
|
||||
type ExtensionRange struct {
|
||||
Start, End int32 // both inclusive
|
||||
}
|
||||
|
||||
// extendableProto is an interface implemented by any protocol buffer generated by the current
|
||||
// proto compiler that may be extended.
|
||||
type extendableProto interface {
|
||||
Message
|
||||
ExtensionRangeArray() []ExtensionRange
|
||||
extensionsWrite() map[int32]Extension
|
||||
extensionsRead() (map[int32]Extension, sync.Locker)
|
||||
}
|
||||
|
||||
// extendableProtoV1 is an interface implemented by a protocol buffer generated by the previous
|
||||
// version of the proto compiler that may be extended.
|
||||
type extendableProtoV1 interface {
|
||||
Message
|
||||
ExtensionRangeArray() []ExtensionRange
|
||||
ExtensionMap() map[int32]Extension
|
||||
}
|
||||
|
||||
// extensionAdapter is a wrapper around extendableProtoV1 that implements extendableProto.
|
||||
type extensionAdapter struct {
|
||||
extendableProtoV1
|
||||
}
|
||||
|
||||
func (e extensionAdapter) extensionsWrite() map[int32]Extension {
|
||||
return e.ExtensionMap()
|
||||
}
|
||||
|
||||
func (e extensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) {
|
||||
return e.ExtensionMap(), notLocker{}
|
||||
}
|
||||
|
||||
// notLocker is a sync.Locker whose Lock and Unlock methods are nops.
|
||||
type notLocker struct{}
|
||||
|
||||
func (n notLocker) Lock() {}
|
||||
func (n notLocker) Unlock() {}
|
||||
|
||||
// extendable returns the extendableProto interface for the given generated proto message.
|
||||
// If the proto message has the old extension format, it returns a wrapper that implements
|
||||
// the extendableProto interface.
|
||||
func extendable(p interface{}) (extendableProto, bool) {
|
||||
if ep, ok := p.(extendableProto); ok {
|
||||
return ep, ok
|
||||
}
|
||||
if ep, ok := p.(extendableProtoV1); ok {
|
||||
return extensionAdapter{ep}, ok
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// XXX_InternalExtensions is an internal representation of proto extensions.
|
||||
//
|
||||
// Each generated message struct type embeds an anonymous XXX_InternalExtensions field,
|
||||
// thus gaining the unexported 'extensions' method, which can be called only from the proto package.
|
||||
//
|
||||
// The methods of XXX_InternalExtensions are not concurrency safe in general,
|
||||
// but calls to logically read-only methods such as has and get may be executed concurrently.
|
||||
type XXX_InternalExtensions struct {
|
||||
// The struct must be indirect so that if a user inadvertently copies a
|
||||
// generated message and its embedded XXX_InternalExtensions, they
|
||||
// avoid the mayhem of a copied mutex.
|
||||
//
|
||||
// The mutex serializes all logically read-only operations to p.extensionMap.
|
||||
// It is up to the client to ensure that write operations to p.extensionMap are
|
||||
// mutually exclusive with other accesses.
|
||||
p *struct {
|
||||
mu sync.Mutex
|
||||
extensionMap map[int32]Extension
|
||||
}
|
||||
}
|
||||
|
||||
// extensionsWrite returns the extension map, creating it on first use.
|
||||
func (e *XXX_InternalExtensions) extensionsWrite() map[int32]Extension {
|
||||
if e.p == nil {
|
||||
e.p = new(struct {
|
||||
mu sync.Mutex
|
||||
extensionMap map[int32]Extension
|
||||
})
|
||||
e.p.extensionMap = make(map[int32]Extension)
|
||||
}
|
||||
return e.p.extensionMap
|
||||
}
|
||||
|
||||
// extensionsRead returns the extensions map for read-only use. It may be nil.
|
||||
// The caller must hold the returned mutex's lock when accessing Elements within the map.
|
||||
func (e *XXX_InternalExtensions) extensionsRead() (map[int32]Extension, sync.Locker) {
|
||||
if e.p == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return e.p.extensionMap, &e.p.mu
|
||||
}
|
||||
|
||||
var extendableProtoType = reflect.TypeOf((*extendableProto)(nil)).Elem()
|
||||
var extendableProtoV1Type = reflect.TypeOf((*extendableProtoV1)(nil)).Elem()
|
||||
|
||||
// ExtensionDesc represents an extension specification.
|
||||
// Used in generated code from the protocol compiler.
|
||||
type ExtensionDesc struct {
|
||||
ExtendedType Message // nil pointer to the type that is being extended
|
||||
ExtensionType interface{} // nil pointer to the extension type
|
||||
Field int32 // field number
|
||||
Name string // fully-qualified name of extension, for text formatting
|
||||
Tag string // protobuf tag style
|
||||
Filename string // name of the file in which the extension is defined
|
||||
}
|
||||
|
||||
func (ed *ExtensionDesc) repeated() bool {
|
||||
t := reflect.TypeOf(ed.ExtensionType)
|
||||
return t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8
|
||||
}
|
||||
|
||||
// Extension represents an extension in a message.
|
||||
type Extension struct {
|
||||
// When an extension is stored in a message using SetExtension
|
||||
// only desc and value are set. When the message is marshaled
|
||||
// enc will be set to the encoded form of the message.
|
||||
//
|
||||
// When a message is unmarshaled and contains extensions, each
|
||||
// extension will have only enc set. When such an extension is
|
||||
// accessed using GetExtension (or GetExtensions) desc and value
|
||||
// will be set.
|
||||
desc *ExtensionDesc
|
||||
value interface{}
|
||||
enc []byte
|
||||
}
|
||||
|
||||
// SetRawExtension is for testing only.
|
||||
func SetRawExtension(base Message, id int32, b []byte) {
|
||||
epb, ok := extendable(base)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
extmap := epb.extensionsWrite()
|
||||
extmap[id] = Extension{enc: b}
|
||||
}
|
||||
|
||||
// isExtensionField returns true iff the given field number is in an extension range.
|
||||
func isExtensionField(pb extendableProto, field int32) bool {
|
||||
for _, er := range pb.ExtensionRangeArray() {
|
||||
if er.Start <= field && field <= er.End {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// checkExtensionTypes checks that the given extension is valid for pb.
|
||||
func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error {
|
||||
var pbi interface{} = pb
|
||||
// Check the extended type.
|
||||
if ea, ok := pbi.(extensionAdapter); ok {
|
||||
pbi = ea.extendableProtoV1
|
||||
}
|
||||
if a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b {
|
||||
return errors.New("proto: bad extended type; " + b.String() + " does not extend " + a.String())
|
||||
}
|
||||
// Check the range.
|
||||
if !isExtensionField(pb, extension.Field) {
|
||||
return errors.New("proto: bad extension number; not in declared ranges")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// extPropKey is sufficient to uniquely identify an extension.
|
||||
type extPropKey struct {
|
||||
base reflect.Type
|
||||
field int32
|
||||
}
|
||||
|
||||
var extProp = struct {
|
||||
sync.RWMutex
|
||||
m map[extPropKey]*Properties
|
||||
}{
|
||||
m: make(map[extPropKey]*Properties),
|
||||
}
|
||||
|
||||
func extensionProperties(ed *ExtensionDesc) *Properties {
|
||||
key := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field}
|
||||
|
||||
extProp.RLock()
|
||||
if prop, ok := extProp.m[key]; ok {
|
||||
extProp.RUnlock()
|
||||
return prop
|
||||
}
|
||||
extProp.RUnlock()
|
||||
|
||||
extProp.Lock()
|
||||
defer extProp.Unlock()
|
||||
// Check again.
|
||||
if prop, ok := extProp.m[key]; ok {
|
||||
return prop
|
||||
}
|
||||
|
||||
prop := new(Properties)
|
||||
prop.Init(reflect.TypeOf(ed.ExtensionType), "unknown_name", ed.Tag, nil)
|
||||
extProp.m[key] = prop
|
||||
return prop
|
||||
}
|
||||
|
||||
// encode encodes any unmarshaled (unencoded) extensions in e.
|
||||
func encodeExtensions(e *XXX_InternalExtensions) error {
|
||||
m, mu := e.extensionsRead()
|
||||
if m == nil {
|
||||
return nil // fast path
|
||||
}
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
return encodeExtensionsMap(m)
|
||||
}
|
||||
|
||||
// encode encodes any unmarshaled (unencoded) extensions in e.
|
||||
func encodeExtensionsMap(m map[int32]Extension) error {
|
||||
for k, e := range m {
|
||||
if e.value == nil || e.desc == nil {
|
||||
// Extension is only in its encoded form.
|
||||
continue
|
||||
}
|
||||
|
||||
// We don't skip extensions that have an encoded form set,
|
||||
// because the extension value may have been mutated after
|
||||
// the last time this function was called.
|
||||
|
||||
et := reflect.TypeOf(e.desc.ExtensionType)
|
||||
props := extensionProperties(e.desc)
|
||||
|
||||
p := NewBuffer(nil)
|
||||
// If e.value has type T, the encoder expects a *struct{ X T }.
|
||||
// Pass a *T with a zero field and hope it all works out.
|
||||
x := reflect.New(et)
|
||||
x.Elem().Set(reflect.ValueOf(e.value))
|
||||
if err := props.enc(p, props, toStructPointer(x)); err != nil {
|
||||
return err
|
||||
}
|
||||
e.enc = p.buf
|
||||
m[k] = e
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func extensionsSize(e *XXX_InternalExtensions) (n int) {
|
||||
m, mu := e.extensionsRead()
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
return extensionsMapSize(m)
|
||||
}
|
||||
|
||||
func extensionsMapSize(m map[int32]Extension) (n int) {
|
||||
for _, e := range m {
|
||||
if e.value == nil || e.desc == nil {
|
||||
// Extension is only in its encoded form.
|
||||
n += len(e.enc)
|
||||
continue
|
||||
}
|
||||
|
||||
// We don't skip extensions that have an encoded form set,
|
||||
// because the extension value may have been mutated after
|
||||
// the last time this function was called.
|
||||
|
||||
et := reflect.TypeOf(e.desc.ExtensionType)
|
||||
props := extensionProperties(e.desc)
|
||||
|
||||
// If e.value has type T, the encoder expects a *struct{ X T }.
|
||||
// Pass a *T with a zero field and hope it all works out.
|
||||
x := reflect.New(et)
|
||||
x.Elem().Set(reflect.ValueOf(e.value))
|
||||
n += props.size(props, toStructPointer(x))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// HasExtension returns whether the given extension is present in pb.
|
||||
func HasExtension(pb Message, extension *ExtensionDesc) bool {
|
||||
// TODO: Check types, field numbers, etc.?
|
||||
epb, ok := extendable(pb)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
extmap, mu := epb.extensionsRead()
|
||||
if extmap == nil {
|
||||
return false
|
||||
}
|
||||
mu.Lock()
|
||||
_, ok = extmap[extension.Field]
|
||||
mu.Unlock()
|
||||
return ok
|
||||
}
|
||||
|
||||
// ClearExtension removes the given extension from pb.
|
||||
func ClearExtension(pb Message, extension *ExtensionDesc) {
|
||||
epb, ok := extendable(pb)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
// TODO: Check types, field numbers, etc.?
|
||||
extmap := epb.extensionsWrite()
|
||||
delete(extmap, extension.Field)
|
||||
}
|
||||
|
||||
// GetExtension parses and returns the given extension of pb.
|
||||
// If the extension is not present and has no default value it returns ErrMissingExtension.
|
||||
func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) {
|
||||
epb, ok := extendable(pb)
|
||||
if !ok {
|
||||
return nil, errors.New("proto: not an extendable proto")
|
||||
}
|
||||
|
||||
if err := checkExtensionTypes(epb, extension); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
emap, mu := epb.extensionsRead()
|
||||
if emap == nil {
|
||||
return defaultExtensionValue(extension)
|
||||
}
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
e, ok := emap[extension.Field]
|
||||
if !ok {
|
||||
// defaultExtensionValue returns the default value or
|
||||
// ErrMissingExtension if there is no default.
|
||||
return defaultExtensionValue(extension)
|
||||
}
|
||||
|
||||
if e.value != nil {
|
||||
// Already decoded. Check the descriptor, though.
|
||||
if e.desc != extension {
|
||||
// This shouldn't happen. If it does, it means that
|
||||
// GetExtension was called twice with two different
|
||||
// descriptors with the same field number.
|
||||
return nil, errors.New("proto: descriptor conflict")
|
||||
}
|
||||
return e.value, nil
|
||||
}
|
||||
|
||||
v, err := decodeExtension(e.enc, extension)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Remember the decoded version and drop the encoded version.
|
||||
// That way it is safe to mutate what we return.
|
||||
e.value = v
|
||||
e.desc = extension
|
||||
e.enc = nil
|
||||
emap[extension.Field] = e
|
||||
return e.value, nil
|
||||
}
|
||||
|
||||
// defaultExtensionValue returns the default value for extension.
|
||||
// If no default for an extension is defined ErrMissingExtension is returned.
|
||||
func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) {
|
||||
t := reflect.TypeOf(extension.ExtensionType)
|
||||
props := extensionProperties(extension)
|
||||
|
||||
sf, _, err := fieldDefault(t, props)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if sf == nil || sf.value == nil {
|
||||
// There is no default value.
|
||||
return nil, ErrMissingExtension
|
||||
}
|
||||
|
||||
if t.Kind() != reflect.Ptr {
|
||||
// We do not need to return a Ptr, we can directly return sf.value.
|
||||
return sf.value, nil
|
||||
}
|
||||
|
||||
// We need to return an interface{} that is a pointer to sf.value.
|
||||
value := reflect.New(t).Elem()
|
||||
value.Set(reflect.New(value.Type().Elem()))
|
||||
if sf.kind == reflect.Int32 {
|
||||
// We may have an int32 or an enum, but the underlying data is int32.
|
||||
// Since we can't set an int32 into a non int32 reflect.value directly
|
||||
// set it as a int32.
|
||||
value.Elem().SetInt(int64(sf.value.(int32)))
|
||||
} else {
|
||||
value.Elem().Set(reflect.ValueOf(sf.value))
|
||||
}
|
||||
return value.Interface(), nil
|
||||
}
|
||||
|
||||
// decodeExtension decodes an extension encoded in b.
|
||||
func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
|
||||
o := NewBuffer(b)
|
||||
|
||||
t := reflect.TypeOf(extension.ExtensionType)
|
||||
|
||||
props := extensionProperties(extension)
|
||||
|
||||
// t is a pointer to a struct, pointer to basic type or a slice.
|
||||
// Allocate a "field" to store the pointer/slice itself; the
|
||||
// pointer/slice will be stored here. We pass
|
||||
// the address of this field to props.dec.
|
||||
// This passes a zero field and a *t and lets props.dec
|
||||
// interpret it as a *struct{ x t }.
|
||||
value := reflect.New(t).Elem()
|
||||
|
||||
for {
|
||||
// Discard wire type and field number varint. It isn't needed.
|
||||
if _, err := o.DecodeVarint(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := props.dec(o, props, toStructPointer(value.Addr())); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if o.index >= len(o.buf) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return value.Interface(), nil
|
||||
}
|
||||
|
||||
// GetExtensions returns a slice of the extensions present in pb that are also listed in es.
|
||||
// The returned slice has the same length as es; missing extensions will appear as nil elements.
|
||||
func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) {
|
||||
epb, ok := extendable(pb)
|
||||
if !ok {
|
||||
return nil, errors.New("proto: not an extendable proto")
|
||||
}
|
||||
extensions = make([]interface{}, len(es))
|
||||
for i, e := range es {
|
||||
extensions[i], err = GetExtension(epb, e)
|
||||
if err == ErrMissingExtension {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ExtensionDescs returns a new slice containing pb's extension descriptors, in undefined order.
|
||||
// For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing
|
||||
// just the Field field, which defines the extension's field number.
|
||||
func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) {
|
||||
epb, ok := extendable(pb)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("proto: %T is not an extendable proto.Message", pb)
|
||||
}
|
||||
registeredExtensions := RegisteredExtensions(pb)
|
||||
|
||||
emap, mu := epb.extensionsRead()
|
||||
if emap == nil {
|
||||
return nil, nil
|
||||
}
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
extensions := make([]*ExtensionDesc, 0, len(emap))
|
||||
for extid, e := range emap {
|
||||
desc := e.desc
|
||||
if desc == nil {
|
||||
desc = registeredExtensions[extid]
|
||||
if desc == nil {
|
||||
desc = &ExtensionDesc{Field: extid}
|
||||
}
|
||||
}
|
||||
|
||||
extensions = append(extensions, desc)
|
||||
}
|
||||
return extensions, nil
|
||||
}
|
||||
|
||||
// SetExtension sets the specified extension of pb to the specified value.
|
||||
func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error {
|
||||
epb, ok := extendable(pb)
|
||||
if !ok {
|
||||
return errors.New("proto: not an extendable proto")
|
||||
}
|
||||
if err := checkExtensionTypes(epb, extension); err != nil {
|
||||
return err
|
||||
}
|
||||
typ := reflect.TypeOf(extension.ExtensionType)
|
||||
if typ != reflect.TypeOf(value) {
|
||||
return errors.New("proto: bad extension value type")
|
||||
}
|
||||
// nil extension values need to be caught early, because the
|
||||
// encoder can't distinguish an ErrNil due to a nil extension
|
||||
// from an ErrNil due to a missing field. Extensions are
|
||||
// always optional, so the encoder would just swallow the error
|
||||
// and drop all the extensions from the encoded message.
|
||||
if reflect.ValueOf(value).IsNil() {
|
||||
return fmt.Errorf("proto: SetExtension called with nil value of type %T", value)
|
||||
}
|
||||
|
||||
extmap := epb.extensionsWrite()
|
||||
extmap[extension.Field] = Extension{desc: extension, value: value}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ClearAllExtensions clears all extensions from pb.
|
||||
func ClearAllExtensions(pb Message) {
|
||||
epb, ok := extendable(pb)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
m := epb.extensionsWrite()
|
||||
for k := range m {
|
||||
delete(m, k)
|
||||
}
|
||||
}
|
||||
|
||||
// A global registry of extensions.
|
||||
// The generated code will register the generated descriptors by calling RegisterExtension.
|
||||
|
||||
var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc)
|
||||
|
||||
// RegisterExtension is called from the generated code.
|
||||
func RegisterExtension(desc *ExtensionDesc) {
|
||||
st := reflect.TypeOf(desc.ExtendedType).Elem()
|
||||
m := extensionMaps[st]
|
||||
if m == nil {
|
||||
m = make(map[int32]*ExtensionDesc)
|
||||
extensionMaps[st] = m
|
||||
}
|
||||
if _, ok := m[desc.Field]; ok {
|
||||
panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field)))
|
||||
}
|
||||
m[desc.Field] = desc
|
||||
}
|
||||
|
||||
// RegisteredExtensions returns a map of the registered extensions of a
|
||||
// protocol buffer struct, indexed by the extension number.
|
||||
// The argument pb should be a nil pointer to the struct type.
|
||||
func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc {
|
||||
return extensionMaps[reflect.TypeOf(pb).Elem()]
|
||||
}
|
897
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/lib.go
generated
vendored
Normal file
897
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/lib.go
generated
vendored
Normal file
|
@ -0,0 +1,897 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/*
|
||||
Package proto converts data structures to and from the wire format of
|
||||
protocol buffers. It works in concert with the Go source code generated
|
||||
for .proto files by the protocol compiler.
|
||||
|
||||
A summary of the properties of the protocol buffer interface
|
||||
for a protocol buffer variable v:
|
||||
|
||||
- Names are turned from camel_case to CamelCase for export.
|
||||
- There are no methods on v to set fields; just treat
|
||||
them as structure fields.
|
||||
- There are getters that return a field's value if set,
|
||||
and return the field's default value if unset.
|
||||
The getters work even if the receiver is a nil message.
|
||||
- The zero value for a struct is its correct initialization state.
|
||||
All desired fields must be set before marshaling.
|
||||
- A Reset() method will restore a protobuf struct to its zero state.
|
||||
- Non-repeated fields are pointers to the values; nil means unset.
|
||||
That is, optional or required field int32 f becomes F *int32.
|
||||
- Repeated fields are slices.
|
||||
- Helper functions are available to aid the setting of fields.
|
||||
msg.Foo = proto.String("hello") // set field
|
||||
- Constants are defined to hold the default values of all fields that
|
||||
have them. They have the form Default_StructName_FieldName.
|
||||
Because the getter methods handle defaulted values,
|
||||
direct use of these constants should be rare.
|
||||
- Enums are given type names and maps from names to values.
|
||||
Enum values are prefixed by the enclosing message's name, or by the
|
||||
enum's type name if it is a top-level enum. Enum types have a String
|
||||
method, and a Enum method to assist in message construction.
|
||||
- Nested messages, groups and enums have type names prefixed with the name of
|
||||
the surrounding message type.
|
||||
- Extensions are given descriptor names that start with E_,
|
||||
followed by an underscore-delimited list of the nested messages
|
||||
that contain it (if any) followed by the CamelCased name of the
|
||||
extension field itself. HasExtension, ClearExtension, GetExtension
|
||||
and SetExtension are functions for manipulating extensions.
|
||||
- Oneof field sets are given a single field in their message,
|
||||
with distinguished wrapper types for each possible field value.
|
||||
- Marshal and Unmarshal are functions to encode and decode the wire format.
|
||||
|
||||
When the .proto file specifies `syntax="proto3"`, there are some differences:
|
||||
|
||||
- Non-repeated fields of non-message type are values instead of pointers.
|
||||
- Enum types do not get an Enum method.
|
||||
|
||||
The simplest way to describe this is to see an example.
|
||||
Given file test.proto, containing
|
||||
|
||||
package example;
|
||||
|
||||
enum FOO { X = 17; }
|
||||
|
||||
message Test {
|
||||
required string label = 1;
|
||||
optional int32 type = 2 [default=77];
|
||||
repeated int64 reps = 3;
|
||||
optional group OptionalGroup = 4 {
|
||||
required string RequiredField = 5;
|
||||
}
|
||||
oneof union {
|
||||
int32 number = 6;
|
||||
string name = 7;
|
||||
}
|
||||
}
|
||||
|
||||
The resulting file, test.pb.go, is:
|
||||
|
||||
package example
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import math "math"
|
||||
|
||||
type FOO int32
|
||||
const (
|
||||
FOO_X FOO = 17
|
||||
)
|
||||
var FOO_name = map[int32]string{
|
||||
17: "X",
|
||||
}
|
||||
var FOO_value = map[string]int32{
|
||||
"X": 17,
|
||||
}
|
||||
|
||||
func (x FOO) Enum() *FOO {
|
||||
p := new(FOO)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
func (x FOO) String() string {
|
||||
return proto.EnumName(FOO_name, int32(x))
|
||||
}
|
||||
func (x *FOO) UnmarshalJSON(data []byte) error {
|
||||
value, err := proto.UnmarshalJSONEnum(FOO_value, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*x = FOO(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
type Test struct {
|
||||
Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"`
|
||||
Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"`
|
||||
Reps []int64 `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"`
|
||||
Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"`
|
||||
// Types that are valid to be assigned to Union:
|
||||
// *Test_Number
|
||||
// *Test_Name
|
||||
Union isTest_Union `protobuf_oneof:"union"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
func (m *Test) Reset() { *m = Test{} }
|
||||
func (m *Test) String() string { return proto.CompactTextString(m) }
|
||||
func (*Test) ProtoMessage() {}
|
||||
|
||||
type isTest_Union interface {
|
||||
isTest_Union()
|
||||
}
|
||||
|
||||
type Test_Number struct {
|
||||
Number int32 `protobuf:"varint,6,opt,name=number"`
|
||||
}
|
||||
type Test_Name struct {
|
||||
Name string `protobuf:"bytes,7,opt,name=name"`
|
||||
}
|
||||
|
||||
func (*Test_Number) isTest_Union() {}
|
||||
func (*Test_Name) isTest_Union() {}
|
||||
|
||||
func (m *Test) GetUnion() isTest_Union {
|
||||
if m != nil {
|
||||
return m.Union
|
||||
}
|
||||
return nil
|
||||
}
|
||||
const Default_Test_Type int32 = 77
|
||||
|
||||
func (m *Test) GetLabel() string {
|
||||
if m != nil && m.Label != nil {
|
||||
return *m.Label
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Test) GetType() int32 {
|
||||
if m != nil && m.Type != nil {
|
||||
return *m.Type
|
||||
}
|
||||
return Default_Test_Type
|
||||
}
|
||||
|
||||
func (m *Test) GetOptionalgroup() *Test_OptionalGroup {
|
||||
if m != nil {
|
||||
return m.Optionalgroup
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Test_OptionalGroup struct {
|
||||
RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"`
|
||||
}
|
||||
func (m *Test_OptionalGroup) Reset() { *m = Test_OptionalGroup{} }
|
||||
func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) }
|
||||
|
||||
func (m *Test_OptionalGroup) GetRequiredField() string {
|
||||
if m != nil && m.RequiredField != nil {
|
||||
return *m.RequiredField
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Test) GetNumber() int32 {
|
||||
if x, ok := m.GetUnion().(*Test_Number); ok {
|
||||
return x.Number
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Test) GetName() string {
|
||||
if x, ok := m.GetUnion().(*Test_Name); ok {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
|
||||
}
|
||||
|
||||
To create and play with a Test object:
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
pb "./example.pb"
|
||||
)
|
||||
|
||||
func main() {
|
||||
test := &pb.Test{
|
||||
Label: proto.String("hello"),
|
||||
Type: proto.Int32(17),
|
||||
Reps: []int64{1, 2, 3},
|
||||
Optionalgroup: &pb.Test_OptionalGroup{
|
||||
RequiredField: proto.String("good bye"),
|
||||
},
|
||||
Union: &pb.Test_Name{"fred"},
|
||||
}
|
||||
data, err := proto.Marshal(test)
|
||||
if err != nil {
|
||||
log.Fatal("marshaling error: ", err)
|
||||
}
|
||||
newTest := &pb.Test{}
|
||||
err = proto.Unmarshal(data, newTest)
|
||||
if err != nil {
|
||||
log.Fatal("unmarshaling error: ", err)
|
||||
}
|
||||
// Now test and newTest contain the same data.
|
||||
if test.GetLabel() != newTest.GetLabel() {
|
||||
log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel())
|
||||
}
|
||||
// Use a type switch to determine which oneof was set.
|
||||
switch u := test.Union.(type) {
|
||||
case *pb.Test_Number: // u.Number contains the number.
|
||||
case *pb.Test_Name: // u.Name contains the string.
|
||||
}
|
||||
// etc.
|
||||
}
|
||||
*/
|
||||
package proto
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Message is implemented by generated protocol buffer messages.
|
||||
type Message interface {
|
||||
Reset()
|
||||
String() string
|
||||
ProtoMessage()
|
||||
}
|
||||
|
||||
// Stats records allocation details about the protocol buffer encoders
|
||||
// and decoders. Useful for tuning the library itself.
|
||||
type Stats struct {
|
||||
Emalloc uint64 // mallocs in encode
|
||||
Dmalloc uint64 // mallocs in decode
|
||||
Encode uint64 // number of encodes
|
||||
Decode uint64 // number of decodes
|
||||
Chit uint64 // number of cache hits
|
||||
Cmiss uint64 // number of cache misses
|
||||
Size uint64 // number of sizes
|
||||
}
|
||||
|
||||
// Set to true to enable stats collection.
|
||||
const collectStats = false
|
||||
|
||||
var stats Stats
|
||||
|
||||
// GetStats returns a copy of the global Stats structure.
|
||||
func GetStats() Stats { return stats }
|
||||
|
||||
// A Buffer is a buffer manager for marshaling and unmarshaling
|
||||
// protocol buffers. It may be reused between invocations to
|
||||
// reduce memory usage. It is not necessary to use a Buffer;
|
||||
// the global functions Marshal and Unmarshal create a
|
||||
// temporary Buffer and are fine for most applications.
|
||||
type Buffer struct {
|
||||
buf []byte // encode/decode byte stream
|
||||
index int // read point
|
||||
|
||||
// pools of basic types to amortize allocation.
|
||||
bools []bool
|
||||
uint32s []uint32
|
||||
uint64s []uint64
|
||||
|
||||
// extra pools, only used with pointer_reflect.go
|
||||
int32s []int32
|
||||
int64s []int64
|
||||
float32s []float32
|
||||
float64s []float64
|
||||
}
|
||||
|
||||
// NewBuffer allocates a new Buffer and initializes its internal data to
|
||||
// the contents of the argument slice.
|
||||
func NewBuffer(e []byte) *Buffer {
|
||||
return &Buffer{buf: e}
|
||||
}
|
||||
|
||||
// Reset resets the Buffer, ready for marshaling a new protocol buffer.
|
||||
func (p *Buffer) Reset() {
|
||||
p.buf = p.buf[0:0] // for reading/writing
|
||||
p.index = 0 // for reading
|
||||
}
|
||||
|
||||
// SetBuf replaces the internal buffer with the slice,
|
||||
// ready for unmarshaling the contents of the slice.
|
||||
func (p *Buffer) SetBuf(s []byte) {
|
||||
p.buf = s
|
||||
p.index = 0
|
||||
}
|
||||
|
||||
// Bytes returns the contents of the Buffer.
|
||||
func (p *Buffer) Bytes() []byte { return p.buf }
|
||||
|
||||
/*
|
||||
* Helper routines for simplifying the creation of optional fields of basic type.
|
||||
*/
|
||||
|
||||
// Bool is a helper routine that allocates a new bool value
|
||||
// to store v and returns a pointer to it.
|
||||
func Bool(v bool) *bool {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Int32 is a helper routine that allocates a new int32 value
|
||||
// to store v and returns a pointer to it.
|
||||
func Int32(v int32) *int32 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// 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.
|
||||
func Int(v int) *int32 {
|
||||
p := new(int32)
|
||||
*p = int32(v)
|
||||
return p
|
||||
}
|
||||
|
||||
// Int64 is a helper routine that allocates a new int64 value
|
||||
// to store v and returns a pointer to it.
|
||||
func Int64(v int64) *int64 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Float32 is a helper routine that allocates a new float32 value
|
||||
// to store v and returns a pointer to it.
|
||||
func Float32(v float32) *float32 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Float64 is a helper routine that allocates a new float64 value
|
||||
// to store v and returns a pointer to it.
|
||||
func Float64(v float64) *float64 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Uint32 is a helper routine that allocates a new uint32 value
|
||||
// to store v and returns a pointer to it.
|
||||
func Uint32(v uint32) *uint32 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Uint64 is a helper routine that allocates a new uint64 value
|
||||
// to store v and returns a pointer to it.
|
||||
func Uint64(v uint64) *uint64 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// String is a helper routine that allocates a new string value
|
||||
// to store v and returns a pointer to it.
|
||||
func String(v string) *string {
|
||||
return &v
|
||||
}
|
||||
|
||||
// EnumName is a helper function to simplify printing protocol buffer enums
|
||||
// by name. Given an enum map and a value, it returns a useful string.
|
||||
func EnumName(m map[int32]string, v int32) string {
|
||||
s, ok := m[v]
|
||||
if ok {
|
||||
return s
|
||||
}
|
||||
return strconv.Itoa(int(v))
|
||||
}
|
||||
|
||||
// UnmarshalJSONEnum is a helper function to simplify recovering enum int values
|
||||
// from their JSON-encoded representation. Given a map from the enum's symbolic
|
||||
// names to its int values, and a byte buffer containing the JSON-encoded
|
||||
// value, it returns an int32 that can be cast to the enum type by the caller.
|
||||
//
|
||||
// The function can deal with both JSON representations, numeric and symbolic.
|
||||
func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) {
|
||||
if data[0] == '"' {
|
||||
// New style: enums are strings.
|
||||
var repr string
|
||||
if err := json.Unmarshal(data, &repr); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
val, ok := m[repr]
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr)
|
||||
}
|
||||
return val, nil
|
||||
}
|
||||
// Old style: enums are ints.
|
||||
var val int32
|
||||
if err := json.Unmarshal(data, &val); err != nil {
|
||||
return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName)
|
||||
}
|
||||
return val, nil
|
||||
}
|
||||
|
||||
// DebugPrint dumps the encoded data in b in a debugging format with a header
|
||||
// including the string s. Used in testing but made available for general debugging.
|
||||
func (p *Buffer) DebugPrint(s string, b []byte) {
|
||||
var u uint64
|
||||
|
||||
obuf := p.buf
|
||||
index := p.index
|
||||
p.buf = b
|
||||
p.index = 0
|
||||
depth := 0
|
||||
|
||||
fmt.Printf("\n--- %s ---\n", s)
|
||||
|
||||
out:
|
||||
for {
|
||||
for i := 0; i < depth; i++ {
|
||||
fmt.Print(" ")
|
||||
}
|
||||
|
||||
index := p.index
|
||||
if index == len(p.buf) {
|
||||
break
|
||||
}
|
||||
|
||||
op, err := p.DecodeVarint()
|
||||
if err != nil {
|
||||
fmt.Printf("%3d: fetching op err %v\n", index, err)
|
||||
break out
|
||||
}
|
||||
tag := op >> 3
|
||||
wire := op & 7
|
||||
|
||||
switch wire {
|
||||
default:
|
||||
fmt.Printf("%3d: t=%3d unknown wire=%d\n",
|
||||
index, tag, wire)
|
||||
break out
|
||||
|
||||
case WireBytes:
|
||||
var r []byte
|
||||
|
||||
r, err = p.DecodeRawBytes(false)
|
||||
if err != nil {
|
||||
break out
|
||||
}
|
||||
fmt.Printf("%3d: t=%3d bytes [%d]", index, tag, len(r))
|
||||
if len(r) <= 6 {
|
||||
for i := 0; i < len(r); i++ {
|
||||
fmt.Printf(" %.2x", r[i])
|
||||
}
|
||||
} else {
|
||||
for i := 0; i < 3; i++ {
|
||||
fmt.Printf(" %.2x", r[i])
|
||||
}
|
||||
fmt.Printf(" ..")
|
||||
for i := len(r) - 3; i < len(r); i++ {
|
||||
fmt.Printf(" %.2x", r[i])
|
||||
}
|
||||
}
|
||||
fmt.Printf("\n")
|
||||
|
||||
case WireFixed32:
|
||||
u, err = p.DecodeFixed32()
|
||||
if err != nil {
|
||||
fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err)
|
||||
break out
|
||||
}
|
||||
fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u)
|
||||
|
||||
case WireFixed64:
|
||||
u, err = p.DecodeFixed64()
|
||||
if err != nil {
|
||||
fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err)
|
||||
break out
|
||||
}
|
||||
fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u)
|
||||
|
||||
case WireVarint:
|
||||
u, err = p.DecodeVarint()
|
||||
if err != nil {
|
||||
fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err)
|
||||
break out
|
||||
}
|
||||
fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u)
|
||||
|
||||
case WireStartGroup:
|
||||
fmt.Printf("%3d: t=%3d start\n", index, tag)
|
||||
depth++
|
||||
|
||||
case WireEndGroup:
|
||||
depth--
|
||||
fmt.Printf("%3d: t=%3d end\n", index, tag)
|
||||
}
|
||||
}
|
||||
|
||||
if depth != 0 {
|
||||
fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth)
|
||||
}
|
||||
fmt.Printf("\n")
|
||||
|
||||
p.buf = obuf
|
||||
p.index = index
|
||||
}
|
||||
|
||||
// SetDefaults sets unset protocol buffer fields to their default values.
|
||||
// It only modifies fields that are both unset and have defined defaults.
|
||||
// It recursively sets default values in any non-nil sub-messages.
|
||||
func SetDefaults(pb Message) {
|
||||
setDefaults(reflect.ValueOf(pb), true, false)
|
||||
}
|
||||
|
||||
// v is a pointer to a struct.
|
||||
func setDefaults(v reflect.Value, recur, zeros bool) {
|
||||
v = v.Elem()
|
||||
|
||||
defaultMu.RLock()
|
||||
dm, ok := defaults[v.Type()]
|
||||
defaultMu.RUnlock()
|
||||
if !ok {
|
||||
dm = buildDefaultMessage(v.Type())
|
||||
defaultMu.Lock()
|
||||
defaults[v.Type()] = dm
|
||||
defaultMu.Unlock()
|
||||
}
|
||||
|
||||
for _, sf := range dm.scalars {
|
||||
f := v.Field(sf.index)
|
||||
if !f.IsNil() {
|
||||
// field already set
|
||||
continue
|
||||
}
|
||||
dv := sf.value
|
||||
if dv == nil && !zeros {
|
||||
// no explicit default, and don't want to set zeros
|
||||
continue
|
||||
}
|
||||
fptr := f.Addr().Interface() // **T
|
||||
// TODO: Consider batching the allocations we do here.
|
||||
switch sf.kind {
|
||||
case reflect.Bool:
|
||||
b := new(bool)
|
||||
if dv != nil {
|
||||
*b = dv.(bool)
|
||||
}
|
||||
*(fptr.(**bool)) = b
|
||||
case reflect.Float32:
|
||||
f := new(float32)
|
||||
if dv != nil {
|
||||
*f = dv.(float32)
|
||||
}
|
||||
*(fptr.(**float32)) = f
|
||||
case reflect.Float64:
|
||||
f := new(float64)
|
||||
if dv != nil {
|
||||
*f = dv.(float64)
|
||||
}
|
||||
*(fptr.(**float64)) = f
|
||||
case reflect.Int32:
|
||||
// might be an enum
|
||||
if ft := f.Type(); ft != int32PtrType {
|
||||
// enum
|
||||
f.Set(reflect.New(ft.Elem()))
|
||||
if dv != nil {
|
||||
f.Elem().SetInt(int64(dv.(int32)))
|
||||
}
|
||||
} else {
|
||||
// int32 field
|
||||
i := new(int32)
|
||||
if dv != nil {
|
||||
*i = dv.(int32)
|
||||
}
|
||||
*(fptr.(**int32)) = i
|
||||
}
|
||||
case reflect.Int64:
|
||||
i := new(int64)
|
||||
if dv != nil {
|
||||
*i = dv.(int64)
|
||||
}
|
||||
*(fptr.(**int64)) = i
|
||||
case reflect.String:
|
||||
s := new(string)
|
||||
if dv != nil {
|
||||
*s = dv.(string)
|
||||
}
|
||||
*(fptr.(**string)) = s
|
||||
case reflect.Uint8:
|
||||
// exceptional case: []byte
|
||||
var b []byte
|
||||
if dv != nil {
|
||||
db := dv.([]byte)
|
||||
b = make([]byte, len(db))
|
||||
copy(b, db)
|
||||
} else {
|
||||
b = []byte{}
|
||||
}
|
||||
*(fptr.(*[]byte)) = b
|
||||
case reflect.Uint32:
|
||||
u := new(uint32)
|
||||
if dv != nil {
|
||||
*u = dv.(uint32)
|
||||
}
|
||||
*(fptr.(**uint32)) = u
|
||||
case reflect.Uint64:
|
||||
u := new(uint64)
|
||||
if dv != nil {
|
||||
*u = dv.(uint64)
|
||||
}
|
||||
*(fptr.(**uint64)) = u
|
||||
default:
|
||||
log.Printf("proto: can't set default for field %v (sf.kind=%v)", f, sf.kind)
|
||||
}
|
||||
}
|
||||
|
||||
for _, ni := range dm.nested {
|
||||
f := v.Field(ni)
|
||||
// f is *T or []*T or map[T]*T
|
||||
switch f.Kind() {
|
||||
case reflect.Ptr:
|
||||
if f.IsNil() {
|
||||
continue
|
||||
}
|
||||
setDefaults(f, recur, zeros)
|
||||
|
||||
case reflect.Slice:
|
||||
for i := 0; i < f.Len(); i++ {
|
||||
e := f.Index(i)
|
||||
if e.IsNil() {
|
||||
continue
|
||||
}
|
||||
setDefaults(e, recur, zeros)
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
for _, k := range f.MapKeys() {
|
||||
e := f.MapIndex(k)
|
||||
if e.IsNil() {
|
||||
continue
|
||||
}
|
||||
setDefaults(e, recur, zeros)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
// defaults maps a protocol buffer struct type to a slice of the fields,
|
||||
// with its scalar fields set to their proto-declared non-zero default values.
|
||||
defaultMu sync.RWMutex
|
||||
defaults = make(map[reflect.Type]defaultMessage)
|
||||
|
||||
int32PtrType = reflect.TypeOf((*int32)(nil))
|
||||
)
|
||||
|
||||
// defaultMessage represents information about the default values of a message.
|
||||
type defaultMessage struct {
|
||||
scalars []scalarField
|
||||
nested []int // struct field index of nested messages
|
||||
}
|
||||
|
||||
type scalarField struct {
|
||||
index int // struct field index
|
||||
kind reflect.Kind // element type (the T in *T or []T)
|
||||
value interface{} // the proto-declared default value, or nil
|
||||
}
|
||||
|
||||
// t is a struct type.
|
||||
func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
|
||||
sprop := GetProperties(t)
|
||||
for _, prop := range sprop.Prop {
|
||||
fi, ok := sprop.decoderTags.get(prop.Tag)
|
||||
if !ok {
|
||||
// XXX_unrecognized
|
||||
continue
|
||||
}
|
||||
ft := t.Field(fi).Type
|
||||
|
||||
sf, nested, err := fieldDefault(ft, prop)
|
||||
switch {
|
||||
case err != nil:
|
||||
log.Print(err)
|
||||
case nested:
|
||||
dm.nested = append(dm.nested, fi)
|
||||
case sf != nil:
|
||||
sf.index = fi
|
||||
dm.scalars = append(dm.scalars, *sf)
|
||||
}
|
||||
}
|
||||
|
||||
return dm
|
||||
}
|
||||
|
||||
// fieldDefault returns the scalarField for field type ft.
|
||||
// sf will be nil if the field can not have a default.
|
||||
// nestedMessage will be true if this is a nested message.
|
||||
// Note that sf.index is not set on return.
|
||||
func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) {
|
||||
var canHaveDefault bool
|
||||
switch ft.Kind() {
|
||||
case reflect.Ptr:
|
||||
if ft.Elem().Kind() == reflect.Struct {
|
||||
nestedMessage = true
|
||||
} else {
|
||||
canHaveDefault = true // proto2 scalar field
|
||||
}
|
||||
|
||||
case reflect.Slice:
|
||||
switch ft.Elem().Kind() {
|
||||
case reflect.Ptr:
|
||||
nestedMessage = true // repeated message
|
||||
case reflect.Uint8:
|
||||
canHaveDefault = true // bytes field
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
if ft.Elem().Kind() == reflect.Ptr {
|
||||
nestedMessage = true // map with message values
|
||||
}
|
||||
}
|
||||
|
||||
if !canHaveDefault {
|
||||
if nestedMessage {
|
||||
return nil, true, nil
|
||||
}
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
// We now know that ft is a pointer or slice.
|
||||
sf = &scalarField{kind: ft.Elem().Kind()}
|
||||
|
||||
// scalar fields without defaults
|
||||
if !prop.HasDefault {
|
||||
return sf, false, nil
|
||||
}
|
||||
|
||||
// a scalar field: either *T or []byte
|
||||
switch ft.Elem().Kind() {
|
||||
case reflect.Bool:
|
||||
x, err := strconv.ParseBool(prop.Default)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("proto: bad default bool %q: %v", prop.Default, err)
|
||||
}
|
||||
sf.value = x
|
||||
case reflect.Float32:
|
||||
x, err := strconv.ParseFloat(prop.Default, 32)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("proto: bad default float32 %q: %v", prop.Default, err)
|
||||
}
|
||||
sf.value = float32(x)
|
||||
case reflect.Float64:
|
||||
x, err := strconv.ParseFloat(prop.Default, 64)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("proto: bad default float64 %q: %v", prop.Default, err)
|
||||
}
|
||||
sf.value = x
|
||||
case reflect.Int32:
|
||||
x, err := strconv.ParseInt(prop.Default, 10, 32)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("proto: bad default int32 %q: %v", prop.Default, err)
|
||||
}
|
||||
sf.value = int32(x)
|
||||
case reflect.Int64:
|
||||
x, err := strconv.ParseInt(prop.Default, 10, 64)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("proto: bad default int64 %q: %v", prop.Default, err)
|
||||
}
|
||||
sf.value = x
|
||||
case reflect.String:
|
||||
sf.value = prop.Default
|
||||
case reflect.Uint8:
|
||||
// []byte (not *uint8)
|
||||
sf.value = []byte(prop.Default)
|
||||
case reflect.Uint32:
|
||||
x, err := strconv.ParseUint(prop.Default, 10, 32)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("proto: bad default uint32 %q: %v", prop.Default, err)
|
||||
}
|
||||
sf.value = uint32(x)
|
||||
case reflect.Uint64:
|
||||
x, err := strconv.ParseUint(prop.Default, 10, 64)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("proto: bad default uint64 %q: %v", prop.Default, err)
|
||||
}
|
||||
sf.value = x
|
||||
default:
|
||||
return nil, false, fmt.Errorf("proto: unhandled def kind %v", ft.Elem().Kind())
|
||||
}
|
||||
|
||||
return sf, false, nil
|
||||
}
|
||||
|
||||
// Map fields may have key types of non-float scalars, strings and enums.
|
||||
// The easiest way to sort them in some deterministic order is to use fmt.
|
||||
// If this turns out to be inefficient we can always consider other options,
|
||||
// such as doing a Schwartzian transform.
|
||||
|
||||
func mapKeys(vs []reflect.Value) sort.Interface {
|
||||
s := mapKeySorter{
|
||||
vs: vs,
|
||||
// default Less function: textual comparison
|
||||
less: func(a, b reflect.Value) bool {
|
||||
return fmt.Sprint(a.Interface()) < fmt.Sprint(b.Interface())
|
||||
},
|
||||
}
|
||||
|
||||
// Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps;
|
||||
// numeric keys are sorted numerically.
|
||||
if len(vs) == 0 {
|
||||
return s
|
||||
}
|
||||
switch vs[0].Kind() {
|
||||
case reflect.Int32, reflect.Int64:
|
||||
s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() }
|
||||
case reflect.Uint32, reflect.Uint64:
|
||||
s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() }
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
type mapKeySorter struct {
|
||||
vs []reflect.Value
|
||||
less func(a, b reflect.Value) bool
|
||||
}
|
||||
|
||||
func (s mapKeySorter) Len() int { return len(s.vs) }
|
||||
func (s mapKeySorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] }
|
||||
func (s mapKeySorter) Less(i, j int) bool {
|
||||
return s.less(s.vs[i], s.vs[j])
|
||||
}
|
||||
|
||||
// isProto3Zero reports whether v is a zero proto3 value.
|
||||
func isProto3Zero(v reflect.Value) bool {
|
||||
switch v.Kind() {
|
||||
case reflect.Bool:
|
||||
return !v.Bool()
|
||||
case reflect.Int32, reflect.Int64:
|
||||
return v.Int() == 0
|
||||
case reflect.Uint32, reflect.Uint64:
|
||||
return v.Uint() == 0
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return v.Float() == 0
|
||||
case reflect.String:
|
||||
return v.String() == ""
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ProtoPackageIsVersion2 is referenced from generated protocol buffer files
|
||||
// to assert that that code is compatible with this version of the proto package.
|
||||
const ProtoPackageIsVersion2 = true
|
||||
|
||||
// ProtoPackageIsVersion1 is referenced from generated protocol buffer files
|
||||
// to assert that that code is compatible with this version of the proto package.
|
||||
const ProtoPackageIsVersion1 = true
|
311
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/message_set.go
generated
vendored
Normal file
311
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/message_set.go
generated
vendored
Normal file
|
@ -0,0 +1,311 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
/*
|
||||
* Support for message sets.
|
||||
*/
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// errNoMessageTypeID occurs when a protocol buffer does not have a message type ID.
|
||||
// A message type ID is required for storing a protocol buffer in a message set.
|
||||
var errNoMessageTypeID = errors.New("proto does not have a message type ID")
|
||||
|
||||
// The first two types (_MessageSet_Item and messageSet)
|
||||
// model what the protocol compiler produces for the following protocol message:
|
||||
// message MessageSet {
|
||||
// repeated group Item = 1 {
|
||||
// required int32 type_id = 2;
|
||||
// required string message = 3;
|
||||
// };
|
||||
// }
|
||||
// That is the MessageSet wire format. We can't use a proto to generate these
|
||||
// because that would introduce a circular dependency between it and this package.
|
||||
|
||||
type _MessageSet_Item struct {
|
||||
TypeId *int32 `protobuf:"varint,2,req,name=type_id"`
|
||||
Message []byte `protobuf:"bytes,3,req,name=message"`
|
||||
}
|
||||
|
||||
type messageSet struct {
|
||||
Item []*_MessageSet_Item `protobuf:"group,1,rep"`
|
||||
XXX_unrecognized []byte
|
||||
// TODO: caching?
|
||||
}
|
||||
|
||||
// Make sure messageSet is a Message.
|
||||
var _ Message = (*messageSet)(nil)
|
||||
|
||||
// messageTypeIder is an interface satisfied by a protocol buffer type
|
||||
// that may be stored in a MessageSet.
|
||||
type messageTypeIder interface {
|
||||
MessageTypeId() int32
|
||||
}
|
||||
|
||||
func (ms *messageSet) find(pb Message) *_MessageSet_Item {
|
||||
mti, ok := pb.(messageTypeIder)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
id := mti.MessageTypeId()
|
||||
for _, item := range ms.Item {
|
||||
if *item.TypeId == id {
|
||||
return item
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ms *messageSet) Has(pb Message) bool {
|
||||
if ms.find(pb) != nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (ms *messageSet) Unmarshal(pb Message) error {
|
||||
if item := ms.find(pb); item != nil {
|
||||
return Unmarshal(item.Message, pb)
|
||||
}
|
||||
if _, ok := pb.(messageTypeIder); !ok {
|
||||
return errNoMessageTypeID
|
||||
}
|
||||
return nil // TODO: return error instead?
|
||||
}
|
||||
|
||||
func (ms *messageSet) Marshal(pb Message) error {
|
||||
msg, err := Marshal(pb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if item := ms.find(pb); item != nil {
|
||||
// reuse existing item
|
||||
item.Message = msg
|
||||
return nil
|
||||
}
|
||||
|
||||
mti, ok := pb.(messageTypeIder)
|
||||
if !ok {
|
||||
return errNoMessageTypeID
|
||||
}
|
||||
|
||||
mtid := mti.MessageTypeId()
|
||||
ms.Item = append(ms.Item, &_MessageSet_Item{
|
||||
TypeId: &mtid,
|
||||
Message: msg,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ms *messageSet) Reset() { *ms = messageSet{} }
|
||||
func (ms *messageSet) String() string { return CompactTextString(ms) }
|
||||
func (*messageSet) ProtoMessage() {}
|
||||
|
||||
// Support for the message_set_wire_format message option.
|
||||
|
||||
func skipVarint(buf []byte) []byte {
|
||||
i := 0
|
||||
for ; buf[i]&0x80 != 0; i++ {
|
||||
}
|
||||
return buf[i+1:]
|
||||
}
|
||||
|
||||
// MarshalMessageSet encodes the extension map represented by m in the message set wire format.
|
||||
// It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option.
|
||||
func MarshalMessageSet(exts interface{}) ([]byte, error) {
|
||||
var m map[int32]Extension
|
||||
switch exts := exts.(type) {
|
||||
case *XXX_InternalExtensions:
|
||||
if err := encodeExtensions(exts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m, _ = exts.extensionsRead()
|
||||
case map[int32]Extension:
|
||||
if err := encodeExtensionsMap(exts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m = exts
|
||||
default:
|
||||
return nil, errors.New("proto: not an extension map")
|
||||
}
|
||||
|
||||
// Sort extension IDs to provide a deterministic encoding.
|
||||
// See also enc_map in encode.go.
|
||||
ids := make([]int, 0, len(m))
|
||||
for id := range m {
|
||||
ids = append(ids, int(id))
|
||||
}
|
||||
sort.Ints(ids)
|
||||
|
||||
ms := &messageSet{Item: make([]*_MessageSet_Item, 0, len(m))}
|
||||
for _, id := range ids {
|
||||
e := m[int32(id)]
|
||||
// Remove the wire type and field number varint, as well as the length varint.
|
||||
msg := skipVarint(skipVarint(e.enc))
|
||||
|
||||
ms.Item = append(ms.Item, &_MessageSet_Item{
|
||||
TypeId: Int32(int32(id)),
|
||||
Message: msg,
|
||||
})
|
||||
}
|
||||
return Marshal(ms)
|
||||
}
|
||||
|
||||
// UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
|
||||
// It is called by generated Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
|
||||
func UnmarshalMessageSet(buf []byte, exts interface{}) error {
|
||||
var m map[int32]Extension
|
||||
switch exts := exts.(type) {
|
||||
case *XXX_InternalExtensions:
|
||||
m = exts.extensionsWrite()
|
||||
case map[int32]Extension:
|
||||
m = exts
|
||||
default:
|
||||
return errors.New("proto: not an extension map")
|
||||
}
|
||||
|
||||
ms := new(messageSet)
|
||||
if err := Unmarshal(buf, ms); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, item := range ms.Item {
|
||||
id := *item.TypeId
|
||||
msg := item.Message
|
||||
|
||||
// Restore wire type and field number varint, plus length varint.
|
||||
// Be careful to preserve duplicate items.
|
||||
b := EncodeVarint(uint64(id)<<3 | WireBytes)
|
||||
if ext, ok := m[id]; ok {
|
||||
// Existing data; rip off the tag and length varint
|
||||
// so we join the new data correctly.
|
||||
// We can assume that ext.enc is set because we are unmarshaling.
|
||||
o := ext.enc[len(b):] // skip wire type and field number
|
||||
_, n := DecodeVarint(o) // calculate length of length varint
|
||||
o = o[n:] // skip length varint
|
||||
msg = append(o, msg...) // join old data and new data
|
||||
}
|
||||
b = append(b, EncodeVarint(uint64(len(msg)))...)
|
||||
b = append(b, msg...)
|
||||
|
||||
m[id] = Extension{enc: b}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalMessageSetJSON encodes the extension map represented by m in JSON format.
|
||||
// It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
|
||||
func MarshalMessageSetJSON(exts interface{}) ([]byte, error) {
|
||||
var m map[int32]Extension
|
||||
switch exts := exts.(type) {
|
||||
case *XXX_InternalExtensions:
|
||||
m, _ = exts.extensionsRead()
|
||||
case map[int32]Extension:
|
||||
m = exts
|
||||
default:
|
||||
return nil, errors.New("proto: not an extension map")
|
||||
}
|
||||
var b bytes.Buffer
|
||||
b.WriteByte('{')
|
||||
|
||||
// Process the map in key order for deterministic output.
|
||||
ids := make([]int32, 0, len(m))
|
||||
for id := range m {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
sort.Sort(int32Slice(ids)) // int32Slice defined in text.go
|
||||
|
||||
for i, id := range ids {
|
||||
ext := m[id]
|
||||
if i > 0 {
|
||||
b.WriteByte(',')
|
||||
}
|
||||
|
||||
msd, ok := messageSetMap[id]
|
||||
if !ok {
|
||||
// Unknown type; we can't render it, so skip it.
|
||||
continue
|
||||
}
|
||||
fmt.Fprintf(&b, `"[%s]":`, msd.name)
|
||||
|
||||
x := ext.value
|
||||
if x == nil {
|
||||
x = reflect.New(msd.t.Elem()).Interface()
|
||||
if err := Unmarshal(ext.enc, x.(Message)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
d, err := json.Marshal(x)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b.Write(d)
|
||||
}
|
||||
b.WriteByte('}')
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
// UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format.
|
||||
// It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
|
||||
func UnmarshalMessageSetJSON(buf []byte, exts interface{}) error {
|
||||
// Common-case fast path.
|
||||
if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// This is fairly tricky, and it's not clear that it is needed.
|
||||
return errors.New("TODO: UnmarshalMessageSetJSON not yet implemented")
|
||||
}
|
||||
|
||||
// A global registry of types that can be used in a MessageSet.
|
||||
|
||||
var messageSetMap = make(map[int32]messageSetDesc)
|
||||
|
||||
type messageSetDesc struct {
|
||||
t reflect.Type // pointer to struct
|
||||
name string
|
||||
}
|
||||
|
||||
// RegisterMessageSetType is called from the generated code.
|
||||
func RegisterMessageSetType(m Message, fieldNum int32, name string) {
|
||||
messageSetMap[fieldNum] = messageSetDesc{
|
||||
t: reflect.TypeOf(m),
|
||||
name: name,
|
||||
}
|
||||
}
|
484
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/pointer_reflect.go
generated
vendored
Normal file
484
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/pointer_reflect.go
generated
vendored
Normal file
|
@ -0,0 +1,484 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// +build appengine js
|
||||
|
||||
// This file contains an implementation of proto field accesses using package reflect.
|
||||
// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
|
||||
// be used on App Engine.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"math"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// A structPointer is a pointer to a struct.
|
||||
type structPointer struct {
|
||||
v reflect.Value
|
||||
}
|
||||
|
||||
// toStructPointer returns a structPointer equivalent to the given reflect value.
|
||||
// The reflect value must itself be a pointer to a struct.
|
||||
func toStructPointer(v reflect.Value) structPointer {
|
||||
return structPointer{v}
|
||||
}
|
||||
|
||||
// IsNil reports whether p is nil.
|
||||
func structPointer_IsNil(p structPointer) bool {
|
||||
return p.v.IsNil()
|
||||
}
|
||||
|
||||
// Interface returns the struct pointer as an interface value.
|
||||
func structPointer_Interface(p structPointer, _ reflect.Type) interface{} {
|
||||
return p.v.Interface()
|
||||
}
|
||||
|
||||
// A field identifies a field in a struct, accessible from a structPointer.
|
||||
// In this implementation, a field is identified by the sequence of field indices
|
||||
// passed to reflect's FieldByIndex.
|
||||
type field []int
|
||||
|
||||
// toField returns a field equivalent to the given reflect field.
|
||||
func toField(f *reflect.StructField) field {
|
||||
return f.Index
|
||||
}
|
||||
|
||||
// invalidField is an invalid field identifier.
|
||||
var invalidField = field(nil)
|
||||
|
||||
// IsValid reports whether the field identifier is valid.
|
||||
func (f field) IsValid() bool { return f != nil }
|
||||
|
||||
// field returns the given field in the struct as a reflect value.
|
||||
func structPointer_field(p structPointer, f field) reflect.Value {
|
||||
// Special case: an extension map entry with a value of type T
|
||||
// passes a *T to the struct-handling code with a zero field,
|
||||
// expecting that it will be treated as equivalent to *struct{ X T },
|
||||
// which has the same memory layout. We have to handle that case
|
||||
// specially, because reflect will panic if we call FieldByIndex on a
|
||||
// non-struct.
|
||||
if f == nil {
|
||||
return p.v.Elem()
|
||||
}
|
||||
|
||||
return p.v.Elem().FieldByIndex(f)
|
||||
}
|
||||
|
||||
// ifield returns the given field in the struct as an interface value.
|
||||
func structPointer_ifield(p structPointer, f field) interface{} {
|
||||
return structPointer_field(p, f).Addr().Interface()
|
||||
}
|
||||
|
||||
// Bytes returns the address of a []byte field in the struct.
|
||||
func structPointer_Bytes(p structPointer, f field) *[]byte {
|
||||
return structPointer_ifield(p, f).(*[]byte)
|
||||
}
|
||||
|
||||
// BytesSlice returns the address of a [][]byte field in the struct.
|
||||
func structPointer_BytesSlice(p structPointer, f field) *[][]byte {
|
||||
return structPointer_ifield(p, f).(*[][]byte)
|
||||
}
|
||||
|
||||
// Bool returns the address of a *bool field in the struct.
|
||||
func structPointer_Bool(p structPointer, f field) **bool {
|
||||
return structPointer_ifield(p, f).(**bool)
|
||||
}
|
||||
|
||||
// BoolVal returns the address of a bool field in the struct.
|
||||
func structPointer_BoolVal(p structPointer, f field) *bool {
|
||||
return structPointer_ifield(p, f).(*bool)
|
||||
}
|
||||
|
||||
// BoolSlice returns the address of a []bool field in the struct.
|
||||
func structPointer_BoolSlice(p structPointer, f field) *[]bool {
|
||||
return structPointer_ifield(p, f).(*[]bool)
|
||||
}
|
||||
|
||||
// String returns the address of a *string field in the struct.
|
||||
func structPointer_String(p structPointer, f field) **string {
|
||||
return structPointer_ifield(p, f).(**string)
|
||||
}
|
||||
|
||||
// StringVal returns the address of a string field in the struct.
|
||||
func structPointer_StringVal(p structPointer, f field) *string {
|
||||
return structPointer_ifield(p, f).(*string)
|
||||
}
|
||||
|
||||
// StringSlice returns the address of a []string field in the struct.
|
||||
func structPointer_StringSlice(p structPointer, f field) *[]string {
|
||||
return structPointer_ifield(p, f).(*[]string)
|
||||
}
|
||||
|
||||
// Extensions returns the address of an extension map field in the struct.
|
||||
func structPointer_Extensions(p structPointer, f field) *XXX_InternalExtensions {
|
||||
return structPointer_ifield(p, f).(*XXX_InternalExtensions)
|
||||
}
|
||||
|
||||
// ExtMap returns the address of an extension map field in the struct.
|
||||
func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
|
||||
return structPointer_ifield(p, f).(*map[int32]Extension)
|
||||
}
|
||||
|
||||
// NewAt returns the reflect.Value for a pointer to a field in the struct.
|
||||
func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value {
|
||||
return structPointer_field(p, f).Addr()
|
||||
}
|
||||
|
||||
// SetStructPointer writes a *struct field in the struct.
|
||||
func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
|
||||
structPointer_field(p, f).Set(q.v)
|
||||
}
|
||||
|
||||
// GetStructPointer reads a *struct field in the struct.
|
||||
func structPointer_GetStructPointer(p structPointer, f field) structPointer {
|
||||
return structPointer{structPointer_field(p, f)}
|
||||
}
|
||||
|
||||
// StructPointerSlice the address of a []*struct field in the struct.
|
||||
func structPointer_StructPointerSlice(p structPointer, f field) structPointerSlice {
|
||||
return structPointerSlice{structPointer_field(p, f)}
|
||||
}
|
||||
|
||||
// A structPointerSlice represents the address of a slice of pointers to structs
|
||||
// (themselves messages or groups). That is, v.Type() is *[]*struct{...}.
|
||||
type structPointerSlice struct {
|
||||
v reflect.Value
|
||||
}
|
||||
|
||||
func (p structPointerSlice) Len() int { return p.v.Len() }
|
||||
func (p structPointerSlice) Index(i int) structPointer { return structPointer{p.v.Index(i)} }
|
||||
func (p structPointerSlice) Append(q structPointer) {
|
||||
p.v.Set(reflect.Append(p.v, q.v))
|
||||
}
|
||||
|
||||
var (
|
||||
int32Type = reflect.TypeOf(int32(0))
|
||||
uint32Type = reflect.TypeOf(uint32(0))
|
||||
float32Type = reflect.TypeOf(float32(0))
|
||||
int64Type = reflect.TypeOf(int64(0))
|
||||
uint64Type = reflect.TypeOf(uint64(0))
|
||||
float64Type = reflect.TypeOf(float64(0))
|
||||
)
|
||||
|
||||
// A word32 represents a field of type *int32, *uint32, *float32, or *enum.
|
||||
// That is, v.Type() is *int32, *uint32, *float32, or *enum and v is assignable.
|
||||
type word32 struct {
|
||||
v reflect.Value
|
||||
}
|
||||
|
||||
// IsNil reports whether p is nil.
|
||||
func word32_IsNil(p word32) bool {
|
||||
return p.v.IsNil()
|
||||
}
|
||||
|
||||
// Set sets p to point at a newly allocated word with bits set to x.
|
||||
func word32_Set(p word32, o *Buffer, x uint32) {
|
||||
t := p.v.Type().Elem()
|
||||
switch t {
|
||||
case int32Type:
|
||||
if len(o.int32s) == 0 {
|
||||
o.int32s = make([]int32, uint32PoolSize)
|
||||
}
|
||||
o.int32s[0] = int32(x)
|
||||
p.v.Set(reflect.ValueOf(&o.int32s[0]))
|
||||
o.int32s = o.int32s[1:]
|
||||
return
|
||||
case uint32Type:
|
||||
if len(o.uint32s) == 0 {
|
||||
o.uint32s = make([]uint32, uint32PoolSize)
|
||||
}
|
||||
o.uint32s[0] = x
|
||||
p.v.Set(reflect.ValueOf(&o.uint32s[0]))
|
||||
o.uint32s = o.uint32s[1:]
|
||||
return
|
||||
case float32Type:
|
||||
if len(o.float32s) == 0 {
|
||||
o.float32s = make([]float32, uint32PoolSize)
|
||||
}
|
||||
o.float32s[0] = math.Float32frombits(x)
|
||||
p.v.Set(reflect.ValueOf(&o.float32s[0]))
|
||||
o.float32s = o.float32s[1:]
|
||||
return
|
||||
}
|
||||
|
||||
// must be enum
|
||||
p.v.Set(reflect.New(t))
|
||||
p.v.Elem().SetInt(int64(int32(x)))
|
||||
}
|
||||
|
||||
// Get gets the bits pointed at by p, as a uint32.
|
||||
func word32_Get(p word32) uint32 {
|
||||
elem := p.v.Elem()
|
||||
switch elem.Kind() {
|
||||
case reflect.Int32:
|
||||
return uint32(elem.Int())
|
||||
case reflect.Uint32:
|
||||
return uint32(elem.Uint())
|
||||
case reflect.Float32:
|
||||
return math.Float32bits(float32(elem.Float()))
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
// Word32 returns a reference to a *int32, *uint32, *float32, or *enum field in the struct.
|
||||
func structPointer_Word32(p structPointer, f field) word32 {
|
||||
return word32{structPointer_field(p, f)}
|
||||
}
|
||||
|
||||
// A word32Val represents a field of type int32, uint32, float32, or enum.
|
||||
// That is, v.Type() is int32, uint32, float32, or enum and v is assignable.
|
||||
type word32Val struct {
|
||||
v reflect.Value
|
||||
}
|
||||
|
||||
// Set sets *p to x.
|
||||
func word32Val_Set(p word32Val, x uint32) {
|
||||
switch p.v.Type() {
|
||||
case int32Type:
|
||||
p.v.SetInt(int64(x))
|
||||
return
|
||||
case uint32Type:
|
||||
p.v.SetUint(uint64(x))
|
||||
return
|
||||
case float32Type:
|
||||
p.v.SetFloat(float64(math.Float32frombits(x)))
|
||||
return
|
||||
}
|
||||
|
||||
// must be enum
|
||||
p.v.SetInt(int64(int32(x)))
|
||||
}
|
||||
|
||||
// Get gets the bits pointed at by p, as a uint32.
|
||||
func word32Val_Get(p word32Val) uint32 {
|
||||
elem := p.v
|
||||
switch elem.Kind() {
|
||||
case reflect.Int32:
|
||||
return uint32(elem.Int())
|
||||
case reflect.Uint32:
|
||||
return uint32(elem.Uint())
|
||||
case reflect.Float32:
|
||||
return math.Float32bits(float32(elem.Float()))
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
// Word32Val returns a reference to a int32, uint32, float32, or enum field in the struct.
|
||||
func structPointer_Word32Val(p structPointer, f field) word32Val {
|
||||
return word32Val{structPointer_field(p, f)}
|
||||
}
|
||||
|
||||
// A word32Slice is a slice of 32-bit values.
|
||||
// That is, v.Type() is []int32, []uint32, []float32, or []enum.
|
||||
type word32Slice struct {
|
||||
v reflect.Value
|
||||
}
|
||||
|
||||
func (p word32Slice) Append(x uint32) {
|
||||
n, m := p.v.Len(), p.v.Cap()
|
||||
if n < m {
|
||||
p.v.SetLen(n + 1)
|
||||
} else {
|
||||
t := p.v.Type().Elem()
|
||||
p.v.Set(reflect.Append(p.v, reflect.Zero(t)))
|
||||
}
|
||||
elem := p.v.Index(n)
|
||||
switch elem.Kind() {
|
||||
case reflect.Int32:
|
||||
elem.SetInt(int64(int32(x)))
|
||||
case reflect.Uint32:
|
||||
elem.SetUint(uint64(x))
|
||||
case reflect.Float32:
|
||||
elem.SetFloat(float64(math.Float32frombits(x)))
|
||||
}
|
||||
}
|
||||
|
||||
func (p word32Slice) Len() int {
|
||||
return p.v.Len()
|
||||
}
|
||||
|
||||
func (p word32Slice) Index(i int) uint32 {
|
||||
elem := p.v.Index(i)
|
||||
switch elem.Kind() {
|
||||
case reflect.Int32:
|
||||
return uint32(elem.Int())
|
||||
case reflect.Uint32:
|
||||
return uint32(elem.Uint())
|
||||
case reflect.Float32:
|
||||
return math.Float32bits(float32(elem.Float()))
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
// Word32Slice returns a reference to a []int32, []uint32, []float32, or []enum field in the struct.
|
||||
func structPointer_Word32Slice(p structPointer, f field) word32Slice {
|
||||
return word32Slice{structPointer_field(p, f)}
|
||||
}
|
||||
|
||||
// word64 is like word32 but for 64-bit values.
|
||||
type word64 struct {
|
||||
v reflect.Value
|
||||
}
|
||||
|
||||
func word64_Set(p word64, o *Buffer, x uint64) {
|
||||
t := p.v.Type().Elem()
|
||||
switch t {
|
||||
case int64Type:
|
||||
if len(o.int64s) == 0 {
|
||||
o.int64s = make([]int64, uint64PoolSize)
|
||||
}
|
||||
o.int64s[0] = int64(x)
|
||||
p.v.Set(reflect.ValueOf(&o.int64s[0]))
|
||||
o.int64s = o.int64s[1:]
|
||||
return
|
||||
case uint64Type:
|
||||
if len(o.uint64s) == 0 {
|
||||
o.uint64s = make([]uint64, uint64PoolSize)
|
||||
}
|
||||
o.uint64s[0] = x
|
||||
p.v.Set(reflect.ValueOf(&o.uint64s[0]))
|
||||
o.uint64s = o.uint64s[1:]
|
||||
return
|
||||
case float64Type:
|
||||
if len(o.float64s) == 0 {
|
||||
o.float64s = make([]float64, uint64PoolSize)
|
||||
}
|
||||
o.float64s[0] = math.Float64frombits(x)
|
||||
p.v.Set(reflect.ValueOf(&o.float64s[0]))
|
||||
o.float64s = o.float64s[1:]
|
||||
return
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
func word64_IsNil(p word64) bool {
|
||||
return p.v.IsNil()
|
||||
}
|
||||
|
||||
func word64_Get(p word64) uint64 {
|
||||
elem := p.v.Elem()
|
||||
switch elem.Kind() {
|
||||
case reflect.Int64:
|
||||
return uint64(elem.Int())
|
||||
case reflect.Uint64:
|
||||
return elem.Uint()
|
||||
case reflect.Float64:
|
||||
return math.Float64bits(elem.Float())
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
func structPointer_Word64(p structPointer, f field) word64 {
|
||||
return word64{structPointer_field(p, f)}
|
||||
}
|
||||
|
||||
// word64Val is like word32Val but for 64-bit values.
|
||||
type word64Val struct {
|
||||
v reflect.Value
|
||||
}
|
||||
|
||||
func word64Val_Set(p word64Val, o *Buffer, x uint64) {
|
||||
switch p.v.Type() {
|
||||
case int64Type:
|
||||
p.v.SetInt(int64(x))
|
||||
return
|
||||
case uint64Type:
|
||||
p.v.SetUint(x)
|
||||
return
|
||||
case float64Type:
|
||||
p.v.SetFloat(math.Float64frombits(x))
|
||||
return
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
func word64Val_Get(p word64Val) uint64 {
|
||||
elem := p.v
|
||||
switch elem.Kind() {
|
||||
case reflect.Int64:
|
||||
return uint64(elem.Int())
|
||||
case reflect.Uint64:
|
||||
return elem.Uint()
|
||||
case reflect.Float64:
|
||||
return math.Float64bits(elem.Float())
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
func structPointer_Word64Val(p structPointer, f field) word64Val {
|
||||
return word64Val{structPointer_field(p, f)}
|
||||
}
|
||||
|
||||
type word64Slice struct {
|
||||
v reflect.Value
|
||||
}
|
||||
|
||||
func (p word64Slice) Append(x uint64) {
|
||||
n, m := p.v.Len(), p.v.Cap()
|
||||
if n < m {
|
||||
p.v.SetLen(n + 1)
|
||||
} else {
|
||||
t := p.v.Type().Elem()
|
||||
p.v.Set(reflect.Append(p.v, reflect.Zero(t)))
|
||||
}
|
||||
elem := p.v.Index(n)
|
||||
switch elem.Kind() {
|
||||
case reflect.Int64:
|
||||
elem.SetInt(int64(int64(x)))
|
||||
case reflect.Uint64:
|
||||
elem.SetUint(uint64(x))
|
||||
case reflect.Float64:
|
||||
elem.SetFloat(float64(math.Float64frombits(x)))
|
||||
}
|
||||
}
|
||||
|
||||
func (p word64Slice) Len() int {
|
||||
return p.v.Len()
|
||||
}
|
||||
|
||||
func (p word64Slice) Index(i int) uint64 {
|
||||
elem := p.v.Index(i)
|
||||
switch elem.Kind() {
|
||||
case reflect.Int64:
|
||||
return uint64(elem.Int())
|
||||
case reflect.Uint64:
|
||||
return uint64(elem.Uint())
|
||||
case reflect.Float64:
|
||||
return math.Float64bits(float64(elem.Float()))
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
func structPointer_Word64Slice(p structPointer, f field) word64Slice {
|
||||
return word64Slice{structPointer_field(p, f)}
|
||||
}
|
270
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go
generated
vendored
Normal file
270
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go
generated
vendored
Normal file
|
@ -0,0 +1,270 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// +build !appengine,!js
|
||||
|
||||
// This file contains the implementation of the proto field accesses using package unsafe.
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// NOTE: These type_Foo functions would more idiomatically be methods,
|
||||
// but Go does not allow methods on pointer types, and we must preserve
|
||||
// some pointer type for the garbage collector. We use these
|
||||
// funcs with clunky names as our poor approximation to methods.
|
||||
//
|
||||
// An alternative would be
|
||||
// type structPointer struct { p unsafe.Pointer }
|
||||
// but that does not registerize as well.
|
||||
|
||||
// A structPointer is a pointer to a struct.
|
||||
type structPointer unsafe.Pointer
|
||||
|
||||
// toStructPointer returns a structPointer equivalent to the given reflect value.
|
||||
func toStructPointer(v reflect.Value) structPointer {
|
||||
return structPointer(unsafe.Pointer(v.Pointer()))
|
||||
}
|
||||
|
||||
// IsNil reports whether p is nil.
|
||||
func structPointer_IsNil(p structPointer) bool {
|
||||
return p == nil
|
||||
}
|
||||
|
||||
// Interface returns the struct pointer, assumed to have element type t,
|
||||
// as an interface value.
|
||||
func structPointer_Interface(p structPointer, t reflect.Type) interface{} {
|
||||
return reflect.NewAt(t, unsafe.Pointer(p)).Interface()
|
||||
}
|
||||
|
||||
// A field identifies a field in a struct, accessible from a structPointer.
|
||||
// In this implementation, a field is identified by its byte offset from the start of the struct.
|
||||
type field uintptr
|
||||
|
||||
// toField returns a field equivalent to the given reflect field.
|
||||
func toField(f *reflect.StructField) field {
|
||||
return field(f.Offset)
|
||||
}
|
||||
|
||||
// invalidField is an invalid field identifier.
|
||||
const invalidField = ^field(0)
|
||||
|
||||
// IsValid reports whether the field identifier is valid.
|
||||
func (f field) IsValid() bool {
|
||||
return f != ^field(0)
|
||||
}
|
||||
|
||||
// Bytes returns the address of a []byte field in the struct.
|
||||
func structPointer_Bytes(p structPointer, f field) *[]byte {
|
||||
return (*[]byte)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||
}
|
||||
|
||||
// BytesSlice returns the address of a [][]byte field in the struct.
|
||||
func structPointer_BytesSlice(p structPointer, f field) *[][]byte {
|
||||
return (*[][]byte)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||
}
|
||||
|
||||
// Bool returns the address of a *bool field in the struct.
|
||||
func structPointer_Bool(p structPointer, f field) **bool {
|
||||
return (**bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||
}
|
||||
|
||||
// BoolVal returns the address of a bool field in the struct.
|
||||
func structPointer_BoolVal(p structPointer, f field) *bool {
|
||||
return (*bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||
}
|
||||
|
||||
// BoolSlice returns the address of a []bool field in the struct.
|
||||
func structPointer_BoolSlice(p structPointer, f field) *[]bool {
|
||||
return (*[]bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||
}
|
||||
|
||||
// String returns the address of a *string field in the struct.
|
||||
func structPointer_String(p structPointer, f field) **string {
|
||||
return (**string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||
}
|
||||
|
||||
// StringVal returns the address of a string field in the struct.
|
||||
func structPointer_StringVal(p structPointer, f field) *string {
|
||||
return (*string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||
}
|
||||
|
||||
// StringSlice returns the address of a []string field in the struct.
|
||||
func structPointer_StringSlice(p structPointer, f field) *[]string {
|
||||
return (*[]string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||
}
|
||||
|
||||
// ExtMap returns the address of an extension map field in the struct.
|
||||
func structPointer_Extensions(p structPointer, f field) *XXX_InternalExtensions {
|
||||
return (*XXX_InternalExtensions)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||
}
|
||||
|
||||
func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
|
||||
return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||
}
|
||||
|
||||
// NewAt returns the reflect.Value for a pointer to a field in the struct.
|
||||
func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value {
|
||||
return reflect.NewAt(typ, unsafe.Pointer(uintptr(p)+uintptr(f)))
|
||||
}
|
||||
|
||||
// SetStructPointer writes a *struct field in the struct.
|
||||
func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
|
||||
*(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))) = q
|
||||
}
|
||||
|
||||
// GetStructPointer reads a *struct field in the struct.
|
||||
func structPointer_GetStructPointer(p structPointer, f field) structPointer {
|
||||
return *(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||
}
|
||||
|
||||
// StructPointerSlice the address of a []*struct field in the struct.
|
||||
func structPointer_StructPointerSlice(p structPointer, f field) *structPointerSlice {
|
||||
return (*structPointerSlice)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||
}
|
||||
|
||||
// A structPointerSlice represents a slice of pointers to structs (themselves submessages or groups).
|
||||
type structPointerSlice []structPointer
|
||||
|
||||
func (v *structPointerSlice) Len() int { return len(*v) }
|
||||
func (v *structPointerSlice) Index(i int) structPointer { return (*v)[i] }
|
||||
func (v *structPointerSlice) Append(p structPointer) { *v = append(*v, p) }
|
||||
|
||||
// A word32 is the address of a "pointer to 32-bit value" field.
|
||||
type word32 **uint32
|
||||
|
||||
// IsNil reports whether *v is nil.
|
||||
func word32_IsNil(p word32) bool {
|
||||
return *p == nil
|
||||
}
|
||||
|
||||
// Set sets *v to point at a newly allocated word set to x.
|
||||
func word32_Set(p word32, o *Buffer, x uint32) {
|
||||
if len(o.uint32s) == 0 {
|
||||
o.uint32s = make([]uint32, uint32PoolSize)
|
||||
}
|
||||
o.uint32s[0] = x
|
||||
*p = &o.uint32s[0]
|
||||
o.uint32s = o.uint32s[1:]
|
||||
}
|
||||
|
||||
// Get gets the value pointed at by *v.
|
||||
func word32_Get(p word32) uint32 {
|
||||
return **p
|
||||
}
|
||||
|
||||
// Word32 returns the address of a *int32, *uint32, *float32, or *enum field in the struct.
|
||||
func structPointer_Word32(p structPointer, f field) word32 {
|
||||
return word32((**uint32)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
||||
}
|
||||
|
||||
// A word32Val is the address of a 32-bit value field.
|
||||
type word32Val *uint32
|
||||
|
||||
// Set sets *p to x.
|
||||
func word32Val_Set(p word32Val, x uint32) {
|
||||
*p = x
|
||||
}
|
||||
|
||||
// Get gets the value pointed at by p.
|
||||
func word32Val_Get(p word32Val) uint32 {
|
||||
return *p
|
||||
}
|
||||
|
||||
// Word32Val returns the address of a *int32, *uint32, *float32, or *enum field in the struct.
|
||||
func structPointer_Word32Val(p structPointer, f field) word32Val {
|
||||
return word32Val((*uint32)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
||||
}
|
||||
|
||||
// A word32Slice is a slice of 32-bit values.
|
||||
type word32Slice []uint32
|
||||
|
||||
func (v *word32Slice) Append(x uint32) { *v = append(*v, x) }
|
||||
func (v *word32Slice) Len() int { return len(*v) }
|
||||
func (v *word32Slice) Index(i int) uint32 { return (*v)[i] }
|
||||
|
||||
// Word32Slice returns the address of a []int32, []uint32, []float32, or []enum field in the struct.
|
||||
func structPointer_Word32Slice(p structPointer, f field) *word32Slice {
|
||||
return (*word32Slice)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||
}
|
||||
|
||||
// word64 is like word32 but for 64-bit values.
|
||||
type word64 **uint64
|
||||
|
||||
func word64_Set(p word64, o *Buffer, x uint64) {
|
||||
if len(o.uint64s) == 0 {
|
||||
o.uint64s = make([]uint64, uint64PoolSize)
|
||||
}
|
||||
o.uint64s[0] = x
|
||||
*p = &o.uint64s[0]
|
||||
o.uint64s = o.uint64s[1:]
|
||||
}
|
||||
|
||||
func word64_IsNil(p word64) bool {
|
||||
return *p == nil
|
||||
}
|
||||
|
||||
func word64_Get(p word64) uint64 {
|
||||
return **p
|
||||
}
|
||||
|
||||
func structPointer_Word64(p structPointer, f field) word64 {
|
||||
return word64((**uint64)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
||||
}
|
||||
|
||||
// word64Val is like word32Val but for 64-bit values.
|
||||
type word64Val *uint64
|
||||
|
||||
func word64Val_Set(p word64Val, o *Buffer, x uint64) {
|
||||
*p = x
|
||||
}
|
||||
|
||||
func word64Val_Get(p word64Val) uint64 {
|
||||
return *p
|
||||
}
|
||||
|
||||
func structPointer_Word64Val(p structPointer, f field) word64Val {
|
||||
return word64Val((*uint64)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
||||
}
|
||||
|
||||
// word64Slice is like word32Slice but for 64-bit values.
|
||||
type word64Slice []uint64
|
||||
|
||||
func (v *word64Slice) Append(x uint64) { *v = append(*v, x) }
|
||||
func (v *word64Slice) Len() int { return len(*v) }
|
||||
func (v *word64Slice) Index(i int) uint64 { return (*v)[i] }
|
||||
|
||||
func structPointer_Word64Slice(p structPointer, f field) *word64Slice {
|
||||
return (*word64Slice)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||
}
|
872
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/properties.go
generated
vendored
Normal file
872
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/properties.go
generated
vendored
Normal file
|
@ -0,0 +1,872 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
/*
|
||||
* Routines for encoding data into the wire format for protocol buffers.
|
||||
*/
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const debug bool = false
|
||||
|
||||
// Constants that identify the encoding of a value on the wire.
|
||||
const (
|
||||
WireVarint = 0
|
||||
WireFixed64 = 1
|
||||
WireBytes = 2
|
||||
WireStartGroup = 3
|
||||
WireEndGroup = 4
|
||||
WireFixed32 = 5
|
||||
)
|
||||
|
||||
const startSize = 10 // initial slice/string sizes
|
||||
|
||||
// Encoders are defined in encode.go
|
||||
// An encoder outputs the full representation of a field, including its
|
||||
// tag and encoder type.
|
||||
type encoder func(p *Buffer, prop *Properties, base structPointer) error
|
||||
|
||||
// A valueEncoder encodes a single integer in a particular encoding.
|
||||
type valueEncoder func(o *Buffer, x uint64) error
|
||||
|
||||
// Sizers are defined in encode.go
|
||||
// A sizer returns the encoded size of a field, including its tag and encoder
|
||||
// type.
|
||||
type sizer func(prop *Properties, base structPointer) int
|
||||
|
||||
// A valueSizer returns the encoded size of a single integer in a particular
|
||||
// encoding.
|
||||
type valueSizer func(x uint64) int
|
||||
|
||||
// Decoders are defined in decode.go
|
||||
// A decoder creates a value from its wire representation.
|
||||
// Unrecognized subelements are saved in unrec.
|
||||
type decoder func(p *Buffer, prop *Properties, base structPointer) error
|
||||
|
||||
// A valueDecoder decodes a single integer in a particular encoding.
|
||||
type valueDecoder func(o *Buffer) (x uint64, err error)
|
||||
|
||||
// A oneofMarshaler does the marshaling for all oneof fields in a message.
|
||||
type oneofMarshaler func(Message, *Buffer) error
|
||||
|
||||
// A oneofUnmarshaler does the unmarshaling for a oneof field in a message.
|
||||
type oneofUnmarshaler func(Message, int, int, *Buffer) (bool, error)
|
||||
|
||||
// A oneofSizer does the sizing for all oneof fields in a message.
|
||||
type oneofSizer func(Message) int
|
||||
|
||||
// tagMap is an optimization over map[int]int for typical protocol buffer
|
||||
// use-cases. Encoded protocol buffers are often in tag order with small tag
|
||||
// numbers.
|
||||
type tagMap struct {
|
||||
fastTags []int
|
||||
slowTags map[int]int
|
||||
}
|
||||
|
||||
// tagMapFastLimit is the upper bound on the tag number that will be stored in
|
||||
// the tagMap slice rather than its map.
|
||||
const tagMapFastLimit = 1024
|
||||
|
||||
func (p *tagMap) get(t int) (int, bool) {
|
||||
if t > 0 && t < tagMapFastLimit {
|
||||
if t >= len(p.fastTags) {
|
||||
return 0, false
|
||||
}
|
||||
fi := p.fastTags[t]
|
||||
return fi, fi >= 0
|
||||
}
|
||||
fi, ok := p.slowTags[t]
|
||||
return fi, ok
|
||||
}
|
||||
|
||||
func (p *tagMap) put(t int, fi int) {
|
||||
if t > 0 && t < tagMapFastLimit {
|
||||
for len(p.fastTags) < t+1 {
|
||||
p.fastTags = append(p.fastTags, -1)
|
||||
}
|
||||
p.fastTags[t] = fi
|
||||
return
|
||||
}
|
||||
if p.slowTags == nil {
|
||||
p.slowTags = make(map[int]int)
|
||||
}
|
||||
p.slowTags[t] = fi
|
||||
}
|
||||
|
||||
// StructProperties represents properties for all the fields of a struct.
|
||||
// decoderTags and decoderOrigNames should only be used by the decoder.
|
||||
type StructProperties struct {
|
||||
Prop []*Properties // properties for each field
|
||||
reqCount int // required count
|
||||
decoderTags tagMap // map from proto tag to struct field number
|
||||
decoderOrigNames map[string]int // map from original name to struct field number
|
||||
order []int // list of struct field numbers in tag order
|
||||
unrecField field // field id of the XXX_unrecognized []byte field
|
||||
extendable bool // is this an extendable proto
|
||||
|
||||
oneofMarshaler oneofMarshaler
|
||||
oneofUnmarshaler oneofUnmarshaler
|
||||
oneofSizer oneofSizer
|
||||
stype reflect.Type
|
||||
|
||||
// OneofTypes contains information about the oneof fields in this message.
|
||||
// It is keyed by the original name of a field.
|
||||
OneofTypes map[string]*OneofProperties
|
||||
}
|
||||
|
||||
// OneofProperties represents information about a specific field in a oneof.
|
||||
type OneofProperties struct {
|
||||
Type reflect.Type // pointer to generated struct type for this oneof field
|
||||
Field int // struct field number of the containing oneof in the message
|
||||
Prop *Properties
|
||||
}
|
||||
|
||||
// Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec.
|
||||
// See encode.go, (*Buffer).enc_struct.
|
||||
|
||||
func (sp *StructProperties) Len() int { return len(sp.order) }
|
||||
func (sp *StructProperties) Less(i, j int) bool {
|
||||
return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag
|
||||
}
|
||||
func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] }
|
||||
|
||||
// Properties represents the protocol-specific behavior of a single struct field.
|
||||
type Properties struct {
|
||||
Name string // name of the field, for error messages
|
||||
OrigName string // original name before protocol compiler (always set)
|
||||
JSONName string // name to use for JSON; determined by protoc
|
||||
Wire string
|
||||
WireType int
|
||||
Tag int
|
||||
Required bool
|
||||
Optional bool
|
||||
Repeated bool
|
||||
Packed bool // relevant for repeated primitives only
|
||||
Enum string // set for enum types only
|
||||
proto3 bool // whether this is known to be a proto3 field; set for []byte only
|
||||
oneof bool // whether this is a oneof field
|
||||
|
||||
Default string // default value
|
||||
HasDefault bool // whether an explicit default was provided
|
||||
def_uint64 uint64
|
||||
|
||||
enc encoder
|
||||
valEnc valueEncoder // set for bool and numeric types only
|
||||
field field
|
||||
tagcode []byte // encoding of EncodeVarint((Tag<<3)|WireType)
|
||||
tagbuf [8]byte
|
||||
stype reflect.Type // set for struct types only
|
||||
sprop *StructProperties // set for struct types only
|
||||
isMarshaler bool
|
||||
isUnmarshaler bool
|
||||
|
||||
mtype reflect.Type // set for map types only
|
||||
mkeyprop *Properties // set for map types only
|
||||
mvalprop *Properties // set for map types only
|
||||
|
||||
size sizer
|
||||
valSize valueSizer // set for bool and numeric types only
|
||||
|
||||
dec decoder
|
||||
valDec valueDecoder // set for bool and numeric types only
|
||||
|
||||
// If this is a packable field, this will be the decoder for the packed version of the field.
|
||||
packedDec decoder
|
||||
}
|
||||
|
||||
// String formats the properties in the protobuf struct field tag style.
|
||||
func (p *Properties) String() string {
|
||||
s := p.Wire
|
||||
s = ","
|
||||
s += strconv.Itoa(p.Tag)
|
||||
if p.Required {
|
||||
s += ",req"
|
||||
}
|
||||
if p.Optional {
|
||||
s += ",opt"
|
||||
}
|
||||
if p.Repeated {
|
||||
s += ",rep"
|
||||
}
|
||||
if p.Packed {
|
||||
s += ",packed"
|
||||
}
|
||||
s += ",name=" + p.OrigName
|
||||
if p.JSONName != p.OrigName {
|
||||
s += ",json=" + p.JSONName
|
||||
}
|
||||
if p.proto3 {
|
||||
s += ",proto3"
|
||||
}
|
||||
if p.oneof {
|
||||
s += ",oneof"
|
||||
}
|
||||
if len(p.Enum) > 0 {
|
||||
s += ",enum=" + p.Enum
|
||||
}
|
||||
if p.HasDefault {
|
||||
s += ",def=" + p.Default
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Parse populates p by parsing a string in the protobuf struct field tag style.
|
||||
func (p *Properties) Parse(s string) {
|
||||
// "bytes,49,opt,name=foo,def=hello!"
|
||||
fields := strings.Split(s, ",") // breaks def=, but handled below.
|
||||
if len(fields) < 2 {
|
||||
fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s)
|
||||
return
|
||||
}
|
||||
|
||||
p.Wire = fields[0]
|
||||
switch p.Wire {
|
||||
case "varint":
|
||||
p.WireType = WireVarint
|
||||
p.valEnc = (*Buffer).EncodeVarint
|
||||
p.valDec = (*Buffer).DecodeVarint
|
||||
p.valSize = sizeVarint
|
||||
case "fixed32":
|
||||
p.WireType = WireFixed32
|
||||
p.valEnc = (*Buffer).EncodeFixed32
|
||||
p.valDec = (*Buffer).DecodeFixed32
|
||||
p.valSize = sizeFixed32
|
||||
case "fixed64":
|
||||
p.WireType = WireFixed64
|
||||
p.valEnc = (*Buffer).EncodeFixed64
|
||||
p.valDec = (*Buffer).DecodeFixed64
|
||||
p.valSize = sizeFixed64
|
||||
case "zigzag32":
|
||||
p.WireType = WireVarint
|
||||
p.valEnc = (*Buffer).EncodeZigzag32
|
||||
p.valDec = (*Buffer).DecodeZigzag32
|
||||
p.valSize = sizeZigzag32
|
||||
case "zigzag64":
|
||||
p.WireType = WireVarint
|
||||
p.valEnc = (*Buffer).EncodeZigzag64
|
||||
p.valDec = (*Buffer).DecodeZigzag64
|
||||
p.valSize = sizeZigzag64
|
||||
case "bytes", "group":
|
||||
p.WireType = WireBytes
|
||||
// no numeric converter for non-numeric types
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s)
|
||||
return
|
||||
}
|
||||
|
||||
var err error
|
||||
p.Tag, err = strconv.Atoi(fields[1])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for i := 2; i < len(fields); i++ {
|
||||
f := fields[i]
|
||||
switch {
|
||||
case f == "req":
|
||||
p.Required = true
|
||||
case f == "opt":
|
||||
p.Optional = true
|
||||
case f == "rep":
|
||||
p.Repeated = true
|
||||
case f == "packed":
|
||||
p.Packed = true
|
||||
case strings.HasPrefix(f, "name="):
|
||||
p.OrigName = f[5:]
|
||||
case strings.HasPrefix(f, "json="):
|
||||
p.JSONName = f[5:]
|
||||
case strings.HasPrefix(f, "enum="):
|
||||
p.Enum = f[5:]
|
||||
case f == "proto3":
|
||||
p.proto3 = true
|
||||
case f == "oneof":
|
||||
p.oneof = true
|
||||
case strings.HasPrefix(f, "def="):
|
||||
p.HasDefault = true
|
||||
p.Default = f[4:] // rest of string
|
||||
if i+1 < len(fields) {
|
||||
// Commas aren't escaped, and def is always last.
|
||||
p.Default += "," + strings.Join(fields[i+1:], ",")
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func logNoSliceEnc(t1, t2 reflect.Type) {
|
||||
fmt.Fprintf(os.Stderr, "proto: no slice oenc for %T = []%T\n", t1, t2)
|
||||
}
|
||||
|
||||
var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()
|
||||
|
||||
// Initialize the fields for encoding and decoding.
|
||||
func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lockGetProp bool) {
|
||||
p.enc = nil
|
||||
p.dec = nil
|
||||
p.size = nil
|
||||
|
||||
switch t1 := typ; t1.Kind() {
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "proto: no coders for %v\n", t1)
|
||||
|
||||
// proto3 scalar types
|
||||
|
||||
case reflect.Bool:
|
||||
p.enc = (*Buffer).enc_proto3_bool
|
||||
p.dec = (*Buffer).dec_proto3_bool
|
||||
p.size = size_proto3_bool
|
||||
case reflect.Int32:
|
||||
p.enc = (*Buffer).enc_proto3_int32
|
||||
p.dec = (*Buffer).dec_proto3_int32
|
||||
p.size = size_proto3_int32
|
||||
case reflect.Uint32:
|
||||
p.enc = (*Buffer).enc_proto3_uint32
|
||||
p.dec = (*Buffer).dec_proto3_int32 // can reuse
|
||||
p.size = size_proto3_uint32
|
||||
case reflect.Int64, reflect.Uint64:
|
||||
p.enc = (*Buffer).enc_proto3_int64
|
||||
p.dec = (*Buffer).dec_proto3_int64
|
||||
p.size = size_proto3_int64
|
||||
case reflect.Float32:
|
||||
p.enc = (*Buffer).enc_proto3_uint32 // can just treat them as bits
|
||||
p.dec = (*Buffer).dec_proto3_int32
|
||||
p.size = size_proto3_uint32
|
||||
case reflect.Float64:
|
||||
p.enc = (*Buffer).enc_proto3_int64 // can just treat them as bits
|
||||
p.dec = (*Buffer).dec_proto3_int64
|
||||
p.size = size_proto3_int64
|
||||
case reflect.String:
|
||||
p.enc = (*Buffer).enc_proto3_string
|
||||
p.dec = (*Buffer).dec_proto3_string
|
||||
p.size = size_proto3_string
|
||||
|
||||
case reflect.Ptr:
|
||||
switch t2 := t1.Elem(); t2.Kind() {
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "proto: no encoder function for %v -> %v\n", t1, t2)
|
||||
break
|
||||
case reflect.Bool:
|
||||
p.enc = (*Buffer).enc_bool
|
||||
p.dec = (*Buffer).dec_bool
|
||||
p.size = size_bool
|
||||
case reflect.Int32:
|
||||
p.enc = (*Buffer).enc_int32
|
||||
p.dec = (*Buffer).dec_int32
|
||||
p.size = size_int32
|
||||
case reflect.Uint32:
|
||||
p.enc = (*Buffer).enc_uint32
|
||||
p.dec = (*Buffer).dec_int32 // can reuse
|
||||
p.size = size_uint32
|
||||
case reflect.Int64, reflect.Uint64:
|
||||
p.enc = (*Buffer).enc_int64
|
||||
p.dec = (*Buffer).dec_int64
|
||||
p.size = size_int64
|
||||
case reflect.Float32:
|
||||
p.enc = (*Buffer).enc_uint32 // can just treat them as bits
|
||||
p.dec = (*Buffer).dec_int32
|
||||
p.size = size_uint32
|
||||
case reflect.Float64:
|
||||
p.enc = (*Buffer).enc_int64 // can just treat them as bits
|
||||
p.dec = (*Buffer).dec_int64
|
||||
p.size = size_int64
|
||||
case reflect.String:
|
||||
p.enc = (*Buffer).enc_string
|
||||
p.dec = (*Buffer).dec_string
|
||||
p.size = size_string
|
||||
case reflect.Struct:
|
||||
p.stype = t1.Elem()
|
||||
p.isMarshaler = isMarshaler(t1)
|
||||
p.isUnmarshaler = isUnmarshaler(t1)
|
||||
if p.Wire == "bytes" {
|
||||
p.enc = (*Buffer).enc_struct_message
|
||||
p.dec = (*Buffer).dec_struct_message
|
||||
p.size = size_struct_message
|
||||
} else {
|
||||
p.enc = (*Buffer).enc_struct_group
|
||||
p.dec = (*Buffer).dec_struct_group
|
||||
p.size = size_struct_group
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.Slice:
|
||||
switch t2 := t1.Elem(); t2.Kind() {
|
||||
default:
|
||||
logNoSliceEnc(t1, t2)
|
||||
break
|
||||
case reflect.Bool:
|
||||
if p.Packed {
|
||||
p.enc = (*Buffer).enc_slice_packed_bool
|
||||
p.size = size_slice_packed_bool
|
||||
} else {
|
||||
p.enc = (*Buffer).enc_slice_bool
|
||||
p.size = size_slice_bool
|
||||
}
|
||||
p.dec = (*Buffer).dec_slice_bool
|
||||
p.packedDec = (*Buffer).dec_slice_packed_bool
|
||||
case reflect.Int32:
|
||||
if p.Packed {
|
||||
p.enc = (*Buffer).enc_slice_packed_int32
|
||||
p.size = size_slice_packed_int32
|
||||
} else {
|
||||
p.enc = (*Buffer).enc_slice_int32
|
||||
p.size = size_slice_int32
|
||||
}
|
||||
p.dec = (*Buffer).dec_slice_int32
|
||||
p.packedDec = (*Buffer).dec_slice_packed_int32
|
||||
case reflect.Uint32:
|
||||
if p.Packed {
|
||||
p.enc = (*Buffer).enc_slice_packed_uint32
|
||||
p.size = size_slice_packed_uint32
|
||||
} else {
|
||||
p.enc = (*Buffer).enc_slice_uint32
|
||||
p.size = size_slice_uint32
|
||||
}
|
||||
p.dec = (*Buffer).dec_slice_int32
|
||||
p.packedDec = (*Buffer).dec_slice_packed_int32
|
||||
case reflect.Int64, reflect.Uint64:
|
||||
if p.Packed {
|
||||
p.enc = (*Buffer).enc_slice_packed_int64
|
||||
p.size = size_slice_packed_int64
|
||||
} else {
|
||||
p.enc = (*Buffer).enc_slice_int64
|
||||
p.size = size_slice_int64
|
||||
}
|
||||
p.dec = (*Buffer).dec_slice_int64
|
||||
p.packedDec = (*Buffer).dec_slice_packed_int64
|
||||
case reflect.Uint8:
|
||||
p.dec = (*Buffer).dec_slice_byte
|
||||
if p.proto3 {
|
||||
p.enc = (*Buffer).enc_proto3_slice_byte
|
||||
p.size = size_proto3_slice_byte
|
||||
} else {
|
||||
p.enc = (*Buffer).enc_slice_byte
|
||||
p.size = size_slice_byte
|
||||
}
|
||||
case reflect.Float32, reflect.Float64:
|
||||
switch t2.Bits() {
|
||||
case 32:
|
||||
// can just treat them as bits
|
||||
if p.Packed {
|
||||
p.enc = (*Buffer).enc_slice_packed_uint32
|
||||
p.size = size_slice_packed_uint32
|
||||
} else {
|
||||
p.enc = (*Buffer).enc_slice_uint32
|
||||
p.size = size_slice_uint32
|
||||
}
|
||||
p.dec = (*Buffer).dec_slice_int32
|
||||
p.packedDec = (*Buffer).dec_slice_packed_int32
|
||||
case 64:
|
||||
// can just treat them as bits
|
||||
if p.Packed {
|
||||
p.enc = (*Buffer).enc_slice_packed_int64
|
||||
p.size = size_slice_packed_int64
|
||||
} else {
|
||||
p.enc = (*Buffer).enc_slice_int64
|
||||
p.size = size_slice_int64
|
||||
}
|
||||
p.dec = (*Buffer).dec_slice_int64
|
||||
p.packedDec = (*Buffer).dec_slice_packed_int64
|
||||
default:
|
||||
logNoSliceEnc(t1, t2)
|
||||
break
|
||||
}
|
||||
case reflect.String:
|
||||
p.enc = (*Buffer).enc_slice_string
|
||||
p.dec = (*Buffer).dec_slice_string
|
||||
p.size = size_slice_string
|
||||
case reflect.Ptr:
|
||||
switch t3 := t2.Elem(); t3.Kind() {
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T -> %T\n", t1, t2, t3)
|
||||
break
|
||||
case reflect.Struct:
|
||||
p.stype = t2.Elem()
|
||||
p.isMarshaler = isMarshaler(t2)
|
||||
p.isUnmarshaler = isUnmarshaler(t2)
|
||||
if p.Wire == "bytes" {
|
||||
p.enc = (*Buffer).enc_slice_struct_message
|
||||
p.dec = (*Buffer).dec_slice_struct_message
|
||||
p.size = size_slice_struct_message
|
||||
} else {
|
||||
p.enc = (*Buffer).enc_slice_struct_group
|
||||
p.dec = (*Buffer).dec_slice_struct_group
|
||||
p.size = size_slice_struct_group
|
||||
}
|
||||
}
|
||||
case reflect.Slice:
|
||||
switch t2.Elem().Kind() {
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "proto: no slice elem oenc for %T -> %T -> %T\n", t1, t2, t2.Elem())
|
||||
break
|
||||
case reflect.Uint8:
|
||||
p.enc = (*Buffer).enc_slice_slice_byte
|
||||
p.dec = (*Buffer).dec_slice_slice_byte
|
||||
p.size = size_slice_slice_byte
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
p.enc = (*Buffer).enc_new_map
|
||||
p.dec = (*Buffer).dec_new_map
|
||||
p.size = size_new_map
|
||||
|
||||
p.mtype = t1
|
||||
p.mkeyprop = &Properties{}
|
||||
p.mkeyprop.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
|
||||
p.mvalprop = &Properties{}
|
||||
vtype := p.mtype.Elem()
|
||||
if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice {
|
||||
// The value type is not a message (*T) or bytes ([]byte),
|
||||
// so we need encoders for the pointer to this type.
|
||||
vtype = reflect.PtrTo(vtype)
|
||||
}
|
||||
p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
|
||||
}
|
||||
|
||||
// precalculate tag code
|
||||
wire := p.WireType
|
||||
if p.Packed {
|
||||
wire = WireBytes
|
||||
}
|
||||
x := uint32(p.Tag)<<3 | uint32(wire)
|
||||
i := 0
|
||||
for i = 0; x > 127; i++ {
|
||||
p.tagbuf[i] = 0x80 | uint8(x&0x7F)
|
||||
x >>= 7
|
||||
}
|
||||
p.tagbuf[i] = uint8(x)
|
||||
p.tagcode = p.tagbuf[0 : i+1]
|
||||
|
||||
if p.stype != nil {
|
||||
if lockGetProp {
|
||||
p.sprop = GetProperties(p.stype)
|
||||
} else {
|
||||
p.sprop = getPropertiesLocked(p.stype)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
|
||||
unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
|
||||
)
|
||||
|
||||
// isMarshaler reports whether type t implements Marshaler.
|
||||
func isMarshaler(t reflect.Type) bool {
|
||||
// We're checking for (likely) pointer-receiver methods
|
||||
// so if t is not a pointer, something is very wrong.
|
||||
// The calls above only invoke isMarshaler on pointer types.
|
||||
if t.Kind() != reflect.Ptr {
|
||||
panic("proto: misuse of isMarshaler")
|
||||
}
|
||||
return t.Implements(marshalerType)
|
||||
}
|
||||
|
||||
// isUnmarshaler reports whether type t implements Unmarshaler.
|
||||
func isUnmarshaler(t reflect.Type) bool {
|
||||
// We're checking for (likely) pointer-receiver methods
|
||||
// so if t is not a pointer, something is very wrong.
|
||||
// The calls above only invoke isUnmarshaler on pointer types.
|
||||
if t.Kind() != reflect.Ptr {
|
||||
panic("proto: misuse of isUnmarshaler")
|
||||
}
|
||||
return t.Implements(unmarshalerType)
|
||||
}
|
||||
|
||||
// Init populates the properties from a protocol buffer struct tag.
|
||||
func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) {
|
||||
p.init(typ, name, tag, f, true)
|
||||
}
|
||||
|
||||
func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) {
|
||||
// "bytes,49,opt,def=hello!"
|
||||
p.Name = name
|
||||
p.OrigName = name
|
||||
if f != nil {
|
||||
p.field = toField(f)
|
||||
}
|
||||
if tag == "" {
|
||||
return
|
||||
}
|
||||
p.Parse(tag)
|
||||
p.setEncAndDec(typ, f, lockGetProp)
|
||||
}
|
||||
|
||||
var (
|
||||
propertiesMu sync.RWMutex
|
||||
propertiesMap = make(map[reflect.Type]*StructProperties)
|
||||
)
|
||||
|
||||
// GetProperties returns the list of properties for the type represented by t.
|
||||
// t must represent a generated struct type of a protocol message.
|
||||
func GetProperties(t reflect.Type) *StructProperties {
|
||||
if t.Kind() != reflect.Struct {
|
||||
panic("proto: type must have kind struct")
|
||||
}
|
||||
|
||||
// Most calls to GetProperties in a long-running program will be
|
||||
// retrieving details for types we have seen before.
|
||||
propertiesMu.RLock()
|
||||
sprop, ok := propertiesMap[t]
|
||||
propertiesMu.RUnlock()
|
||||
if ok {
|
||||
if collectStats {
|
||||
stats.Chit++
|
||||
}
|
||||
return sprop
|
||||
}
|
||||
|
||||
propertiesMu.Lock()
|
||||
sprop = getPropertiesLocked(t)
|
||||
propertiesMu.Unlock()
|
||||
return sprop
|
||||
}
|
||||
|
||||
// getPropertiesLocked requires that propertiesMu is held.
|
||||
func getPropertiesLocked(t reflect.Type) *StructProperties {
|
||||
if prop, ok := propertiesMap[t]; ok {
|
||||
if collectStats {
|
||||
stats.Chit++
|
||||
}
|
||||
return prop
|
||||
}
|
||||
if collectStats {
|
||||
stats.Cmiss++
|
||||
}
|
||||
|
||||
prop := new(StructProperties)
|
||||
// in case of recursive protos, fill this in now.
|
||||
propertiesMap[t] = prop
|
||||
|
||||
// build properties
|
||||
prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType) ||
|
||||
reflect.PtrTo(t).Implements(extendableProtoV1Type)
|
||||
prop.unrecField = invalidField
|
||||
prop.Prop = make([]*Properties, t.NumField())
|
||||
prop.order = make([]int, t.NumField())
|
||||
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
f := t.Field(i)
|
||||
p := new(Properties)
|
||||
name := f.Name
|
||||
p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false)
|
||||
|
||||
if f.Name == "XXX_InternalExtensions" { // special case
|
||||
p.enc = (*Buffer).enc_exts
|
||||
p.dec = nil // not needed
|
||||
p.size = size_exts
|
||||
} else if f.Name == "XXX_extensions" { // special case
|
||||
p.enc = (*Buffer).enc_map
|
||||
p.dec = nil // not needed
|
||||
p.size = size_map
|
||||
} else if f.Name == "XXX_unrecognized" { // special case
|
||||
prop.unrecField = toField(&f)
|
||||
}
|
||||
oneof := f.Tag.Get("protobuf_oneof") // special case
|
||||
if oneof != "" {
|
||||
// Oneof fields don't use the traditional protobuf tag.
|
||||
p.OrigName = oneof
|
||||
}
|
||||
prop.Prop[i] = p
|
||||
prop.order[i] = i
|
||||
if debug {
|
||||
print(i, " ", f.Name, " ", t.String(), " ")
|
||||
if p.Tag > 0 {
|
||||
print(p.String())
|
||||
}
|
||||
print("\n")
|
||||
}
|
||||
if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && oneof == "" {
|
||||
fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]")
|
||||
}
|
||||
}
|
||||
|
||||
// Re-order prop.order.
|
||||
sort.Sort(prop)
|
||||
|
||||
type oneofMessage interface {
|
||||
XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
|
||||
}
|
||||
if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok {
|
||||
var oots []interface{}
|
||||
prop.oneofMarshaler, prop.oneofUnmarshaler, prop.oneofSizer, oots = om.XXX_OneofFuncs()
|
||||
prop.stype = t
|
||||
|
||||
// Interpret oneof metadata.
|
||||
prop.OneofTypes = make(map[string]*OneofProperties)
|
||||
for _, oot := range oots {
|
||||
oop := &OneofProperties{
|
||||
Type: reflect.ValueOf(oot).Type(), // *T
|
||||
Prop: new(Properties),
|
||||
}
|
||||
sft := oop.Type.Elem().Field(0)
|
||||
oop.Prop.Name = sft.Name
|
||||
oop.Prop.Parse(sft.Tag.Get("protobuf"))
|
||||
// There will be exactly one interface field that
|
||||
// this new value is assignable to.
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
f := t.Field(i)
|
||||
if f.Type.Kind() != reflect.Interface {
|
||||
continue
|
||||
}
|
||||
if !oop.Type.AssignableTo(f.Type) {
|
||||
continue
|
||||
}
|
||||
oop.Field = i
|
||||
break
|
||||
}
|
||||
prop.OneofTypes[oop.Prop.OrigName] = oop
|
||||
}
|
||||
}
|
||||
|
||||
// build required counts
|
||||
// build tags
|
||||
reqCount := 0
|
||||
prop.decoderOrigNames = make(map[string]int)
|
||||
for i, p := range prop.Prop {
|
||||
if strings.HasPrefix(p.Name, "XXX_") {
|
||||
// Internal fields should not appear in tags/origNames maps.
|
||||
// They are handled specially when encoding and decoding.
|
||||
continue
|
||||
}
|
||||
if p.Required {
|
||||
reqCount++
|
||||
}
|
||||
prop.decoderTags.put(p.Tag, i)
|
||||
prop.decoderOrigNames[p.OrigName] = i
|
||||
}
|
||||
prop.reqCount = reqCount
|
||||
|
||||
return prop
|
||||
}
|
||||
|
||||
// Return the Properties object for the x[0]'th field of the structure.
|
||||
func propByIndex(t reflect.Type, x []int) *Properties {
|
||||
if len(x) != 1 {
|
||||
fmt.Fprintf(os.Stderr, "proto: field index dimension %d (not 1) for type %s\n", len(x), t)
|
||||
return nil
|
||||
}
|
||||
prop := GetProperties(t)
|
||||
return prop.Prop[x[0]]
|
||||
}
|
||||
|
||||
// Get the address and type of a pointer to a struct from an interface.
|
||||
func getbase(pb Message) (t reflect.Type, b structPointer, err error) {
|
||||
if pb == nil {
|
||||
err = ErrNil
|
||||
return
|
||||
}
|
||||
// get the reflect type of the pointer to the struct.
|
||||
t = reflect.TypeOf(pb)
|
||||
// get the address of the struct.
|
||||
value := reflect.ValueOf(pb)
|
||||
b = toStructPointer(value)
|
||||
return
|
||||
}
|
||||
|
||||
// A global registry of enum types.
|
||||
// The generated code will register the generated maps by calling RegisterEnum.
|
||||
|
||||
var enumValueMaps = make(map[string]map[string]int32)
|
||||
|
||||
// RegisterEnum is called from the generated code to install the enum descriptor
|
||||
// maps into the global table to aid parsing text format protocol buffers.
|
||||
func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) {
|
||||
if _, ok := enumValueMaps[typeName]; ok {
|
||||
panic("proto: duplicate enum registered: " + typeName)
|
||||
}
|
||||
enumValueMaps[typeName] = valueMap
|
||||
}
|
||||
|
||||
// EnumValueMap returns the mapping from names to integers of the
|
||||
// enum type enumType, or a nil if not found.
|
||||
func EnumValueMap(enumType string) map[string]int32 {
|
||||
return enumValueMaps[enumType]
|
||||
}
|
||||
|
||||
// A registry of all linked message types.
|
||||
// The string is a fully-qualified proto name ("pkg.Message").
|
||||
var (
|
||||
protoTypes = make(map[string]reflect.Type)
|
||||
revProtoTypes = make(map[reflect.Type]string)
|
||||
)
|
||||
|
||||
// RegisterType is called from generated code and maps from the fully qualified
|
||||
// proto name to the type (pointer to struct) of the protocol buffer.
|
||||
func RegisterType(x Message, name string) {
|
||||
if _, ok := protoTypes[name]; ok {
|
||||
// TODO: Some day, make this a panic.
|
||||
log.Printf("proto: duplicate proto type registered: %s", name)
|
||||
return
|
||||
}
|
||||
t := reflect.TypeOf(x)
|
||||
protoTypes[name] = t
|
||||
revProtoTypes[t] = name
|
||||
}
|
||||
|
||||
// MessageName returns the fully-qualified proto name for the given message type.
|
||||
func MessageName(x Message) string {
|
||||
type xname interface {
|
||||
XXX_MessageName() string
|
||||
}
|
||||
if m, ok := x.(xname); ok {
|
||||
return m.XXX_MessageName()
|
||||
}
|
||||
return revProtoTypes[reflect.TypeOf(x)]
|
||||
}
|
||||
|
||||
// MessageType returns the message type (pointer to struct) for a named message.
|
||||
func MessageType(name string) reflect.Type { return protoTypes[name] }
|
||||
|
||||
// A registry of all linked proto files.
|
||||
var (
|
||||
protoFiles = make(map[string][]byte) // file name => fileDescriptor
|
||||
)
|
||||
|
||||
// RegisterFile is called from generated code and maps from the
|
||||
// full file name of a .proto file to its compressed FileDescriptorProto.
|
||||
func RegisterFile(filename string, fileDescriptor []byte) {
|
||||
protoFiles[filename] = fileDescriptor
|
||||
}
|
||||
|
||||
// FileDescriptor returns the compressed FileDescriptorProto for a .proto file.
|
||||
func FileDescriptor(filename string) []byte { return protoFiles[filename] }
|
854
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/text.go
generated
vendored
Normal file
854
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/text.go
generated
vendored
Normal file
|
@ -0,0 +1,854 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
// Functions for writing the text protocol buffer format.
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"math"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
newline = []byte("\n")
|
||||
spaces = []byte(" ")
|
||||
gtNewline = []byte(">\n")
|
||||
endBraceNewline = []byte("}\n")
|
||||
backslashN = []byte{'\\', 'n'}
|
||||
backslashR = []byte{'\\', 'r'}
|
||||
backslashT = []byte{'\\', 't'}
|
||||
backslashDQ = []byte{'\\', '"'}
|
||||
backslashBS = []byte{'\\', '\\'}
|
||||
posInf = []byte("inf")
|
||||
negInf = []byte("-inf")
|
||||
nan = []byte("nan")
|
||||
)
|
||||
|
||||
type writer interface {
|
||||
io.Writer
|
||||
WriteByte(byte) error
|
||||
}
|
||||
|
||||
// textWriter is an io.Writer that tracks its indentation level.
|
||||
type textWriter struct {
|
||||
ind int
|
||||
complete bool // if the current position is a complete line
|
||||
compact bool // whether to write out as a one-liner
|
||||
w writer
|
||||
}
|
||||
|
||||
func (w *textWriter) WriteString(s string) (n int, err error) {
|
||||
if !strings.Contains(s, "\n") {
|
||||
if !w.compact && w.complete {
|
||||
w.writeIndent()
|
||||
}
|
||||
w.complete = false
|
||||
return io.WriteString(w.w, s)
|
||||
}
|
||||
// WriteString is typically called without newlines, so this
|
||||
// codepath and its copy are rare. We copy to avoid
|
||||
// duplicating all of Write's logic here.
|
||||
return w.Write([]byte(s))
|
||||
}
|
||||
|
||||
func (w *textWriter) Write(p []byte) (n int, err error) {
|
||||
newlines := bytes.Count(p, newline)
|
||||
if newlines == 0 {
|
||||
if !w.compact && w.complete {
|
||||
w.writeIndent()
|
||||
}
|
||||
n, err = w.w.Write(p)
|
||||
w.complete = false
|
||||
return n, err
|
||||
}
|
||||
|
||||
frags := bytes.SplitN(p, newline, newlines+1)
|
||||
if w.compact {
|
||||
for i, frag := range frags {
|
||||
if i > 0 {
|
||||
if err := w.w.WriteByte(' '); err != nil {
|
||||
return n, err
|
||||
}
|
||||
n++
|
||||
}
|
||||
nn, err := w.w.Write(frag)
|
||||
n += nn
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
for i, frag := range frags {
|
||||
if w.complete {
|
||||
w.writeIndent()
|
||||
}
|
||||
nn, err := w.w.Write(frag)
|
||||
n += nn
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
if i+1 < len(frags) {
|
||||
if err := w.w.WriteByte('\n'); err != nil {
|
||||
return n, err
|
||||
}
|
||||
n++
|
||||
}
|
||||
}
|
||||
w.complete = len(frags[len(frags)-1]) == 0
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func (w *textWriter) WriteByte(c byte) error {
|
||||
if w.compact && c == '\n' {
|
||||
c = ' '
|
||||
}
|
||||
if !w.compact && w.complete {
|
||||
w.writeIndent()
|
||||
}
|
||||
err := w.w.WriteByte(c)
|
||||
w.complete = c == '\n'
|
||||
return err
|
||||
}
|
||||
|
||||
func (w *textWriter) indent() { w.ind++ }
|
||||
|
||||
func (w *textWriter) unindent() {
|
||||
if w.ind == 0 {
|
||||
log.Print("proto: textWriter unindented too far")
|
||||
return
|
||||
}
|
||||
w.ind--
|
||||
}
|
||||
|
||||
func writeName(w *textWriter, props *Properties) error {
|
||||
if _, err := w.WriteString(props.OrigName); err != nil {
|
||||
return err
|
||||
}
|
||||
if props.Wire != "group" {
|
||||
return w.WriteByte(':')
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// raw is the interface satisfied by RawMessage.
|
||||
type raw interface {
|
||||
Bytes() []byte
|
||||
}
|
||||
|
||||
func requiresQuotes(u string) bool {
|
||||
// When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted.
|
||||
for _, ch := range u {
|
||||
switch {
|
||||
case ch == '.' || ch == '/' || ch == '_':
|
||||
continue
|
||||
case '0' <= ch && ch <= '9':
|
||||
continue
|
||||
case 'A' <= ch && ch <= 'Z':
|
||||
continue
|
||||
case 'a' <= ch && ch <= 'z':
|
||||
continue
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// isAny reports whether sv is a google.protobuf.Any message
|
||||
func isAny(sv reflect.Value) bool {
|
||||
type wkt interface {
|
||||
XXX_WellKnownType() string
|
||||
}
|
||||
t, ok := sv.Addr().Interface().(wkt)
|
||||
return ok && t.XXX_WellKnownType() == "Any"
|
||||
}
|
||||
|
||||
// writeProto3Any writes an expanded google.protobuf.Any message.
|
||||
//
|
||||
// It returns (false, nil) if sv value can't be unmarshaled (e.g. because
|
||||
// required messages are not linked in).
|
||||
//
|
||||
// It returns (true, error) when sv was written in expanded format or an error
|
||||
// was encountered.
|
||||
func (tm *TextMarshaler) writeProto3Any(w *textWriter, sv reflect.Value) (bool, error) {
|
||||
turl := sv.FieldByName("TypeUrl")
|
||||
val := sv.FieldByName("Value")
|
||||
if !turl.IsValid() || !val.IsValid() {
|
||||
return true, errors.New("proto: invalid google.protobuf.Any message")
|
||||
}
|
||||
|
||||
b, ok := val.Interface().([]byte)
|
||||
if !ok {
|
||||
return true, errors.New("proto: invalid google.protobuf.Any message")
|
||||
}
|
||||
|
||||
parts := strings.Split(turl.String(), "/")
|
||||
mt := MessageType(parts[len(parts)-1])
|
||||
if mt == nil {
|
||||
return false, nil
|
||||
}
|
||||
m := reflect.New(mt.Elem())
|
||||
if err := Unmarshal(b, m.Interface().(Message)); err != nil {
|
||||
return false, nil
|
||||
}
|
||||
w.Write([]byte("["))
|
||||
u := turl.String()
|
||||
if requiresQuotes(u) {
|
||||
writeString(w, u)
|
||||
} else {
|
||||
w.Write([]byte(u))
|
||||
}
|
||||
if w.compact {
|
||||
w.Write([]byte("]:<"))
|
||||
} else {
|
||||
w.Write([]byte("]: <\n"))
|
||||
w.ind++
|
||||
}
|
||||
if err := tm.writeStruct(w, m.Elem()); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if w.compact {
|
||||
w.Write([]byte("> "))
|
||||
} else {
|
||||
w.ind--
|
||||
w.Write([]byte(">\n"))
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
|
||||
if tm.ExpandAny && isAny(sv) {
|
||||
if canExpand, err := tm.writeProto3Any(w, sv); canExpand {
|
||||
return err
|
||||
}
|
||||
}
|
||||
st := sv.Type()
|
||||
sprops := GetProperties(st)
|
||||
for i := 0; i < sv.NumField(); i++ {
|
||||
fv := sv.Field(i)
|
||||
props := sprops.Prop[i]
|
||||
name := st.Field(i).Name
|
||||
|
||||
if strings.HasPrefix(name, "XXX_") {
|
||||
// There are two XXX_ fields:
|
||||
// XXX_unrecognized []byte
|
||||
// XXX_extensions map[int32]proto.Extension
|
||||
// The first is handled here;
|
||||
// the second is handled at the bottom of this function.
|
||||
if name == "XXX_unrecognized" && !fv.IsNil() {
|
||||
if err := writeUnknownStruct(w, fv.Interface().([]byte)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if fv.Kind() == reflect.Ptr && fv.IsNil() {
|
||||
// Field not filled in. This could be an optional field or
|
||||
// a required field that wasn't filled in. Either way, there
|
||||
// isn't anything we can show for it.
|
||||
continue
|
||||
}
|
||||
if fv.Kind() == reflect.Slice && fv.IsNil() {
|
||||
// Repeated field that is empty, or a bytes field that is unused.
|
||||
continue
|
||||
}
|
||||
|
||||
if props.Repeated && fv.Kind() == reflect.Slice {
|
||||
// Repeated field.
|
||||
for j := 0; j < fv.Len(); j++ {
|
||||
if err := writeName(w, props); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
v := fv.Index(j)
|
||||
if v.Kind() == reflect.Ptr && v.IsNil() {
|
||||
// A nil message in a repeated field is not valid,
|
||||
// but we can handle that more gracefully than panicking.
|
||||
if _, err := w.Write([]byte("<nil>\n")); err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err := tm.writeAny(w, v, props); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if fv.Kind() == reflect.Map {
|
||||
// Map fields are rendered as a repeated struct with key/value fields.
|
||||
keys := fv.MapKeys()
|
||||
sort.Sort(mapKeys(keys))
|
||||
for _, key := range keys {
|
||||
val := fv.MapIndex(key)
|
||||
if err := writeName(w, props); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// open struct
|
||||
if err := w.WriteByte('<'); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
w.indent()
|
||||
// key
|
||||
if _, err := w.WriteString("key:"); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := tm.writeAny(w, key, props.mkeyprop); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
// nil values aren't legal, but we can avoid panicking because of them.
|
||||
if val.Kind() != reflect.Ptr || !val.IsNil() {
|
||||
// value
|
||||
if _, err := w.WriteString("value:"); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := tm.writeAny(w, val, props.mvalprop); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// close struct
|
||||
w.unindent()
|
||||
if err := w.WriteByte('>'); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if props.proto3 && fv.Kind() == reflect.Slice && fv.Len() == 0 {
|
||||
// empty bytes field
|
||||
continue
|
||||
}
|
||||
if fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice {
|
||||
// proto3 non-repeated scalar field; skip if zero value
|
||||
if isProto3Zero(fv) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if fv.Kind() == reflect.Interface {
|
||||
// Check if it is a oneof.
|
||||
if st.Field(i).Tag.Get("protobuf_oneof") != "" {
|
||||
// fv is nil, or holds a pointer to generated struct.
|
||||
// That generated struct has exactly one field,
|
||||
// which has a protobuf struct tag.
|
||||
if fv.IsNil() {
|
||||
continue
|
||||
}
|
||||
inner := fv.Elem().Elem() // interface -> *T -> T
|
||||
tag := inner.Type().Field(0).Tag.Get("protobuf")
|
||||
props = new(Properties) // Overwrite the outer props var, but not its pointee.
|
||||
props.Parse(tag)
|
||||
// Write the value in the oneof, not the oneof itself.
|
||||
fv = inner.Field(0)
|
||||
|
||||
// Special case to cope with malformed messages gracefully:
|
||||
// If the value in the oneof is a nil pointer, don't panic
|
||||
// in writeAny.
|
||||
if fv.Kind() == reflect.Ptr && fv.IsNil() {
|
||||
// Use errors.New so writeAny won't render quotes.
|
||||
msg := errors.New("/* nil */")
|
||||
fv = reflect.ValueOf(&msg).Elem()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := writeName(w, props); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if b, ok := fv.Interface().(raw); ok {
|
||||
if err := writeRaw(w, b.Bytes()); err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Enums have a String method, so writeAny will work fine.
|
||||
if err := tm.writeAny(w, fv, props); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Extensions (the XXX_extensions field).
|
||||
pv := sv.Addr()
|
||||
if _, ok := extendable(pv.Interface()); ok {
|
||||
if err := tm.writeExtensions(w, pv); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// writeRaw writes an uninterpreted raw message.
|
||||
func writeRaw(w *textWriter, b []byte) error {
|
||||
if err := w.WriteByte('<'); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
w.indent()
|
||||
if err := writeUnknownStruct(w, b); err != nil {
|
||||
return err
|
||||
}
|
||||
w.unindent()
|
||||
if err := w.WriteByte('>'); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// writeAny writes an arbitrary field.
|
||||
func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Properties) error {
|
||||
v = reflect.Indirect(v)
|
||||
|
||||
// Floats have special cases.
|
||||
if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 {
|
||||
x := v.Float()
|
||||
var b []byte
|
||||
switch {
|
||||
case math.IsInf(x, 1):
|
||||
b = posInf
|
||||
case math.IsInf(x, -1):
|
||||
b = negInf
|
||||
case math.IsNaN(x):
|
||||
b = nan
|
||||
}
|
||||
if b != nil {
|
||||
_, err := w.Write(b)
|
||||
return err
|
||||
}
|
||||
// Other values are handled below.
|
||||
}
|
||||
|
||||
// We don't attempt to serialise every possible value type; only those
|
||||
// that can occur in protocol buffers.
|
||||
switch v.Kind() {
|
||||
case reflect.Slice:
|
||||
// Should only be a []byte; repeated fields are handled in writeStruct.
|
||||
if err := writeString(w, string(v.Bytes())); err != nil {
|
||||
return err
|
||||
}
|
||||
case reflect.String:
|
||||
if err := writeString(w, v.String()); err != nil {
|
||||
return err
|
||||
}
|
||||
case reflect.Struct:
|
||||
// Required/optional group/message.
|
||||
var bra, ket byte = '<', '>'
|
||||
if props != nil && props.Wire == "group" {
|
||||
bra, ket = '{', '}'
|
||||
}
|
||||
if err := w.WriteByte(bra); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
w.indent()
|
||||
if etm, ok := v.Interface().(encoding.TextMarshaler); ok {
|
||||
text, err := etm.MarshalText()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = w.Write(text); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err := tm.writeStruct(w, v); err != nil {
|
||||
return err
|
||||
}
|
||||
w.unindent()
|
||||
if err := w.WriteByte(ket); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
_, err := fmt.Fprint(w, v.Interface())
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// equivalent to C's isprint.
|
||||
func isprint(c byte) bool {
|
||||
return c >= 0x20 && c < 0x7f
|
||||
}
|
||||
|
||||
// writeString writes a string in the protocol buffer text format.
|
||||
// It is similar to strconv.Quote except we don't use Go escape sequences,
|
||||
// we treat the string as a byte sequence, and we use octal escapes.
|
||||
// These differences are to maintain interoperability with the other
|
||||
// languages' implementations of the text format.
|
||||
func writeString(w *textWriter, s string) error {
|
||||
// use WriteByte here to get any needed indent
|
||||
if err := w.WriteByte('"'); err != nil {
|
||||
return err
|
||||
}
|
||||
// Loop over the bytes, not the runes.
|
||||
for i := 0; i < len(s); i++ {
|
||||
var err error
|
||||
// Divergence from C++: we don't escape apostrophes.
|
||||
// There's no need to escape them, and the C++ parser
|
||||
// copes with a naked apostrophe.
|
||||
switch c := s[i]; c {
|
||||
case '\n':
|
||||
_, err = w.w.Write(backslashN)
|
||||
case '\r':
|
||||
_, err = w.w.Write(backslashR)
|
||||
case '\t':
|
||||
_, err = w.w.Write(backslashT)
|
||||
case '"':
|
||||
_, err = w.w.Write(backslashDQ)
|
||||
case '\\':
|
||||
_, err = w.w.Write(backslashBS)
|
||||
default:
|
||||
if isprint(c) {
|
||||
err = w.w.WriteByte(c)
|
||||
} else {
|
||||
_, err = fmt.Fprintf(w.w, "\\%03o", c)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return w.WriteByte('"')
|
||||
}
|
||||
|
||||
func writeUnknownStruct(w *textWriter, data []byte) (err error) {
|
||||
if !w.compact {
|
||||
if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
b := NewBuffer(data)
|
||||
for b.index < len(b.buf) {
|
||||
x, err := b.DecodeVarint()
|
||||
if err != nil {
|
||||
_, err := fmt.Fprintf(w, "/* %v */\n", err)
|
||||
return err
|
||||
}
|
||||
wire, tag := x&7, x>>3
|
||||
if wire == WireEndGroup {
|
||||
w.unindent()
|
||||
if _, err := w.Write(endBraceNewline); err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
if _, err := fmt.Fprint(w, tag); err != nil {
|
||||
return err
|
||||
}
|
||||
if wire != WireStartGroup {
|
||||
if err := w.WriteByte(':'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if !w.compact || wire == WireStartGroup {
|
||||
if err := w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
switch wire {
|
||||
case WireBytes:
|
||||
buf, e := b.DecodeRawBytes(false)
|
||||
if e == nil {
|
||||
_, err = fmt.Fprintf(w, "%q", buf)
|
||||
} else {
|
||||
_, err = fmt.Fprintf(w, "/* %v */", e)
|
||||
}
|
||||
case WireFixed32:
|
||||
x, err = b.DecodeFixed32()
|
||||
err = writeUnknownInt(w, x, err)
|
||||
case WireFixed64:
|
||||
x, err = b.DecodeFixed64()
|
||||
err = writeUnknownInt(w, x, err)
|
||||
case WireStartGroup:
|
||||
err = w.WriteByte('{')
|
||||
w.indent()
|
||||
case WireVarint:
|
||||
x, err = b.DecodeVarint()
|
||||
err = writeUnknownInt(w, x, err)
|
||||
default:
|
||||
_, err = fmt.Fprintf(w, "/* unknown wire type %d */", wire)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeUnknownInt(w *textWriter, x uint64, err error) error {
|
||||
if err == nil {
|
||||
_, err = fmt.Fprint(w, x)
|
||||
} else {
|
||||
_, err = fmt.Fprintf(w, "/* %v */", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
type int32Slice []int32
|
||||
|
||||
func (s int32Slice) Len() int { return len(s) }
|
||||
func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] }
|
||||
func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
// writeExtensions writes all the extensions in pv.
|
||||
// pv is assumed to be a pointer to a protocol message struct that is extendable.
|
||||
func (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error {
|
||||
emap := extensionMaps[pv.Type().Elem()]
|
||||
ep, _ := extendable(pv.Interface())
|
||||
|
||||
// Order the extensions by ID.
|
||||
// This isn't strictly necessary, but it will give us
|
||||
// canonical output, which will also make testing easier.
|
||||
m, mu := ep.extensionsRead()
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
mu.Lock()
|
||||
ids := make([]int32, 0, len(m))
|
||||
for id := range m {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
sort.Sort(int32Slice(ids))
|
||||
mu.Unlock()
|
||||
|
||||
for _, extNum := range ids {
|
||||
ext := m[extNum]
|
||||
var desc *ExtensionDesc
|
||||
if emap != nil {
|
||||
desc = emap[extNum]
|
||||
}
|
||||
if desc == nil {
|
||||
// Unknown extension.
|
||||
if err := writeUnknownStruct(w, ext.enc); err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
pb, err := GetExtension(ep, desc)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed getting extension: %v", err)
|
||||
}
|
||||
|
||||
// Repeated extensions will appear as a slice.
|
||||
if !desc.repeated() {
|
||||
if err := tm.writeExtension(w, desc.Name, pb); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
v := reflect.ValueOf(pb)
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
if err := tm.writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tm *TextMarshaler) writeExtension(w *textWriter, name string, pb interface{}) error {
|
||||
if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil {
|
||||
return err
|
||||
}
|
||||
if !w.compact {
|
||||
if err := w.WriteByte(' '); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := tm.writeAny(w, reflect.ValueOf(pb), nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.WriteByte('\n'); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *textWriter) writeIndent() {
|
||||
if !w.complete {
|
||||
return
|
||||
}
|
||||
remain := w.ind * 2
|
||||
for remain > 0 {
|
||||
n := remain
|
||||
if n > len(spaces) {
|
||||
n = len(spaces)
|
||||
}
|
||||
w.w.Write(spaces[:n])
|
||||
remain -= n
|
||||
}
|
||||
w.complete = false
|
||||
}
|
||||
|
||||
// TextMarshaler is a configurable text format marshaler.
|
||||
type TextMarshaler struct {
|
||||
Compact bool // use compact text format (one line).
|
||||
ExpandAny bool // expand google.protobuf.Any messages of known types
|
||||
}
|
||||
|
||||
// Marshal writes a given protocol buffer in text format.
|
||||
// The only errors returned are from w.
|
||||
func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error {
|
||||
val := reflect.ValueOf(pb)
|
||||
if pb == nil || val.IsNil() {
|
||||
w.Write([]byte("<nil>"))
|
||||
return nil
|
||||
}
|
||||
var bw *bufio.Writer
|
||||
ww, ok := w.(writer)
|
||||
if !ok {
|
||||
bw = bufio.NewWriter(w)
|
||||
ww = bw
|
||||
}
|
||||
aw := &textWriter{
|
||||
w: ww,
|
||||
complete: true,
|
||||
compact: tm.Compact,
|
||||
}
|
||||
|
||||
if etm, ok := pb.(encoding.TextMarshaler); ok {
|
||||
text, err := etm.MarshalText()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = aw.Write(text); err != nil {
|
||||
return err
|
||||
}
|
||||
if bw != nil {
|
||||
return bw.Flush()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// Dereference the received pointer so we don't have outer < and >.
|
||||
v := reflect.Indirect(val)
|
||||
if err := tm.writeStruct(aw, v); err != nil {
|
||||
return err
|
||||
}
|
||||
if bw != nil {
|
||||
return bw.Flush()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Text is the same as Marshal, but returns the string directly.
|
||||
func (tm *TextMarshaler) Text(pb Message) string {
|
||||
var buf bytes.Buffer
|
||||
tm.Marshal(&buf, pb)
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
var (
|
||||
defaultTextMarshaler = TextMarshaler{}
|
||||
compactTextMarshaler = TextMarshaler{Compact: true}
|
||||
)
|
||||
|
||||
// TODO: consider removing some of the Marshal functions below.
|
||||
|
||||
// MarshalText writes a given protocol buffer in text format.
|
||||
// The only errors returned are from w.
|
||||
func MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) }
|
||||
|
||||
// MarshalTextString is the same as MarshalText, but returns the string directly.
|
||||
func MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) }
|
||||
|
||||
// CompactText writes a given protocol buffer in compact text format (one line).
|
||||
func CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) }
|
||||
|
||||
// CompactTextString is the same as CompactText, but returns the string directly.
|
||||
func CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) }
|
895
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/text_parser.go
generated
vendored
Normal file
895
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/golang/protobuf/proto/text_parser.go
generated
vendored
Normal file
|
@ -0,0 +1,895 @@
|
|||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package proto
|
||||
|
||||
// Functions for parsing the Text protocol buffer format.
|
||||
// TODO: message sets.
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// Error string emitted when deserializing Any and fields are already set
|
||||
const anyRepeatedlyUnpacked = "Any message unpacked multiple times, or %q already set"
|
||||
|
||||
type ParseError struct {
|
||||
Message string
|
||||
Line int // 1-based line number
|
||||
Offset int // 0-based byte offset from start of input
|
||||
}
|
||||
|
||||
func (p *ParseError) Error() string {
|
||||
if p.Line == 1 {
|
||||
// show offset only for first line
|
||||
return fmt.Sprintf("line 1.%d: %v", p.Offset, p.Message)
|
||||
}
|
||||
return fmt.Sprintf("line %d: %v", p.Line, p.Message)
|
||||
}
|
||||
|
||||
type token struct {
|
||||
value string
|
||||
err *ParseError
|
||||
line int // line number
|
||||
offset int // byte number from start of input, not start of line
|
||||
unquoted string // the unquoted version of value, if it was a quoted string
|
||||
}
|
||||
|
||||
func (t *token) String() string {
|
||||
if t.err == nil {
|
||||
return fmt.Sprintf("%q (line=%d, offset=%d)", t.value, t.line, t.offset)
|
||||
}
|
||||
return fmt.Sprintf("parse error: %v", t.err)
|
||||
}
|
||||
|
||||
type textParser struct {
|
||||
s string // remaining input
|
||||
done bool // whether the parsing is finished (success or error)
|
||||
backed bool // whether back() was called
|
||||
offset, line int
|
||||
cur token
|
||||
}
|
||||
|
||||
func newTextParser(s string) *textParser {
|
||||
p := new(textParser)
|
||||
p.s = s
|
||||
p.line = 1
|
||||
p.cur.line = 1
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *textParser) errorf(format string, a ...interface{}) *ParseError {
|
||||
pe := &ParseError{fmt.Sprintf(format, a...), p.cur.line, p.cur.offset}
|
||||
p.cur.err = pe
|
||||
p.done = true
|
||||
return pe
|
||||
}
|
||||
|
||||
// Numbers and identifiers are matched by [-+._A-Za-z0-9]
|
||||
func isIdentOrNumberChar(c byte) bool {
|
||||
switch {
|
||||
case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z':
|
||||
return true
|
||||
case '0' <= c && c <= '9':
|
||||
return true
|
||||
}
|
||||
switch c {
|
||||
case '-', '+', '.', '_':
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isWhitespace(c byte) bool {
|
||||
switch c {
|
||||
case ' ', '\t', '\n', '\r':
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isQuote(c byte) bool {
|
||||
switch c {
|
||||
case '"', '\'':
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *textParser) skipWhitespace() {
|
||||
i := 0
|
||||
for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') {
|
||||
if p.s[i] == '#' {
|
||||
// comment; skip to end of line or input
|
||||
for i < len(p.s) && p.s[i] != '\n' {
|
||||
i++
|
||||
}
|
||||
if i == len(p.s) {
|
||||
break
|
||||
}
|
||||
}
|
||||
if p.s[i] == '\n' {
|
||||
p.line++
|
||||
}
|
||||
i++
|
||||
}
|
||||
p.offset += i
|
||||
p.s = p.s[i:len(p.s)]
|
||||
if len(p.s) == 0 {
|
||||
p.done = true
|
||||
}
|
||||
}
|
||||
|
||||
func (p *textParser) advance() {
|
||||
// Skip whitespace
|
||||
p.skipWhitespace()
|
||||
if p.done {
|
||||
return
|
||||
}
|
||||
|
||||
// Start of non-whitespace
|
||||
p.cur.err = nil
|
||||
p.cur.offset, p.cur.line = p.offset, p.line
|
||||
p.cur.unquoted = ""
|
||||
switch p.s[0] {
|
||||
case '<', '>', '{', '}', ':', '[', ']', ';', ',', '/':
|
||||
// Single symbol
|
||||
p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)]
|
||||
case '"', '\'':
|
||||
// Quoted string
|
||||
i := 1
|
||||
for i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\n' {
|
||||
if p.s[i] == '\\' && i+1 < len(p.s) {
|
||||
// skip escaped char
|
||||
i++
|
||||
}
|
||||
i++
|
||||
}
|
||||
if i >= len(p.s) || p.s[i] != p.s[0] {
|
||||
p.errorf("unmatched quote")
|
||||
return
|
||||
}
|
||||
unq, err := unquoteC(p.s[1:i], rune(p.s[0]))
|
||||
if err != nil {
|
||||
p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err)
|
||||
return
|
||||
}
|
||||
p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)]
|
||||
p.cur.unquoted = unq
|
||||
default:
|
||||
i := 0
|
||||
for i < len(p.s) && isIdentOrNumberChar(p.s[i]) {
|
||||
i++
|
||||
}
|
||||
if i == 0 {
|
||||
p.errorf("unexpected byte %#x", p.s[0])
|
||||
return
|
||||
}
|
||||
p.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)]
|
||||
}
|
||||
p.offset += len(p.cur.value)
|
||||
}
|
||||
|
||||
var (
|
||||
errBadUTF8 = errors.New("proto: bad UTF-8")
|
||||
errBadHex = errors.New("proto: bad hexadecimal")
|
||||
)
|
||||
|
||||
func unquoteC(s string, quote rune) (string, error) {
|
||||
// This is based on C++'s tokenizer.cc.
|
||||
// Despite its name, this is *not* parsing C syntax.
|
||||
// For instance, "\0" is an invalid quoted string.
|
||||
|
||||
// Avoid allocation in trivial cases.
|
||||
simple := true
|
||||
for _, r := range s {
|
||||
if r == '\\' || r == quote {
|
||||
simple = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if simple {
|
||||
return s, nil
|
||||
}
|
||||
|
||||
buf := make([]byte, 0, 3*len(s)/2)
|
||||
for len(s) > 0 {
|
||||
r, n := utf8.DecodeRuneInString(s)
|
||||
if r == utf8.RuneError && n == 1 {
|
||||
return "", errBadUTF8
|
||||
}
|
||||
s = s[n:]
|
||||
if r != '\\' {
|
||||
if r < utf8.RuneSelf {
|
||||
buf = append(buf, byte(r))
|
||||
} else {
|
||||
buf = append(buf, string(r)...)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
ch, tail, err := unescape(s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
buf = append(buf, ch...)
|
||||
s = tail
|
||||
}
|
||||
return string(buf), nil
|
||||
}
|
||||
|
||||
func unescape(s string) (ch string, tail string, err error) {
|
||||
r, n := utf8.DecodeRuneInString(s)
|
||||
if r == utf8.RuneError && n == 1 {
|
||||
return "", "", errBadUTF8
|
||||
}
|
||||
s = s[n:]
|
||||
switch r {
|
||||
case 'a':
|
||||
return "\a", s, nil
|
||||
case 'b':
|
||||
return "\b", s, nil
|
||||
case 'f':
|
||||
return "\f", s, nil
|
||||
case 'n':
|
||||
return "\n", s, nil
|
||||
case 'r':
|
||||
return "\r", s, nil
|
||||
case 't':
|
||||
return "\t", s, nil
|
||||
case 'v':
|
||||
return "\v", s, nil
|
||||
case '?':
|
||||
return "?", s, nil // trigraph workaround
|
||||
case '\'', '"', '\\':
|
||||
return string(r), s, nil
|
||||
case '0', '1', '2', '3', '4', '5', '6', '7', 'x', 'X':
|
||||
if len(s) < 2 {
|
||||
return "", "", fmt.Errorf(`\%c requires 2 following digits`, r)
|
||||
}
|
||||
base := 8
|
||||
ss := s[:2]
|
||||
s = s[2:]
|
||||
if r == 'x' || r == 'X' {
|
||||
base = 16
|
||||
} else {
|
||||
ss = string(r) + ss
|
||||
}
|
||||
i, err := strconv.ParseUint(ss, base, 8)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
return string([]byte{byte(i)}), s, nil
|
||||
case 'u', 'U':
|
||||
n := 4
|
||||
if r == 'U' {
|
||||
n = 8
|
||||
}
|
||||
if len(s) < n {
|
||||
return "", "", fmt.Errorf(`\%c requires %d digits`, r, n)
|
||||
}
|
||||
|
||||
bs := make([]byte, n/2)
|
||||
for i := 0; i < n; i += 2 {
|
||||
a, ok1 := unhex(s[i])
|
||||
b, ok2 := unhex(s[i+1])
|
||||
if !ok1 || !ok2 {
|
||||
return "", "", errBadHex
|
||||
}
|
||||
bs[i/2] = a<<4 | b
|
||||
}
|
||||
s = s[n:]
|
||||
return string(bs), s, nil
|
||||
}
|
||||
return "", "", fmt.Errorf(`unknown escape \%c`, r)
|
||||
}
|
||||
|
||||
// Adapted from src/pkg/strconv/quote.go.
|
||||
func unhex(b byte) (v byte, ok bool) {
|
||||
switch {
|
||||
case '0' <= b && b <= '9':
|
||||
return b - '0', true
|
||||
case 'a' <= b && b <= 'f':
|
||||
return b - 'a' + 10, true
|
||||
case 'A' <= b && b <= 'F':
|
||||
return b - 'A' + 10, true
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// Back off the parser by one token. Can only be done between calls to next().
|
||||
// It makes the next advance() a no-op.
|
||||
func (p *textParser) back() { p.backed = true }
|
||||
|
||||
// Advances the parser and returns the new current token.
|
||||
func (p *textParser) next() *token {
|
||||
if p.backed || p.done {
|
||||
p.backed = false
|
||||
return &p.cur
|
||||
}
|
||||
p.advance()
|
||||
if p.done {
|
||||
p.cur.value = ""
|
||||
} else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) {
|
||||
// Look for multiple quoted strings separated by whitespace,
|
||||
// and concatenate them.
|
||||
cat := p.cur
|
||||
for {
|
||||
p.skipWhitespace()
|
||||
if p.done || !isQuote(p.s[0]) {
|
||||
break
|
||||
}
|
||||
p.advance()
|
||||
if p.cur.err != nil {
|
||||
return &p.cur
|
||||
}
|
||||
cat.value += " " + p.cur.value
|
||||
cat.unquoted += p.cur.unquoted
|
||||
}
|
||||
p.done = false // parser may have seen EOF, but we want to return cat
|
||||
p.cur = cat
|
||||
}
|
||||
return &p.cur
|
||||
}
|
||||
|
||||
func (p *textParser) consumeToken(s string) error {
|
||||
tok := p.next()
|
||||
if tok.err != nil {
|
||||
return tok.err
|
||||
}
|
||||
if tok.value != s {
|
||||
p.back()
|
||||
return p.errorf("expected %q, found %q", s, tok.value)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Return a RequiredNotSetError indicating which required field was not set.
|
||||
func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSetError {
|
||||
st := sv.Type()
|
||||
sprops := GetProperties(st)
|
||||
for i := 0; i < st.NumField(); i++ {
|
||||
if !isNil(sv.Field(i)) {
|
||||
continue
|
||||
}
|
||||
|
||||
props := sprops.Prop[i]
|
||||
if props.Required {
|
||||
return &RequiredNotSetError{fmt.Sprintf("%v.%v", st, props.OrigName)}
|
||||
}
|
||||
}
|
||||
return &RequiredNotSetError{fmt.Sprintf("%v.<unknown field name>", st)} // should not happen
|
||||
}
|
||||
|
||||
// Returns the index in the struct for the named field, as well as the parsed tag properties.
|
||||
func structFieldByName(sprops *StructProperties, name string) (int, *Properties, bool) {
|
||||
i, ok := sprops.decoderOrigNames[name]
|
||||
if ok {
|
||||
return i, sprops.Prop[i], true
|
||||
}
|
||||
return -1, nil, false
|
||||
}
|
||||
|
||||
// Consume a ':' from the input stream (if the next token is a colon),
|
||||
// returning an error if a colon is needed but not present.
|
||||
func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseError {
|
||||
tok := p.next()
|
||||
if tok.err != nil {
|
||||
return tok.err
|
||||
}
|
||||
if tok.value != ":" {
|
||||
// Colon is optional when the field is a group or message.
|
||||
needColon := true
|
||||
switch props.Wire {
|
||||
case "group":
|
||||
needColon = false
|
||||
case "bytes":
|
||||
// A "bytes" field is either a message, a string, or a repeated field;
|
||||
// those three become *T, *string and []T respectively, so we can check for
|
||||
// this field being a pointer to a non-string.
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
// *T or *string
|
||||
if typ.Elem().Kind() == reflect.String {
|
||||
break
|
||||
}
|
||||
} else if typ.Kind() == reflect.Slice {
|
||||
// []T or []*T
|
||||
if typ.Elem().Kind() != reflect.Ptr {
|
||||
break
|
||||
}
|
||||
} else if typ.Kind() == reflect.String {
|
||||
// The proto3 exception is for a string field,
|
||||
// which requires a colon.
|
||||
break
|
||||
}
|
||||
needColon = false
|
||||
}
|
||||
if needColon {
|
||||
return p.errorf("expected ':', found %q", tok.value)
|
||||
}
|
||||
p.back()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
|
||||
st := sv.Type()
|
||||
sprops := GetProperties(st)
|
||||
reqCount := sprops.reqCount
|
||||
var reqFieldErr error
|
||||
fieldSet := make(map[string]bool)
|
||||
// A struct is a sequence of "name: value", terminated by one of
|
||||
// '>' or '}', or the end of the input. A name may also be
|
||||
// "[extension]" or "[type/url]".
|
||||
//
|
||||
// The whole struct can also be an expanded Any message, like:
|
||||
// [type/url] < ... struct contents ... >
|
||||
for {
|
||||
tok := p.next()
|
||||
if tok.err != nil {
|
||||
return tok.err
|
||||
}
|
||||
if tok.value == terminator {
|
||||
break
|
||||
}
|
||||
if tok.value == "[" {
|
||||
// Looks like an extension or an Any.
|
||||
//
|
||||
// TODO: Check whether we need to handle
|
||||
// namespace rooted names (e.g. ".something.Foo").
|
||||
extName, err := p.consumeExtName()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if s := strings.LastIndex(extName, "/"); s >= 0 {
|
||||
// If it contains a slash, it's an Any type URL.
|
||||
messageName := extName[s+1:]
|
||||
mt := MessageType(messageName)
|
||||
if mt == nil {
|
||||
return p.errorf("unrecognized message %q in google.protobuf.Any", messageName)
|
||||
}
|
||||
tok = p.next()
|
||||
if tok.err != nil {
|
||||
return tok.err
|
||||
}
|
||||
// consume an optional colon
|
||||
if tok.value == ":" {
|
||||
tok = p.next()
|
||||
if tok.err != nil {
|
||||
return tok.err
|
||||
}
|
||||
}
|
||||
var terminator string
|
||||
switch tok.value {
|
||||
case "<":
|
||||
terminator = ">"
|
||||
case "{":
|
||||
terminator = "}"
|
||||
default:
|
||||
return p.errorf("expected '{' or '<', found %q", tok.value)
|
||||
}
|
||||
v := reflect.New(mt.Elem())
|
||||
if pe := p.readStruct(v.Elem(), terminator); pe != nil {
|
||||
return pe
|
||||
}
|
||||
b, err := Marshal(v.Interface().(Message))
|
||||
if err != nil {
|
||||
return p.errorf("failed to marshal message of type %q: %v", messageName, err)
|
||||
}
|
||||
if fieldSet["type_url"] {
|
||||
return p.errorf(anyRepeatedlyUnpacked, "type_url")
|
||||
}
|
||||
if fieldSet["value"] {
|
||||
return p.errorf(anyRepeatedlyUnpacked, "value")
|
||||
}
|
||||
sv.FieldByName("TypeUrl").SetString(extName)
|
||||
sv.FieldByName("Value").SetBytes(b)
|
||||
fieldSet["type_url"] = true
|
||||
fieldSet["value"] = true
|
||||
continue
|
||||
}
|
||||
|
||||
var desc *ExtensionDesc
|
||||
// This could be faster, but it's functional.
|
||||
// TODO: Do something smarter than a linear scan.
|
||||
for _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) {
|
||||
if d.Name == extName {
|
||||
desc = d
|
||||
break
|
||||
}
|
||||
}
|
||||
if desc == nil {
|
||||
return p.errorf("unrecognized extension %q", extName)
|
||||
}
|
||||
|
||||
props := &Properties{}
|
||||
props.Parse(desc.Tag)
|
||||
|
||||
typ := reflect.TypeOf(desc.ExtensionType)
|
||||
if err := p.checkForColon(props, typ); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rep := desc.repeated()
|
||||
|
||||
// Read the extension structure, and set it in
|
||||
// the value we're constructing.
|
||||
var ext reflect.Value
|
||||
if !rep {
|
||||
ext = reflect.New(typ).Elem()
|
||||
} else {
|
||||
ext = reflect.New(typ.Elem()).Elem()
|
||||
}
|
||||
if err := p.readAny(ext, props); err != nil {
|
||||
if _, ok := err.(*RequiredNotSetError); !ok {
|
||||
return err
|
||||
}
|
||||
reqFieldErr = err
|
||||
}
|
||||
ep := sv.Addr().Interface().(Message)
|
||||
if !rep {
|
||||
SetExtension(ep, desc, ext.Interface())
|
||||
} else {
|
||||
old, err := GetExtension(ep, desc)
|
||||
var sl reflect.Value
|
||||
if err == nil {
|
||||
sl = reflect.ValueOf(old) // existing slice
|
||||
} else {
|
||||
sl = reflect.MakeSlice(typ, 0, 1)
|
||||
}
|
||||
sl = reflect.Append(sl, ext)
|
||||
SetExtension(ep, desc, sl.Interface())
|
||||
}
|
||||
if err := p.consumeOptionalSeparator(); err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// This is a normal, non-extension field.
|
||||
name := tok.value
|
||||
var dst reflect.Value
|
||||
fi, props, ok := structFieldByName(sprops, name)
|
||||
if ok {
|
||||
dst = sv.Field(fi)
|
||||
} else if oop, ok := sprops.OneofTypes[name]; ok {
|
||||
// It is a oneof.
|
||||
props = oop.Prop
|
||||
nv := reflect.New(oop.Type.Elem())
|
||||
dst = nv.Elem().Field(0)
|
||||
field := sv.Field(oop.Field)
|
||||
if !field.IsNil() {
|
||||
return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, sv.Type().Field(oop.Field).Name)
|
||||
}
|
||||
field.Set(nv)
|
||||
}
|
||||
if !dst.IsValid() {
|
||||
return p.errorf("unknown field name %q in %v", name, st)
|
||||
}
|
||||
|
||||
if dst.Kind() == reflect.Map {
|
||||
// Consume any colon.
|
||||
if err := p.checkForColon(props, dst.Type()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Construct the map if it doesn't already exist.
|
||||
if dst.IsNil() {
|
||||
dst.Set(reflect.MakeMap(dst.Type()))
|
||||
}
|
||||
key := reflect.New(dst.Type().Key()).Elem()
|
||||
val := reflect.New(dst.Type().Elem()).Elem()
|
||||
|
||||
// The map entry should be this sequence of tokens:
|
||||
// < key : KEY value : VALUE >
|
||||
// However, implementations may omit key or value, and technically
|
||||
// we should support them in any order. See b/28924776 for a time
|
||||
// this went wrong.
|
||||
|
||||
tok := p.next()
|
||||
var terminator string
|
||||
switch tok.value {
|
||||
case "<":
|
||||
terminator = ">"
|
||||
case "{":
|
||||
terminator = "}"
|
||||
default:
|
||||
return p.errorf("expected '{' or '<', found %q", tok.value)
|
||||
}
|
||||
for {
|
||||
tok := p.next()
|
||||
if tok.err != nil {
|
||||
return tok.err
|
||||
}
|
||||
if tok.value == terminator {
|
||||
break
|
||||
}
|
||||
switch tok.value {
|
||||
case "key":
|
||||
if err := p.consumeToken(":"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.readAny(key, props.mkeyprop); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.consumeOptionalSeparator(); err != nil {
|
||||
return err
|
||||
}
|
||||
case "value":
|
||||
if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.readAny(val, props.mvalprop); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.consumeOptionalSeparator(); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
p.back()
|
||||
return p.errorf(`expected "key", "value", or %q, found %q`, terminator, tok.value)
|
||||
}
|
||||
}
|
||||
|
||||
dst.SetMapIndex(key, val)
|
||||
continue
|
||||
}
|
||||
|
||||
// Check that it's not already set if it's not a repeated field.
|
||||
if !props.Repeated && fieldSet[name] {
|
||||
return p.errorf("non-repeated field %q was repeated", name)
|
||||
}
|
||||
|
||||
if err := p.checkForColon(props, dst.Type()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Parse into the field.
|
||||
fieldSet[name] = true
|
||||
if err := p.readAny(dst, props); err != nil {
|
||||
if _, ok := err.(*RequiredNotSetError); !ok {
|
||||
return err
|
||||
}
|
||||
reqFieldErr = err
|
||||
}
|
||||
if props.Required {
|
||||
reqCount--
|
||||
}
|
||||
|
||||
if err := p.consumeOptionalSeparator(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if reqCount > 0 {
|
||||
return p.missingRequiredFieldError(sv)
|
||||
}
|
||||
return reqFieldErr
|
||||
}
|
||||
|
||||
// consumeExtName consumes extension name or expanded Any type URL and the
|
||||
// following ']'. It returns the name or URL consumed.
|
||||
func (p *textParser) consumeExtName() (string, error) {
|
||||
tok := p.next()
|
||||
if tok.err != nil {
|
||||
return "", tok.err
|
||||
}
|
||||
|
||||
// If extension name or type url is quoted, it's a single token.
|
||||
if len(tok.value) > 2 && isQuote(tok.value[0]) && tok.value[len(tok.value)-1] == tok.value[0] {
|
||||
name, err := unquoteC(tok.value[1:len(tok.value)-1], rune(tok.value[0]))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return name, p.consumeToken("]")
|
||||
}
|
||||
|
||||
// Consume everything up to "]"
|
||||
var parts []string
|
||||
for tok.value != "]" {
|
||||
parts = append(parts, tok.value)
|
||||
tok = p.next()
|
||||
if tok.err != nil {
|
||||
return "", p.errorf("unrecognized type_url or extension name: %s", tok.err)
|
||||
}
|
||||
}
|
||||
return strings.Join(parts, ""), nil
|
||||
}
|
||||
|
||||
// consumeOptionalSeparator consumes an optional semicolon or comma.
|
||||
// It is used in readStruct to provide backward compatibility.
|
||||
func (p *textParser) consumeOptionalSeparator() error {
|
||||
tok := p.next()
|
||||
if tok.err != nil {
|
||||
return tok.err
|
||||
}
|
||||
if tok.value != ";" && tok.value != "," {
|
||||
p.back()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *textParser) readAny(v reflect.Value, props *Properties) error {
|
||||
tok := p.next()
|
||||
if tok.err != nil {
|
||||
return tok.err
|
||||
}
|
||||
if tok.value == "" {
|
||||
return p.errorf("unexpected EOF")
|
||||
}
|
||||
|
||||
switch fv := v; fv.Kind() {
|
||||
case reflect.Slice:
|
||||
at := v.Type()
|
||||
if at.Elem().Kind() == reflect.Uint8 {
|
||||
// Special case for []byte
|
||||
if tok.value[0] != '"' && tok.value[0] != '\'' {
|
||||
// Deliberately written out here, as the error after
|
||||
// this switch statement would write "invalid []byte: ...",
|
||||
// which is not as user-friendly.
|
||||
return p.errorf("invalid string: %v", tok.value)
|
||||
}
|
||||
bytes := []byte(tok.unquoted)
|
||||
fv.Set(reflect.ValueOf(bytes))
|
||||
return nil
|
||||
}
|
||||
// Repeated field.
|
||||
if tok.value == "[" {
|
||||
// Repeated field with list notation, like [1,2,3].
|
||||
for {
|
||||
fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem()))
|
||||
err := p.readAny(fv.Index(fv.Len()-1), props)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tok := p.next()
|
||||
if tok.err != nil {
|
||||
return tok.err
|
||||
}
|
||||
if tok.value == "]" {
|
||||
break
|
||||
}
|
||||
if tok.value != "," {
|
||||
return p.errorf("Expected ']' or ',' found %q", tok.value)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// One value of the repeated field.
|
||||
p.back()
|
||||
fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem()))
|
||||
return p.readAny(fv.Index(fv.Len()-1), props)
|
||||
case reflect.Bool:
|
||||
// true/1/t/True or false/f/0/False.
|
||||
switch tok.value {
|
||||
case "true", "1", "t", "True":
|
||||
fv.SetBool(true)
|
||||
return nil
|
||||
case "false", "0", "f", "False":
|
||||
fv.SetBool(false)
|
||||
return nil
|
||||
}
|
||||
case reflect.Float32, reflect.Float64:
|
||||
v := tok.value
|
||||
// Ignore 'f' for compatibility with output generated by C++, but don't
|
||||
// remove 'f' when the value is "-inf" or "inf".
|
||||
if strings.HasSuffix(v, "f") && tok.value != "-inf" && tok.value != "inf" {
|
||||
v = v[:len(v)-1]
|
||||
}
|
||||
if f, err := strconv.ParseFloat(v, fv.Type().Bits()); err == nil {
|
||||
fv.SetFloat(f)
|
||||
return nil
|
||||
}
|
||||
case reflect.Int32:
|
||||
if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil {
|
||||
fv.SetInt(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(props.Enum) == 0 {
|
||||
break
|
||||
}
|
||||
m, ok := enumValueMaps[props.Enum]
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
x, ok := m[tok.value]
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
fv.SetInt(int64(x))
|
||||
return nil
|
||||
case reflect.Int64:
|
||||
if x, err := strconv.ParseInt(tok.value, 0, 64); err == nil {
|
||||
fv.SetInt(x)
|
||||
return nil
|
||||
}
|
||||
|
||||
case reflect.Ptr:
|
||||
// A basic field (indirected through pointer), or a repeated message/group
|
||||
p.back()
|
||||
fv.Set(reflect.New(fv.Type().Elem()))
|
||||
return p.readAny(fv.Elem(), props)
|
||||
case reflect.String:
|
||||
if tok.value[0] == '"' || tok.value[0] == '\'' {
|
||||
fv.SetString(tok.unquoted)
|
||||
return nil
|
||||
}
|
||||
case reflect.Struct:
|
||||
var terminator string
|
||||
switch tok.value {
|
||||
case "{":
|
||||
terminator = "}"
|
||||
case "<":
|
||||
terminator = ">"
|
||||
default:
|
||||
return p.errorf("expected '{' or '<', found %q", tok.value)
|
||||
}
|
||||
// TODO: Handle nested messages which implement encoding.TextUnmarshaler.
|
||||
return p.readStruct(fv, terminator)
|
||||
case reflect.Uint32:
|
||||
if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil {
|
||||
fv.SetUint(x)
|
||||
return nil
|
||||
}
|
||||
case reflect.Uint64:
|
||||
if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil {
|
||||
fv.SetUint(x)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return p.errorf("invalid %v: %v", v.Type(), tok.value)
|
||||
}
|
||||
|
||||
// UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb
|
||||
// before starting to unmarshal, so any existing data in pb is always removed.
|
||||
// If a required field is not set and no other error occurs,
|
||||
// UnmarshalText returns *RequiredNotSetError.
|
||||
func UnmarshalText(s string, pb Message) error {
|
||||
if um, ok := pb.(encoding.TextUnmarshaler); ok {
|
||||
err := um.UnmarshalText([]byte(s))
|
||||
return err
|
||||
}
|
||||
pb.Reset()
|
||||
v := reflect.ValueOf(pb)
|
||||
if pe := newTextParser(s).readStruct(v.Elem(), ""); pe != nil {
|
||||
return pe
|
||||
}
|
||||
return nil
|
||||
}
|
27
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/google/go-querystring/LICENSE
generated
vendored
Normal file
27
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/google/go-querystring/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
Copyright (c) 2013 Google. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
320
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/google/go-querystring/query/encode.go
generated
vendored
Normal file
320
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/google/go-querystring/query/encode.go
generated
vendored
Normal file
|
@ -0,0 +1,320 @@
|
|||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package query implements encoding of structs into URL query parameters.
|
||||
//
|
||||
// As a simple example:
|
||||
//
|
||||
// type Options struct {
|
||||
// Query string `url:"q"`
|
||||
// ShowAll bool `url:"all"`
|
||||
// Page int `url:"page"`
|
||||
// }
|
||||
//
|
||||
// opt := Options{ "foo", true, 2 }
|
||||
// v, _ := query.Values(opt)
|
||||
// fmt.Print(v.Encode()) // will output: "q=foo&all=true&page=2"
|
||||
//
|
||||
// The exact mapping between Go values and url.Values is described in the
|
||||
// documentation for the Values() function.
|
||||
package query
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var timeType = reflect.TypeOf(time.Time{})
|
||||
|
||||
var encoderType = reflect.TypeOf(new(Encoder)).Elem()
|
||||
|
||||
// Encoder is an interface implemented by any type that wishes to encode
|
||||
// itself into URL values in a non-standard way.
|
||||
type Encoder interface {
|
||||
EncodeValues(key string, v *url.Values) error
|
||||
}
|
||||
|
||||
// Values returns the url.Values encoding of v.
|
||||
//
|
||||
// Values expects to be passed a struct, and traverses it recursively using the
|
||||
// following encoding rules.
|
||||
//
|
||||
// Each exported struct field is encoded as a URL parameter unless
|
||||
//
|
||||
// - the field's tag is "-", or
|
||||
// - the field is empty and its tag specifies the "omitempty" option
|
||||
//
|
||||
// The empty values are false, 0, any nil pointer or interface value, any array
|
||||
// slice, map, or string of length zero, and any time.Time that returns true
|
||||
// for IsZero().
|
||||
//
|
||||
// The URL parameter name defaults to the struct field name but can be
|
||||
// specified in the struct field's tag value. The "url" key in the struct
|
||||
// field's tag value is the key name, followed by an optional comma and
|
||||
// options. For example:
|
||||
//
|
||||
// // Field is ignored by this package.
|
||||
// Field int `url:"-"`
|
||||
//
|
||||
// // Field appears as URL parameter "myName".
|
||||
// Field int `url:"myName"`
|
||||
//
|
||||
// // Field appears as URL parameter "myName" and the field is omitted if
|
||||
// // its value is empty
|
||||
// Field int `url:"myName,omitempty"`
|
||||
//
|
||||
// // Field appears as URL parameter "Field" (the default), but the field
|
||||
// // is skipped if empty. Note the leading comma.
|
||||
// Field int `url:",omitempty"`
|
||||
//
|
||||
// For encoding individual field values, the following type-dependent rules
|
||||
// apply:
|
||||
//
|
||||
// Boolean values default to encoding as the strings "true" or "false".
|
||||
// Including the "int" option signals that the field should be encoded as the
|
||||
// strings "1" or "0".
|
||||
//
|
||||
// time.Time values default to encoding as RFC3339 timestamps. Including the
|
||||
// "unix" option signals that the field should be encoded as a Unix time (see
|
||||
// time.Unix())
|
||||
//
|
||||
// Slice and Array values default to encoding as multiple URL values of the
|
||||
// same name. Including the "comma" option signals that the field should be
|
||||
// encoded as a single comma-delimited value. Including the "space" option
|
||||
// similarly encodes the value as a single space-delimited string. Including
|
||||
// the "semicolon" option will encode the value as a semicolon-delimited string.
|
||||
// Including the "brackets" option signals that the multiple URL values should
|
||||
// have "[]" appended to the value name. "numbered" will append a number to
|
||||
// the end of each incidence of the value name, example:
|
||||
// name0=value0&name1=value1, etc.
|
||||
//
|
||||
// Anonymous struct fields are usually encoded as if their inner exported
|
||||
// fields were fields in the outer struct, subject to the standard Go
|
||||
// visibility rules. An anonymous struct field with a name given in its URL
|
||||
// tag is treated as having that name, rather than being anonymous.
|
||||
//
|
||||
// Non-nil pointer values are encoded as the value pointed to.
|
||||
//
|
||||
// Nested structs are encoded including parent fields in value names for
|
||||
// scoping. e.g:
|
||||
//
|
||||
// "user[name]=acme&user[addr][postcode]=1234&user[addr][city]=SFO"
|
||||
//
|
||||
// All other values are encoded using their default string representation.
|
||||
//
|
||||
// Multiple fields that encode to the same URL parameter name will be included
|
||||
// as multiple URL values of the same name.
|
||||
func Values(v interface{}) (url.Values, error) {
|
||||
values := make(url.Values)
|
||||
val := reflect.ValueOf(v)
|
||||
for val.Kind() == reflect.Ptr {
|
||||
if val.IsNil() {
|
||||
return values, nil
|
||||
}
|
||||
val = val.Elem()
|
||||
}
|
||||
|
||||
if v == nil {
|
||||
return values, nil
|
||||
}
|
||||
|
||||
if val.Kind() != reflect.Struct {
|
||||
return nil, fmt.Errorf("query: Values() expects struct input. Got %v", val.Kind())
|
||||
}
|
||||
|
||||
err := reflectValue(values, val, "")
|
||||
return values, err
|
||||
}
|
||||
|
||||
// reflectValue populates the values parameter from the struct fields in val.
|
||||
// Embedded structs are followed recursively (using the rules defined in the
|
||||
// Values function documentation) breadth-first.
|
||||
func reflectValue(values url.Values, val reflect.Value, scope string) error {
|
||||
var embedded []reflect.Value
|
||||
|
||||
typ := val.Type()
|
||||
for i := 0; i < typ.NumField(); i++ {
|
||||
sf := typ.Field(i)
|
||||
if sf.PkgPath != "" && !sf.Anonymous { // unexported
|
||||
continue
|
||||
}
|
||||
|
||||
sv := val.Field(i)
|
||||
tag := sf.Tag.Get("url")
|
||||
if tag == "-" {
|
||||
continue
|
||||
}
|
||||
name, opts := parseTag(tag)
|
||||
if name == "" {
|
||||
if sf.Anonymous && sv.Kind() == reflect.Struct {
|
||||
// save embedded struct for later processing
|
||||
embedded = append(embedded, sv)
|
||||
continue
|
||||
}
|
||||
|
||||
name = sf.Name
|
||||
}
|
||||
|
||||
if scope != "" {
|
||||
name = scope + "[" + name + "]"
|
||||
}
|
||||
|
||||
if opts.Contains("omitempty") && isEmptyValue(sv) {
|
||||
continue
|
||||
}
|
||||
|
||||
if sv.Type().Implements(encoderType) {
|
||||
if !reflect.Indirect(sv).IsValid() {
|
||||
sv = reflect.New(sv.Type().Elem())
|
||||
}
|
||||
|
||||
m := sv.Interface().(Encoder)
|
||||
if err := m.EncodeValues(name, &values); err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if sv.Kind() == reflect.Slice || sv.Kind() == reflect.Array {
|
||||
var del byte
|
||||
if opts.Contains("comma") {
|
||||
del = ','
|
||||
} else if opts.Contains("space") {
|
||||
del = ' '
|
||||
} else if opts.Contains("semicolon") {
|
||||
del = ';'
|
||||
} else if opts.Contains("brackets") {
|
||||
name = name + "[]"
|
||||
}
|
||||
|
||||
if del != 0 {
|
||||
s := new(bytes.Buffer)
|
||||
first := true
|
||||
for i := 0; i < sv.Len(); i++ {
|
||||
if first {
|
||||
first = false
|
||||
} else {
|
||||
s.WriteByte(del)
|
||||
}
|
||||
s.WriteString(valueString(sv.Index(i), opts))
|
||||
}
|
||||
values.Add(name, s.String())
|
||||
} else {
|
||||
for i := 0; i < sv.Len(); i++ {
|
||||
k := name
|
||||
if opts.Contains("numbered") {
|
||||
k = fmt.Sprintf("%s%d", name, i)
|
||||
}
|
||||
values.Add(k, valueString(sv.Index(i), opts))
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
for sv.Kind() == reflect.Ptr {
|
||||
if sv.IsNil() {
|
||||
break
|
||||
}
|
||||
sv = sv.Elem()
|
||||
}
|
||||
|
||||
if sv.Type() == timeType {
|
||||
values.Add(name, valueString(sv, opts))
|
||||
continue
|
||||
}
|
||||
|
||||
if sv.Kind() == reflect.Struct {
|
||||
reflectValue(values, sv, name)
|
||||
continue
|
||||
}
|
||||
|
||||
values.Add(name, valueString(sv, opts))
|
||||
}
|
||||
|
||||
for _, f := range embedded {
|
||||
if err := reflectValue(values, f, scope); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// valueString returns the string representation of a value.
|
||||
func valueString(v reflect.Value, opts tagOptions) string {
|
||||
for v.Kind() == reflect.Ptr {
|
||||
if v.IsNil() {
|
||||
return ""
|
||||
}
|
||||
v = v.Elem()
|
||||
}
|
||||
|
||||
if v.Kind() == reflect.Bool && opts.Contains("int") {
|
||||
if v.Bool() {
|
||||
return "1"
|
||||
}
|
||||
return "0"
|
||||
}
|
||||
|
||||
if v.Type() == timeType {
|
||||
t := v.Interface().(time.Time)
|
||||
if opts.Contains("unix") {
|
||||
return strconv.FormatInt(t.Unix(), 10)
|
||||
}
|
||||
return t.Format(time.RFC3339)
|
||||
}
|
||||
|
||||
return fmt.Sprint(v.Interface())
|
||||
}
|
||||
|
||||
// isEmptyValue checks if a value should be considered empty for the purposes
|
||||
// of omitting fields with the "omitempty" option.
|
||||
func isEmptyValue(v reflect.Value) bool {
|
||||
switch v.Kind() {
|
||||
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
|
||||
return v.Len() == 0
|
||||
case reflect.Bool:
|
||||
return !v.Bool()
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return v.Int() == 0
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
return v.Uint() == 0
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return v.Float() == 0
|
||||
case reflect.Interface, reflect.Ptr:
|
||||
return v.IsNil()
|
||||
}
|
||||
|
||||
if v.Type() == timeType {
|
||||
return v.Interface().(time.Time).IsZero()
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// tagOptions is the string following a comma in a struct field's "url" tag, or
|
||||
// the empty string. It does not include the leading comma.
|
||||
type tagOptions []string
|
||||
|
||||
// parseTag splits a struct field's url tag into its name and comma-separated
|
||||
// options.
|
||||
func parseTag(tag string) (string, tagOptions) {
|
||||
s := strings.Split(tag, ",")
|
||||
return s[0], s[1:]
|
||||
}
|
||||
|
||||
// Contains checks whether the tagOptions contains the specified option.
|
||||
func (o tagOptions) Contains(option string) bool {
|
||||
for _, s := range o {
|
||||
if s == option {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
27
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/tent/http-link-go/LICENSE
generated
vendored
Normal file
27
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/tent/http-link-go/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
Copyright (c) 2013 Tent.is, LLC. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Tent.is, LLC nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
12
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/tent/http-link-go/README.md
generated
vendored
Normal file
12
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/tent/http-link-go/README.md
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
# http-link-go [![Build Status](https://travis-ci.org/tent/http-link-go.png?branch=master)](https://travis-ci.org/tent/http-link-go)
|
||||
|
||||
http-link-go implements parsing and serialization of Link header values as
|
||||
defined in [RFC 5988](https://tools.ietf.org/html/rfc5988).
|
||||
|
||||
[**Documentation**](http://godoc.org/github.com/tent/http-link-go)
|
||||
|
||||
## Installation
|
||||
|
||||
```text
|
||||
go get github.com/tent/http-link-go
|
||||
```
|
185
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/tent/http-link-go/link.go
generated
vendored
Normal file
185
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/github.com/tent/http-link-go/link.go
generated
vendored
Normal file
|
@ -0,0 +1,185 @@
|
|||
// Package link implements parsing and serialization of Link header values as
|
||||
// defined in RFC 5988.
|
||||
package link
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"sort"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
type Link struct {
|
||||
URI string
|
||||
Rel string
|
||||
Params map[string]string
|
||||
}
|
||||
|
||||
// Format serializes a slice of Links into a header value. It does not currently
|
||||
// implement RFC 2231 handling of non-ASCII character encoding and language
|
||||
// information.
|
||||
func Format(links []Link) string {
|
||||
buf := &bytes.Buffer{}
|
||||
for i, link := range links {
|
||||
if i > 0 {
|
||||
buf.Write([]byte(", "))
|
||||
}
|
||||
buf.WriteByte('<')
|
||||
buf.WriteString(link.URI)
|
||||
buf.WriteByte('>')
|
||||
|
||||
writeParam(buf, "rel", link.Rel)
|
||||
|
||||
keys := make([]string, 0, len(link.Params))
|
||||
for k := range link.Params {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
for _, k := range keys {
|
||||
writeParam(buf, k, link.Params[k])
|
||||
}
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func writeParam(buf *bytes.Buffer, key, value string) {
|
||||
buf.Write([]byte("; "))
|
||||
buf.WriteString(key)
|
||||
buf.Write([]byte(`="`))
|
||||
buf.WriteString(value)
|
||||
buf.WriteByte('"')
|
||||
}
|
||||
|
||||
// Parse parses a Link header value into a slice of Links. It does not currently
|
||||
// implement RFC 2231 handling of non-ASCII character encoding and language
|
||||
// information.
|
||||
func Parse(l string) ([]Link, error) {
|
||||
v := []byte(l)
|
||||
v = bytes.TrimSpace(v)
|
||||
if len(v) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
links := make([]Link, 0, 1)
|
||||
for len(v) > 0 {
|
||||
if v[0] != '<' {
|
||||
return nil, errors.New("link: does not start with <")
|
||||
}
|
||||
lend := bytes.IndexByte(v, '>')
|
||||
if lend == -1 {
|
||||
return nil, errors.New("link: does not contain ending >")
|
||||
}
|
||||
|
||||
params := make(map[string]string)
|
||||
link := Link{URI: string(v[1:lend]), Params: params}
|
||||
links = append(links, link)
|
||||
|
||||
// trim off parsed url
|
||||
v = v[lend+1:]
|
||||
if len(v) == 0 {
|
||||
break
|
||||
}
|
||||
v = bytes.TrimLeftFunc(v, unicode.IsSpace)
|
||||
|
||||
for len(v) > 0 {
|
||||
if v[0] != ';' && v[0] != ',' {
|
||||
return nil, errors.New(`link: expected ";" or "'", got "` + string(v[0:1]) + `"`)
|
||||
}
|
||||
var next bool
|
||||
if v[0] == ',' {
|
||||
next = true
|
||||
}
|
||||
v = bytes.TrimLeftFunc(v[1:], unicode.IsSpace)
|
||||
if next || len(v) == 0 {
|
||||
break
|
||||
}
|
||||
var key, value []byte
|
||||
key, value, v = consumeParam(v)
|
||||
if key == nil || value == nil {
|
||||
return nil, errors.New("link: malformed param")
|
||||
}
|
||||
if k := string(key); k == "rel" {
|
||||
if links[len(links)-1].Rel == "" {
|
||||
links[len(links)-1].Rel = string(value)
|
||||
}
|
||||
} else {
|
||||
params[k] = string(value)
|
||||
}
|
||||
v = bytes.TrimLeftFunc(v, unicode.IsSpace)
|
||||
}
|
||||
}
|
||||
|
||||
return links, nil
|
||||
}
|
||||
|
||||
func isTokenChar(r rune) bool {
|
||||
return r > 0x20 && r < 0x7f && r != '"' && r != ',' && r != '=' && r != ';'
|
||||
}
|
||||
|
||||
func isNotTokenChar(r rune) bool { return !isTokenChar(r) }
|
||||
|
||||
func consumeToken(v []byte) (token, rest []byte) {
|
||||
notPos := bytes.IndexFunc(v, isNotTokenChar)
|
||||
if notPos == -1 {
|
||||
return v, nil
|
||||
}
|
||||
if notPos == 0 {
|
||||
return nil, v
|
||||
}
|
||||
return v[0:notPos], v[notPos:]
|
||||
}
|
||||
|
||||
func consumeValue(v []byte) (value, rest []byte) {
|
||||
if v[0] != '"' {
|
||||
return nil, v
|
||||
}
|
||||
|
||||
rest = v[1:]
|
||||
buffer := &bytes.Buffer{}
|
||||
var nextIsLiteral bool
|
||||
for idx, r := range string(rest) {
|
||||
switch {
|
||||
case nextIsLiteral:
|
||||
buffer.WriteRune(r)
|
||||
nextIsLiteral = false
|
||||
case r == '"':
|
||||
return buffer.Bytes(), rest[idx+1:]
|
||||
case r == '\\':
|
||||
nextIsLiteral = true
|
||||
case r != '\r' && r != '\n':
|
||||
buffer.WriteRune(r)
|
||||
default:
|
||||
return nil, v
|
||||
}
|
||||
}
|
||||
return nil, v
|
||||
}
|
||||
|
||||
func consumeParam(v []byte) (param, value, rest []byte) {
|
||||
param, rest = consumeToken(v)
|
||||
param = bytes.ToLower(param)
|
||||
if param == nil {
|
||||
return nil, nil, v
|
||||
}
|
||||
|
||||
rest = bytes.TrimLeftFunc(rest, unicode.IsSpace)
|
||||
if len(rest) == 0 || rest[0] != '=' {
|
||||
return nil, nil, v
|
||||
}
|
||||
rest = rest[1:] // consume equals sign
|
||||
rest = bytes.TrimLeftFunc(rest, unicode.IsSpace)
|
||||
if len(rest) == 0 {
|
||||
return nil, nil, v
|
||||
}
|
||||
if rest[0] != '"' {
|
||||
value, rest = consumeToken(rest)
|
||||
} else {
|
||||
value, rest = consumeValue(rest)
|
||||
}
|
||||
if value == nil {
|
||||
return nil, nil, v
|
||||
}
|
||||
return param, value, rest
|
||||
}
|
27
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/golang.org/x/net/LICENSE
generated
vendored
Normal file
27
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/golang.org/x/net/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
22
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/golang.org/x/net/PATENTS
generated
vendored
Normal file
22
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/golang.org/x/net/PATENTS
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
Additional IP Rights Grant (Patents)
|
||||
|
||||
"This implementation" means the copyrightable works distributed by
|
||||
Google as part of the Go project.
|
||||
|
||||
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||
no-charge, royalty-free, irrevocable (except as stated in this section)
|
||||
patent license to make, have made, use, offer to sell, sell, import,
|
||||
transfer and otherwise run, modify and propagate the contents of this
|
||||
implementation of Go, where such license applies only to those patent
|
||||
claims, both currently owned or controlled by Google and acquired in
|
||||
the future, licensable by Google that are necessarily infringed by this
|
||||
implementation of Go. This grant does not include claims that would be
|
||||
infringed only as a consequence of further modification of this
|
||||
implementation. If you or your agent or exclusive licensee institute or
|
||||
order or agree to the institution of patent litigation against any
|
||||
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||
that this implementation of Go or any code incorporated within this
|
||||
implementation of Go constitutes direct or contributory patent
|
||||
infringement, or inducement of patent infringement, then any patent
|
||||
rights granted to you under this License for this implementation of Go
|
||||
shall terminate as of the date such litigation is filed.
|
54
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/golang.org/x/net/context/context.go
generated
vendored
Normal file
54
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/golang.org/x/net/context/context.go
generated
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package context defines the Context type, which carries deadlines,
|
||||
// cancelation signals, and other request-scoped values across API boundaries
|
||||
// and between processes.
|
||||
//
|
||||
// Incoming requests to a server should create a Context, and outgoing calls to
|
||||
// servers should accept a Context. The chain of function calls between must
|
||||
// propagate the Context, optionally replacing it with a modified copy created
|
||||
// using WithDeadline, WithTimeout, WithCancel, or WithValue.
|
||||
//
|
||||
// Programs that use Contexts should follow these rules to keep interfaces
|
||||
// consistent across packages and enable static analysis tools to check context
|
||||
// propagation:
|
||||
//
|
||||
// Do not store Contexts inside a struct type; instead, pass a Context
|
||||
// explicitly to each function that needs it. The Context should be the first
|
||||
// parameter, typically named ctx:
|
||||
//
|
||||
// func DoSomething(ctx context.Context, arg Arg) error {
|
||||
// // ... use ctx ...
|
||||
// }
|
||||
//
|
||||
// Do not pass a nil Context, even if a function permits it. Pass context.TODO
|
||||
// if you are unsure about which Context to use.
|
||||
//
|
||||
// Use context Values only for request-scoped data that transits processes and
|
||||
// APIs, not for passing optional parameters to functions.
|
||||
//
|
||||
// The same Context may be passed to functions running in different goroutines;
|
||||
// Contexts are safe for simultaneous use by multiple goroutines.
|
||||
//
|
||||
// See http://blog.golang.org/context for example code for a server that uses
|
||||
// Contexts.
|
||||
package context // import "golang.org/x/net/context"
|
||||
|
||||
// Background returns a non-nil, empty Context. It is never canceled, has no
|
||||
// values, and has no deadline. It is typically used by the main function,
|
||||
// initialization, and tests, and as the top-level Context for incoming
|
||||
// requests.
|
||||
func Background() Context {
|
||||
return background
|
||||
}
|
||||
|
||||
// TODO returns a non-nil, empty Context. Code should use context.TODO when
|
||||
// it's unclear which Context to use or it is not yet available (because the
|
||||
// surrounding function has not yet been extended to accept a Context
|
||||
// parameter). TODO is recognized by static analysis tools that determine
|
||||
// whether Contexts are propagated correctly in a program.
|
||||
func TODO() Context {
|
||||
return todo
|
||||
}
|
74
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go
generated
vendored
Normal file
74
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go
generated
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.7
|
||||
|
||||
// Package ctxhttp provides helper functions for performing context-aware HTTP requests.
|
||||
package ctxhttp // import "golang.org/x/net/context/ctxhttp"
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// Do sends an HTTP request with the provided http.Client and returns
|
||||
// an HTTP response.
|
||||
//
|
||||
// If the client is nil, http.DefaultClient is used.
|
||||
//
|
||||
// The provided ctx must be non-nil. If it is canceled or times out,
|
||||
// ctx.Err() will be returned.
|
||||
func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) {
|
||||
if client == nil {
|
||||
client = http.DefaultClient
|
||||
}
|
||||
resp, err := client.Do(req.WithContext(ctx))
|
||||
// If we got an error, and the context has been canceled,
|
||||
// the context's error is probably more useful.
|
||||
if err != nil {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
err = ctx.Err()
|
||||
default:
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// Get issues a GET request via the Do function.
|
||||
func Get(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return Do(ctx, client, req)
|
||||
}
|
||||
|
||||
// Head issues a HEAD request via the Do function.
|
||||
func Head(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
|
||||
req, err := http.NewRequest("HEAD", url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return Do(ctx, client, req)
|
||||
}
|
||||
|
||||
// Post issues a POST request via the Do function.
|
||||
func Post(ctx context.Context, client *http.Client, url string, bodyType string, body io.Reader) (*http.Response, error) {
|
||||
req, err := http.NewRequest("POST", url, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", bodyType)
|
||||
return Do(ctx, client, req)
|
||||
}
|
||||
|
||||
// PostForm issues a POST request via the Do function.
|
||||
func PostForm(ctx context.Context, client *http.Client, url string, data url.Values) (*http.Response, error) {
|
||||
return Post(ctx, client, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
|
||||
}
|
147
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go
generated
vendored
Normal file
147
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go
generated
vendored
Normal file
|
@ -0,0 +1,147 @@
|
|||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !go1.7
|
||||
|
||||
package ctxhttp // import "golang.org/x/net/context/ctxhttp"
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
func nop() {}
|
||||
|
||||
var (
|
||||
testHookContextDoneBeforeHeaders = nop
|
||||
testHookDoReturned = nop
|
||||
testHookDidBodyClose = nop
|
||||
)
|
||||
|
||||
// Do sends an HTTP request with the provided http.Client and returns an HTTP response.
|
||||
// If the client is nil, http.DefaultClient is used.
|
||||
// If the context is canceled or times out, ctx.Err() will be returned.
|
||||
func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) {
|
||||
if client == nil {
|
||||
client = http.DefaultClient
|
||||
}
|
||||
|
||||
// TODO(djd): Respect any existing value of req.Cancel.
|
||||
cancel := make(chan struct{})
|
||||
req.Cancel = cancel
|
||||
|
||||
type responseAndError struct {
|
||||
resp *http.Response
|
||||
err error
|
||||
}
|
||||
result := make(chan responseAndError, 1)
|
||||
|
||||
// Make local copies of test hooks closed over by goroutines below.
|
||||
// Prevents data races in tests.
|
||||
testHookDoReturned := testHookDoReturned
|
||||
testHookDidBodyClose := testHookDidBodyClose
|
||||
|
||||
go func() {
|
||||
resp, err := client.Do(req)
|
||||
testHookDoReturned()
|
||||
result <- responseAndError{resp, err}
|
||||
}()
|
||||
|
||||
var resp *http.Response
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
testHookContextDoneBeforeHeaders()
|
||||
close(cancel)
|
||||
// Clean up after the goroutine calling client.Do:
|
||||
go func() {
|
||||
if r := <-result; r.resp != nil {
|
||||
testHookDidBodyClose()
|
||||
r.resp.Body.Close()
|
||||
}
|
||||
}()
|
||||
return nil, ctx.Err()
|
||||
case r := <-result:
|
||||
var err error
|
||||
resp, err = r.resp, r.err
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
}
|
||||
|
||||
c := make(chan struct{})
|
||||
go func() {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
close(cancel)
|
||||
case <-c:
|
||||
// The response's Body is closed.
|
||||
}
|
||||
}()
|
||||
resp.Body = ¬ifyingReader{resp.Body, c}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Get issues a GET request via the Do function.
|
||||
func Get(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return Do(ctx, client, req)
|
||||
}
|
||||
|
||||
// Head issues a HEAD request via the Do function.
|
||||
func Head(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
|
||||
req, err := http.NewRequest("HEAD", url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return Do(ctx, client, req)
|
||||
}
|
||||
|
||||
// Post issues a POST request via the Do function.
|
||||
func Post(ctx context.Context, client *http.Client, url string, bodyType string, body io.Reader) (*http.Response, error) {
|
||||
req, err := http.NewRequest("POST", url, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", bodyType)
|
||||
return Do(ctx, client, req)
|
||||
}
|
||||
|
||||
// PostForm issues a POST request via the Do function.
|
||||
func PostForm(ctx context.Context, client *http.Client, url string, data url.Values) (*http.Response, error) {
|
||||
return Post(ctx, client, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
|
||||
}
|
||||
|
||||
// notifyingReader is an io.ReadCloser that closes the notify channel after
|
||||
// Close is called or a Read fails on the underlying ReadCloser.
|
||||
type notifyingReader struct {
|
||||
io.ReadCloser
|
||||
notify chan<- struct{}
|
||||
}
|
||||
|
||||
func (r *notifyingReader) Read(p []byte) (int, error) {
|
||||
n, err := r.ReadCloser.Read(p)
|
||||
if err != nil && r.notify != nil {
|
||||
close(r.notify)
|
||||
r.notify = nil
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (r *notifyingReader) Close() error {
|
||||
err := r.ReadCloser.Close()
|
||||
if r.notify != nil {
|
||||
close(r.notify)
|
||||
r.notify = nil
|
||||
}
|
||||
return err
|
||||
}
|
72
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/golang.org/x/net/context/go17.go
generated
vendored
Normal file
72
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/golang.org/x/net/context/go17.go
generated
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.7
|
||||
|
||||
package context
|
||||
|
||||
import (
|
||||
"context" // standard library's context, as of Go 1.7
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
todo = context.TODO()
|
||||
background = context.Background()
|
||||
)
|
||||
|
||||
// Canceled is the error returned by Context.Err when the context is canceled.
|
||||
var Canceled = context.Canceled
|
||||
|
||||
// DeadlineExceeded is the error returned by Context.Err when the context's
|
||||
// deadline passes.
|
||||
var DeadlineExceeded = context.DeadlineExceeded
|
||||
|
||||
// WithCancel returns a copy of parent with a new Done channel. The returned
|
||||
// context's Done channel is closed when the returned cancel function is called
|
||||
// or when the parent context's Done channel is closed, whichever happens first.
|
||||
//
|
||||
// Canceling this context releases resources associated with it, so code should
|
||||
// call cancel as soon as the operations running in this Context complete.
|
||||
func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
|
||||
ctx, f := context.WithCancel(parent)
|
||||
return ctx, CancelFunc(f)
|
||||
}
|
||||
|
||||
// WithDeadline returns a copy of the parent context with the deadline adjusted
|
||||
// to be no later than d. If the parent's deadline is already earlier than d,
|
||||
// WithDeadline(parent, d) is semantically equivalent to parent. The returned
|
||||
// context's Done channel is closed when the deadline expires, when the returned
|
||||
// cancel function is called, or when the parent context's Done channel is
|
||||
// closed, whichever happens first.
|
||||
//
|
||||
// Canceling this context releases resources associated with it, so code should
|
||||
// call cancel as soon as the operations running in this Context complete.
|
||||
func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
|
||||
ctx, f := context.WithDeadline(parent, deadline)
|
||||
return ctx, CancelFunc(f)
|
||||
}
|
||||
|
||||
// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
|
||||
//
|
||||
// Canceling this context releases resources associated with it, so code should
|
||||
// call cancel as soon as the operations running in this Context complete:
|
||||
//
|
||||
// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
|
||||
// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
|
||||
// defer cancel() // releases resources if slowOperation completes before timeout elapses
|
||||
// return slowOperation(ctx)
|
||||
// }
|
||||
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
|
||||
return WithDeadline(parent, time.Now().Add(timeout))
|
||||
}
|
||||
|
||||
// WithValue returns a copy of parent in which the value associated with key is
|
||||
// val.
|
||||
//
|
||||
// Use context Values only for request-scoped data that transits processes and
|
||||
// APIs, not for passing optional parameters to functions.
|
||||
func WithValue(parent Context, key interface{}, val interface{}) Context {
|
||||
return context.WithValue(parent, key, val)
|
||||
}
|
20
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/golang.org/x/net/context/go19.go
generated
vendored
Normal file
20
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/golang.org/x/net/context/go19.go
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.9
|
||||
|
||||
package context
|
||||
|
||||
import "context" // standard library's context, as of Go 1.7
|
||||
|
||||
// A Context carries a deadline, a cancelation signal, and other values across
|
||||
// API boundaries.
|
||||
//
|
||||
// Context's methods may be called by multiple goroutines simultaneously.
|
||||
type Context = context.Context
|
||||
|
||||
// A CancelFunc tells an operation to abandon its work.
|
||||
// A CancelFunc does not wait for the work to stop.
|
||||
// After the first call, subsequent calls to a CancelFunc do nothing.
|
||||
type CancelFunc = context.CancelFunc
|
300
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/golang.org/x/net/context/pre_go17.go
generated
vendored
Normal file
300
vendor/github.com/hashicorp/go-discover/provider/digitalocean/vendor/golang.org/x/net/context/pre_go17.go
generated
vendored
Normal file
|
@ -0,0 +1,300 @@
|
|||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !go1.7
|
||||
|
||||
package context
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// An emptyCtx is never canceled, has no values, and has no deadline. It is not
|
||||
// struct{}, since vars of this type must have distinct addresses.
|
||||
type emptyCtx int
|
||||
|
||||
func (*emptyCtx) Deadline() (deadline time.Time, ok bool) {
|
||||
return
|
||||
}
|
||||
|
||||
func (*emptyCtx) Done() <-chan struct{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*emptyCtx) Err() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*emptyCtx) Value(key interface{}) interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *emptyCtx) String() string {
|
||||
switch e {
|
||||
case background:
|
||||
return "context.Background"
|
||||
case todo:
|
||||
return "context.TODO"
|
||||
}
|
||||
return "unknown empty Context"
|
||||
}
|
||||
|
||||
var (
|
||||
background = new(emptyCtx)
|
||||
todo = new(emptyCtx)
|
||||
)
|
||||
|
||||
// Canceled is the error returned by Context.Err when the context is canceled.
|
||||
var Canceled = errors.New("context canceled")
|
||||
|
||||
// DeadlineExceeded is the error returned by Context.Err when the context's
|
||||
// deadline passes.
|
||||
var DeadlineExceeded = errors.New("context deadline exceeded")
|
||||
|
||||
// WithCancel returns a copy of parent with a new Done channel. The returned
|
||||
// context's Done channel is closed when the returned cancel function is called
|
||||
// or when the parent context's Done channel is closed, whichever happens first.
|
||||
//
|
||||
// Canceling this context releases resources associated with it, so code should
|
||||
// call cancel as soon as the operations running in this Context complete.
|
||||
func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
|
||||
c := newCancelCtx(parent)
|
||||
propagateCancel(parent, c)
|
||||
return c, func() { c.cancel(true, Canceled) }
|
||||
}
|
||||
|
||||
// newCancelCtx returns an initialized cancelCtx.
|
||||
func newCancelCtx(parent Context) *cancelCtx {
|
||||
return &cancelCtx{
|
||||
Context: parent,
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
// propagateCancel arranges for child to be canceled when parent is.
|
||||
func propagateCancel(parent Context, child canceler) {
|
||||
if parent.Done() == nil {
|
||||
return // parent is never canceled
|
||||
}
|
||||
if p, ok := parentCancelCtx(parent); ok {
|
||||
p.mu.Lock()
|
||||
if p.err != nil {
|
||||
// parent has already been canceled
|
||||
child.cancel(false, p.err)
|
||||
} else {
|
||||
if p.children == nil {
|
||||
p.children = make(map[canceler]bool)
|
||||
}
|
||||
p.children[child] = true
|
||||
}
|
||||
p.mu.Unlock()
|
||||
} else {
|
||||
go func() {
|
||||
select {
|
||||
case <-parent.Done():
|
||||
child.cancel(false, parent.Err())
|
||||
case <-child.Done():
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
// parentCancelCtx follows a chain of parent references until it finds a
|
||||
// *cancelCtx. This function understands how each of the concrete types in this
|
||||
// package represents its parent.
|
||||
func parentCancelCtx(parent Context) (*cancelCtx, bool) {
|
||||
for {
|
||||
switch c := parent.(type) {
|
||||
case *cancelCtx:
|
||||
return c, true
|
||||
case *timerCtx:
|
||||
return c.cancelCtx, true
|
||||
case *valueCtx:
|
||||
parent = c.Context
|
||||
default:
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// removeChild removes a context from its parent.
|
||||
func removeChild(parent Context, child canceler) {
|
||||
p, ok := parentCancelCtx(parent)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
p.mu.Lock()
|
||||
if p.children != nil {
|
||||
delete(p.children, child)
|
||||
}
|
||||
p.mu.Unlock()
|
||||
}
|
||||
|
||||
// A canceler is a context type that can be canceled directly. The
|
||||
// implementations are *cancelCtx and *timerCtx.
|
||||
type canceler interface {
|
||||
cancel(removeFromParent bool, err error)
|
||||
Done() <-chan struct{}
|
||||
}
|
||||
|
||||
// A cancelCtx can be canceled. When canceled, it also cancels any children
|
||||
// that implement canceler.
|
||||
type cancelCtx struct {
|
||||
Context
|
||||
|
||||
done chan struct{} // closed by the first cancel call.
|
||||
|
||||
mu sync.Mutex
|
||||
children map[canceler]bool // set to nil by the first cancel call
|
||||
err error // set to non-nil by the first cancel call
|
||||
}
|
||||
|
||||
func (c *cancelCtx) Done() <-chan struct{} {
|
||||
return c.done
|
||||
}
|
||||
|
||||
func (c *cancelCtx) Err() error {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
return c.err
|
||||
}
|
||||
|
||||
func (c *cancelCtx) String() string {
|
||||
return fmt.Sprintf("%v.WithCancel", c.Context)
|
||||
}
|
||||
|
||||
// cancel closes c.done, cancels each of c's children, and, if
|
||||
// removeFromParent is true, removes c from its parent's children.
|
||||
func (c *cancelCtx) cancel(removeFromParent bool, err error) {
|
||||
if err == nil {
|
||||
panic("context: internal error: missing cancel error")
|
||||
}
|
||||
c.mu.Lock()
|
||||
if c.err != nil {
|
||||
c.mu.Unlock()
|
||||
return // already canceled
|
||||
}
|
||||
c.err = err
|
||||
close(c.done)
|
||||
for child := range c.children {
|
||||
// NOTE: acquiring the child's lock while holding parent's lock.
|
||||
child.cancel(false, err)
|
||||
}
|
||||
c.children = nil
|
||||
c.mu.Unlock()
|
||||
|
||||
if removeFromParent {
|
||||
removeChild(c.Context, c)
|
||||
}
|
||||
}
|
||||
|
||||
// WithDeadline returns a copy of the parent context with the deadline adjusted
|
||||
// to be no later than d. If the parent's deadline is already earlier than d,
|
||||
// WithDeadline(parent, d) is semantically equivalent to parent. The returned
|
||||
// context's Done channel is closed when the deadline expires, when the returned
|
||||
// cancel function is called, or when the parent context's Done channel is
|
||||
// closed, whichever happens first.
|
||||
//
|
||||
// Canceling this context releases resources associated with it, so code should
|
||||
// call cancel as soon as the operations running in this Context complete.
|
||||
func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
|
||||
if cur, ok := parent.Deadline(); ok && cur.Before(deadline) {
|
||||
// The current deadline is already sooner than the new one.
|
||||
return WithCancel(parent)
|
||||
}
|
||||
c := &timerCtx{
|
||||
cancelCtx: newCancelCtx(parent),
|
||||
deadline: deadline,
|
||||
}
|
||||
propagateCancel(parent, c)
|
||||
d := deadline.Sub(time.Now())
|
||||
if d <= 0 {
|
||||
c.cancel(true, DeadlineExceeded) // deadline has already passed
|
||||
return c, func() { c.cancel(true, Canceled) }
|
||||
}
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if c.err == nil {
|
||||
c.timer = time.AfterFunc(d, func() {
|
||||
c.cancel(true, DeadlineExceeded)
|
||||
})
|
||||
}
|
||||
return c, func() { c.cancel(true, Canceled) }
|
||||
}
|
||||
|
||||
// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to
|
||||
// implement Done and Err. It implements cancel by stopping its timer then
|
||||
// delegating to cancelCtx.cancel.
|
||||
type timerCtx struct {
|
||||
*cancelCtx
|
||||
timer *time.Timer // Under cancelCtx.mu.
|
||||
|
||||
deadline time.Time
|
||||
}
|
||||
|
||||
func (c *timerCtx) Deadline() (deadline time.Time, ok bool) {
|
||||
return c.deadline, true
|
||||
}
|
||||
|
||||
func (c *timerCtx) String() string {
|
||||
return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, c.deadline.Sub(time.Now()))
|
||||
}
|
||||
|
||||
func (c *timerCtx) cancel(removeFromParent bool, err error) {
|
||||
c.cancelCtx.cancel(false, err)
|
||||
if removeFromParent {
|
||||
// Remove this timerCtx from its parent cancelCtx's children.
|
||||
removeChild(c.cancelCtx.Context, c)
|
||||
}
|
||||
c.mu.Lock()
|
||||
if c.timer != nil {
|
||||
c.timer.Stop()
|
||||
c.timer = nil
|
||||
}
|
||||
c.mu.Unlock()
|
||||
}
|
||||
|
||||
// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
|
||||
//
|
||||
// Canceling this context releases resources associated with it, so code should
|
||||
// call cancel as soon as the operations running in this Context complete:
|
||||
//
|
||||
// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
|
||||
// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
|
||||
// defer cancel() // releases resources if slowOperation completes before timeout elapses
|
||||
// return slowOperation(ctx)
|
||||
// }
|
||||
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
|
||||
return WithDeadline(parent, time.Now().Add(timeout))
|
||||
}
|
||||
|
||||
// WithValue returns a copy of parent in which the value associated with key is
|
||||
// val.
|
||||
//
|
||||
// Use context Values only for request-scoped data that transits processes and
|
||||
// APIs, not for passing optional parameters to functions.
|
||||
func WithValue(parent Context, key interface{}, val interface{}) Context {
|
||||
return &valueCtx{parent, key, val}
|
||||
}
|
||||
|
||||
// A valueCtx carries a key-value pair. It implements Value for that key and
|
||||
// delegates all other calls to the embedded Context.
|
||||
type valueCtx struct {
|
||||
Context
|
||||
key, val interface{}
|
||||
}
|
||||
|
||||
func (c *valueCtx) String() string {
|
||||
return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val)
|
||||
}
|
||||
|
||||
func (c *valueCtx) Value(key interface{}) interface{} {
|
||||
if c.key == key {
|
||||
return c.val
|
||||
}
|
||||
return c.Context.Value(key)
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue