mirror of
https://github.com/taigrr/wtf
synced 2025-01-18 04:03:14 -08:00
Removing vendor directory
This commit is contained in:
parent
c1f9c910e1
commit
6747784acd
2
Makefile
2
Makefile
@ -30,7 +30,7 @@ APP=wtfutil
|
||||
|
||||
## build: builds a local version
|
||||
build:
|
||||
go build -o bin/${APP} -mod=vendor
|
||||
go build -o bin/${APP}
|
||||
@echo "Done building"
|
||||
|
||||
## clean: removes old build cruft
|
||||
|
202
vendor/cloud.google.com/go/LICENSE
generated
vendored
202
vendor/cloud.google.com/go/LICENSE
generated
vendored
@ -1,202 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://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
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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
|
||||
|
||||
http://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.
|
513
vendor/cloud.google.com/go/compute/metadata/metadata.go
generated
vendored
513
vendor/cloud.google.com/go/compute/metadata/metadata.go
generated
vendored
@ -1,513 +0,0 @@
|
||||
// Copyright 2014 Google LLC
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
// Package metadata provides access to Google Compute Engine (GCE)
|
||||
// metadata and API service accounts.
|
||||
//
|
||||
// This package is a wrapper around the GCE metadata service,
|
||||
// as documented at https://developers.google.com/compute/docs/metadata.
|
||||
package metadata // import "cloud.google.com/go/compute/metadata"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
// metadataIP is the documented metadata server IP address.
|
||||
metadataIP = "169.254.169.254"
|
||||
|
||||
// metadataHostEnv is the environment variable specifying the
|
||||
// GCE metadata hostname. If empty, the default value of
|
||||
// metadataIP ("169.254.169.254") is used instead.
|
||||
// This is variable name is not defined by any spec, as far as
|
||||
// I know; it was made up for the Go package.
|
||||
metadataHostEnv = "GCE_METADATA_HOST"
|
||||
|
||||
userAgent = "gcloud-golang/0.1"
|
||||
)
|
||||
|
||||
type cachedValue struct {
|
||||
k string
|
||||
trim bool
|
||||
mu sync.Mutex
|
||||
v string
|
||||
}
|
||||
|
||||
var (
|
||||
projID = &cachedValue{k: "project/project-id", trim: true}
|
||||
projNum = &cachedValue{k: "project/numeric-project-id", trim: true}
|
||||
instID = &cachedValue{k: "instance/id", trim: true}
|
||||
)
|
||||
|
||||
var (
|
||||
defaultClient = &Client{hc: &http.Client{
|
||||
Transport: &http.Transport{
|
||||
Dial: (&net.Dialer{
|
||||
Timeout: 2 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
}).Dial,
|
||||
ResponseHeaderTimeout: 2 * time.Second,
|
||||
},
|
||||
}}
|
||||
subscribeClient = &Client{hc: &http.Client{
|
||||
Transport: &http.Transport{
|
||||
Dial: (&net.Dialer{
|
||||
Timeout: 2 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
}).Dial,
|
||||
},
|
||||
}}
|
||||
)
|
||||
|
||||
// NotDefinedError is returned when requested metadata is not defined.
|
||||
//
|
||||
// The underlying string is the suffix after "/computeMetadata/v1/".
|
||||
//
|
||||
// This error is not returned if the value is defined to be the empty
|
||||
// string.
|
||||
type NotDefinedError string
|
||||
|
||||
func (suffix NotDefinedError) Error() string {
|
||||
return fmt.Sprintf("metadata: GCE metadata %q not defined", string(suffix))
|
||||
}
|
||||
|
||||
func (c *cachedValue) get(cl *Client) (v string, err error) {
|
||||
defer c.mu.Unlock()
|
||||
c.mu.Lock()
|
||||
if c.v != "" {
|
||||
return c.v, nil
|
||||
}
|
||||
if c.trim {
|
||||
v, err = cl.getTrimmed(c.k)
|
||||
} else {
|
||||
v, err = cl.Get(c.k)
|
||||
}
|
||||
if err == nil {
|
||||
c.v = v
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
onGCEOnce sync.Once
|
||||
onGCE bool
|
||||
)
|
||||
|
||||
// OnGCE reports whether this process is running on Google Compute Engine.
|
||||
func OnGCE() bool {
|
||||
onGCEOnce.Do(initOnGCE)
|
||||
return onGCE
|
||||
}
|
||||
|
||||
func initOnGCE() {
|
||||
onGCE = testOnGCE()
|
||||
}
|
||||
|
||||
func testOnGCE() bool {
|
||||
// The user explicitly said they're on GCE, so trust them.
|
||||
if os.Getenv(metadataHostEnv) != "" {
|
||||
return true
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
resc := make(chan bool, 2)
|
||||
|
||||
// Try two strategies in parallel.
|
||||
// See https://github.com/googleapis/google-cloud-go/issues/194
|
||||
go func() {
|
||||
req, _ := http.NewRequest("GET", "http://"+metadataIP, nil)
|
||||
req.Header.Set("User-Agent", userAgent)
|
||||
res, err := defaultClient.hc.Do(req.WithContext(ctx))
|
||||
if err != nil {
|
||||
resc <- false
|
||||
return
|
||||
}
|
||||
defer res.Body.Close()
|
||||
resc <- res.Header.Get("Metadata-Flavor") == "Google"
|
||||
}()
|
||||
|
||||
go func() {
|
||||
addrs, err := net.LookupHost("metadata.google.internal")
|
||||
if err != nil || len(addrs) == 0 {
|
||||
resc <- false
|
||||
return
|
||||
}
|
||||
resc <- strsContains(addrs, metadataIP)
|
||||
}()
|
||||
|
||||
tryHarder := systemInfoSuggestsGCE()
|
||||
if tryHarder {
|
||||
res := <-resc
|
||||
if res {
|
||||
// The first strategy succeeded, so let's use it.
|
||||
return true
|
||||
}
|
||||
// Wait for either the DNS or metadata server probe to
|
||||
// contradict the other one and say we are running on
|
||||
// GCE. Give it a lot of time to do so, since the system
|
||||
// info already suggests we're running on a GCE BIOS.
|
||||
timer := time.NewTimer(5 * time.Second)
|
||||
defer timer.Stop()
|
||||
select {
|
||||
case res = <-resc:
|
||||
return res
|
||||
case <-timer.C:
|
||||
// Too slow. Who knows what this system is.
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// There's no hint from the system info that we're running on
|
||||
// GCE, so use the first probe's result as truth, whether it's
|
||||
// true or false. The goal here is to optimize for speed for
|
||||
// users who are NOT running on GCE. We can't assume that
|
||||
// either a DNS lookup or an HTTP request to a blackholed IP
|
||||
// address is fast. Worst case this should return when the
|
||||
// metaClient's Transport.ResponseHeaderTimeout or
|
||||
// Transport.Dial.Timeout fires (in two seconds).
|
||||
return <-resc
|
||||
}
|
||||
|
||||
// systemInfoSuggestsGCE reports whether the local system (without
|
||||
// doing network requests) suggests that we're running on GCE. If this
|
||||
// returns true, testOnGCE tries a bit harder to reach its metadata
|
||||
// server.
|
||||
func systemInfoSuggestsGCE() bool {
|
||||
if runtime.GOOS != "linux" {
|
||||
// We don't have any non-Linux clues available, at least yet.
|
||||
return false
|
||||
}
|
||||
slurp, _ := ioutil.ReadFile("/sys/class/dmi/id/product_name")
|
||||
name := strings.TrimSpace(string(slurp))
|
||||
return name == "Google" || name == "Google Compute Engine"
|
||||
}
|
||||
|
||||
// Subscribe calls Client.Subscribe on a client designed for subscribing (one with no
|
||||
// ResponseHeaderTimeout).
|
||||
func Subscribe(suffix string, fn func(v string, ok bool) error) error {
|
||||
return subscribeClient.Subscribe(suffix, fn)
|
||||
}
|
||||
|
||||
// Get calls Client.Get on the default client.
|
||||
func Get(suffix string) (string, error) { return defaultClient.Get(suffix) }
|
||||
|
||||
// ProjectID returns the current instance's project ID string.
|
||||
func ProjectID() (string, error) { return defaultClient.ProjectID() }
|
||||
|
||||
// NumericProjectID returns the current instance's numeric project ID.
|
||||
func NumericProjectID() (string, error) { return defaultClient.NumericProjectID() }
|
||||
|
||||
// InternalIP returns the instance's primary internal IP address.
|
||||
func InternalIP() (string, error) { return defaultClient.InternalIP() }
|
||||
|
||||
// ExternalIP returns the instance's primary external (public) IP address.
|
||||
func ExternalIP() (string, error) { return defaultClient.ExternalIP() }
|
||||
|
||||
// Hostname returns the instance's hostname. This will be of the form
|
||||
// "<instanceID>.c.<projID>.internal".
|
||||
func Hostname() (string, error) { return defaultClient.Hostname() }
|
||||
|
||||
// InstanceTags returns the list of user-defined instance tags,
|
||||
// assigned when initially creating a GCE instance.
|
||||
func InstanceTags() ([]string, error) { return defaultClient.InstanceTags() }
|
||||
|
||||
// InstanceID returns the current VM's numeric instance ID.
|
||||
func InstanceID() (string, error) { return defaultClient.InstanceID() }
|
||||
|
||||
// InstanceName returns the current VM's instance ID string.
|
||||
func InstanceName() (string, error) { return defaultClient.InstanceName() }
|
||||
|
||||
// Zone returns the current VM's zone, such as "us-central1-b".
|
||||
func Zone() (string, error) { return defaultClient.Zone() }
|
||||
|
||||
// InstanceAttributes calls Client.InstanceAttributes on the default client.
|
||||
func InstanceAttributes() ([]string, error) { return defaultClient.InstanceAttributes() }
|
||||
|
||||
// ProjectAttributes calls Client.ProjectAttributes on the default client.
|
||||
func ProjectAttributes() ([]string, error) { return defaultClient.ProjectAttributes() }
|
||||
|
||||
// InstanceAttributeValue calls Client.InstanceAttributeValue on the default client.
|
||||
func InstanceAttributeValue(attr string) (string, error) {
|
||||
return defaultClient.InstanceAttributeValue(attr)
|
||||
}
|
||||
|
||||
// ProjectAttributeValue calls Client.ProjectAttributeValue on the default client.
|
||||
func ProjectAttributeValue(attr string) (string, error) {
|
||||
return defaultClient.ProjectAttributeValue(attr)
|
||||
}
|
||||
|
||||
// Scopes calls Client.Scopes on the default client.
|
||||
func Scopes(serviceAccount string) ([]string, error) { return defaultClient.Scopes(serviceAccount) }
|
||||
|
||||
func strsContains(ss []string, s string) bool {
|
||||
for _, v := range ss {
|
||||
if v == s {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// A Client provides metadata.
|
||||
type Client struct {
|
||||
hc *http.Client
|
||||
}
|
||||
|
||||
// NewClient returns a Client that can be used to fetch metadata. All HTTP requests
|
||||
// will use the given http.Client instead of the default client.
|
||||
func NewClient(c *http.Client) *Client {
|
||||
return &Client{hc: c}
|
||||
}
|
||||
|
||||
// getETag returns a value from the metadata service as well as the associated ETag.
|
||||
// This func is otherwise equivalent to Get.
|
||||
func (c *Client) getETag(suffix string) (value, etag string, err error) {
|
||||
// Using a fixed IP makes it very difficult to spoof the metadata service in
|
||||
// a container, which is an important use-case for local testing of cloud
|
||||
// deployments. To enable spoofing of the metadata service, the environment
|
||||
// variable GCE_METADATA_HOST is first inspected to decide where metadata
|
||||
// requests shall go.
|
||||
host := os.Getenv(metadataHostEnv)
|
||||
if host == "" {
|
||||
// Using 169.254.169.254 instead of "metadata" here because Go
|
||||
// binaries built with the "netgo" tag and without cgo won't
|
||||
// know the search suffix for "metadata" is
|
||||
// ".google.internal", and this IP address is documented as
|
||||
// being stable anyway.
|
||||
host = metadataIP
|
||||
}
|
||||
u := "http://" + host + "/computeMetadata/v1/" + suffix
|
||||
req, _ := http.NewRequest("GET", u, nil)
|
||||
req.Header.Set("Metadata-Flavor", "Google")
|
||||
req.Header.Set("User-Agent", userAgent)
|
||||
res, err := c.hc.Do(req)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode == http.StatusNotFound {
|
||||
return "", "", NotDefinedError(suffix)
|
||||
}
|
||||
all, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
if res.StatusCode != 200 {
|
||||
return "", "", &Error{Code: res.StatusCode, Message: string(all)}
|
||||
}
|
||||
return string(all), res.Header.Get("Etag"), nil
|
||||
}
|
||||
|
||||
// Get returns a value from the metadata service.
|
||||
// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/".
|
||||
//
|
||||
// If the GCE_METADATA_HOST environment variable is not defined, a default of
|
||||
// 169.254.169.254 will be used instead.
|
||||
//
|
||||
// If the requested metadata is not defined, the returned error will
|
||||
// be of type NotDefinedError.
|
||||
func (c *Client) Get(suffix string) (string, error) {
|
||||
val, _, err := c.getETag(suffix)
|
||||
return val, err
|
||||
}
|
||||
|
||||
func (c *Client) getTrimmed(suffix string) (s string, err error) {
|
||||
s, err = c.Get(suffix)
|
||||
s = strings.TrimSpace(s)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Client) lines(suffix string) ([]string, error) {
|
||||
j, err := c.Get(suffix)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s := strings.Split(strings.TrimSpace(j), "\n")
|
||||
for i := range s {
|
||||
s[i] = strings.TrimSpace(s[i])
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// ProjectID returns the current instance's project ID string.
|
||||
func (c *Client) ProjectID() (string, error) { return projID.get(c) }
|
||||
|
||||
// NumericProjectID returns the current instance's numeric project ID.
|
||||
func (c *Client) NumericProjectID() (string, error) { return projNum.get(c) }
|
||||
|
||||
// InstanceID returns the current VM's numeric instance ID.
|
||||
func (c *Client) InstanceID() (string, error) { return instID.get(c) }
|
||||
|
||||
// InternalIP returns the instance's primary internal IP address.
|
||||
func (c *Client) InternalIP() (string, error) {
|
||||
return c.getTrimmed("instance/network-interfaces/0/ip")
|
||||
}
|
||||
|
||||
// ExternalIP returns the instance's primary external (public) IP address.
|
||||
func (c *Client) ExternalIP() (string, error) {
|
||||
return c.getTrimmed("instance/network-interfaces/0/access-configs/0/external-ip")
|
||||
}
|
||||
|
||||
// Hostname returns the instance's hostname. This will be of the form
|
||||
// "<instanceID>.c.<projID>.internal".
|
||||
func (c *Client) Hostname() (string, error) {
|
||||
return c.getTrimmed("instance/hostname")
|
||||
}
|
||||
|
||||
// InstanceTags returns the list of user-defined instance tags,
|
||||
// assigned when initially creating a GCE instance.
|
||||
func (c *Client) InstanceTags() ([]string, error) {
|
||||
var s []string
|
||||
j, err := c.Get("instance/tags")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := json.NewDecoder(strings.NewReader(j)).Decode(&s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// InstanceName returns the current VM's instance ID string.
|
||||
func (c *Client) InstanceName() (string, error) {
|
||||
host, err := c.Hostname()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return strings.Split(host, ".")[0], nil
|
||||
}
|
||||
|
||||
// Zone returns the current VM's zone, such as "us-central1-b".
|
||||
func (c *Client) Zone() (string, error) {
|
||||
zone, err := c.getTrimmed("instance/zone")
|
||||
// zone is of the form "projects/<projNum>/zones/<zoneName>".
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return zone[strings.LastIndex(zone, "/")+1:], nil
|
||||
}
|
||||
|
||||
// InstanceAttributes returns the list of user-defined attributes,
|
||||
// assigned when initially creating a GCE VM instance. The value of an
|
||||
// attribute can be obtained with InstanceAttributeValue.
|
||||
func (c *Client) InstanceAttributes() ([]string, error) { return c.lines("instance/attributes/") }
|
||||
|
||||
// ProjectAttributes returns the list of user-defined attributes
|
||||
// applying to the project as a whole, not just this VM. The value of
|
||||
// an attribute can be obtained with ProjectAttributeValue.
|
||||
func (c *Client) ProjectAttributes() ([]string, error) { return c.lines("project/attributes/") }
|
||||
|
||||
// InstanceAttributeValue returns the value of the provided VM
|
||||
// instance attribute.
|
||||
//
|
||||
// If the requested attribute is not defined, the returned error will
|
||||
// be of type NotDefinedError.
|
||||
//
|
||||
// InstanceAttributeValue may return ("", nil) if the attribute was
|
||||
// defined to be the empty string.
|
||||
func (c *Client) InstanceAttributeValue(attr string) (string, error) {
|
||||
return c.Get("instance/attributes/" + attr)
|
||||
}
|
||||
|
||||
// ProjectAttributeValue returns the value of the provided
|
||||
// project attribute.
|
||||
//
|
||||
// If the requested attribute is not defined, the returned error will
|
||||
// be of type NotDefinedError.
|
||||
//
|
||||
// ProjectAttributeValue may return ("", nil) if the attribute was
|
||||
// defined to be the empty string.
|
||||
func (c *Client) ProjectAttributeValue(attr string) (string, error) {
|
||||
return c.Get("project/attributes/" + attr)
|
||||
}
|
||||
|
||||
// Scopes returns the service account scopes for the given account.
|
||||
// The account may be empty or the string "default" to use the instance's
|
||||
// main account.
|
||||
func (c *Client) Scopes(serviceAccount string) ([]string, error) {
|
||||
if serviceAccount == "" {
|
||||
serviceAccount = "default"
|
||||
}
|
||||
return c.lines("instance/service-accounts/" + serviceAccount + "/scopes")
|
||||
}
|
||||
|
||||
// Subscribe subscribes to a value from the metadata service.
|
||||
// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/".
|
||||
// The suffix may contain query parameters.
|
||||
//
|
||||
// Subscribe calls fn with the latest metadata value indicated by the provided
|
||||
// suffix. If the metadata value is deleted, fn is called with the empty string
|
||||
// and ok false. Subscribe blocks until fn returns a non-nil error or the value
|
||||
// is deleted. Subscribe returns the error value returned from the last call to
|
||||
// fn, which may be nil when ok == false.
|
||||
func (c *Client) Subscribe(suffix string, fn func(v string, ok bool) error) error {
|
||||
const failedSubscribeSleep = time.Second * 5
|
||||
|
||||
// First check to see if the metadata value exists at all.
|
||||
val, lastETag, err := c.getETag(suffix)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := fn(val, true); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ok := true
|
||||
if strings.ContainsRune(suffix, '?') {
|
||||
suffix += "&wait_for_change=true&last_etag="
|
||||
} else {
|
||||
suffix += "?wait_for_change=true&last_etag="
|
||||
}
|
||||
for {
|
||||
val, etag, err := c.getETag(suffix + url.QueryEscape(lastETag))
|
||||
if err != nil {
|
||||
if _, deleted := err.(NotDefinedError); !deleted {
|
||||
time.Sleep(failedSubscribeSleep)
|
||||
continue // Retry on other errors.
|
||||
}
|
||||
ok = false
|
||||
}
|
||||
lastETag = etag
|
||||
|
||||
if err := fn(val, ok); err != nil || !ok {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Error contains an error response from the server.
|
||||
type Error struct {
|
||||
// Code is the HTTP response status code.
|
||||
Code int
|
||||
// Message is the server response message.
|
||||
Message string
|
||||
}
|
||||
|
||||
func (e *Error) Error() string {
|
||||
return fmt.Sprintf("compute: Received %d `%s`", e.Code, e.Message)
|
||||
}
|
201
vendor/code.cloudfoundry.org/bytefmt/LICENSE
generated
vendored
201
vendor/code.cloudfoundry.org/bytefmt/LICENSE
generated
vendored
@ -1,201 +0,0 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://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
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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
|
||||
|
||||
http://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.
|
20
vendor/code.cloudfoundry.org/bytefmt/NOTICE
generated
vendored
20
vendor/code.cloudfoundry.org/bytefmt/NOTICE
generated
vendored
@ -1,20 +0,0 @@
|
||||
Copyright (c) 2015-Present CloudFoundry.org Foundation, Inc. All Rights Reserved.
|
||||
|
||||
This project contains software that is Copyright (c) 2013-2015 Pivotal Software, Inc.
|
||||
|
||||
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
|
||||
|
||||
http://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.
|
||||
|
||||
This project may include a number of subcomponents with separate
|
||||
copyright notices and license terms. Your use of these subcomponents
|
||||
is subject to the terms and conditions of each subcomponent's license,
|
||||
as noted in the LICENSE file.
|
15
vendor/code.cloudfoundry.org/bytefmt/README.md
generated
vendored
15
vendor/code.cloudfoundry.org/bytefmt/README.md
generated
vendored
@ -1,15 +0,0 @@
|
||||
bytefmt
|
||||
=======
|
||||
|
||||
**Note**: This repository should be imported as `code.cloudfoundry.org/bytefmt`.
|
||||
|
||||
Human-readable byte formatter.
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
bytefmt.ByteSize(100.5*bytefmt.MEGABYTE) // returns "100.5M"
|
||||
bytefmt.ByteSize(uint64(1024)) // returns "1K"
|
||||
```
|
||||
|
||||
For documentation, please see http://godoc.org/code.cloudfoundry.org/bytefmt
|
121
vendor/code.cloudfoundry.org/bytefmt/bytes.go
generated
vendored
121
vendor/code.cloudfoundry.org/bytefmt/bytes.go
generated
vendored
@ -1,121 +0,0 @@
|
||||
// Package bytefmt contains helper methods and constants for converting to and from a human-readable byte format.
|
||||
//
|
||||
// bytefmt.ByteSize(100.5*bytefmt.MEGABYTE) // "100.5M"
|
||||
// bytefmt.ByteSize(uint64(1024)) // "1K"
|
||||
//
|
||||
package bytefmt
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
const (
|
||||
BYTE = 1 << (10 * iota)
|
||||
KILOBYTE
|
||||
MEGABYTE
|
||||
GIGABYTE
|
||||
TERABYTE
|
||||
PETABYTE
|
||||
EXABYTE
|
||||
)
|
||||
|
||||
var invalidByteQuantityError = errors.New("byte quantity must be a positive integer with a unit of measurement like M, MB, MiB, G, GiB, or GB")
|
||||
|
||||
// ByteSize returns a human-readable byte string of the form 10M, 12.5K, and so forth. The following units are available:
|
||||
// E: Exabyte
|
||||
// P: Petabyte
|
||||
// T: Terabyte
|
||||
// G: Gigabyte
|
||||
// M: Megabyte
|
||||
// K: Kilobyte
|
||||
// B: Byte
|
||||
// The unit that results in the smallest number greater than or equal to 1 is always chosen.
|
||||
func ByteSize(bytes uint64) string {
|
||||
unit := ""
|
||||
value := float64(bytes)
|
||||
|
||||
switch {
|
||||
case bytes >= EXABYTE:
|
||||
unit = "E"
|
||||
value = value / EXABYTE
|
||||
case bytes >= PETABYTE:
|
||||
unit = "P"
|
||||
value = value / PETABYTE
|
||||
case bytes >= TERABYTE:
|
||||
unit = "T"
|
||||
value = value / TERABYTE
|
||||
case bytes >= GIGABYTE:
|
||||
unit = "G"
|
||||
value = value / GIGABYTE
|
||||
case bytes >= MEGABYTE:
|
||||
unit = "M"
|
||||
value = value / MEGABYTE
|
||||
case bytes >= KILOBYTE:
|
||||
unit = "K"
|
||||
value = value / KILOBYTE
|
||||
case bytes >= BYTE:
|
||||
unit = "B"
|
||||
case bytes == 0:
|
||||
return "0B"
|
||||
}
|
||||
|
||||
result := strconv.FormatFloat(value, 'f', 1, 64)
|
||||
result = strings.TrimSuffix(result, ".0")
|
||||
return result + unit
|
||||
}
|
||||
|
||||
// ToMegabytes parses a string formatted by ByteSize as megabytes.
|
||||
func ToMegabytes(s string) (uint64, error) {
|
||||
bytes, err := ToBytes(s)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return bytes / MEGABYTE, nil
|
||||
}
|
||||
|
||||
// ToBytes parses a string formatted by ByteSize as bytes. Note binary-prefixed and SI prefixed units both mean a base-2 units
|
||||
// KB = K = KiB = 1024
|
||||
// MB = M = MiB = 1024 * K
|
||||
// GB = G = GiB = 1024 * M
|
||||
// TB = T = TiB = 1024 * G
|
||||
// PB = P = PiB = 1024 * T
|
||||
// EB = E = EiB = 1024 * P
|
||||
func ToBytes(s string) (uint64, error) {
|
||||
s = strings.TrimSpace(s)
|
||||
s = strings.ToUpper(s)
|
||||
|
||||
i := strings.IndexFunc(s, unicode.IsLetter)
|
||||
|
||||
if i == -1 {
|
||||
return 0, invalidByteQuantityError
|
||||
}
|
||||
|
||||
bytesString, multiple := s[:i], s[i:]
|
||||
bytes, err := strconv.ParseFloat(bytesString, 64)
|
||||
if err != nil || bytes < 0 {
|
||||
return 0, invalidByteQuantityError
|
||||
}
|
||||
|
||||
switch multiple {
|
||||
case "E", "EB", "EIB":
|
||||
return uint64(bytes * EXABYTE), nil
|
||||
case "P", "PB", "PIB":
|
||||
return uint64(bytes * PETABYTE), nil
|
||||
case "T", "TB", "TIB":
|
||||
return uint64(bytes * TERABYTE), nil
|
||||
case "G", "GB", "GIB":
|
||||
return uint64(bytes * GIGABYTE), nil
|
||||
case "M", "MB", "MIB":
|
||||
return uint64(bytes * MEGABYTE), nil
|
||||
case "K", "KB", "KIB":
|
||||
return uint64(bytes * KILOBYTE), nil
|
||||
case "B":
|
||||
return uint64(bytes), nil
|
||||
default:
|
||||
return 0, invalidByteQuantityError
|
||||
}
|
||||
}
|
1
vendor/code.cloudfoundry.org/bytefmt/package.go
generated
vendored
1
vendor/code.cloudfoundry.org/bytefmt/package.go
generated
vendored
@ -1 +0,0 @@
|
||||
package bytefmt // import "code.cloudfoundry.org/bytefmt"
|
191
vendor/github.com/Azure/go-autorest/LICENSE
generated
vendored
191
vendor/github.com/Azure/go-autorest/LICENSE
generated
vendored
@ -1,191 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://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 Microsoft Corporation
|
||||
|
||||
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
|
||||
|
||||
http://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.
|
292
vendor/github.com/Azure/go-autorest/autorest/adal/README.md
generated
vendored
292
vendor/github.com/Azure/go-autorest/autorest/adal/README.md
generated
vendored
@ -1,292 +0,0 @@
|
||||
# Azure Active Directory authentication for Go
|
||||
|
||||
This is a standalone package for authenticating with Azure Active
|
||||
Directory from other Go libraries and applications, in particular the [Azure SDK
|
||||
for Go](https://github.com/Azure/azure-sdk-for-go).
|
||||
|
||||
Note: Despite the package's name it is not related to other "ADAL" libraries
|
||||
maintained in the [github.com/AzureAD](https://github.com/AzureAD) org. Issues
|
||||
should be opened in [this repo's](https://github.com/Azure/go-autorest/issues)
|
||||
or [the SDK's](https://github.com/Azure/azure-sdk-for-go/issues) issue
|
||||
trackers.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
go get -u github.com/Azure/go-autorest/autorest/adal
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
An Active Directory application is required in order to use this library. An application can be registered in the [Azure Portal](https://portal.azure.com/) by following these [guidelines](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-integrating-applications) or using the [Azure CLI](https://github.com/Azure/azure-cli).
|
||||
|
||||
### Register an Azure AD Application with secret
|
||||
|
||||
|
||||
1. Register a new application with a `secret` credential
|
||||
|
||||
```
|
||||
az ad app create \
|
||||
--display-name example-app \
|
||||
--homepage https://example-app/home \
|
||||
--identifier-uris https://example-app/app \
|
||||
--password secret
|
||||
```
|
||||
|
||||
2. Create a service principal using the `Application ID` from previous step
|
||||
|
||||
```
|
||||
az ad sp create --id "Application ID"
|
||||
```
|
||||
|
||||
* Replace `Application ID` with `appId` from step 1.
|
||||
|
||||
### Register an Azure AD Application with certificate
|
||||
|
||||
1. Create a private key
|
||||
|
||||
```
|
||||
openssl genrsa -out "example-app.key" 2048
|
||||
```
|
||||
|
||||
2. Create the certificate
|
||||
|
||||
```
|
||||
openssl req -new -key "example-app.key" -subj "/CN=example-app" -out "example-app.csr"
|
||||
openssl x509 -req -in "example-app.csr" -signkey "example-app.key" -out "example-app.crt" -days 10000
|
||||
```
|
||||
|
||||
3. Create the PKCS12 version of the certificate containing also the private key
|
||||
|
||||
```
|
||||
openssl pkcs12 -export -out "example-app.pfx" -inkey "example-app.key" -in "example-app.crt" -passout pass:
|
||||
|
||||
```
|
||||
|
||||
4. Register a new application with the certificate content form `example-app.crt`
|
||||
|
||||
```
|
||||
certificateContents="$(tail -n+2 "example-app.crt" | head -n-1)"
|
||||
|
||||
az ad app create \
|
||||
--display-name example-app \
|
||||
--homepage https://example-app/home \
|
||||
--identifier-uris https://example-app/app \
|
||||
--key-usage Verify --end-date 2018-01-01 \
|
||||
--key-value "${certificateContents}"
|
||||
```
|
||||
|
||||
5. Create a service principal using the `Application ID` from previous step
|
||||
|
||||
```
|
||||
az ad sp create --id "APPLICATION_ID"
|
||||
```
|
||||
|
||||
* Replace `APPLICATION_ID` with `appId` from step 4.
|
||||
|
||||
|
||||
### Grant the necessary permissions
|
||||
|
||||
Azure relies on a Role-Based Access Control (RBAC) model to manage the access to resources at a fine-grained
|
||||
level. There is a set of [pre-defined roles](https://docs.microsoft.com/en-us/azure/active-directory/role-based-access-built-in-roles)
|
||||
which can be assigned to a service principal of an Azure AD application depending of your needs.
|
||||
|
||||
```
|
||||
az role assignment create --assigner "SERVICE_PRINCIPAL_ID" --role "ROLE_NAME"
|
||||
```
|
||||
|
||||
* Replace the `SERVICE_PRINCIPAL_ID` with the `appId` from previous step.
|
||||
* Replace the `ROLE_NAME` with a role name of your choice.
|
||||
|
||||
It is also possible to define custom role definitions.
|
||||
|
||||
```
|
||||
az role definition create --role-definition role-definition.json
|
||||
```
|
||||
|
||||
* Check [custom roles](https://docs.microsoft.com/en-us/azure/active-directory/role-based-access-control-custom-roles) for more details regarding the content of `role-definition.json` file.
|
||||
|
||||
|
||||
### Acquire Access Token
|
||||
|
||||
The common configuration used by all flows:
|
||||
|
||||
```Go
|
||||
const activeDirectoryEndpoint = "https://login.microsoftonline.com/"
|
||||
tenantID := "TENANT_ID"
|
||||
oauthConfig, err := adal.NewOAuthConfig(activeDirectoryEndpoint, tenantID)
|
||||
|
||||
applicationID := "APPLICATION_ID"
|
||||
|
||||
callback := func(token adal.Token) error {
|
||||
// This is called after the token is acquired
|
||||
}
|
||||
|
||||
// The resource for which the token is acquired
|
||||
resource := "https://management.core.windows.net/"
|
||||
```
|
||||
|
||||
* Replace the `TENANT_ID` with your tenant ID.
|
||||
* Replace the `APPLICATION_ID` with the value from previous section.
|
||||
|
||||
#### Client Credentials
|
||||
|
||||
```Go
|
||||
applicationSecret := "APPLICATION_SECRET"
|
||||
|
||||
spt, err := adal.NewServicePrincipalToken(
|
||||
oauthConfig,
|
||||
appliationID,
|
||||
applicationSecret,
|
||||
resource,
|
||||
callbacks...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Acquire a new access token
|
||||
err = spt.Refresh()
|
||||
if (err == nil) {
|
||||
token := spt.Token
|
||||
}
|
||||
```
|
||||
|
||||
* Replace the `APPLICATION_SECRET` with the `password` value from previous section.
|
||||
|
||||
#### Client Certificate
|
||||
|
||||
```Go
|
||||
certificatePath := "./example-app.pfx"
|
||||
|
||||
certData, err := ioutil.ReadFile(certificatePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read the certificate file (%s): %v", certificatePath, err)
|
||||
}
|
||||
|
||||
// Get the certificate and private key from pfx file
|
||||
certificate, rsaPrivateKey, err := decodePkcs12(certData, "")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decode pkcs12 certificate while creating spt: %v", err)
|
||||
}
|
||||
|
||||
spt, err := adal.NewServicePrincipalTokenFromCertificate(
|
||||
oauthConfig,
|
||||
applicationID,
|
||||
certificate,
|
||||
rsaPrivateKey,
|
||||
resource,
|
||||
callbacks...)
|
||||
|
||||
// Acquire a new access token
|
||||
err = spt.Refresh()
|
||||
if (err == nil) {
|
||||
token := spt.Token
|
||||
}
|
||||
```
|
||||
|
||||
* Update the certificate path to point to the example-app.pfx file which was created in previous section.
|
||||
|
||||
|
||||
#### Device Code
|
||||
|
||||
```Go
|
||||
oauthClient := &http.Client{}
|
||||
|
||||
// Acquire the device code
|
||||
deviceCode, err := adal.InitiateDeviceAuth(
|
||||
oauthClient,
|
||||
oauthConfig,
|
||||
applicationID,
|
||||
resource)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to start device auth flow: %s", err)
|
||||
}
|
||||
|
||||
// Display the authentication message
|
||||
fmt.Println(*deviceCode.Message)
|
||||
|
||||
// Wait here until the user is authenticated
|
||||
token, err := adal.WaitForUserCompletion(oauthClient, deviceCode)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to finish device auth flow: %s", err)
|
||||
}
|
||||
|
||||
spt, err := adal.NewServicePrincipalTokenFromManualToken(
|
||||
oauthConfig,
|
||||
applicationID,
|
||||
resource,
|
||||
*token,
|
||||
callbacks...)
|
||||
|
||||
if (err == nil) {
|
||||
token := spt.Token
|
||||
}
|
||||
```
|
||||
|
||||
#### Username password authenticate
|
||||
|
||||
```Go
|
||||
spt, err := adal.NewServicePrincipalTokenFromUsernamePassword(
|
||||
oauthConfig,
|
||||
applicationID,
|
||||
username,
|
||||
password,
|
||||
resource,
|
||||
callbacks...)
|
||||
|
||||
if (err == nil) {
|
||||
token := spt.Token
|
||||
}
|
||||
```
|
||||
|
||||
#### Authorization code authenticate
|
||||
|
||||
``` Go
|
||||
spt, err := adal.NewServicePrincipalTokenFromAuthorizationCode(
|
||||
oauthConfig,
|
||||
applicationID,
|
||||
clientSecret,
|
||||
authorizationCode,
|
||||
redirectURI,
|
||||
resource,
|
||||
callbacks...)
|
||||
|
||||
err = spt.Refresh()
|
||||
if (err == nil) {
|
||||
token := spt.Token
|
||||
}
|
||||
```
|
||||
|
||||
### Command Line Tool
|
||||
|
||||
A command line tool is available in `cmd/adal.go` that can acquire a token for a given resource. It supports all flows mentioned above.
|
||||
|
||||
```
|
||||
adal -h
|
||||
|
||||
Usage of ./adal:
|
||||
-applicationId string
|
||||
application id
|
||||
-certificatePath string
|
||||
path to pk12/PFC application certificate
|
||||
-mode string
|
||||
authentication mode (device, secret, cert, refresh) (default "device")
|
||||
-resource string
|
||||
resource for which the token is requested
|
||||
-secret string
|
||||
application secret
|
||||
-tenantId string
|
||||
tenant id
|
||||
-tokenCachePath string
|
||||
location of oath token cache (default "/home/cgc/.adal/accessToken.json")
|
||||
```
|
||||
|
||||
Example acquire a token for `https://management.core.windows.net/` using device code flow:
|
||||
|
||||
```
|
||||
adal -mode device \
|
||||
-applicationId "APPLICATION_ID" \
|
||||
-tenantId "TENANT_ID" \
|
||||
-resource https://management.core.windows.net/
|
||||
|
||||
```
|
91
vendor/github.com/Azure/go-autorest/autorest/adal/config.go
generated
vendored
91
vendor/github.com/Azure/go-autorest/autorest/adal/config.go
generated
vendored
@ -1,91 +0,0 @@
|
||||
package adal
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// OAuthConfig represents the endpoints needed
|
||||
// in OAuth operations
|
||||
type OAuthConfig struct {
|
||||
AuthorityEndpoint url.URL `json:"authorityEndpoint"`
|
||||
AuthorizeEndpoint url.URL `json:"authorizeEndpoint"`
|
||||
TokenEndpoint url.URL `json:"tokenEndpoint"`
|
||||
DeviceCodeEndpoint url.URL `json:"deviceCodeEndpoint"`
|
||||
}
|
||||
|
||||
// IsZero returns true if the OAuthConfig object is zero-initialized.
|
||||
func (oac OAuthConfig) IsZero() bool {
|
||||
return oac == OAuthConfig{}
|
||||
}
|
||||
|
||||
func validateStringParam(param, name string) error {
|
||||
if len(param) == 0 {
|
||||
return fmt.Errorf("parameter '" + name + "' cannot be empty")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewOAuthConfig returns an OAuthConfig with tenant specific urls
|
||||
func NewOAuthConfig(activeDirectoryEndpoint, tenantID string) (*OAuthConfig, error) {
|
||||
apiVer := "1.0"
|
||||
return NewOAuthConfigWithAPIVersion(activeDirectoryEndpoint, tenantID, &apiVer)
|
||||
}
|
||||
|
||||
// NewOAuthConfigWithAPIVersion returns an OAuthConfig with tenant specific urls.
|
||||
// If apiVersion is not nil the "api-version" query parameter will be appended to the endpoint URLs with the specified value.
|
||||
func NewOAuthConfigWithAPIVersion(activeDirectoryEndpoint, tenantID string, apiVersion *string) (*OAuthConfig, error) {
|
||||
if err := validateStringParam(activeDirectoryEndpoint, "activeDirectoryEndpoint"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
api := ""
|
||||
// it's legal for tenantID to be empty so don't validate it
|
||||
if apiVersion != nil {
|
||||
if err := validateStringParam(*apiVersion, "apiVersion"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
api = fmt.Sprintf("?api-version=%s", *apiVersion)
|
||||
}
|
||||
const activeDirectoryEndpointTemplate = "%s/oauth2/%s%s"
|
||||
u, err := url.Parse(activeDirectoryEndpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
authorityURL, err := u.Parse(tenantID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
authorizeURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "authorize", api))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tokenURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "token", api))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
deviceCodeURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "devicecode", api))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &OAuthConfig{
|
||||
AuthorityEndpoint: *authorityURL,
|
||||
AuthorizeEndpoint: *authorizeURL,
|
||||
TokenEndpoint: *tokenURL,
|
||||
DeviceCodeEndpoint: *deviceCodeURL,
|
||||
}, nil
|
||||
}
|
242
vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go
generated
vendored
242
vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go
generated
vendored
@ -1,242 +0,0 @@
|
||||
package adal
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
/*
|
||||
This file is largely based on rjw57/oauth2device's code, with the follow differences:
|
||||
* scope -> resource, and only allow a single one
|
||||
* receive "Message" in the DeviceCode struct and show it to users as the prompt
|
||||
* azure-xplat-cli has the following behavior that this emulates:
|
||||
- does not send client_secret during the token exchange
|
||||
- sends resource again in the token exchange request
|
||||
*/
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
logPrefix = "autorest/adal/devicetoken:"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrDeviceGeneric represents an unknown error from the token endpoint when using device flow
|
||||
ErrDeviceGeneric = fmt.Errorf("%s Error while retrieving OAuth token: Unknown Error", logPrefix)
|
||||
|
||||
// ErrDeviceAccessDenied represents an access denied error from the token endpoint when using device flow
|
||||
ErrDeviceAccessDenied = fmt.Errorf("%s Error while retrieving OAuth token: Access Denied", logPrefix)
|
||||
|
||||
// ErrDeviceAuthorizationPending represents the server waiting on the user to complete the device flow
|
||||
ErrDeviceAuthorizationPending = fmt.Errorf("%s Error while retrieving OAuth token: Authorization Pending", logPrefix)
|
||||
|
||||
// ErrDeviceCodeExpired represents the server timing out and expiring the code during device flow
|
||||
ErrDeviceCodeExpired = fmt.Errorf("%s Error while retrieving OAuth token: Code Expired", logPrefix)
|
||||
|
||||
// ErrDeviceSlowDown represents the service telling us we're polling too often during device flow
|
||||
ErrDeviceSlowDown = fmt.Errorf("%s Error while retrieving OAuth token: Slow Down", logPrefix)
|
||||
|
||||
// ErrDeviceCodeEmpty represents an empty device code from the device endpoint while using device flow
|
||||
ErrDeviceCodeEmpty = fmt.Errorf("%s Error while retrieving device code: Device Code Empty", logPrefix)
|
||||
|
||||
// ErrOAuthTokenEmpty represents an empty OAuth token from the token endpoint when using device flow
|
||||
ErrOAuthTokenEmpty = fmt.Errorf("%s Error while retrieving OAuth token: Token Empty", logPrefix)
|
||||
|
||||
errCodeSendingFails = "Error occurred while sending request for Device Authorization Code"
|
||||
errCodeHandlingFails = "Error occurred while handling response from the Device Endpoint"
|
||||
errTokenSendingFails = "Error occurred while sending request with device code for a token"
|
||||
errTokenHandlingFails = "Error occurred while handling response from the Token Endpoint (during device flow)"
|
||||
errStatusNotOK = "Error HTTP status != 200"
|
||||
)
|
||||
|
||||
// DeviceCode is the object returned by the device auth endpoint
|
||||
// It contains information to instruct the user to complete the auth flow
|
||||
type DeviceCode struct {
|
||||
DeviceCode *string `json:"device_code,omitempty"`
|
||||
UserCode *string `json:"user_code,omitempty"`
|
||||
VerificationURL *string `json:"verification_url,omitempty"`
|
||||
ExpiresIn *int64 `json:"expires_in,string,omitempty"`
|
||||
Interval *int64 `json:"interval,string,omitempty"`
|
||||
|
||||
Message *string `json:"message"` // Azure specific
|
||||
Resource string // store the following, stored when initiating, used when exchanging
|
||||
OAuthConfig OAuthConfig
|
||||
ClientID string
|
||||
}
|
||||
|
||||
// TokenError is the object returned by the token exchange endpoint
|
||||
// when something is amiss
|
||||
type TokenError struct {
|
||||
Error *string `json:"error,omitempty"`
|
||||
ErrorCodes []int `json:"error_codes,omitempty"`
|
||||
ErrorDescription *string `json:"error_description,omitempty"`
|
||||
Timestamp *string `json:"timestamp,omitempty"`
|
||||
TraceID *string `json:"trace_id,omitempty"`
|
||||
}
|
||||
|
||||
// DeviceToken is the object return by the token exchange endpoint
|
||||
// It can either look like a Token or an ErrorToken, so put both here
|
||||
// and check for presence of "Error" to know if we are in error state
|
||||
type deviceToken struct {
|
||||
Token
|
||||
TokenError
|
||||
}
|
||||
|
||||
// InitiateDeviceAuth initiates a device auth flow. It returns a DeviceCode
|
||||
// that can be used with CheckForUserCompletion or WaitForUserCompletion.
|
||||
func InitiateDeviceAuth(sender Sender, oauthConfig OAuthConfig, clientID, resource string) (*DeviceCode, error) {
|
||||
v := url.Values{
|
||||
"client_id": []string{clientID},
|
||||
"resource": []string{resource},
|
||||
}
|
||||
|
||||
s := v.Encode()
|
||||
body := ioutil.NopCloser(strings.NewReader(s))
|
||||
|
||||
req, err := http.NewRequest(http.MethodPost, oauthConfig.DeviceCodeEndpoint.String(), body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeSendingFails, err.Error())
|
||||
}
|
||||
|
||||
req.ContentLength = int64(len(s))
|
||||
req.Header.Set(contentType, mimeTypeFormPost)
|
||||
resp, err := sender.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeSendingFails, err.Error())
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
rb, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeHandlingFails, err.Error())
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeHandlingFails, errStatusNotOK)
|
||||
}
|
||||
|
||||
if len(strings.Trim(string(rb), " ")) == 0 {
|
||||
return nil, ErrDeviceCodeEmpty
|
||||
}
|
||||
|
||||
var code DeviceCode
|
||||
err = json.Unmarshal(rb, &code)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeHandlingFails, err.Error())
|
||||
}
|
||||
|
||||
code.ClientID = clientID
|
||||
code.Resource = resource
|
||||
code.OAuthConfig = oauthConfig
|
||||
|
||||
return &code, nil
|
||||
}
|
||||
|
||||
// CheckForUserCompletion takes a DeviceCode and checks with the Azure AD OAuth endpoint
|
||||
// to see if the device flow has: been completed, timed out, or otherwise failed
|
||||
func CheckForUserCompletion(sender Sender, code *DeviceCode) (*Token, error) {
|
||||
v := url.Values{
|
||||
"client_id": []string{code.ClientID},
|
||||
"code": []string{*code.DeviceCode},
|
||||
"grant_type": []string{OAuthGrantTypeDeviceCode},
|
||||
"resource": []string{code.Resource},
|
||||
}
|
||||
|
||||
s := v.Encode()
|
||||
body := ioutil.NopCloser(strings.NewReader(s))
|
||||
|
||||
req, err := http.NewRequest(http.MethodPost, code.OAuthConfig.TokenEndpoint.String(), body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenSendingFails, err.Error())
|
||||
}
|
||||
|
||||
req.ContentLength = int64(len(s))
|
||||
req.Header.Set(contentType, mimeTypeFormPost)
|
||||
resp, err := sender.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenSendingFails, err.Error())
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
rb, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenHandlingFails, err.Error())
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK && len(strings.Trim(string(rb), " ")) == 0 {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenHandlingFails, errStatusNotOK)
|
||||
}
|
||||
if len(strings.Trim(string(rb), " ")) == 0 {
|
||||
return nil, ErrOAuthTokenEmpty
|
||||
}
|
||||
|
||||
var token deviceToken
|
||||
err = json.Unmarshal(rb, &token)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenHandlingFails, err.Error())
|
||||
}
|
||||
|
||||
if token.Error == nil {
|
||||
return &token.Token, nil
|
||||
}
|
||||
|
||||
switch *token.Error {
|
||||
case "authorization_pending":
|
||||
return nil, ErrDeviceAuthorizationPending
|
||||
case "slow_down":
|
||||
return nil, ErrDeviceSlowDown
|
||||
case "access_denied":
|
||||
return nil, ErrDeviceAccessDenied
|
||||
case "code_expired":
|
||||
return nil, ErrDeviceCodeExpired
|
||||
default:
|
||||
return nil, ErrDeviceGeneric
|
||||
}
|
||||
}
|
||||
|
||||
// WaitForUserCompletion calls CheckForUserCompletion repeatedly until a token is granted or an error state occurs.
|
||||
// This prevents the user from looping and checking against 'ErrDeviceAuthorizationPending'.
|
||||
func WaitForUserCompletion(sender Sender, code *DeviceCode) (*Token, error) {
|
||||
intervalDuration := time.Duration(*code.Interval) * time.Second
|
||||
waitDuration := intervalDuration
|
||||
|
||||
for {
|
||||
token, err := CheckForUserCompletion(sender, code)
|
||||
|
||||
if err == nil {
|
||||
return token, nil
|
||||
}
|
||||
|
||||
switch err {
|
||||
case ErrDeviceSlowDown:
|
||||
waitDuration += waitDuration
|
||||
case ErrDeviceAuthorizationPending:
|
||||
// noop
|
||||
default: // everything else is "fatal" to us
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if waitDuration > (intervalDuration * 3) {
|
||||
return nil, fmt.Errorf("%s Error waiting for user to complete device flow. Server told us to slow_down too much", logPrefix)
|
||||
}
|
||||
|
||||
time.Sleep(waitDuration)
|
||||
}
|
||||
}
|
73
vendor/github.com/Azure/go-autorest/autorest/adal/persist.go
generated
vendored
73
vendor/github.com/Azure/go-autorest/autorest/adal/persist.go
generated
vendored
@ -1,73 +0,0 @@
|
||||
package adal
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// LoadToken restores a Token object from a file located at 'path'.
|
||||
func LoadToken(path string) (*Token, error) {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open file (%s) while loading token: %v", path, err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var token Token
|
||||
|
||||
dec := json.NewDecoder(file)
|
||||
if err = dec.Decode(&token); err != nil {
|
||||
return nil, fmt.Errorf("failed to decode contents of file (%s) into Token representation: %v", path, err)
|
||||
}
|
||||
return &token, nil
|
||||
}
|
||||
|
||||
// SaveToken persists an oauth token at the given location on disk.
|
||||
// It moves the new file into place so it can safely be used to replace an existing file
|
||||
// that maybe accessed by multiple processes.
|
||||
func SaveToken(path string, mode os.FileMode, token Token) error {
|
||||
dir := filepath.Dir(path)
|
||||
err := os.MkdirAll(dir, os.ModePerm)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create directory (%s) to store token in: %v", dir, err)
|
||||
}
|
||||
|
||||
newFile, err := ioutil.TempFile(dir, "token")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create the temp file to write the token: %v", err)
|
||||
}
|
||||
tempPath := newFile.Name()
|
||||
|
||||
if err := json.NewEncoder(newFile).Encode(token); err != nil {
|
||||
return fmt.Errorf("failed to encode token to file (%s) while saving token: %v", tempPath, err)
|
||||
}
|
||||
if err := newFile.Close(); err != nil {
|
||||
return fmt.Errorf("failed to close temp file %s: %v", tempPath, err)
|
||||
}
|
||||
|
||||
// Atomic replace to avoid multi-writer file corruptions
|
||||
if err := os.Rename(tempPath, path); err != nil {
|
||||
return fmt.Errorf("failed to move temporary token to desired output location. src=%s dst=%s: %v", tempPath, path, err)
|
||||
}
|
||||
if err := os.Chmod(path, mode); err != nil {
|
||||
return fmt.Errorf("failed to chmod the token file %s: %v", path, err)
|
||||
}
|
||||
return nil
|
||||
}
|
60
vendor/github.com/Azure/go-autorest/autorest/adal/sender.go
generated
vendored
60
vendor/github.com/Azure/go-autorest/autorest/adal/sender.go
generated
vendored
@ -1,60 +0,0 @@
|
||||
package adal
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const (
|
||||
contentType = "Content-Type"
|
||||
mimeTypeFormPost = "application/x-www-form-urlencoded"
|
||||
)
|
||||
|
||||
// Sender is the interface that wraps the Do method to send HTTP requests.
|
||||
//
|
||||
// The standard http.Client conforms to this interface.
|
||||
type Sender interface {
|
||||
Do(*http.Request) (*http.Response, error)
|
||||
}
|
||||
|
||||
// SenderFunc is a method that implements the Sender interface.
|
||||
type SenderFunc func(*http.Request) (*http.Response, error)
|
||||
|
||||
// Do implements the Sender interface on SenderFunc.
|
||||
func (sf SenderFunc) Do(r *http.Request) (*http.Response, error) {
|
||||
return sf(r)
|
||||
}
|
||||
|
||||
// SendDecorator takes and possibly decorates, by wrapping, a Sender. Decorators may affect the
|
||||
// http.Request and pass it along or, first, pass the http.Request along then react to the
|
||||
// http.Response result.
|
||||
type SendDecorator func(Sender) Sender
|
||||
|
||||
// CreateSender creates, decorates, and returns, as a Sender, the default http.Client.
|
||||
func CreateSender(decorators ...SendDecorator) Sender {
|
||||
return DecorateSender(&http.Client{}, decorators...)
|
||||
}
|
||||
|
||||
// DecorateSender accepts a Sender and a, possibly empty, set of SendDecorators, which is applies to
|
||||
// the Sender. Decorators are applied in the order received, but their affect upon the request
|
||||
// depends on whether they are a pre-decorator (change the http.Request and then pass it along) or a
|
||||
// post-decorator (pass the http.Request along and react to the results in http.Response).
|
||||
func DecorateSender(s Sender, decorators ...SendDecorator) Sender {
|
||||
for _, decorate := range decorators {
|
||||
s = decorate(s)
|
||||
}
|
||||
return s
|
||||
}
|
980
vendor/github.com/Azure/go-autorest/autorest/adal/token.go
generated
vendored
980
vendor/github.com/Azure/go-autorest/autorest/adal/token.go
generated
vendored
@ -1,980 +0,0 @@
|
||||
package adal
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/sha1"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest/date"
|
||||
"github.com/Azure/go-autorest/version"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultRefresh = 5 * time.Minute
|
||||
|
||||
// OAuthGrantTypeDeviceCode is the "grant_type" identifier used in device flow
|
||||
OAuthGrantTypeDeviceCode = "device_code"
|
||||
|
||||
// OAuthGrantTypeClientCredentials is the "grant_type" identifier used in credential flows
|
||||
OAuthGrantTypeClientCredentials = "client_credentials"
|
||||
|
||||
// OAuthGrantTypeUserPass is the "grant_type" identifier used in username and password auth flows
|
||||
OAuthGrantTypeUserPass = "password"
|
||||
|
||||
// OAuthGrantTypeRefreshToken is the "grant_type" identifier used in refresh token flows
|
||||
OAuthGrantTypeRefreshToken = "refresh_token"
|
||||
|
||||
// OAuthGrantTypeAuthorizationCode is the "grant_type" identifier used in authorization code flows
|
||||
OAuthGrantTypeAuthorizationCode = "authorization_code"
|
||||
|
||||
// metadataHeader is the header required by MSI extension
|
||||
metadataHeader = "Metadata"
|
||||
|
||||
// msiEndpoint is the well known endpoint for getting MSI authentications tokens
|
||||
msiEndpoint = "http://169.254.169.254/metadata/identity/oauth2/token"
|
||||
|
||||
// the default number of attempts to refresh an MSI authentication token
|
||||
defaultMaxMSIRefreshAttempts = 5
|
||||
)
|
||||
|
||||
// OAuthTokenProvider is an interface which should be implemented by an access token retriever
|
||||
type OAuthTokenProvider interface {
|
||||
OAuthToken() string
|
||||
}
|
||||
|
||||
// TokenRefreshError is an interface used by errors returned during token refresh.
|
||||
type TokenRefreshError interface {
|
||||
error
|
||||
Response() *http.Response
|
||||
}
|
||||
|
||||
// Refresher is an interface for token refresh functionality
|
||||
type Refresher interface {
|
||||
Refresh() error
|
||||
RefreshExchange(resource string) error
|
||||
EnsureFresh() error
|
||||
}
|
||||
|
||||
// RefresherWithContext is an interface for token refresh functionality
|
||||
type RefresherWithContext interface {
|
||||
RefreshWithContext(ctx context.Context) error
|
||||
RefreshExchangeWithContext(ctx context.Context, resource string) error
|
||||
EnsureFreshWithContext(ctx context.Context) error
|
||||
}
|
||||
|
||||
// TokenRefreshCallback is the type representing callbacks that will be called after
|
||||
// a successful token refresh
|
||||
type TokenRefreshCallback func(Token) error
|
||||
|
||||
// Token encapsulates the access token used to authorize Azure requests.
|
||||
// https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-client-creds-grant-flow#service-to-service-access-token-response
|
||||
type Token struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
|
||||
ExpiresIn json.Number `json:"expires_in"`
|
||||
ExpiresOn json.Number `json:"expires_on"`
|
||||
NotBefore json.Number `json:"not_before"`
|
||||
|
||||
Resource string `json:"resource"`
|
||||
Type string `json:"token_type"`
|
||||
}
|
||||
|
||||
func newToken() Token {
|
||||
return Token{
|
||||
ExpiresIn: "0",
|
||||
ExpiresOn: "0",
|
||||
NotBefore: "0",
|
||||
}
|
||||
}
|
||||
|
||||
// IsZero returns true if the token object is zero-initialized.
|
||||
func (t Token) IsZero() bool {
|
||||
return t == Token{}
|
||||
}
|
||||
|
||||
// Expires returns the time.Time when the Token expires.
|
||||
func (t Token) Expires() time.Time {
|
||||
s, err := t.ExpiresOn.Float64()
|
||||
if err != nil {
|
||||
s = -3600
|
||||
}
|
||||
|
||||
expiration := date.NewUnixTimeFromSeconds(s)
|
||||
|
||||
return time.Time(expiration).UTC()
|
||||
}
|
||||
|
||||
// IsExpired returns true if the Token is expired, false otherwise.
|
||||
func (t Token) IsExpired() bool {
|
||||
return t.WillExpireIn(0)
|
||||
}
|
||||
|
||||
// WillExpireIn returns true if the Token will expire after the passed time.Duration interval
|
||||
// from now, false otherwise.
|
||||
func (t Token) WillExpireIn(d time.Duration) bool {
|
||||
return !t.Expires().After(time.Now().Add(d))
|
||||
}
|
||||
|
||||
//OAuthToken return the current access token
|
||||
func (t *Token) OAuthToken() string {
|
||||
return t.AccessToken
|
||||
}
|
||||
|
||||
// ServicePrincipalSecret is an interface that allows various secret mechanism to fill the form
|
||||
// that is submitted when acquiring an oAuth token.
|
||||
type ServicePrincipalSecret interface {
|
||||
SetAuthenticationValues(spt *ServicePrincipalToken, values *url.Values) error
|
||||
}
|
||||
|
||||
// ServicePrincipalNoSecret represents a secret type that contains no secret
|
||||
// meaning it is not valid for fetching a fresh token. This is used by Manual
|
||||
type ServicePrincipalNoSecret struct {
|
||||
}
|
||||
|
||||
// SetAuthenticationValues is a method of the interface ServicePrincipalSecret
|
||||
// It only returns an error for the ServicePrincipalNoSecret type
|
||||
func (noSecret *ServicePrincipalNoSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error {
|
||||
return fmt.Errorf("Manually created ServicePrincipalToken does not contain secret material to retrieve a new access token")
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (noSecret ServicePrincipalNoSecret) MarshalJSON() ([]byte, error) {
|
||||
type tokenType struct {
|
||||
Type string `json:"type"`
|
||||
}
|
||||
return json.Marshal(tokenType{
|
||||
Type: "ServicePrincipalNoSecret",
|
||||
})
|
||||
}
|
||||
|
||||
// ServicePrincipalTokenSecret implements ServicePrincipalSecret for client_secret type authorization.
|
||||
type ServicePrincipalTokenSecret struct {
|
||||
ClientSecret string `json:"value"`
|
||||
}
|
||||
|
||||
// SetAuthenticationValues is a method of the interface ServicePrincipalSecret.
|
||||
// It will populate the form submitted during oAuth Token Acquisition using the client_secret.
|
||||
func (tokenSecret *ServicePrincipalTokenSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error {
|
||||
v.Set("client_secret", tokenSecret.ClientSecret)
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (tokenSecret ServicePrincipalTokenSecret) MarshalJSON() ([]byte, error) {
|
||||
type tokenType struct {
|
||||
Type string `json:"type"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
return json.Marshal(tokenType{
|
||||
Type: "ServicePrincipalTokenSecret",
|
||||
Value: tokenSecret.ClientSecret,
|
||||
})
|
||||
}
|
||||
|
||||
// ServicePrincipalCertificateSecret implements ServicePrincipalSecret for generic RSA cert auth with signed JWTs.
|
||||
type ServicePrincipalCertificateSecret struct {
|
||||
Certificate *x509.Certificate
|
||||
PrivateKey *rsa.PrivateKey
|
||||
}
|
||||
|
||||
// SignJwt returns the JWT signed with the certificate's private key.
|
||||
func (secret *ServicePrincipalCertificateSecret) SignJwt(spt *ServicePrincipalToken) (string, error) {
|
||||
hasher := sha1.New()
|
||||
_, err := hasher.Write(secret.Certificate.Raw)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
thumbprint := base64.URLEncoding.EncodeToString(hasher.Sum(nil))
|
||||
|
||||
// The jti (JWT ID) claim provides a unique identifier for the JWT.
|
||||
jti := make([]byte, 20)
|
||||
_, err = rand.Read(jti)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
token := jwt.New(jwt.SigningMethodRS256)
|
||||
token.Header["x5t"] = thumbprint
|
||||
x5c := []string{base64.StdEncoding.EncodeToString(secret.Certificate.Raw)}
|
||||
token.Header["x5c"] = x5c
|
||||
token.Claims = jwt.MapClaims{
|
||||
"aud": spt.inner.OauthConfig.TokenEndpoint.String(),
|
||||
"iss": spt.inner.ClientID,
|
||||
"sub": spt.inner.ClientID,
|
||||
"jti": base64.URLEncoding.EncodeToString(jti),
|
||||
"nbf": time.Now().Unix(),
|
||||
"exp": time.Now().Add(time.Hour * 24).Unix(),
|
||||
}
|
||||
|
||||
signedString, err := token.SignedString(secret.PrivateKey)
|
||||
return signedString, err
|
||||
}
|
||||
|
||||
// SetAuthenticationValues is a method of the interface ServicePrincipalSecret.
|
||||
// It will populate the form submitted during oAuth Token Acquisition using a JWT signed with a certificate.
|
||||
func (secret *ServicePrincipalCertificateSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error {
|
||||
jwt, err := secret.SignJwt(spt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
v.Set("client_assertion", jwt)
|
||||
v.Set("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer")
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (secret ServicePrincipalCertificateSecret) MarshalJSON() ([]byte, error) {
|
||||
return nil, errors.New("marshalling ServicePrincipalCertificateSecret is not supported")
|
||||
}
|
||||
|
||||
// ServicePrincipalMSISecret implements ServicePrincipalSecret for machines running the MSI Extension.
|
||||
type ServicePrincipalMSISecret struct {
|
||||
}
|
||||
|
||||
// SetAuthenticationValues is a method of the interface ServicePrincipalSecret.
|
||||
func (msiSecret *ServicePrincipalMSISecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (msiSecret ServicePrincipalMSISecret) MarshalJSON() ([]byte, error) {
|
||||
return nil, errors.New("marshalling ServicePrincipalMSISecret is not supported")
|
||||
}
|
||||
|
||||
// ServicePrincipalUsernamePasswordSecret implements ServicePrincipalSecret for username and password auth.
|
||||
type ServicePrincipalUsernamePasswordSecret struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
// SetAuthenticationValues is a method of the interface ServicePrincipalSecret.
|
||||
func (secret *ServicePrincipalUsernamePasswordSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error {
|
||||
v.Set("username", secret.Username)
|
||||
v.Set("password", secret.Password)
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (secret ServicePrincipalUsernamePasswordSecret) MarshalJSON() ([]byte, error) {
|
||||
type tokenType struct {
|
||||
Type string `json:"type"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
return json.Marshal(tokenType{
|
||||
Type: "ServicePrincipalUsernamePasswordSecret",
|
||||
Username: secret.Username,
|
||||
Password: secret.Password,
|
||||
})
|
||||
}
|
||||
|
||||
// ServicePrincipalAuthorizationCodeSecret implements ServicePrincipalSecret for authorization code auth.
|
||||
type ServicePrincipalAuthorizationCodeSecret struct {
|
||||
ClientSecret string `json:"value"`
|
||||
AuthorizationCode string `json:"authCode"`
|
||||
RedirectURI string `json:"redirect"`
|
||||
}
|
||||
|
||||
// SetAuthenticationValues is a method of the interface ServicePrincipalSecret.
|
||||
func (secret *ServicePrincipalAuthorizationCodeSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error {
|
||||
v.Set("code", secret.AuthorizationCode)
|
||||
v.Set("client_secret", secret.ClientSecret)
|
||||
v.Set("redirect_uri", secret.RedirectURI)
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (secret ServicePrincipalAuthorizationCodeSecret) MarshalJSON() ([]byte, error) {
|
||||
type tokenType struct {
|
||||
Type string `json:"type"`
|
||||
Value string `json:"value"`
|
||||
AuthCode string `json:"authCode"`
|
||||
Redirect string `json:"redirect"`
|
||||
}
|
||||
return json.Marshal(tokenType{
|
||||
Type: "ServicePrincipalAuthorizationCodeSecret",
|
||||
Value: secret.ClientSecret,
|
||||
AuthCode: secret.AuthorizationCode,
|
||||
Redirect: secret.RedirectURI,
|
||||
})
|
||||
}
|
||||
|
||||
// ServicePrincipalToken encapsulates a Token created for a Service Principal.
|
||||
type ServicePrincipalToken struct {
|
||||
inner servicePrincipalToken
|
||||
refreshLock *sync.RWMutex
|
||||
sender Sender
|
||||
refreshCallbacks []TokenRefreshCallback
|
||||
// MaxMSIRefreshAttempts is the maximum number of attempts to refresh an MSI token.
|
||||
MaxMSIRefreshAttempts int
|
||||
}
|
||||
|
||||
// MarshalTokenJSON returns the marshalled inner token.
|
||||
func (spt ServicePrincipalToken) MarshalTokenJSON() ([]byte, error) {
|
||||
return json.Marshal(spt.inner.Token)
|
||||
}
|
||||
|
||||
// SetRefreshCallbacks replaces any existing refresh callbacks with the specified callbacks.
|
||||
func (spt *ServicePrincipalToken) SetRefreshCallbacks(callbacks []TokenRefreshCallback) {
|
||||
spt.refreshCallbacks = callbacks
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (spt ServicePrincipalToken) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(spt.inner)
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||
func (spt *ServicePrincipalToken) UnmarshalJSON(data []byte) error {
|
||||
// need to determine the token type
|
||||
raw := map[string]interface{}{}
|
||||
err := json.Unmarshal(data, &raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
secret := raw["secret"].(map[string]interface{})
|
||||
switch secret["type"] {
|
||||
case "ServicePrincipalNoSecret":
|
||||
spt.inner.Secret = &ServicePrincipalNoSecret{}
|
||||
case "ServicePrincipalTokenSecret":
|
||||
spt.inner.Secret = &ServicePrincipalTokenSecret{}
|
||||
case "ServicePrincipalCertificateSecret":
|
||||
return errors.New("unmarshalling ServicePrincipalCertificateSecret is not supported")
|
||||
case "ServicePrincipalMSISecret":
|
||||
return errors.New("unmarshalling ServicePrincipalMSISecret is not supported")
|
||||
case "ServicePrincipalUsernamePasswordSecret":
|
||||
spt.inner.Secret = &ServicePrincipalUsernamePasswordSecret{}
|
||||
case "ServicePrincipalAuthorizationCodeSecret":
|
||||
spt.inner.Secret = &ServicePrincipalAuthorizationCodeSecret{}
|
||||
default:
|
||||
return fmt.Errorf("unrecognized token type '%s'", secret["type"])
|
||||
}
|
||||
err = json.Unmarshal(data, &spt.inner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
spt.refreshLock = &sync.RWMutex{}
|
||||
spt.sender = &http.Client{}
|
||||
return nil
|
||||
}
|
||||
|
||||
// internal type used for marshalling/unmarshalling
|
||||
type servicePrincipalToken struct {
|
||||
Token Token `json:"token"`
|
||||
Secret ServicePrincipalSecret `json:"secret"`
|
||||
OauthConfig OAuthConfig `json:"oauth"`
|
||||
ClientID string `json:"clientID"`
|
||||
Resource string `json:"resource"`
|
||||
AutoRefresh bool `json:"autoRefresh"`
|
||||
RefreshWithin time.Duration `json:"refreshWithin"`
|
||||
}
|
||||
|
||||
func validateOAuthConfig(oac OAuthConfig) error {
|
||||
if oac.IsZero() {
|
||||
return fmt.Errorf("parameter 'oauthConfig' cannot be zero-initialized")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewServicePrincipalTokenWithSecret create a ServicePrincipalToken using the supplied ServicePrincipalSecret implementation.
|
||||
func NewServicePrincipalTokenWithSecret(oauthConfig OAuthConfig, id string, resource string, secret ServicePrincipalSecret, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
if err := validateOAuthConfig(oauthConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(id, "id"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(resource, "resource"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if secret == nil {
|
||||
return nil, fmt.Errorf("parameter 'secret' cannot be nil")
|
||||
}
|
||||
spt := &ServicePrincipalToken{
|
||||
inner: servicePrincipalToken{
|
||||
Token: newToken(),
|
||||
OauthConfig: oauthConfig,
|
||||
Secret: secret,
|
||||
ClientID: id,
|
||||
Resource: resource,
|
||||
AutoRefresh: true,
|
||||
RefreshWithin: defaultRefresh,
|
||||
},
|
||||
refreshLock: &sync.RWMutex{},
|
||||
sender: &http.Client{},
|
||||
refreshCallbacks: callbacks,
|
||||
}
|
||||
return spt, nil
|
||||
}
|
||||
|
||||
// NewServicePrincipalTokenFromManualToken creates a ServicePrincipalToken using the supplied token
|
||||
func NewServicePrincipalTokenFromManualToken(oauthConfig OAuthConfig, clientID string, resource string, token Token, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
if err := validateOAuthConfig(oauthConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(clientID, "clientID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(resource, "resource"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if token.IsZero() {
|
||||
return nil, fmt.Errorf("parameter 'token' cannot be zero-initialized")
|
||||
}
|
||||
spt, err := NewServicePrincipalTokenWithSecret(
|
||||
oauthConfig,
|
||||
clientID,
|
||||
resource,
|
||||
&ServicePrincipalNoSecret{},
|
||||
callbacks...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
spt.inner.Token = token
|
||||
|
||||
return spt, nil
|
||||
}
|
||||
|
||||
// NewServicePrincipalTokenFromManualTokenSecret creates a ServicePrincipalToken using the supplied token and secret
|
||||
func NewServicePrincipalTokenFromManualTokenSecret(oauthConfig OAuthConfig, clientID string, resource string, token Token, secret ServicePrincipalSecret, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
if err := validateOAuthConfig(oauthConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(clientID, "clientID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(resource, "resource"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if secret == nil {
|
||||
return nil, fmt.Errorf("parameter 'secret' cannot be nil")
|
||||
}
|
||||
if token.IsZero() {
|
||||
return nil, fmt.Errorf("parameter 'token' cannot be zero-initialized")
|
||||
}
|
||||
spt, err := NewServicePrincipalTokenWithSecret(
|
||||
oauthConfig,
|
||||
clientID,
|
||||
resource,
|
||||
secret,
|
||||
callbacks...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
spt.inner.Token = token
|
||||
|
||||
return spt, nil
|
||||
}
|
||||
|
||||
// NewServicePrincipalToken creates a ServicePrincipalToken from the supplied Service Principal
|
||||
// credentials scoped to the named resource.
|
||||
func NewServicePrincipalToken(oauthConfig OAuthConfig, clientID string, secret string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
if err := validateOAuthConfig(oauthConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(clientID, "clientID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(secret, "secret"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(resource, "resource"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewServicePrincipalTokenWithSecret(
|
||||
oauthConfig,
|
||||
clientID,
|
||||
resource,
|
||||
&ServicePrincipalTokenSecret{
|
||||
ClientSecret: secret,
|
||||
},
|
||||
callbacks...,
|
||||
)
|
||||
}
|
||||
|
||||
// NewServicePrincipalTokenFromCertificate creates a ServicePrincipalToken from the supplied pkcs12 bytes.
|
||||
func NewServicePrincipalTokenFromCertificate(oauthConfig OAuthConfig, clientID string, certificate *x509.Certificate, privateKey *rsa.PrivateKey, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
if err := validateOAuthConfig(oauthConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(clientID, "clientID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(resource, "resource"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if certificate == nil {
|
||||
return nil, fmt.Errorf("parameter 'certificate' cannot be nil")
|
||||
}
|
||||
if privateKey == nil {
|
||||
return nil, fmt.Errorf("parameter 'privateKey' cannot be nil")
|
||||
}
|
||||
return NewServicePrincipalTokenWithSecret(
|
||||
oauthConfig,
|
||||
clientID,
|
||||
resource,
|
||||
&ServicePrincipalCertificateSecret{
|
||||
PrivateKey: privateKey,
|
||||
Certificate: certificate,
|
||||
},
|
||||
callbacks...,
|
||||
)
|
||||
}
|
||||
|
||||
// NewServicePrincipalTokenFromUsernamePassword creates a ServicePrincipalToken from the username and password.
|
||||
func NewServicePrincipalTokenFromUsernamePassword(oauthConfig OAuthConfig, clientID string, username string, password string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
if err := validateOAuthConfig(oauthConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(clientID, "clientID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(username, "username"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(password, "password"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(resource, "resource"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewServicePrincipalTokenWithSecret(
|
||||
oauthConfig,
|
||||
clientID,
|
||||
resource,
|
||||
&ServicePrincipalUsernamePasswordSecret{
|
||||
Username: username,
|
||||
Password: password,
|
||||
},
|
||||
callbacks...,
|
||||
)
|
||||
}
|
||||
|
||||
// NewServicePrincipalTokenFromAuthorizationCode creates a ServicePrincipalToken from the
|
||||
func NewServicePrincipalTokenFromAuthorizationCode(oauthConfig OAuthConfig, clientID string, clientSecret string, authorizationCode string, redirectURI string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
|
||||
if err := validateOAuthConfig(oauthConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(clientID, "clientID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(clientSecret, "clientSecret"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(authorizationCode, "authorizationCode"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(redirectURI, "redirectURI"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(resource, "resource"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewServicePrincipalTokenWithSecret(
|
||||
oauthConfig,
|
||||
clientID,
|
||||
resource,
|
||||
&ServicePrincipalAuthorizationCodeSecret{
|
||||
ClientSecret: clientSecret,
|
||||
AuthorizationCode: authorizationCode,
|
||||
RedirectURI: redirectURI,
|
||||
},
|
||||
callbacks...,
|
||||
)
|
||||
}
|
||||
|
||||
// GetMSIVMEndpoint gets the MSI endpoint on Virtual Machines.
|
||||
func GetMSIVMEndpoint() (string, error) {
|
||||
return msiEndpoint, nil
|
||||
}
|
||||
|
||||
// NewServicePrincipalTokenFromMSI creates a ServicePrincipalToken via the MSI VM Extension.
|
||||
// It will use the system assigned identity when creating the token.
|
||||
func NewServicePrincipalTokenFromMSI(msiEndpoint, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
return newServicePrincipalTokenFromMSI(msiEndpoint, resource, nil, callbacks...)
|
||||
}
|
||||
|
||||
// NewServicePrincipalTokenFromMSIWithUserAssignedID creates a ServicePrincipalToken via the MSI VM Extension.
|
||||
// It will use the specified user assigned identity when creating the token.
|
||||
func NewServicePrincipalTokenFromMSIWithUserAssignedID(msiEndpoint, resource string, userAssignedID string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
return newServicePrincipalTokenFromMSI(msiEndpoint, resource, &userAssignedID, callbacks...)
|
||||
}
|
||||
|
||||
func newServicePrincipalTokenFromMSI(msiEndpoint, resource string, userAssignedID *string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
if err := validateStringParam(msiEndpoint, "msiEndpoint"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(resource, "resource"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if userAssignedID != nil {
|
||||
if err := validateStringParam(*userAssignedID, "userAssignedID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// We set the oauth config token endpoint to be MSI's endpoint
|
||||
msiEndpointURL, err := url.Parse(msiEndpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v := url.Values{}
|
||||
v.Set("resource", resource)
|
||||
v.Set("api-version", "2018-02-01")
|
||||
if userAssignedID != nil {
|
||||
v.Set("client_id", *userAssignedID)
|
||||
}
|
||||
msiEndpointURL.RawQuery = v.Encode()
|
||||
|
||||
spt := &ServicePrincipalToken{
|
||||
inner: servicePrincipalToken{
|
||||
Token: newToken(),
|
||||
OauthConfig: OAuthConfig{
|
||||
TokenEndpoint: *msiEndpointURL,
|
||||
},
|
||||
Secret: &ServicePrincipalMSISecret{},
|
||||
Resource: resource,
|
||||
AutoRefresh: true,
|
||||
RefreshWithin: defaultRefresh,
|
||||
},
|
||||
refreshLock: &sync.RWMutex{},
|
||||
sender: &http.Client{},
|
||||
refreshCallbacks: callbacks,
|
||||
MaxMSIRefreshAttempts: defaultMaxMSIRefreshAttempts,
|
||||
}
|
||||
|
||||
if userAssignedID != nil {
|
||||
spt.inner.ClientID = *userAssignedID
|
||||
}
|
||||
|
||||
return spt, nil
|
||||
}
|
||||
|
||||
// internal type that implements TokenRefreshError
|
||||
type tokenRefreshError struct {
|
||||
message string
|
||||
resp *http.Response
|
||||
}
|
||||
|
||||
// Error implements the error interface which is part of the TokenRefreshError interface.
|
||||
func (tre tokenRefreshError) Error() string {
|
||||
return tre.message
|
||||
}
|
||||
|
||||
// Response implements the TokenRefreshError interface, it returns the raw HTTP response from the refresh operation.
|
||||
func (tre tokenRefreshError) Response() *http.Response {
|
||||
return tre.resp
|
||||
}
|
||||
|
||||
func newTokenRefreshError(message string, resp *http.Response) TokenRefreshError {
|
||||
return tokenRefreshError{message: message, resp: resp}
|
||||
}
|
||||
|
||||
// EnsureFresh will refresh the token if it will expire within the refresh window (as set by
|
||||
// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use.
|
||||
func (spt *ServicePrincipalToken) EnsureFresh() error {
|
||||
return spt.EnsureFreshWithContext(context.Background())
|
||||
}
|
||||
|
||||
// EnsureFreshWithContext will refresh the token if it will expire within the refresh window (as set by
|
||||
// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use.
|
||||
func (spt *ServicePrincipalToken) EnsureFreshWithContext(ctx context.Context) error {
|
||||
if spt.inner.AutoRefresh && spt.inner.Token.WillExpireIn(spt.inner.RefreshWithin) {
|
||||
// take the write lock then check to see if the token was already refreshed
|
||||
spt.refreshLock.Lock()
|
||||
defer spt.refreshLock.Unlock()
|
||||
if spt.inner.Token.WillExpireIn(spt.inner.RefreshWithin) {
|
||||
return spt.refreshInternal(ctx, spt.inner.Resource)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// InvokeRefreshCallbacks calls any TokenRefreshCallbacks that were added to the SPT during initialization
|
||||
func (spt *ServicePrincipalToken) InvokeRefreshCallbacks(token Token) error {
|
||||
if spt.refreshCallbacks != nil {
|
||||
for _, callback := range spt.refreshCallbacks {
|
||||
err := callback(spt.inner.Token)
|
||||
if err != nil {
|
||||
return fmt.Errorf("adal: TokenRefreshCallback handler failed. Error = '%v'", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Refresh obtains a fresh token for the Service Principal.
|
||||
// This method is not safe for concurrent use and should be syncrhonized.
|
||||
func (spt *ServicePrincipalToken) Refresh() error {
|
||||
return spt.RefreshWithContext(context.Background())
|
||||
}
|
||||
|
||||
// RefreshWithContext obtains a fresh token for the Service Principal.
|
||||
// This method is not safe for concurrent use and should be syncrhonized.
|
||||
func (spt *ServicePrincipalToken) RefreshWithContext(ctx context.Context) error {
|
||||
spt.refreshLock.Lock()
|
||||
defer spt.refreshLock.Unlock()
|
||||
return spt.refreshInternal(ctx, spt.inner.Resource)
|
||||
}
|
||||
|
||||
// RefreshExchange refreshes the token, but for a different resource.
|
||||
// This method is not safe for concurrent use and should be syncrhonized.
|
||||
func (spt *ServicePrincipalToken) RefreshExchange(resource string) error {
|
||||
return spt.RefreshExchangeWithContext(context.Background(), resource)
|
||||
}
|
||||
|
||||
// RefreshExchangeWithContext refreshes the token, but for a different resource.
|
||||
// This method is not safe for concurrent use and should be syncrhonized.
|
||||
func (spt *ServicePrincipalToken) RefreshExchangeWithContext(ctx context.Context, resource string) error {
|
||||
spt.refreshLock.Lock()
|
||||
defer spt.refreshLock.Unlock()
|
||||
return spt.refreshInternal(ctx, resource)
|
||||
}
|
||||
|
||||
func (spt *ServicePrincipalToken) getGrantType() string {
|
||||
switch spt.inner.Secret.(type) {
|
||||
case *ServicePrincipalUsernamePasswordSecret:
|
||||
return OAuthGrantTypeUserPass
|
||||
case *ServicePrincipalAuthorizationCodeSecret:
|
||||
return OAuthGrantTypeAuthorizationCode
|
||||
default:
|
||||
return OAuthGrantTypeClientCredentials
|
||||
}
|
||||
}
|
||||
|
||||
func isIMDS(u url.URL) bool {
|
||||
imds, err := url.Parse(msiEndpoint)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return u.Host == imds.Host && u.Path == imds.Path
|
||||
}
|
||||
|
||||
func (spt *ServicePrincipalToken) refreshInternal(ctx context.Context, resource string) error {
|
||||
req, err := http.NewRequest(http.MethodPost, spt.inner.OauthConfig.TokenEndpoint.String(), nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("adal: Failed to build the refresh request. Error = '%v'", err)
|
||||
}
|
||||
req.Header.Add("User-Agent", version.UserAgent())
|
||||
req = req.WithContext(ctx)
|
||||
if !isIMDS(spt.inner.OauthConfig.TokenEndpoint) {
|
||||
v := url.Values{}
|
||||
v.Set("client_id", spt.inner.ClientID)
|
||||
v.Set("resource", resource)
|
||||
|
||||
if spt.inner.Token.RefreshToken != "" {
|
||||
v.Set("grant_type", OAuthGrantTypeRefreshToken)
|
||||
v.Set("refresh_token", spt.inner.Token.RefreshToken)
|
||||
// web apps must specify client_secret when refreshing tokens
|
||||
// see https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-code#refreshing-the-access-tokens
|
||||
if spt.getGrantType() == OAuthGrantTypeAuthorizationCode {
|
||||
err := spt.inner.Secret.SetAuthenticationValues(spt, &v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
v.Set("grant_type", spt.getGrantType())
|
||||
err := spt.inner.Secret.SetAuthenticationValues(spt, &v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
s := v.Encode()
|
||||
body := ioutil.NopCloser(strings.NewReader(s))
|
||||
req.ContentLength = int64(len(s))
|
||||
req.Header.Set(contentType, mimeTypeFormPost)
|
||||
req.Body = body
|
||||
}
|
||||
|
||||
if _, ok := spt.inner.Secret.(*ServicePrincipalMSISecret); ok {
|
||||
req.Method = http.MethodGet
|
||||
req.Header.Set(metadataHeader, "true")
|
||||
}
|
||||
|
||||
var resp *http.Response
|
||||
if isIMDS(spt.inner.OauthConfig.TokenEndpoint) {
|
||||
resp, err = retryForIMDS(spt.sender, req, spt.MaxMSIRefreshAttempts)
|
||||
} else {
|
||||
resp, err = spt.sender.Do(req)
|
||||
}
|
||||
if err != nil {
|
||||
return newTokenRefreshError(fmt.Sprintf("adal: Failed to execute the refresh request. Error = '%v'", err), nil)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
rb, err := ioutil.ReadAll(resp.Body)
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
if err != nil {
|
||||
return newTokenRefreshError(fmt.Sprintf("adal: Refresh request failed. Status Code = '%d'. Failed reading response body: %v", resp.StatusCode, err), resp)
|
||||
}
|
||||
return newTokenRefreshError(fmt.Sprintf("adal: Refresh request failed. Status Code = '%d'. Response body: %s", resp.StatusCode, string(rb)), resp)
|
||||
}
|
||||
|
||||
// for the following error cases don't return a TokenRefreshError. the operation succeeded
|
||||
// but some transient failure happened during deserialization. by returning a generic error
|
||||
// the retry logic will kick in (we don't retry on TokenRefreshError).
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("adal: Failed to read a new service principal token during refresh. Error = '%v'", err)
|
||||
}
|
||||
if len(strings.Trim(string(rb), " ")) == 0 {
|
||||
return fmt.Errorf("adal: Empty service principal token received during refresh")
|
||||
}
|
||||
var token Token
|
||||
err = json.Unmarshal(rb, &token)
|
||||
if err != nil {
|
||||
return fmt.Errorf("adal: Failed to unmarshal the service principal token during refresh. Error = '%v' JSON = '%s'", err, string(rb))
|
||||
}
|
||||
|
||||
spt.inner.Token = token
|
||||
|
||||
return spt.InvokeRefreshCallbacks(token)
|
||||
}
|
||||
|
||||
// retry logic specific to retrieving a token from the IMDS endpoint
|
||||
func retryForIMDS(sender Sender, req *http.Request, maxAttempts int) (resp *http.Response, err error) {
|
||||
// copied from client.go due to circular dependency
|
||||
retries := []int{
|
||||
http.StatusRequestTimeout, // 408
|
||||
http.StatusTooManyRequests, // 429
|
||||
http.StatusInternalServerError, // 500
|
||||
http.StatusBadGateway, // 502
|
||||
http.StatusServiceUnavailable, // 503
|
||||
http.StatusGatewayTimeout, // 504
|
||||
}
|
||||
// extra retry status codes specific to IMDS
|
||||
retries = append(retries,
|
||||
http.StatusNotFound,
|
||||
http.StatusGone,
|
||||
// all remaining 5xx
|
||||
http.StatusNotImplemented,
|
||||
http.StatusHTTPVersionNotSupported,
|
||||
http.StatusVariantAlsoNegotiates,
|
||||
http.StatusInsufficientStorage,
|
||||
http.StatusLoopDetected,
|
||||
http.StatusNotExtended,
|
||||
http.StatusNetworkAuthenticationRequired)
|
||||
|
||||
// see https://docs.microsoft.com/en-us/azure/active-directory/managed-service-identity/how-to-use-vm-token#retry-guidance
|
||||
|
||||
const maxDelay time.Duration = 60 * time.Second
|
||||
|
||||
attempt := 0
|
||||
delay := time.Duration(0)
|
||||
|
||||
for attempt < maxAttempts {
|
||||
resp, err = sender.Do(req)
|
||||
// retry on temporary network errors, e.g. transient network failures.
|
||||
// if we don't receive a response then assume we can't connect to the
|
||||
// endpoint so we're likely not running on an Azure VM so don't retry.
|
||||
if (err != nil && !isTemporaryNetworkError(err)) || resp == nil || resp.StatusCode == http.StatusOK || !containsInt(retries, resp.StatusCode) {
|
||||
return
|
||||
}
|
||||
|
||||
// perform exponential backoff with a cap.
|
||||
// must increment attempt before calculating delay.
|
||||
attempt++
|
||||
// the base value of 2 is the "delta backoff" as specified in the guidance doc
|
||||
delay += (time.Duration(math.Pow(2, float64(attempt))) * time.Second)
|
||||
if delay > maxDelay {
|
||||
delay = maxDelay
|
||||
}
|
||||
|
||||
select {
|
||||
case <-time.After(delay):
|
||||
// intentionally left blank
|
||||
case <-req.Context().Done():
|
||||
err = req.Context().Err()
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// returns true if the specified error is a temporary network error or false if it's not.
|
||||
// if the error doesn't implement the net.Error interface the return value is true.
|
||||
func isTemporaryNetworkError(err error) bool {
|
||||
if netErr, ok := err.(net.Error); !ok || (ok && netErr.Temporary()) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// returns true if slice ints contains the value n
|
||||
func containsInt(ints []int, n int) bool {
|
||||
for _, i := range ints {
|
||||
if i == n {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// SetAutoRefresh enables or disables automatic refreshing of stale tokens.
|
||||
func (spt *ServicePrincipalToken) SetAutoRefresh(autoRefresh bool) {
|
||||
spt.inner.AutoRefresh = autoRefresh
|
||||
}
|
||||
|
||||
// SetRefreshWithin sets the interval within which if the token will expire, EnsureFresh will
|
||||
// refresh the token.
|
||||
func (spt *ServicePrincipalToken) SetRefreshWithin(d time.Duration) {
|
||||
spt.inner.RefreshWithin = d
|
||||
return
|
||||
}
|
||||
|
||||
// SetSender sets the http.Client used when obtaining the Service Principal token. An
|
||||
// undecorated http.Client is used by default.
|
||||
func (spt *ServicePrincipalToken) SetSender(s Sender) { spt.sender = s }
|
||||
|
||||
// OAuthToken implements the OAuthTokenProvider interface. It returns the current access token.
|
||||
func (spt *ServicePrincipalToken) OAuthToken() string {
|
||||
spt.refreshLock.RLock()
|
||||
defer spt.refreshLock.RUnlock()
|
||||
return spt.inner.Token.OAuthToken()
|
||||
}
|
||||
|
||||
// Token returns a copy of the current token.
|
||||
func (spt *ServicePrincipalToken) Token() Token {
|
||||
spt.refreshLock.RLock()
|
||||
defer spt.refreshLock.RUnlock()
|
||||
return spt.inner.Token
|
||||
}
|
259
vendor/github.com/Azure/go-autorest/autorest/authorization.go
generated
vendored
259
vendor/github.com/Azure/go-autorest/autorest/authorization.go
generated
vendored
@ -1,259 +0,0 @@
|
||||
package autorest
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest/adal"
|
||||
)
|
||||
|
||||
const (
|
||||
bearerChallengeHeader = "Www-Authenticate"
|
||||
bearer = "Bearer"
|
||||
tenantID = "tenantID"
|
||||
apiKeyAuthorizerHeader = "Ocp-Apim-Subscription-Key"
|
||||
bingAPISdkHeader = "X-BingApis-SDK-Client"
|
||||
golangBingAPISdkHeaderValue = "Go-SDK"
|
||||
)
|
||||
|
||||
// Authorizer is the interface that provides a PrepareDecorator used to supply request
|
||||
// authorization. Most often, the Authorizer decorator runs last so it has access to the full
|
||||
// state of the formed HTTP request.
|
||||
type Authorizer interface {
|
||||
WithAuthorization() PrepareDecorator
|
||||
}
|
||||
|
||||
// NullAuthorizer implements a default, "do nothing" Authorizer.
|
||||
type NullAuthorizer struct{}
|
||||
|
||||
// WithAuthorization returns a PrepareDecorator that does nothing.
|
||||
func (na NullAuthorizer) WithAuthorization() PrepareDecorator {
|
||||
return WithNothing()
|
||||
}
|
||||
|
||||
// APIKeyAuthorizer implements API Key authorization.
|
||||
type APIKeyAuthorizer struct {
|
||||
headers map[string]interface{}
|
||||
queryParameters map[string]interface{}
|
||||
}
|
||||
|
||||
// NewAPIKeyAuthorizerWithHeaders creates an ApiKeyAuthorizer with headers.
|
||||
func NewAPIKeyAuthorizerWithHeaders(headers map[string]interface{}) *APIKeyAuthorizer {
|
||||
return NewAPIKeyAuthorizer(headers, nil)
|
||||
}
|
||||
|
||||
// NewAPIKeyAuthorizerWithQueryParameters creates an ApiKeyAuthorizer with query parameters.
|
||||
func NewAPIKeyAuthorizerWithQueryParameters(queryParameters map[string]interface{}) *APIKeyAuthorizer {
|
||||
return NewAPIKeyAuthorizer(nil, queryParameters)
|
||||
}
|
||||
|
||||
// NewAPIKeyAuthorizer creates an ApiKeyAuthorizer with headers.
|
||||
func NewAPIKeyAuthorizer(headers map[string]interface{}, queryParameters map[string]interface{}) *APIKeyAuthorizer {
|
||||
return &APIKeyAuthorizer{headers: headers, queryParameters: queryParameters}
|
||||
}
|
||||
|
||||
// WithAuthorization returns a PrepareDecorator that adds an HTTP headers and Query Paramaters
|
||||
func (aka *APIKeyAuthorizer) WithAuthorization() PrepareDecorator {
|
||||
return func(p Preparer) Preparer {
|
||||
return DecoratePreparer(p, WithHeaders(aka.headers), WithQueryParameters(aka.queryParameters))
|
||||
}
|
||||
}
|
||||
|
||||
// CognitiveServicesAuthorizer implements authorization for Cognitive Services.
|
||||
type CognitiveServicesAuthorizer struct {
|
||||
subscriptionKey string
|
||||
}
|
||||
|
||||
// NewCognitiveServicesAuthorizer is
|
||||
func NewCognitiveServicesAuthorizer(subscriptionKey string) *CognitiveServicesAuthorizer {
|
||||
return &CognitiveServicesAuthorizer{subscriptionKey: subscriptionKey}
|
||||
}
|
||||
|
||||
// WithAuthorization is
|
||||
func (csa *CognitiveServicesAuthorizer) WithAuthorization() PrepareDecorator {
|
||||
headers := make(map[string]interface{})
|
||||
headers[apiKeyAuthorizerHeader] = csa.subscriptionKey
|
||||
headers[bingAPISdkHeader] = golangBingAPISdkHeaderValue
|
||||
|
||||
return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization()
|
||||
}
|
||||
|
||||
// BearerAuthorizer implements the bearer authorization
|
||||
type BearerAuthorizer struct {
|
||||
tokenProvider adal.OAuthTokenProvider
|
||||
}
|
||||
|
||||
// NewBearerAuthorizer crates a BearerAuthorizer using the given token provider
|
||||
func NewBearerAuthorizer(tp adal.OAuthTokenProvider) *BearerAuthorizer {
|
||||
return &BearerAuthorizer{tokenProvider: tp}
|
||||
}
|
||||
|
||||
// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose
|
||||
// value is "Bearer " followed by the token.
|
||||
//
|
||||
// By default, the token will be automatically refreshed through the Refresher interface.
|
||||
func (ba *BearerAuthorizer) WithAuthorization() PrepareDecorator {
|
||||
return func(p Preparer) Preparer {
|
||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
r, err := p.Prepare(r)
|
||||
if err == nil {
|
||||
// the ordering is important here, prefer RefresherWithContext if available
|
||||
if refresher, ok := ba.tokenProvider.(adal.RefresherWithContext); ok {
|
||||
err = refresher.EnsureFreshWithContext(r.Context())
|
||||
} else if refresher, ok := ba.tokenProvider.(adal.Refresher); ok {
|
||||
err = refresher.EnsureFresh()
|
||||
}
|
||||
if err != nil {
|
||||
var resp *http.Response
|
||||
if tokError, ok := err.(adal.TokenRefreshError); ok {
|
||||
resp = tokError.Response()
|
||||
}
|
||||
return r, NewErrorWithError(err, "azure.BearerAuthorizer", "WithAuthorization", resp,
|
||||
"Failed to refresh the Token for request to %s", r.URL)
|
||||
}
|
||||
return Prepare(r, WithHeader(headerAuthorization, fmt.Sprintf("Bearer %s", ba.tokenProvider.OAuthToken())))
|
||||
}
|
||||
return r, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// BearerAuthorizerCallbackFunc is the authentication callback signature.
|
||||
type BearerAuthorizerCallbackFunc func(tenantID, resource string) (*BearerAuthorizer, error)
|
||||
|
||||
// BearerAuthorizerCallback implements bearer authorization via a callback.
|
||||
type BearerAuthorizerCallback struct {
|
||||
sender Sender
|
||||
callback BearerAuthorizerCallbackFunc
|
||||
}
|
||||
|
||||
// NewBearerAuthorizerCallback creates a bearer authorization callback. The callback
|
||||
// is invoked when the HTTP request is submitted.
|
||||
func NewBearerAuthorizerCallback(sender Sender, callback BearerAuthorizerCallbackFunc) *BearerAuthorizerCallback {
|
||||
if sender == nil {
|
||||
sender = &http.Client{}
|
||||
}
|
||||
return &BearerAuthorizerCallback{sender: sender, callback: callback}
|
||||
}
|
||||
|
||||
// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose value
|
||||
// is "Bearer " followed by the token. The BearerAuthorizer is obtained via a user-supplied callback.
|
||||
//
|
||||
// By default, the token will be automatically refreshed through the Refresher interface.
|
||||
func (bacb *BearerAuthorizerCallback) WithAuthorization() PrepareDecorator {
|
||||
return func(p Preparer) Preparer {
|
||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
r, err := p.Prepare(r)
|
||||
if err == nil {
|
||||
// make a copy of the request and remove the body as it's not
|
||||
// required and avoids us having to create a copy of it.
|
||||
rCopy := *r
|
||||
removeRequestBody(&rCopy)
|
||||
|
||||
resp, err := bacb.sender.Do(&rCopy)
|
||||
if err == nil && resp.StatusCode == 401 {
|
||||
defer resp.Body.Close()
|
||||
if hasBearerChallenge(resp) {
|
||||
bc, err := newBearerChallenge(resp)
|
||||
if err != nil {
|
||||
return r, err
|
||||
}
|
||||
if bacb.callback != nil {
|
||||
ba, err := bacb.callback(bc.values[tenantID], bc.values["resource"])
|
||||
if err != nil {
|
||||
return r, err
|
||||
}
|
||||
return Prepare(r, ba.WithAuthorization())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return r, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// returns true if the HTTP response contains a bearer challenge
|
||||
func hasBearerChallenge(resp *http.Response) bool {
|
||||
authHeader := resp.Header.Get(bearerChallengeHeader)
|
||||
if len(authHeader) == 0 || strings.Index(authHeader, bearer) < 0 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
type bearerChallenge struct {
|
||||
values map[string]string
|
||||
}
|
||||
|
||||
func newBearerChallenge(resp *http.Response) (bc bearerChallenge, err error) {
|
||||
challenge := strings.TrimSpace(resp.Header.Get(bearerChallengeHeader))
|
||||
trimmedChallenge := challenge[len(bearer)+1:]
|
||||
|
||||
// challenge is a set of key=value pairs that are comma delimited
|
||||
pairs := strings.Split(trimmedChallenge, ",")
|
||||
if len(pairs) < 1 {
|
||||
err = fmt.Errorf("challenge '%s' contains no pairs", challenge)
|
||||
return bc, err
|
||||
}
|
||||
|
||||
bc.values = make(map[string]string)
|
||||
for i := range pairs {
|
||||
trimmedPair := strings.TrimSpace(pairs[i])
|
||||
pair := strings.Split(trimmedPair, "=")
|
||||
if len(pair) == 2 {
|
||||
// remove the enclosing quotes
|
||||
key := strings.Trim(pair[0], "\"")
|
||||
value := strings.Trim(pair[1], "\"")
|
||||
|
||||
switch key {
|
||||
case "authorization", "authorization_uri":
|
||||
// strip the tenant ID from the authorization URL
|
||||
asURL, err := url.Parse(value)
|
||||
if err != nil {
|
||||
return bc, err
|
||||
}
|
||||
bc.values[tenantID] = asURL.Path[1:]
|
||||
default:
|
||||
bc.values[key] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bc, err
|
||||
}
|
||||
|
||||
// EventGridKeyAuthorizer implements authorization for event grid using key authentication.
|
||||
type EventGridKeyAuthorizer struct {
|
||||
topicKey string
|
||||
}
|
||||
|
||||
// NewEventGridKeyAuthorizer creates a new EventGridKeyAuthorizer
|
||||
// with the specified topic key.
|
||||
func NewEventGridKeyAuthorizer(topicKey string) EventGridKeyAuthorizer {
|
||||
return EventGridKeyAuthorizer{topicKey: topicKey}
|
||||
}
|
||||
|
||||
// WithAuthorization returns a PrepareDecorator that adds the aeg-sas-key authentication header.
|
||||
func (egta EventGridKeyAuthorizer) WithAuthorization() PrepareDecorator {
|
||||
headers := map[string]interface{}{
|
||||
"aeg-sas-key": egta.topicKey,
|
||||
}
|
||||
return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization()
|
||||
}
|
150
vendor/github.com/Azure/go-autorest/autorest/autorest.go
generated
vendored
150
vendor/github.com/Azure/go-autorest/autorest/autorest.go
generated
vendored
@ -1,150 +0,0 @@
|
||||
/*
|
||||
Package autorest implements an HTTP request pipeline suitable for use across multiple go-routines
|
||||
and provides the shared routines relied on by AutoRest (see https://github.com/Azure/autorest/)
|
||||
generated Go code.
|
||||
|
||||
The package breaks sending and responding to HTTP requests into three phases: Preparing, Sending,
|
||||
and Responding. A typical pattern is:
|
||||
|
||||
req, err := Prepare(&http.Request{},
|
||||
token.WithAuthorization())
|
||||
|
||||
resp, err := Send(req,
|
||||
WithLogging(logger),
|
||||
DoErrorIfStatusCode(http.StatusInternalServerError),
|
||||
DoCloseIfError(),
|
||||
DoRetryForAttempts(5, time.Second))
|
||||
|
||||
err = Respond(resp,
|
||||
ByDiscardingBody(),
|
||||
ByClosing())
|
||||
|
||||
Each phase relies on decorators to modify and / or manage processing. Decorators may first modify
|
||||
and then pass the data along, pass the data first and then modify the result, or wrap themselves
|
||||
around passing the data (such as a logger might do). Decorators run in the order provided. For
|
||||
example, the following:
|
||||
|
||||
req, err := Prepare(&http.Request{},
|
||||
WithBaseURL("https://microsoft.com/"),
|
||||
WithPath("a"),
|
||||
WithPath("b"),
|
||||
WithPath("c"))
|
||||
|
||||
will set the URL to:
|
||||
|
||||
https://microsoft.com/a/b/c
|
||||
|
||||
Preparers and Responders may be shared and re-used (assuming the underlying decorators support
|
||||
sharing and re-use). Performant use is obtained by creating one or more Preparers and Responders
|
||||
shared among multiple go-routines, and a single Sender shared among multiple sending go-routines,
|
||||
all bound together by means of input / output channels.
|
||||
|
||||
Decorators hold their passed state within a closure (such as the path components in the example
|
||||
above). Be careful to share Preparers and Responders only in a context where such held state
|
||||
applies. For example, it may not make sense to share a Preparer that applies a query string from a
|
||||
fixed set of values. Similarly, sharing a Responder that reads the response body into a passed
|
||||
struct (e.g., ByUnmarshallingJson) is likely incorrect.
|
||||
|
||||
Lastly, the Swagger specification (https://swagger.io) that drives AutoRest
|
||||
(https://github.com/Azure/autorest/) precisely defines two date forms: date and date-time. The
|
||||
github.com/Azure/go-autorest/autorest/date package provides time.Time derivations to ensure
|
||||
correct parsing and formatting.
|
||||
|
||||
Errors raised by autorest objects and methods will conform to the autorest.Error interface.
|
||||
|
||||
See the included examples for more detail. For details on the suggested use of this package by
|
||||
generated clients, see the Client described below.
|
||||
*/
|
||||
package autorest
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
// HeaderLocation specifies the HTTP Location header.
|
||||
HeaderLocation = "Location"
|
||||
|
||||
// HeaderRetryAfter specifies the HTTP Retry-After header.
|
||||
HeaderRetryAfter = "Retry-After"
|
||||
)
|
||||
|
||||
// ResponseHasStatusCode returns true if the status code in the HTTP Response is in the passed set
|
||||
// and false otherwise.
|
||||
func ResponseHasStatusCode(resp *http.Response, codes ...int) bool {
|
||||
if resp == nil {
|
||||
return false
|
||||
}
|
||||
return containsInt(codes, resp.StatusCode)
|
||||
}
|
||||
|
||||
// GetLocation retrieves the URL from the Location header of the passed response.
|
||||
func GetLocation(resp *http.Response) string {
|
||||
return resp.Header.Get(HeaderLocation)
|
||||
}
|
||||
|
||||
// GetRetryAfter extracts the retry delay from the Retry-After header of the passed response. If
|
||||
// the header is absent or is malformed, it will return the supplied default delay time.Duration.
|
||||
func GetRetryAfter(resp *http.Response, defaultDelay time.Duration) time.Duration {
|
||||
retry := resp.Header.Get(HeaderRetryAfter)
|
||||
if retry == "" {
|
||||
return defaultDelay
|
||||
}
|
||||
|
||||
d, err := time.ParseDuration(retry + "s")
|
||||
if err != nil {
|
||||
return defaultDelay
|
||||
}
|
||||
|
||||
return d
|
||||
}
|
||||
|
||||
// NewPollingRequest allocates and returns a new http.Request to poll for the passed response.
|
||||
func NewPollingRequest(resp *http.Response, cancel <-chan struct{}) (*http.Request, error) {
|
||||
location := GetLocation(resp)
|
||||
if location == "" {
|
||||
return nil, NewErrorWithResponse("autorest", "NewPollingRequest", resp, "Location header missing from response that requires polling")
|
||||
}
|
||||
|
||||
req, err := Prepare(&http.Request{Cancel: cancel},
|
||||
AsGet(),
|
||||
WithBaseURL(location))
|
||||
if err != nil {
|
||||
return nil, NewErrorWithError(err, "autorest", "NewPollingRequest", nil, "Failure creating poll request to %s", location)
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// NewPollingRequestWithContext allocates and returns a new http.Request with the specified context to poll for the passed response.
|
||||
func NewPollingRequestWithContext(ctx context.Context, resp *http.Response) (*http.Request, error) {
|
||||
location := GetLocation(resp)
|
||||
if location == "" {
|
||||
return nil, NewErrorWithResponse("autorest", "NewPollingRequestWithContext", resp, "Location header missing from response that requires polling")
|
||||
}
|
||||
|
||||
req, err := Prepare((&http.Request{}).WithContext(ctx),
|
||||
AsGet(),
|
||||
WithBaseURL(location))
|
||||
if err != nil {
|
||||
return nil, NewErrorWithError(err, "autorest", "NewPollingRequestWithContext", nil, "Failure creating poll request to %s", location)
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
972
vendor/github.com/Azure/go-autorest/autorest/azure/async.go
generated
vendored
972
vendor/github.com/Azure/go-autorest/autorest/azure/async.go
generated
vendored
@ -1,972 +0,0 @@
|
||||
package azure
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
)
|
||||
|
||||
const (
|
||||
headerAsyncOperation = "Azure-AsyncOperation"
|
||||
)
|
||||
|
||||
const (
|
||||
operationInProgress string = "InProgress"
|
||||
operationCanceled string = "Canceled"
|
||||
operationFailed string = "Failed"
|
||||
operationSucceeded string = "Succeeded"
|
||||
)
|
||||
|
||||
var pollingCodes = [...]int{http.StatusNoContent, http.StatusAccepted, http.StatusCreated, http.StatusOK}
|
||||
|
||||
// Future provides a mechanism to access the status and results of an asynchronous request.
|
||||
// Since futures are stateful they should be passed by value to avoid race conditions.
|
||||
type Future struct {
|
||||
req *http.Request // legacy
|
||||
pt pollingTracker
|
||||
}
|
||||
|
||||
// NewFuture returns a new Future object initialized with the specified request.
|
||||
// Deprecated: Please use NewFutureFromResponse instead.
|
||||
func NewFuture(req *http.Request) Future {
|
||||
return Future{req: req}
|
||||
}
|
||||
|
||||
// NewFutureFromResponse returns a new Future object initialized
|
||||
// with the initial response from an asynchronous operation.
|
||||
func NewFutureFromResponse(resp *http.Response) (Future, error) {
|
||||
pt, err := createPollingTracker(resp)
|
||||
return Future{pt: pt}, err
|
||||
}
|
||||
|
||||
// Response returns the last HTTP response.
|
||||
func (f Future) Response() *http.Response {
|
||||
if f.pt == nil {
|
||||
return nil
|
||||
}
|
||||
return f.pt.latestResponse()
|
||||
}
|
||||
|
||||
// Status returns the last status message of the operation.
|
||||
func (f Future) Status() string {
|
||||
if f.pt == nil {
|
||||
return ""
|
||||
}
|
||||
return f.pt.pollingStatus()
|
||||
}
|
||||
|
||||
// PollingMethod returns the method used to monitor the status of the asynchronous operation.
|
||||
func (f Future) PollingMethod() PollingMethodType {
|
||||
if f.pt == nil {
|
||||
return PollingUnknown
|
||||
}
|
||||
return f.pt.pollingMethod()
|
||||
}
|
||||
|
||||
// Done queries the service to see if the operation has completed.
|
||||
// Deprecated: Use DoneWithContext()
|
||||
func (f *Future) Done(sender autorest.Sender) (bool, error) {
|
||||
return f.DoneWithContext(context.Background(), sender)
|
||||
}
|
||||
|
||||
// DoneWithContext queries the service to see if the operation has completed.
|
||||
func (f *Future) DoneWithContext(ctx context.Context, sender autorest.Sender) (done bool, err error) {
|
||||
// support for legacy Future implementation
|
||||
if f.req != nil {
|
||||
resp, err := sender.Do(f.req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
pt, err := createPollingTracker(resp)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
f.pt = pt
|
||||
f.req = nil
|
||||
}
|
||||
// end legacy
|
||||
if f.pt == nil {
|
||||
return false, autorest.NewError("Future", "Done", "future is not initialized")
|
||||
}
|
||||
if f.pt.hasTerminated() {
|
||||
return true, f.pt.pollingError()
|
||||
}
|
||||
if err := f.pt.pollForStatus(ctx, sender); err != nil {
|
||||
return false, err
|
||||
}
|
||||
if err := f.pt.checkForErrors(); err != nil {
|
||||
return f.pt.hasTerminated(), err
|
||||
}
|
||||
if err := f.pt.updatePollingState(f.pt.provisioningStateApplicable()); err != nil {
|
||||
return false, err
|
||||
}
|
||||
if err := f.pt.initPollingMethod(); err != nil {
|
||||
return false, err
|
||||
}
|
||||
if err := f.pt.updatePollingMethod(); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return f.pt.hasTerminated(), f.pt.pollingError()
|
||||
}
|
||||
|
||||
// GetPollingDelay returns a duration the application should wait before checking
|
||||
// the status of the asynchronous request and true; this value is returned from
|
||||
// the service via the Retry-After response header. If the header wasn't returned
|
||||
// then the function returns the zero-value time.Duration and false.
|
||||
func (f Future) GetPollingDelay() (time.Duration, bool) {
|
||||
if f.pt == nil {
|
||||
return 0, false
|
||||
}
|
||||
resp := f.pt.latestResponse()
|
||||
if resp == nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
retry := resp.Header.Get(autorest.HeaderRetryAfter)
|
||||
if retry == "" {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
d, err := time.ParseDuration(retry + "s")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return d, true
|
||||
}
|
||||
|
||||
// WaitForCompletion will return when one of the following conditions is met: the long
|
||||
// running operation has completed, the provided context is cancelled, or the client's
|
||||
// polling duration has been exceeded. It will retry failed polling attempts based on
|
||||
// the retry value defined in the client up to the maximum retry attempts.
|
||||
// Deprecated: Please use WaitForCompletionRef() instead.
|
||||
func (f Future) WaitForCompletion(ctx context.Context, client autorest.Client) error {
|
||||
return f.WaitForCompletionRef(ctx, client)
|
||||
}
|
||||
|
||||
// WaitForCompletionRef will return when one of the following conditions is met: the long
|
||||
// running operation has completed, the provided context is cancelled, or the client's
|
||||
// polling duration has been exceeded. It will retry failed polling attempts based on
|
||||
// the retry value defined in the client up to the maximum retry attempts.
|
||||
// If no deadline is specified in the context then the client.PollingDuration will be
|
||||
// used to determine if a default deadline should be used.
|
||||
// If PollingDuration is greater than zero the value will be used as the context's timeout.
|
||||
// If PollingDuration is zero then no default deadline will be used.
|
||||
func (f *Future) WaitForCompletionRef(ctx context.Context, client autorest.Client) (err error) {
|
||||
cancelCtx := ctx
|
||||
// if the provided context already has a deadline don't override it
|
||||
_, hasDeadline := ctx.Deadline()
|
||||
if d := client.PollingDuration; !hasDeadline && d != 0 {
|
||||
var cancel context.CancelFunc
|
||||
cancelCtx, cancel = context.WithTimeout(ctx, d)
|
||||
defer cancel()
|
||||
}
|
||||
|
||||
done, err := f.DoneWithContext(ctx, client)
|
||||
for attempts := 0; !done; done, err = f.DoneWithContext(ctx, client) {
|
||||
if attempts >= client.RetryAttempts {
|
||||
return autorest.NewErrorWithError(err, "Future", "WaitForCompletion", f.pt.latestResponse(), "the number of retries has been exceeded")
|
||||
}
|
||||
// we want delayAttempt to be zero in the non-error case so
|
||||
// that DelayForBackoff doesn't perform exponential back-off
|
||||
var delayAttempt int
|
||||
var delay time.Duration
|
||||
if err == nil {
|
||||
// check for Retry-After delay, if not present use the client's polling delay
|
||||
var ok bool
|
||||
delay, ok = f.GetPollingDelay()
|
||||
if !ok {
|
||||
delay = client.PollingDelay
|
||||
}
|
||||
} else {
|
||||
// there was an error polling for status so perform exponential
|
||||
// back-off based on the number of attempts using the client's retry
|
||||
// duration. update attempts after delayAttempt to avoid off-by-one.
|
||||
delayAttempt = attempts
|
||||
delay = client.RetryDuration
|
||||
attempts++
|
||||
}
|
||||
// wait until the delay elapses or the context is cancelled
|
||||
delayElapsed := autorest.DelayForBackoff(delay, delayAttempt, cancelCtx.Done())
|
||||
if !delayElapsed {
|
||||
return autorest.NewErrorWithError(cancelCtx.Err(), "Future", "WaitForCompletion", f.pt.latestResponse(), "context has been cancelled")
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (f Future) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(f.pt)
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||
func (f *Future) UnmarshalJSON(data []byte) error {
|
||||
// unmarshal into JSON object to determine the tracker type
|
||||
obj := map[string]interface{}{}
|
||||
err := json.Unmarshal(data, &obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if obj["method"] == nil {
|
||||
return autorest.NewError("Future", "UnmarshalJSON", "missing 'method' property")
|
||||
}
|
||||
method := obj["method"].(string)
|
||||
switch strings.ToUpper(method) {
|
||||
case http.MethodDelete:
|
||||
f.pt = &pollingTrackerDelete{}
|
||||
case http.MethodPatch:
|
||||
f.pt = &pollingTrackerPatch{}
|
||||
case http.MethodPost:
|
||||
f.pt = &pollingTrackerPost{}
|
||||
case http.MethodPut:
|
||||
f.pt = &pollingTrackerPut{}
|
||||
default:
|
||||
return autorest.NewError("Future", "UnmarshalJSON", "unsupoorted method '%s'", method)
|
||||
}
|
||||
// now unmarshal into the tracker
|
||||
return json.Unmarshal(data, &f.pt)
|
||||
}
|
||||
|
||||
// PollingURL returns the URL used for retrieving the status of the long-running operation.
|
||||
func (f Future) PollingURL() string {
|
||||
if f.pt == nil {
|
||||
return ""
|
||||
}
|
||||
return f.pt.pollingURL()
|
||||
}
|
||||
|
||||
// GetResult should be called once polling has completed successfully.
|
||||
// It makes the final GET call to retrieve the resultant payload.
|
||||
func (f Future) GetResult(sender autorest.Sender) (*http.Response, error) {
|
||||
if f.pt.finalGetURL() == "" {
|
||||
// we can end up in this situation if the async operation returns a 200
|
||||
// with no polling URLs. in that case return the response which should
|
||||
// contain the JSON payload (only do this for successful terminal cases).
|
||||
if lr := f.pt.latestResponse(); lr != nil && f.pt.hasSucceeded() {
|
||||
return lr, nil
|
||||
}
|
||||
return nil, autorest.NewError("Future", "GetResult", "missing URL for retrieving result")
|
||||
}
|
||||
req, err := http.NewRequest(http.MethodGet, f.pt.finalGetURL(), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return sender.Do(req)
|
||||
}
|
||||
|
||||
type pollingTracker interface {
|
||||
// these methods can differ per tracker
|
||||
|
||||
// checks the response headers and status code to determine the polling mechanism
|
||||
updatePollingMethod() error
|
||||
|
||||
// checks the response for tracker-specific error conditions
|
||||
checkForErrors() error
|
||||
|
||||
// returns true if provisioning state should be checked
|
||||
provisioningStateApplicable() bool
|
||||
|
||||
// methods common to all trackers
|
||||
|
||||
// initializes a tracker's polling URL and method, called for each iteration.
|
||||
// these values can be overridden by each polling tracker as required.
|
||||
initPollingMethod() error
|
||||
|
||||
// initializes the tracker's internal state, call this when the tracker is created
|
||||
initializeState() error
|
||||
|
||||
// makes an HTTP request to check the status of the LRO
|
||||
pollForStatus(ctx context.Context, sender autorest.Sender) error
|
||||
|
||||
// updates internal tracker state, call this after each call to pollForStatus
|
||||
updatePollingState(provStateApl bool) error
|
||||
|
||||
// returns the error response from the service, can be nil
|
||||
pollingError() error
|
||||
|
||||
// returns the polling method being used
|
||||
pollingMethod() PollingMethodType
|
||||
|
||||
// returns the state of the LRO as returned from the service
|
||||
pollingStatus() string
|
||||
|
||||
// returns the URL used for polling status
|
||||
pollingURL() string
|
||||
|
||||
// returns the URL used for the final GET to retrieve the resource
|
||||
finalGetURL() string
|
||||
|
||||
// returns true if the LRO is in a terminal state
|
||||
hasTerminated() bool
|
||||
|
||||
// returns true if the LRO is in a failed terminal state
|
||||
hasFailed() bool
|
||||
|
||||
// returns true if the LRO is in a successful terminal state
|
||||
hasSucceeded() bool
|
||||
|
||||
// returns the cached HTTP response after a call to pollForStatus(), can be nil
|
||||
latestResponse() *http.Response
|
||||
}
|
||||
|
||||
type pollingTrackerBase struct {
|
||||
// resp is the last response, either from the submission of the LRO or from polling
|
||||
resp *http.Response
|
||||
|
||||
// method is the HTTP verb, this is needed for deserialization
|
||||
Method string `json:"method"`
|
||||
|
||||
// rawBody is the raw JSON response body
|
||||
rawBody map[string]interface{}
|
||||
|
||||
// denotes if polling is using async-operation or location header
|
||||
Pm PollingMethodType `json:"pollingMethod"`
|
||||
|
||||
// the URL to poll for status
|
||||
URI string `json:"pollingURI"`
|
||||
|
||||
// the state of the LRO as returned from the service
|
||||
State string `json:"lroState"`
|
||||
|
||||
// the URL to GET for the final result
|
||||
FinalGetURI string `json:"resultURI"`
|
||||
|
||||
// used to hold an error object returned from the service
|
||||
Err *ServiceError `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
func (pt *pollingTrackerBase) initializeState() error {
|
||||
// determine the initial polling state based on response body and/or HTTP status
|
||||
// code. this is applicable to the initial LRO response, not polling responses!
|
||||
pt.Method = pt.resp.Request.Method
|
||||
if err := pt.updateRawBody(); err != nil {
|
||||
return err
|
||||
}
|
||||
switch pt.resp.StatusCode {
|
||||
case http.StatusOK:
|
||||
if ps := pt.getProvisioningState(); ps != nil {
|
||||
pt.State = *ps
|
||||
if pt.hasFailed() {
|
||||
pt.updateErrorFromResponse()
|
||||
return pt.pollingError()
|
||||
}
|
||||
} else {
|
||||
pt.State = operationSucceeded
|
||||
}
|
||||
case http.StatusCreated:
|
||||
if ps := pt.getProvisioningState(); ps != nil {
|
||||
pt.State = *ps
|
||||
} else {
|
||||
pt.State = operationInProgress
|
||||
}
|
||||
case http.StatusAccepted:
|
||||
pt.State = operationInProgress
|
||||
case http.StatusNoContent:
|
||||
pt.State = operationSucceeded
|
||||
default:
|
||||
pt.State = operationFailed
|
||||
pt.updateErrorFromResponse()
|
||||
return pt.pollingError()
|
||||
}
|
||||
return pt.initPollingMethod()
|
||||
}
|
||||
|
||||
func (pt pollingTrackerBase) getProvisioningState() *string {
|
||||
if pt.rawBody != nil && pt.rawBody["properties"] != nil {
|
||||
p := pt.rawBody["properties"].(map[string]interface{})
|
||||
if ps := p["provisioningState"]; ps != nil {
|
||||
s := ps.(string)
|
||||
return &s
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pt *pollingTrackerBase) updateRawBody() error {
|
||||
pt.rawBody = map[string]interface{}{}
|
||||
if pt.resp.ContentLength != 0 {
|
||||
defer pt.resp.Body.Close()
|
||||
b, err := ioutil.ReadAll(pt.resp.Body)
|
||||
if err != nil {
|
||||
return autorest.NewErrorWithError(err, "pollingTrackerBase", "updateRawBody", nil, "failed to read response body")
|
||||
}
|
||||
// observed in 204 responses over HTTP/2.0; the content length is -1 but body is empty
|
||||
if len(b) == 0 {
|
||||
return nil
|
||||
}
|
||||
// put the body back so it's available to other callers
|
||||
pt.resp.Body = ioutil.NopCloser(bytes.NewReader(b))
|
||||
if err = json.Unmarshal(b, &pt.rawBody); err != nil {
|
||||
return autorest.NewErrorWithError(err, "pollingTrackerBase", "updateRawBody", nil, "failed to unmarshal response body")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pt *pollingTrackerBase) pollForStatus(ctx context.Context, sender autorest.Sender) error {
|
||||
req, err := http.NewRequest(http.MethodGet, pt.URI, nil)
|
||||
if err != nil {
|
||||
return autorest.NewErrorWithError(err, "pollingTrackerBase", "pollForStatus", nil, "failed to create HTTP request")
|
||||
}
|
||||
|
||||
req = req.WithContext(ctx)
|
||||
pt.resp, err = sender.Do(req)
|
||||
if err != nil {
|
||||
return autorest.NewErrorWithError(err, "pollingTrackerBase", "pollForStatus", nil, "failed to send HTTP request")
|
||||
}
|
||||
if autorest.ResponseHasStatusCode(pt.resp, pollingCodes[:]...) {
|
||||
// reset the service error on success case
|
||||
pt.Err = nil
|
||||
err = pt.updateRawBody()
|
||||
} else {
|
||||
// check response body for error content
|
||||
pt.updateErrorFromResponse()
|
||||
err = pt.pollingError()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// attempts to unmarshal a ServiceError type from the response body.
|
||||
// if that fails then make a best attempt at creating something meaningful.
|
||||
// NOTE: this assumes that the async operation has failed.
|
||||
func (pt *pollingTrackerBase) updateErrorFromResponse() {
|
||||
var err error
|
||||
if pt.resp.ContentLength != 0 {
|
||||
type respErr struct {
|
||||
ServiceError *ServiceError `json:"error"`
|
||||
}
|
||||
re := respErr{}
|
||||
defer pt.resp.Body.Close()
|
||||
var b []byte
|
||||
if b, err = ioutil.ReadAll(pt.resp.Body); err != nil || len(b) == 0 {
|
||||
goto Default
|
||||
}
|
||||
if err = json.Unmarshal(b, &re); err != nil {
|
||||
goto Default
|
||||
}
|
||||
// unmarshalling the error didn't yield anything, try unwrapped error
|
||||
if re.ServiceError == nil {
|
||||
err = json.Unmarshal(b, &re.ServiceError)
|
||||
if err != nil {
|
||||
goto Default
|
||||
}
|
||||
}
|
||||
// the unmarshaller will ensure re.ServiceError is non-nil
|
||||
// even if there was no content unmarshalled so check the code.
|
||||
if re.ServiceError.Code != "" {
|
||||
pt.Err = re.ServiceError
|
||||
return
|
||||
}
|
||||
}
|
||||
Default:
|
||||
se := &ServiceError{
|
||||
Code: pt.pollingStatus(),
|
||||
Message: "The async operation failed.",
|
||||
}
|
||||
if err != nil {
|
||||
se.InnerError = make(map[string]interface{})
|
||||
se.InnerError["unmarshalError"] = err.Error()
|
||||
}
|
||||
// stick the response body into the error object in hopes
|
||||
// it contains something useful to help diagnose the failure.
|
||||
if len(pt.rawBody) > 0 {
|
||||
se.AdditionalInfo = []map[string]interface{}{
|
||||
pt.rawBody,
|
||||
}
|
||||
}
|
||||
pt.Err = se
|
||||
}
|
||||
|
||||
func (pt *pollingTrackerBase) updatePollingState(provStateApl bool) error {
|
||||
if pt.Pm == PollingAsyncOperation && pt.rawBody["status"] != nil {
|
||||
pt.State = pt.rawBody["status"].(string)
|
||||
} else {
|
||||
if pt.resp.StatusCode == http.StatusAccepted {
|
||||
pt.State = operationInProgress
|
||||
} else if provStateApl {
|
||||
if ps := pt.getProvisioningState(); ps != nil {
|
||||
pt.State = *ps
|
||||
} else {
|
||||
pt.State = operationSucceeded
|
||||
}
|
||||
} else {
|
||||
return autorest.NewError("pollingTrackerBase", "updatePollingState", "the response from the async operation has an invalid status code")
|
||||
}
|
||||
}
|
||||
// if the operation has failed update the error state
|
||||
if pt.hasFailed() {
|
||||
pt.updateErrorFromResponse()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pt pollingTrackerBase) pollingError() error {
|
||||
if pt.Err == nil {
|
||||
return nil
|
||||
}
|
||||
return pt.Err
|
||||
}
|
||||
|
||||
func (pt pollingTrackerBase) pollingMethod() PollingMethodType {
|
||||
return pt.Pm
|
||||
}
|
||||
|
||||
func (pt pollingTrackerBase) pollingStatus() string {
|
||||
return pt.State
|
||||
}
|
||||
|
||||
func (pt pollingTrackerBase) pollingURL() string {
|
||||
return pt.URI
|
||||
}
|
||||
|
||||
func (pt pollingTrackerBase) finalGetURL() string {
|
||||
return pt.FinalGetURI
|
||||
}
|
||||
|
||||
func (pt pollingTrackerBase) hasTerminated() bool {
|
||||
return strings.EqualFold(pt.State, operationCanceled) || strings.EqualFold(pt.State, operationFailed) || strings.EqualFold(pt.State, operationSucceeded)
|
||||
}
|
||||
|
||||
func (pt pollingTrackerBase) hasFailed() bool {
|
||||
return strings.EqualFold(pt.State, operationCanceled) || strings.EqualFold(pt.State, operationFailed)
|
||||
}
|
||||
|
||||
func (pt pollingTrackerBase) hasSucceeded() bool {
|
||||
return strings.EqualFold(pt.State, operationSucceeded)
|
||||
}
|
||||
|
||||
func (pt pollingTrackerBase) latestResponse() *http.Response {
|
||||
return pt.resp
|
||||
}
|
||||
|
||||
// error checking common to all trackers
|
||||
func (pt pollingTrackerBase) baseCheckForErrors() error {
|
||||
// for Azure-AsyncOperations the response body cannot be nil or empty
|
||||
if pt.Pm == PollingAsyncOperation {
|
||||
if pt.resp.Body == nil || pt.resp.ContentLength == 0 {
|
||||
return autorest.NewError("pollingTrackerBase", "baseCheckForErrors", "for Azure-AsyncOperation response body cannot be nil")
|
||||
}
|
||||
if pt.rawBody["status"] == nil {
|
||||
return autorest.NewError("pollingTrackerBase", "baseCheckForErrors", "missing status property in Azure-AsyncOperation response body")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// default initialization of polling URL/method. each verb tracker will update this as required.
|
||||
func (pt *pollingTrackerBase) initPollingMethod() error {
|
||||
if ao, err := getURLFromAsyncOpHeader(pt.resp); err != nil {
|
||||
return err
|
||||
} else if ao != "" {
|
||||
pt.URI = ao
|
||||
pt.Pm = PollingAsyncOperation
|
||||
return nil
|
||||
}
|
||||
if lh, err := getURLFromLocationHeader(pt.resp); err != nil {
|
||||
return err
|
||||
} else if lh != "" {
|
||||
pt.URI = lh
|
||||
pt.Pm = PollingLocation
|
||||
return nil
|
||||
}
|
||||
// it's ok if we didn't find a polling header, this will be handled elsewhere
|
||||
return nil
|
||||
}
|
||||
|
||||
// DELETE
|
||||
|
||||
type pollingTrackerDelete struct {
|
||||
pollingTrackerBase
|
||||
}
|
||||
|
||||
func (pt *pollingTrackerDelete) updatePollingMethod() error {
|
||||
// for 201 the Location header is required
|
||||
if pt.resp.StatusCode == http.StatusCreated {
|
||||
if lh, err := getURLFromLocationHeader(pt.resp); err != nil {
|
||||
return err
|
||||
} else if lh == "" {
|
||||
return autorest.NewError("pollingTrackerDelete", "updateHeaders", "missing Location header in 201 response")
|
||||
} else {
|
||||
pt.URI = lh
|
||||
}
|
||||
pt.Pm = PollingLocation
|
||||
pt.FinalGetURI = pt.URI
|
||||
}
|
||||
// for 202 prefer the Azure-AsyncOperation header but fall back to Location if necessary
|
||||
if pt.resp.StatusCode == http.StatusAccepted {
|
||||
ao, err := getURLFromAsyncOpHeader(pt.resp)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if ao != "" {
|
||||
pt.URI = ao
|
||||
pt.Pm = PollingAsyncOperation
|
||||
}
|
||||
// if the Location header is invalid and we already have a polling URL
|
||||
// then we don't care if the Location header URL is malformed.
|
||||
if lh, err := getURLFromLocationHeader(pt.resp); err != nil && pt.URI == "" {
|
||||
return err
|
||||
} else if lh != "" {
|
||||
if ao == "" {
|
||||
pt.URI = lh
|
||||
pt.Pm = PollingLocation
|
||||
}
|
||||
// when both headers are returned we use the value in the Location header for the final GET
|
||||
pt.FinalGetURI = lh
|
||||
}
|
||||
// make sure a polling URL was found
|
||||
if pt.URI == "" {
|
||||
return autorest.NewError("pollingTrackerPost", "updateHeaders", "didn't get any suitable polling URLs in 202 response")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pt pollingTrackerDelete) checkForErrors() error {
|
||||
return pt.baseCheckForErrors()
|
||||
}
|
||||
|
||||
func (pt pollingTrackerDelete) provisioningStateApplicable() bool {
|
||||
return pt.resp.StatusCode == http.StatusOK || pt.resp.StatusCode == http.StatusNoContent
|
||||
}
|
||||
|
||||
// PATCH
|
||||
|
||||
type pollingTrackerPatch struct {
|
||||
pollingTrackerBase
|
||||
}
|
||||
|
||||
func (pt *pollingTrackerPatch) updatePollingMethod() error {
|
||||
// by default we can use the original URL for polling and final GET
|
||||
if pt.URI == "" {
|
||||
pt.URI = pt.resp.Request.URL.String()
|
||||
}
|
||||
if pt.FinalGetURI == "" {
|
||||
pt.FinalGetURI = pt.resp.Request.URL.String()
|
||||
}
|
||||
if pt.Pm == PollingUnknown {
|
||||
pt.Pm = PollingRequestURI
|
||||
}
|
||||
// for 201 it's permissible for no headers to be returned
|
||||
if pt.resp.StatusCode == http.StatusCreated {
|
||||
if ao, err := getURLFromAsyncOpHeader(pt.resp); err != nil {
|
||||
return err
|
||||
} else if ao != "" {
|
||||
pt.URI = ao
|
||||
pt.Pm = PollingAsyncOperation
|
||||
}
|
||||
}
|
||||
// for 202 prefer the Azure-AsyncOperation header but fall back to Location if necessary
|
||||
// note the absence of the "final GET" mechanism for PATCH
|
||||
if pt.resp.StatusCode == http.StatusAccepted {
|
||||
ao, err := getURLFromAsyncOpHeader(pt.resp)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if ao != "" {
|
||||
pt.URI = ao
|
||||
pt.Pm = PollingAsyncOperation
|
||||
}
|
||||
if ao == "" {
|
||||
if lh, err := getURLFromLocationHeader(pt.resp); err != nil {
|
||||
return err
|
||||
} else if lh == "" {
|
||||
return autorest.NewError("pollingTrackerPatch", "updateHeaders", "didn't get any suitable polling URLs in 202 response")
|
||||
} else {
|
||||
pt.URI = lh
|
||||
pt.Pm = PollingLocation
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pt pollingTrackerPatch) checkForErrors() error {
|
||||
return pt.baseCheckForErrors()
|
||||
}
|
||||
|
||||
func (pt pollingTrackerPatch) provisioningStateApplicable() bool {
|
||||
return pt.resp.StatusCode == http.StatusOK || pt.resp.StatusCode == http.StatusCreated
|
||||
}
|
||||
|
||||
// POST
|
||||
|
||||
type pollingTrackerPost struct {
|
||||
pollingTrackerBase
|
||||
}
|
||||
|
||||
func (pt *pollingTrackerPost) updatePollingMethod() error {
|
||||
// 201 requires Location header
|
||||
if pt.resp.StatusCode == http.StatusCreated {
|
||||
if lh, err := getURLFromLocationHeader(pt.resp); err != nil {
|
||||
return err
|
||||
} else if lh == "" {
|
||||
return autorest.NewError("pollingTrackerPost", "updateHeaders", "missing Location header in 201 response")
|
||||
} else {
|
||||
pt.URI = lh
|
||||
pt.FinalGetURI = lh
|
||||
pt.Pm = PollingLocation
|
||||
}
|
||||
}
|
||||
// for 202 prefer the Azure-AsyncOperation header but fall back to Location if necessary
|
||||
if pt.resp.StatusCode == http.StatusAccepted {
|
||||
ao, err := getURLFromAsyncOpHeader(pt.resp)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if ao != "" {
|
||||
pt.URI = ao
|
||||
pt.Pm = PollingAsyncOperation
|
||||
}
|
||||
// if the Location header is invalid and we already have a polling URL
|
||||
// then we don't care if the Location header URL is malformed.
|
||||
if lh, err := getURLFromLocationHeader(pt.resp); err != nil && pt.URI == "" {
|
||||
return err
|
||||
} else if lh != "" {
|
||||
if ao == "" {
|
||||
pt.URI = lh
|
||||
pt.Pm = PollingLocation
|
||||
}
|
||||
// when both headers are returned we use the value in the Location header for the final GET
|
||||
pt.FinalGetURI = lh
|
||||
}
|
||||
// make sure a polling URL was found
|
||||
if pt.URI == "" {
|
||||
return autorest.NewError("pollingTrackerPost", "updateHeaders", "didn't get any suitable polling URLs in 202 response")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pt pollingTrackerPost) checkForErrors() error {
|
||||
return pt.baseCheckForErrors()
|
||||
}
|
||||
|
||||
func (pt pollingTrackerPost) provisioningStateApplicable() bool {
|
||||
return pt.resp.StatusCode == http.StatusOK || pt.resp.StatusCode == http.StatusNoContent
|
||||
}
|
||||
|
||||
// PUT
|
||||
|
||||
type pollingTrackerPut struct {
|
||||
pollingTrackerBase
|
||||
}
|
||||
|
||||
func (pt *pollingTrackerPut) updatePollingMethod() error {
|
||||
// by default we can use the original URL for polling and final GET
|
||||
if pt.URI == "" {
|
||||
pt.URI = pt.resp.Request.URL.String()
|
||||
}
|
||||
if pt.FinalGetURI == "" {
|
||||
pt.FinalGetURI = pt.resp.Request.URL.String()
|
||||
}
|
||||
if pt.Pm == PollingUnknown {
|
||||
pt.Pm = PollingRequestURI
|
||||
}
|
||||
// for 201 it's permissible for no headers to be returned
|
||||
if pt.resp.StatusCode == http.StatusCreated {
|
||||
if ao, err := getURLFromAsyncOpHeader(pt.resp); err != nil {
|
||||
return err
|
||||
} else if ao != "" {
|
||||
pt.URI = ao
|
||||
pt.Pm = PollingAsyncOperation
|
||||
}
|
||||
}
|
||||
// for 202 prefer the Azure-AsyncOperation header but fall back to Location if necessary
|
||||
if pt.resp.StatusCode == http.StatusAccepted {
|
||||
ao, err := getURLFromAsyncOpHeader(pt.resp)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if ao != "" {
|
||||
pt.URI = ao
|
||||
pt.Pm = PollingAsyncOperation
|
||||
}
|
||||
// if the Location header is invalid and we already have a polling URL
|
||||
// then we don't care if the Location header URL is malformed.
|
||||
if lh, err := getURLFromLocationHeader(pt.resp); err != nil && pt.URI == "" {
|
||||
return err
|
||||
} else if lh != "" {
|
||||
if ao == "" {
|
||||
pt.URI = lh
|
||||
pt.Pm = PollingLocation
|
||||
}
|
||||
}
|
||||
// make sure a polling URL was found
|
||||
if pt.URI == "" {
|
||||
return autorest.NewError("pollingTrackerPut", "updateHeaders", "didn't get any suitable polling URLs in 202 response")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pt pollingTrackerPut) checkForErrors() error {
|
||||
err := pt.baseCheckForErrors()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// if there are no LRO headers then the body cannot be empty
|
||||
ao, err := getURLFromAsyncOpHeader(pt.resp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
lh, err := getURLFromLocationHeader(pt.resp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if ao == "" && lh == "" && len(pt.rawBody) == 0 {
|
||||
return autorest.NewError("pollingTrackerPut", "checkForErrors", "the response did not contain a body")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pt pollingTrackerPut) provisioningStateApplicable() bool {
|
||||
return pt.resp.StatusCode == http.StatusOK || pt.resp.StatusCode == http.StatusCreated
|
||||
}
|
||||
|
||||
// creates a polling tracker based on the verb of the original request
|
||||
func createPollingTracker(resp *http.Response) (pollingTracker, error) {
|
||||
var pt pollingTracker
|
||||
switch strings.ToUpper(resp.Request.Method) {
|
||||
case http.MethodDelete:
|
||||
pt = &pollingTrackerDelete{pollingTrackerBase: pollingTrackerBase{resp: resp}}
|
||||
case http.MethodPatch:
|
||||
pt = &pollingTrackerPatch{pollingTrackerBase: pollingTrackerBase{resp: resp}}
|
||||
case http.MethodPost:
|
||||
pt = &pollingTrackerPost{pollingTrackerBase: pollingTrackerBase{resp: resp}}
|
||||
case http.MethodPut:
|
||||
pt = &pollingTrackerPut{pollingTrackerBase: pollingTrackerBase{resp: resp}}
|
||||
default:
|
||||
return nil, autorest.NewError("azure", "createPollingTracker", "unsupported HTTP method %s", resp.Request.Method)
|
||||
}
|
||||
if err := pt.initializeState(); err != nil {
|
||||
return pt, err
|
||||
}
|
||||
// this initializes the polling header values, we do this during creation in case the
|
||||
// initial response send us invalid values; this way the API call will return a non-nil
|
||||
// error (not doing this means the error shows up in Future.Done)
|
||||
return pt, pt.updatePollingMethod()
|
||||
}
|
||||
|
||||
// gets the polling URL from the Azure-AsyncOperation header.
|
||||
// ensures the URL is well-formed and absolute.
|
||||
func getURLFromAsyncOpHeader(resp *http.Response) (string, error) {
|
||||
s := resp.Header.Get(http.CanonicalHeaderKey(headerAsyncOperation))
|
||||
if s == "" {
|
||||
return "", nil
|
||||
}
|
||||
if !isValidURL(s) {
|
||||
return "", autorest.NewError("azure", "getURLFromAsyncOpHeader", "invalid polling URL '%s'", s)
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// gets the polling URL from the Location header.
|
||||
// ensures the URL is well-formed and absolute.
|
||||
func getURLFromLocationHeader(resp *http.Response) (string, error) {
|
||||
s := resp.Header.Get(http.CanonicalHeaderKey(autorest.HeaderLocation))
|
||||
if s == "" {
|
||||
return "", nil
|
||||
}
|
||||
if !isValidURL(s) {
|
||||
return "", autorest.NewError("azure", "getURLFromLocationHeader", "invalid polling URL '%s'", s)
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// verify that the URL is valid and absolute
|
||||
func isValidURL(s string) bool {
|
||||
u, err := url.Parse(s)
|
||||
return err == nil && u.IsAbs()
|
||||
}
|
||||
|
||||
// DoPollForAsynchronous returns a SendDecorator that polls if the http.Response is for an Azure
|
||||
// long-running operation. It will delay between requests for the duration specified in the
|
||||
// RetryAfter header or, if the header is absent, the passed delay. Polling may be canceled via
|
||||
// the context associated with the http.Request.
|
||||
// Deprecated: Prefer using Futures to allow for non-blocking async operations.
|
||||
func DoPollForAsynchronous(delay time.Duration) autorest.SendDecorator {
|
||||
return func(s autorest.Sender) autorest.Sender {
|
||||
return autorest.SenderFunc(func(r *http.Request) (*http.Response, error) {
|
||||
resp, err := s.Do(r)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
if !autorest.ResponseHasStatusCode(resp, pollingCodes[:]...) {
|
||||
return resp, nil
|
||||
}
|
||||
future, err := NewFutureFromResponse(resp)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
// retry until either the LRO completes or we receive an error
|
||||
var done bool
|
||||
for done, err = future.Done(s); !done && err == nil; done, err = future.Done(s) {
|
||||
// check for Retry-After delay, if not present use the specified polling delay
|
||||
if pd, ok := future.GetPollingDelay(); ok {
|
||||
delay = pd
|
||||
}
|
||||
// wait until the delay elapses or the context is cancelled
|
||||
if delayElapsed := autorest.DelayForBackoff(delay, 0, r.Context().Done()); !delayElapsed {
|
||||
return future.Response(),
|
||||
autorest.NewErrorWithError(r.Context().Err(), "azure", "DoPollForAsynchronous", future.Response(), "context has been cancelled")
|
||||
}
|
||||
}
|
||||
return future.Response(), err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// PollingMethodType defines a type used for enumerating polling mechanisms.
|
||||
type PollingMethodType string
|
||||
|
||||
const (
|
||||
// PollingAsyncOperation indicates the polling method uses the Azure-AsyncOperation header.
|
||||
PollingAsyncOperation PollingMethodType = "AsyncOperation"
|
||||
|
||||
// PollingLocation indicates the polling method uses the Location header.
|
||||
PollingLocation PollingMethodType = "Location"
|
||||
|
||||
// PollingRequestURI indicates the polling method uses the original request URI.
|
||||
PollingRequestURI PollingMethodType = "RequestURI"
|
||||
|
||||
// PollingUnknown indicates an unknown polling method and is the default value.
|
||||
PollingUnknown PollingMethodType = ""
|
||||
)
|
||||
|
||||
// AsyncOpIncompleteError is the type that's returned from a future that has not completed.
|
||||
type AsyncOpIncompleteError struct {
|
||||
// FutureType is the name of the type composed of a azure.Future.
|
||||
FutureType string
|
||||
}
|
||||
|
||||
// Error returns an error message including the originating type name of the error.
|
||||
func (e AsyncOpIncompleteError) Error() string {
|
||||
return fmt.Sprintf("%s: asynchronous operation has not completed", e.FutureType)
|
||||
}
|
||||
|
||||
// NewAsyncOpIncompleteError creates a new AsyncOpIncompleteError with the specified parameters.
|
||||
func NewAsyncOpIncompleteError(futureType string) AsyncOpIncompleteError {
|
||||
return AsyncOpIncompleteError{
|
||||
FutureType: futureType,
|
||||
}
|
||||
}
|
326
vendor/github.com/Azure/go-autorest/autorest/azure/azure.go
generated
vendored
326
vendor/github.com/Azure/go-autorest/autorest/azure/azure.go
generated
vendored
@ -1,326 +0,0 @@
|
||||
// Package azure provides Azure-specific implementations used with AutoRest.
|
||||
// See the included examples for more detail.
|
||||
package azure
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
)
|
||||
|
||||
const (
|
||||
// HeaderClientID is the Azure extension header to set a user-specified request ID.
|
||||
HeaderClientID = "x-ms-client-request-id"
|
||||
|
||||
// HeaderReturnClientID is the Azure extension header to set if the user-specified request ID
|
||||
// should be included in the response.
|
||||
HeaderReturnClientID = "x-ms-return-client-request-id"
|
||||
|
||||
// HeaderRequestID is the Azure extension header of the service generated request ID returned
|
||||
// in the response.
|
||||
HeaderRequestID = "x-ms-request-id"
|
||||
)
|
||||
|
||||
// ServiceError encapsulates the error response from an Azure service.
|
||||
// It adhears to the OData v4 specification for error responses.
|
||||
type ServiceError struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Target *string `json:"target"`
|
||||
Details []map[string]interface{} `json:"details"`
|
||||
InnerError map[string]interface{} `json:"innererror"`
|
||||
AdditionalInfo []map[string]interface{} `json:"additionalInfo"`
|
||||
}
|
||||
|
||||
func (se ServiceError) Error() string {
|
||||
result := fmt.Sprintf("Code=%q Message=%q", se.Code, se.Message)
|
||||
|
||||
if se.Target != nil {
|
||||
result += fmt.Sprintf(" Target=%q", *se.Target)
|
||||
}
|
||||
|
||||
if se.Details != nil {
|
||||
d, err := json.Marshal(se.Details)
|
||||
if err != nil {
|
||||
result += fmt.Sprintf(" Details=%v", se.Details)
|
||||
}
|
||||
result += fmt.Sprintf(" Details=%v", string(d))
|
||||
}
|
||||
|
||||
if se.InnerError != nil {
|
||||
d, err := json.Marshal(se.InnerError)
|
||||
if err != nil {
|
||||
result += fmt.Sprintf(" InnerError=%v", se.InnerError)
|
||||
}
|
||||
result += fmt.Sprintf(" InnerError=%v", string(d))
|
||||
}
|
||||
|
||||
if se.AdditionalInfo != nil {
|
||||
d, err := json.Marshal(se.AdditionalInfo)
|
||||
if err != nil {
|
||||
result += fmt.Sprintf(" AdditionalInfo=%v", se.AdditionalInfo)
|
||||
}
|
||||
result += fmt.Sprintf(" AdditionalInfo=%v", string(d))
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface for the ServiceError type.
|
||||
func (se *ServiceError) UnmarshalJSON(b []byte) error {
|
||||
// per the OData v4 spec the details field must be an array of JSON objects.
|
||||
// unfortunately not all services adhear to the spec and just return a single
|
||||
// object instead of an array with one object. so we have to perform some
|
||||
// shenanigans to accommodate both cases.
|
||||
// http://docs.oasis-open.org/odata/odata-json-format/v4.0/os/odata-json-format-v4.0-os.html#_Toc372793091
|
||||
|
||||
type serviceError1 struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Target *string `json:"target"`
|
||||
Details []map[string]interface{} `json:"details"`
|
||||
InnerError map[string]interface{} `json:"innererror"`
|
||||
AdditionalInfo []map[string]interface{} `json:"additionalInfo"`
|
||||
}
|
||||
|
||||
type serviceError2 struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Target *string `json:"target"`
|
||||
Details map[string]interface{} `json:"details"`
|
||||
InnerError map[string]interface{} `json:"innererror"`
|
||||
AdditionalInfo []map[string]interface{} `json:"additionalInfo"`
|
||||
}
|
||||
|
||||
se1 := serviceError1{}
|
||||
err := json.Unmarshal(b, &se1)
|
||||
if err == nil {
|
||||
se.populate(se1.Code, se1.Message, se1.Target, se1.Details, se1.InnerError, se1.AdditionalInfo)
|
||||
return nil
|
||||
}
|
||||
|
||||
se2 := serviceError2{}
|
||||
err = json.Unmarshal(b, &se2)
|
||||
if err == nil {
|
||||
se.populate(se2.Code, se2.Message, se2.Target, nil, se2.InnerError, se2.AdditionalInfo)
|
||||
se.Details = append(se.Details, se2.Details)
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (se *ServiceError) populate(code, message string, target *string, details []map[string]interface{}, inner map[string]interface{}, additional []map[string]interface{}) {
|
||||
se.Code = code
|
||||
se.Message = message
|
||||
se.Target = target
|
||||
se.Details = details
|
||||
se.InnerError = inner
|
||||
se.AdditionalInfo = additional
|
||||
}
|
||||
|
||||
// RequestError describes an error response returned by Azure service.
|
||||
type RequestError struct {
|
||||
autorest.DetailedError
|
||||
|
||||
// The error returned by the Azure service.
|
||||
ServiceError *ServiceError `json:"error"`
|
||||
|
||||
// The request id (from the x-ms-request-id-header) of the request.
|
||||
RequestID string
|
||||
}
|
||||
|
||||
// Error returns a human-friendly error message from service error.
|
||||
func (e RequestError) Error() string {
|
||||
return fmt.Sprintf("autorest/azure: Service returned an error. Status=%v %v",
|
||||
e.StatusCode, e.ServiceError)
|
||||
}
|
||||
|
||||
// IsAzureError returns true if the passed error is an Azure Service error; false otherwise.
|
||||
func IsAzureError(e error) bool {
|
||||
_, ok := e.(*RequestError)
|
||||
return ok
|
||||
}
|
||||
|
||||
// Resource contains details about an Azure resource.
|
||||
type Resource struct {
|
||||
SubscriptionID string
|
||||
ResourceGroup string
|
||||
Provider string
|
||||
ResourceType string
|
||||
ResourceName string
|
||||
}
|
||||
|
||||
// ParseResourceID parses a resource ID into a ResourceDetails struct.
|
||||
// See https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-template-functions-resource#return-value-4.
|
||||
func ParseResourceID(resourceID string) (Resource, error) {
|
||||
|
||||
const resourceIDPatternText = `(?i)subscriptions/(.+)/resourceGroups/(.+)/providers/(.+?)/(.+?)/(.+)`
|
||||
resourceIDPattern := regexp.MustCompile(resourceIDPatternText)
|
||||
match := resourceIDPattern.FindStringSubmatch(resourceID)
|
||||
|
||||
if len(match) == 0 {
|
||||
return Resource{}, fmt.Errorf("parsing failed for %s. Invalid resource Id format", resourceID)
|
||||
}
|
||||
|
||||
v := strings.Split(match[5], "/")
|
||||
resourceName := v[len(v)-1]
|
||||
|
||||
result := Resource{
|
||||
SubscriptionID: match[1],
|
||||
ResourceGroup: match[2],
|
||||
Provider: match[3],
|
||||
ResourceType: match[4],
|
||||
ResourceName: resourceName,
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// NewErrorWithError creates a new Error conforming object from the
|
||||
// passed packageType, method, statusCode of the given resp (UndefinedStatusCode
|
||||
// if resp is nil), message, and original error. message is treated as a format
|
||||
// string to which the optional args apply.
|
||||
func NewErrorWithError(original error, packageType string, method string, resp *http.Response, message string, args ...interface{}) RequestError {
|
||||
if v, ok := original.(*RequestError); ok {
|
||||
return *v
|
||||
}
|
||||
|
||||
statusCode := autorest.UndefinedStatusCode
|
||||
if resp != nil {
|
||||
statusCode = resp.StatusCode
|
||||
}
|
||||
return RequestError{
|
||||
DetailedError: autorest.DetailedError{
|
||||
Original: original,
|
||||
PackageType: packageType,
|
||||
Method: method,
|
||||
StatusCode: statusCode,
|
||||
Message: fmt.Sprintf(message, args...),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// WithReturningClientID returns a PrepareDecorator that adds an HTTP extension header of
|
||||
// x-ms-client-request-id whose value is the passed, undecorated UUID (e.g.,
|
||||
// "0F39878C-5F76-4DB8-A25D-61D2C193C3CA"). It also sets the x-ms-return-client-request-id
|
||||
// header to true such that UUID accompanies the http.Response.
|
||||
func WithReturningClientID(uuid string) autorest.PrepareDecorator {
|
||||
preparer := autorest.CreatePreparer(
|
||||
WithClientID(uuid),
|
||||
WithReturnClientID(true))
|
||||
|
||||
return func(p autorest.Preparer) autorest.Preparer {
|
||||
return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
r, err := p.Prepare(r)
|
||||
if err != nil {
|
||||
return r, err
|
||||
}
|
||||
return preparer.Prepare(r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// WithClientID returns a PrepareDecorator that adds an HTTP extension header of
|
||||
// x-ms-client-request-id whose value is passed, undecorated UUID (e.g.,
|
||||
// "0F39878C-5F76-4DB8-A25D-61D2C193C3CA").
|
||||
func WithClientID(uuid string) autorest.PrepareDecorator {
|
||||
return autorest.WithHeader(HeaderClientID, uuid)
|
||||
}
|
||||
|
||||
// WithReturnClientID returns a PrepareDecorator that adds an HTTP extension header of
|
||||
// x-ms-return-client-request-id whose boolean value indicates if the value of the
|
||||
// x-ms-client-request-id header should be included in the http.Response.
|
||||
func WithReturnClientID(b bool) autorest.PrepareDecorator {
|
||||
return autorest.WithHeader(HeaderReturnClientID, strconv.FormatBool(b))
|
||||
}
|
||||
|
||||
// ExtractClientID extracts the client identifier from the x-ms-client-request-id header set on the
|
||||
// http.Request sent to the service (and returned in the http.Response)
|
||||
func ExtractClientID(resp *http.Response) string {
|
||||
return autorest.ExtractHeaderValue(HeaderClientID, resp)
|
||||
}
|
||||
|
||||
// ExtractRequestID extracts the Azure server generated request identifier from the
|
||||
// x-ms-request-id header.
|
||||
func ExtractRequestID(resp *http.Response) string {
|
||||
return autorest.ExtractHeaderValue(HeaderRequestID, resp)
|
||||
}
|
||||
|
||||
// WithErrorUnlessStatusCode returns a RespondDecorator that emits an
|
||||
// azure.RequestError by reading the response body unless the response HTTP status code
|
||||
// is among the set passed.
|
||||
//
|
||||
// If there is a chance service may return responses other than the Azure error
|
||||
// format and the response cannot be parsed into an error, a decoding error will
|
||||
// be returned containing the response body. In any case, the Responder will
|
||||
// return an error if the status code is not satisfied.
|
||||
//
|
||||
// If this Responder returns an error, the response body will be replaced with
|
||||
// an in-memory reader, which needs no further closing.
|
||||
func WithErrorUnlessStatusCode(codes ...int) autorest.RespondDecorator {
|
||||
return func(r autorest.Responder) autorest.Responder {
|
||||
return autorest.ResponderFunc(func(resp *http.Response) error {
|
||||
err := r.Respond(resp)
|
||||
if err == nil && !autorest.ResponseHasStatusCode(resp, codes...) {
|
||||
var e RequestError
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Copy and replace the Body in case it does not contain an error object.
|
||||
// This will leave the Body available to the caller.
|
||||
b, decodeErr := autorest.CopyAndDecode(autorest.EncodedAsJSON, resp.Body, &e)
|
||||
resp.Body = ioutil.NopCloser(&b)
|
||||
if decodeErr != nil {
|
||||
return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b.String(), decodeErr)
|
||||
}
|
||||
if e.ServiceError == nil {
|
||||
// Check if error is unwrapped ServiceError
|
||||
if err := json.Unmarshal(b.Bytes(), &e.ServiceError); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if e.ServiceError.Message == "" {
|
||||
// if we're here it means the returned error wasn't OData v4 compliant.
|
||||
// try to unmarshal the body as raw JSON in hopes of getting something.
|
||||
rawBody := map[string]interface{}{}
|
||||
if err := json.Unmarshal(b.Bytes(), &rawBody); err != nil {
|
||||
return err
|
||||
}
|
||||
e.ServiceError = &ServiceError{
|
||||
Code: "Unknown",
|
||||
Message: "Unknown service error",
|
||||
}
|
||||
if len(rawBody) > 0 {
|
||||
e.ServiceError.Details = []map[string]interface{}{rawBody}
|
||||
}
|
||||
}
|
||||
e.Response = resp
|
||||
e.RequestID = ExtractRequestID(resp)
|
||||
if e.StatusCode == nil {
|
||||
e.StatusCode = resp.StatusCode
|
||||
}
|
||||
err = &e
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
||||
}
|
191
vendor/github.com/Azure/go-autorest/autorest/azure/environments.go
generated
vendored
191
vendor/github.com/Azure/go-autorest/autorest/azure/environments.go
generated
vendored
@ -1,191 +0,0 @@
|
||||
package azure
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// EnvironmentFilepathName captures the name of the environment variable containing the path to the file
|
||||
// to be used while populating the Azure Environment.
|
||||
const EnvironmentFilepathName = "AZURE_ENVIRONMENT_FILEPATH"
|
||||
|
||||
var environments = map[string]Environment{
|
||||
"AZURECHINACLOUD": ChinaCloud,
|
||||
"AZUREGERMANCLOUD": GermanCloud,
|
||||
"AZUREPUBLICCLOUD": PublicCloud,
|
||||
"AZUREUSGOVERNMENTCLOUD": USGovernmentCloud,
|
||||
}
|
||||
|
||||
// Environment represents a set of endpoints for each of Azure's Clouds.
|
||||
type Environment struct {
|
||||
Name string `json:"name"`
|
||||
ManagementPortalURL string `json:"managementPortalURL"`
|
||||
PublishSettingsURL string `json:"publishSettingsURL"`
|
||||
ServiceManagementEndpoint string `json:"serviceManagementEndpoint"`
|
||||
ResourceManagerEndpoint string `json:"resourceManagerEndpoint"`
|
||||
ActiveDirectoryEndpoint string `json:"activeDirectoryEndpoint"`
|
||||
GalleryEndpoint string `json:"galleryEndpoint"`
|
||||
KeyVaultEndpoint string `json:"keyVaultEndpoint"`
|
||||
GraphEndpoint string `json:"graphEndpoint"`
|
||||
ServiceBusEndpoint string `json:"serviceBusEndpoint"`
|
||||
BatchManagementEndpoint string `json:"batchManagementEndpoint"`
|
||||
StorageEndpointSuffix string `json:"storageEndpointSuffix"`
|
||||
SQLDatabaseDNSSuffix string `json:"sqlDatabaseDNSSuffix"`
|
||||
TrafficManagerDNSSuffix string `json:"trafficManagerDNSSuffix"`
|
||||
KeyVaultDNSSuffix string `json:"keyVaultDNSSuffix"`
|
||||
ServiceBusEndpointSuffix string `json:"serviceBusEndpointSuffix"`
|
||||
ServiceManagementVMDNSSuffix string `json:"serviceManagementVMDNSSuffix"`
|
||||
ResourceManagerVMDNSSuffix string `json:"resourceManagerVMDNSSuffix"`
|
||||
ContainerRegistryDNSSuffix string `json:"containerRegistryDNSSuffix"`
|
||||
TokenAudience string `json:"tokenAudience"`
|
||||
}
|
||||
|
||||
var (
|
||||
// PublicCloud is the default public Azure cloud environment
|
||||
PublicCloud = Environment{
|
||||
Name: "AzurePublicCloud",
|
||||
ManagementPortalURL: "https://manage.windowsazure.com/",
|
||||
PublishSettingsURL: "https://manage.windowsazure.com/publishsettings/index",
|
||||
ServiceManagementEndpoint: "https://management.core.windows.net/",
|
||||
ResourceManagerEndpoint: "https://management.azure.com/",
|
||||
ActiveDirectoryEndpoint: "https://login.microsoftonline.com/",
|
||||
GalleryEndpoint: "https://gallery.azure.com/",
|
||||
KeyVaultEndpoint: "https://vault.azure.net/",
|
||||
GraphEndpoint: "https://graph.windows.net/",
|
||||
ServiceBusEndpoint: "https://servicebus.windows.net/",
|
||||
BatchManagementEndpoint: "https://batch.core.windows.net/",
|
||||
StorageEndpointSuffix: "core.windows.net",
|
||||
SQLDatabaseDNSSuffix: "database.windows.net",
|
||||
TrafficManagerDNSSuffix: "trafficmanager.net",
|
||||
KeyVaultDNSSuffix: "vault.azure.net",
|
||||
ServiceBusEndpointSuffix: "servicebus.windows.net",
|
||||
ServiceManagementVMDNSSuffix: "cloudapp.net",
|
||||
ResourceManagerVMDNSSuffix: "cloudapp.azure.com",
|
||||
ContainerRegistryDNSSuffix: "azurecr.io",
|
||||
TokenAudience: "https://management.azure.com/",
|
||||
}
|
||||
|
||||
// USGovernmentCloud is the cloud environment for the US Government
|
||||
USGovernmentCloud = Environment{
|
||||
Name: "AzureUSGovernmentCloud",
|
||||
ManagementPortalURL: "https://manage.windowsazure.us/",
|
||||
PublishSettingsURL: "https://manage.windowsazure.us/publishsettings/index",
|
||||
ServiceManagementEndpoint: "https://management.core.usgovcloudapi.net/",
|
||||
ResourceManagerEndpoint: "https://management.usgovcloudapi.net/",
|
||||
ActiveDirectoryEndpoint: "https://login.microsoftonline.us/",
|
||||
GalleryEndpoint: "https://gallery.usgovcloudapi.net/",
|
||||
KeyVaultEndpoint: "https://vault.usgovcloudapi.net/",
|
||||
GraphEndpoint: "https://graph.windows.net/",
|
||||
ServiceBusEndpoint: "https://servicebus.usgovcloudapi.net/",
|
||||
BatchManagementEndpoint: "https://batch.core.usgovcloudapi.net/",
|
||||
StorageEndpointSuffix: "core.usgovcloudapi.net",
|
||||
SQLDatabaseDNSSuffix: "database.usgovcloudapi.net",
|
||||
TrafficManagerDNSSuffix: "usgovtrafficmanager.net",
|
||||
KeyVaultDNSSuffix: "vault.usgovcloudapi.net",
|
||||
ServiceBusEndpointSuffix: "servicebus.usgovcloudapi.net",
|
||||
ServiceManagementVMDNSSuffix: "usgovcloudapp.net",
|
||||
ResourceManagerVMDNSSuffix: "cloudapp.windowsazure.us",
|
||||
ContainerRegistryDNSSuffix: "azurecr.io",
|
||||
TokenAudience: "https://management.usgovcloudapi.net/",
|
||||
}
|
||||
|
||||
// ChinaCloud is the cloud environment operated in China
|
||||
ChinaCloud = Environment{
|
||||
Name: "AzureChinaCloud",
|
||||
ManagementPortalURL: "https://manage.chinacloudapi.com/",
|
||||
PublishSettingsURL: "https://manage.chinacloudapi.com/publishsettings/index",
|
||||
ServiceManagementEndpoint: "https://management.core.chinacloudapi.cn/",
|
||||
ResourceManagerEndpoint: "https://management.chinacloudapi.cn/",
|
||||
ActiveDirectoryEndpoint: "https://login.chinacloudapi.cn/",
|
||||
GalleryEndpoint: "https://gallery.chinacloudapi.cn/",
|
||||
KeyVaultEndpoint: "https://vault.azure.cn/",
|
||||
GraphEndpoint: "https://graph.chinacloudapi.cn/",
|
||||
ServiceBusEndpoint: "https://servicebus.chinacloudapi.cn/",
|
||||
BatchManagementEndpoint: "https://batch.chinacloudapi.cn/",
|
||||
StorageEndpointSuffix: "core.chinacloudapi.cn",
|
||||
SQLDatabaseDNSSuffix: "database.chinacloudapi.cn",
|
||||
TrafficManagerDNSSuffix: "trafficmanager.cn",
|
||||
KeyVaultDNSSuffix: "vault.azure.cn",
|
||||
ServiceBusEndpointSuffix: "servicebus.chinacloudapi.cn",
|
||||
ServiceManagementVMDNSSuffix: "chinacloudapp.cn",
|
||||
ResourceManagerVMDNSSuffix: "cloudapp.azure.cn",
|
||||
ContainerRegistryDNSSuffix: "azurecr.io",
|
||||
TokenAudience: "https://management.chinacloudapi.cn/",
|
||||
}
|
||||
|
||||
// GermanCloud is the cloud environment operated in Germany
|
||||
GermanCloud = Environment{
|
||||
Name: "AzureGermanCloud",
|
||||
ManagementPortalURL: "http://portal.microsoftazure.de/",
|
||||
PublishSettingsURL: "https://manage.microsoftazure.de/publishsettings/index",
|
||||
ServiceManagementEndpoint: "https://management.core.cloudapi.de/",
|
||||
ResourceManagerEndpoint: "https://management.microsoftazure.de/",
|
||||
ActiveDirectoryEndpoint: "https://login.microsoftonline.de/",
|
||||
GalleryEndpoint: "https://gallery.cloudapi.de/",
|
||||
KeyVaultEndpoint: "https://vault.microsoftazure.de/",
|
||||
GraphEndpoint: "https://graph.cloudapi.de/",
|
||||
ServiceBusEndpoint: "https://servicebus.cloudapi.de/",
|
||||
BatchManagementEndpoint: "https://batch.cloudapi.de/",
|
||||
StorageEndpointSuffix: "core.cloudapi.de",
|
||||
SQLDatabaseDNSSuffix: "database.cloudapi.de",
|
||||
TrafficManagerDNSSuffix: "azuretrafficmanager.de",
|
||||
KeyVaultDNSSuffix: "vault.microsoftazure.de",
|
||||
ServiceBusEndpointSuffix: "servicebus.cloudapi.de",
|
||||
ServiceManagementVMDNSSuffix: "azurecloudapp.de",
|
||||
ResourceManagerVMDNSSuffix: "cloudapp.microsoftazure.de",
|
||||
ContainerRegistryDNSSuffix: "azurecr.io",
|
||||
TokenAudience: "https://management.microsoftazure.de/",
|
||||
}
|
||||
)
|
||||
|
||||
// EnvironmentFromName returns an Environment based on the common name specified.
|
||||
func EnvironmentFromName(name string) (Environment, error) {
|
||||
// IMPORTANT
|
||||
// As per @radhikagupta5:
|
||||
// This is technical debt, fundamentally here because Kubernetes is not currently accepting
|
||||
// contributions to the providers. Once that is an option, the provider should be updated to
|
||||
// directly call `EnvironmentFromFile`. Until then, we rely on dispatching Azure Stack environment creation
|
||||
// from this method based on the name that is provided to us.
|
||||
if strings.EqualFold(name, "AZURESTACKCLOUD") {
|
||||
return EnvironmentFromFile(os.Getenv(EnvironmentFilepathName))
|
||||
}
|
||||
|
||||
name = strings.ToUpper(name)
|
||||
env, ok := environments[name]
|
||||
if !ok {
|
||||
return env, fmt.Errorf("autorest/azure: There is no cloud environment matching the name %q", name)
|
||||
}
|
||||
|
||||
return env, nil
|
||||
}
|
||||
|
||||
// EnvironmentFromFile loads an Environment from a configuration file available on disk.
|
||||
// This function is particularly useful in the Hybrid Cloud model, where one must define their own
|
||||
// endpoints.
|
||||
func EnvironmentFromFile(location string) (unmarshaled Environment, err error) {
|
||||
fileContents, err := ioutil.ReadFile(location)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = json.Unmarshal(fileContents, &unmarshaled)
|
||||
|
||||
return
|
||||
}
|
245
vendor/github.com/Azure/go-autorest/autorest/azure/metadata_environment.go
generated
vendored
245
vendor/github.com/Azure/go-autorest/autorest/azure/metadata_environment.go
generated
vendored
@ -1,245 +0,0 @@
|
||||
package azure
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
)
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
type audience []string
|
||||
|
||||
type authentication struct {
|
||||
LoginEndpoint string `json:"loginEndpoint"`
|
||||
Audiences audience `json:"audiences"`
|
||||
}
|
||||
|
||||
type environmentMetadataInfo struct {
|
||||
GalleryEndpoint string `json:"galleryEndpoint"`
|
||||
GraphEndpoint string `json:"graphEndpoint"`
|
||||
PortalEndpoint string `json:"portalEndpoint"`
|
||||
Authentication authentication `json:"authentication"`
|
||||
}
|
||||
|
||||
// EnvironmentProperty represent property names that clients can override
|
||||
type EnvironmentProperty string
|
||||
|
||||
const (
|
||||
// EnvironmentName ...
|
||||
EnvironmentName EnvironmentProperty = "name"
|
||||
// EnvironmentManagementPortalURL ..
|
||||
EnvironmentManagementPortalURL EnvironmentProperty = "managementPortalURL"
|
||||
// EnvironmentPublishSettingsURL ...
|
||||
EnvironmentPublishSettingsURL EnvironmentProperty = "publishSettingsURL"
|
||||
// EnvironmentServiceManagementEndpoint ...
|
||||
EnvironmentServiceManagementEndpoint EnvironmentProperty = "serviceManagementEndpoint"
|
||||
// EnvironmentResourceManagerEndpoint ...
|
||||
EnvironmentResourceManagerEndpoint EnvironmentProperty = "resourceManagerEndpoint"
|
||||
// EnvironmentActiveDirectoryEndpoint ...
|
||||
EnvironmentActiveDirectoryEndpoint EnvironmentProperty = "activeDirectoryEndpoint"
|
||||
// EnvironmentGalleryEndpoint ...
|
||||
EnvironmentGalleryEndpoint EnvironmentProperty = "galleryEndpoint"
|
||||
// EnvironmentKeyVaultEndpoint ...
|
||||
EnvironmentKeyVaultEndpoint EnvironmentProperty = "keyVaultEndpoint"
|
||||
// EnvironmentGraphEndpoint ...
|
||||
EnvironmentGraphEndpoint EnvironmentProperty = "graphEndpoint"
|
||||
// EnvironmentServiceBusEndpoint ...
|
||||
EnvironmentServiceBusEndpoint EnvironmentProperty = "serviceBusEndpoint"
|
||||
// EnvironmentBatchManagementEndpoint ...
|
||||
EnvironmentBatchManagementEndpoint EnvironmentProperty = "batchManagementEndpoint"
|
||||
// EnvironmentStorageEndpointSuffix ...
|
||||
EnvironmentStorageEndpointSuffix EnvironmentProperty = "storageEndpointSuffix"
|
||||
// EnvironmentSQLDatabaseDNSSuffix ...
|
||||
EnvironmentSQLDatabaseDNSSuffix EnvironmentProperty = "sqlDatabaseDNSSuffix"
|
||||
// EnvironmentTrafficManagerDNSSuffix ...
|
||||
EnvironmentTrafficManagerDNSSuffix EnvironmentProperty = "trafficManagerDNSSuffix"
|
||||
// EnvironmentKeyVaultDNSSuffix ...
|
||||
EnvironmentKeyVaultDNSSuffix EnvironmentProperty = "keyVaultDNSSuffix"
|
||||
// EnvironmentServiceBusEndpointSuffix ...
|
||||
EnvironmentServiceBusEndpointSuffix EnvironmentProperty = "serviceBusEndpointSuffix"
|
||||
// EnvironmentServiceManagementVMDNSSuffix ...
|
||||
EnvironmentServiceManagementVMDNSSuffix EnvironmentProperty = "serviceManagementVMDNSSuffix"
|
||||
// EnvironmentResourceManagerVMDNSSuffix ...
|
||||
EnvironmentResourceManagerVMDNSSuffix EnvironmentProperty = "resourceManagerVMDNSSuffix"
|
||||
// EnvironmentContainerRegistryDNSSuffix ...
|
||||
EnvironmentContainerRegistryDNSSuffix EnvironmentProperty = "containerRegistryDNSSuffix"
|
||||
// EnvironmentTokenAudience ...
|
||||
EnvironmentTokenAudience EnvironmentProperty = "tokenAudience"
|
||||
)
|
||||
|
||||
// OverrideProperty represents property name and value that clients can override
|
||||
type OverrideProperty struct {
|
||||
Key EnvironmentProperty
|
||||
Value string
|
||||
}
|
||||
|
||||
// EnvironmentFromURL loads an Environment from a URL
|
||||
// This function is particularly useful in the Hybrid Cloud model, where one may define their own
|
||||
// endpoints.
|
||||
func EnvironmentFromURL(resourceManagerEndpoint string, properties ...OverrideProperty) (environment Environment, err error) {
|
||||
var metadataEnvProperties environmentMetadataInfo
|
||||
|
||||
if resourceManagerEndpoint == "" {
|
||||
return environment, fmt.Errorf("Metadata resource manager endpoint is empty")
|
||||
}
|
||||
|
||||
if metadataEnvProperties, err = retrieveMetadataEnvironment(resourceManagerEndpoint); err != nil {
|
||||
return environment, err
|
||||
}
|
||||
|
||||
// Give priority to user's override values
|
||||
overrideProperties(&environment, properties)
|
||||
|
||||
if environment.Name == "" {
|
||||
environment.Name = "HybridEnvironment"
|
||||
}
|
||||
stampDNSSuffix := environment.StorageEndpointSuffix
|
||||
if stampDNSSuffix == "" {
|
||||
stampDNSSuffix = strings.TrimSuffix(strings.TrimPrefix(strings.Replace(resourceManagerEndpoint, strings.Split(resourceManagerEndpoint, ".")[0], "", 1), "."), "/")
|
||||
environment.StorageEndpointSuffix = stampDNSSuffix
|
||||
}
|
||||
if environment.KeyVaultDNSSuffix == "" {
|
||||
environment.KeyVaultDNSSuffix = fmt.Sprintf("%s.%s", "vault", stampDNSSuffix)
|
||||
}
|
||||
if environment.KeyVaultEndpoint == "" {
|
||||
environment.KeyVaultEndpoint = fmt.Sprintf("%s%s", "https://", environment.KeyVaultDNSSuffix)
|
||||
}
|
||||
if environment.TokenAudience == "" {
|
||||
environment.TokenAudience = metadataEnvProperties.Authentication.Audiences[0]
|
||||
}
|
||||
if environment.ActiveDirectoryEndpoint == "" {
|
||||
environment.ActiveDirectoryEndpoint = metadataEnvProperties.Authentication.LoginEndpoint
|
||||
}
|
||||
if environment.ResourceManagerEndpoint == "" {
|
||||
environment.ResourceManagerEndpoint = resourceManagerEndpoint
|
||||
}
|
||||
if environment.GalleryEndpoint == "" {
|
||||
environment.GalleryEndpoint = metadataEnvProperties.GalleryEndpoint
|
||||
}
|
||||
if environment.GraphEndpoint == "" {
|
||||
environment.GraphEndpoint = metadataEnvProperties.GraphEndpoint
|
||||
}
|
||||
|
||||
return environment, nil
|
||||
}
|
||||
|
||||
func overrideProperties(environment *Environment, properties []OverrideProperty) {
|
||||
for _, property := range properties {
|
||||
switch property.Key {
|
||||
case EnvironmentName:
|
||||
{
|
||||
environment.Name = property.Value
|
||||
}
|
||||
case EnvironmentManagementPortalURL:
|
||||
{
|
||||
environment.ManagementPortalURL = property.Value
|
||||
}
|
||||
case EnvironmentPublishSettingsURL:
|
||||
{
|
||||
environment.PublishSettingsURL = property.Value
|
||||
}
|
||||
case EnvironmentServiceManagementEndpoint:
|
||||
{
|
||||
environment.ServiceManagementEndpoint = property.Value
|
||||
}
|
||||
case EnvironmentResourceManagerEndpoint:
|
||||
{
|
||||
environment.ResourceManagerEndpoint = property.Value
|
||||
}
|
||||
case EnvironmentActiveDirectoryEndpoint:
|
||||
{
|
||||
environment.ActiveDirectoryEndpoint = property.Value
|
||||
}
|
||||
case EnvironmentGalleryEndpoint:
|
||||
{
|
||||
environment.GalleryEndpoint = property.Value
|
||||
}
|
||||
case EnvironmentKeyVaultEndpoint:
|
||||
{
|
||||
environment.KeyVaultEndpoint = property.Value
|
||||
}
|
||||
case EnvironmentGraphEndpoint:
|
||||
{
|
||||
environment.GraphEndpoint = property.Value
|
||||
}
|
||||
case EnvironmentServiceBusEndpoint:
|
||||
{
|
||||
environment.ServiceBusEndpoint = property.Value
|
||||
}
|
||||
case EnvironmentBatchManagementEndpoint:
|
||||
{
|
||||
environment.BatchManagementEndpoint = property.Value
|
||||
}
|
||||
case EnvironmentStorageEndpointSuffix:
|
||||
{
|
||||
environment.StorageEndpointSuffix = property.Value
|
||||
}
|
||||
case EnvironmentSQLDatabaseDNSSuffix:
|
||||
{
|
||||
environment.SQLDatabaseDNSSuffix = property.Value
|
||||
}
|
||||
case EnvironmentTrafficManagerDNSSuffix:
|
||||
{
|
||||
environment.TrafficManagerDNSSuffix = property.Value
|
||||
}
|
||||
case EnvironmentKeyVaultDNSSuffix:
|
||||
{
|
||||
environment.KeyVaultDNSSuffix = property.Value
|
||||
}
|
||||
case EnvironmentServiceBusEndpointSuffix:
|
||||
{
|
||||
environment.ServiceBusEndpointSuffix = property.Value
|
||||
}
|
||||
case EnvironmentServiceManagementVMDNSSuffix:
|
||||
{
|
||||
environment.ServiceManagementVMDNSSuffix = property.Value
|
||||
}
|
||||
case EnvironmentResourceManagerVMDNSSuffix:
|
||||
{
|
||||
environment.ResourceManagerVMDNSSuffix = property.Value
|
||||
}
|
||||
case EnvironmentContainerRegistryDNSSuffix:
|
||||
{
|
||||
environment.ContainerRegistryDNSSuffix = property.Value
|
||||
}
|
||||
case EnvironmentTokenAudience:
|
||||
{
|
||||
environment.TokenAudience = property.Value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func retrieveMetadataEnvironment(endpoint string) (environment environmentMetadataInfo, err error) {
|
||||
client := autorest.NewClientWithUserAgent("")
|
||||
managementEndpoint := fmt.Sprintf("%s%s", strings.TrimSuffix(endpoint, "/"), "/metadata/endpoints?api-version=1.0")
|
||||
req, _ := http.NewRequest("GET", managementEndpoint, nil)
|
||||
response, err := client.Do(req)
|
||||
if err != nil {
|
||||
return environment, err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
jsonResponse, err := ioutil.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
return environment, err
|
||||
}
|
||||
err = json.Unmarshal(jsonResponse, &environment)
|
||||
return environment, err
|
||||
}
|
200
vendor/github.com/Azure/go-autorest/autorest/azure/rp.go
generated
vendored
200
vendor/github.com/Azure/go-autorest/autorest/azure/rp.go
generated
vendored
@ -1,200 +0,0 @@
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
package azure
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
)
|
||||
|
||||
// DoRetryWithRegistration tries to register the resource provider in case it is unregistered.
|
||||
// It also handles request retries
|
||||
func DoRetryWithRegistration(client autorest.Client) autorest.SendDecorator {
|
||||
return func(s autorest.Sender) autorest.Sender {
|
||||
return autorest.SenderFunc(func(r *http.Request) (resp *http.Response, err error) {
|
||||
rr := autorest.NewRetriableRequest(r)
|
||||
for currentAttempt := 0; currentAttempt < client.RetryAttempts; currentAttempt++ {
|
||||
err = rr.Prepare()
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
resp, err = autorest.SendWithSender(s, rr.Request(),
|
||||
autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...),
|
||||
)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusConflict || client.SkipResourceProviderRegistration {
|
||||
return resp, err
|
||||
}
|
||||
var re RequestError
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
autorest.ByUnmarshallingJSON(&re),
|
||||
)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
err = re
|
||||
|
||||
if re.ServiceError != nil && re.ServiceError.Code == "MissingSubscriptionRegistration" {
|
||||
regErr := register(client, r, re)
|
||||
if regErr != nil {
|
||||
return resp, fmt.Errorf("failed auto registering Resource Provider: %s. Original error: %s", regErr, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func getProvider(re RequestError) (string, error) {
|
||||
if re.ServiceError != nil && len(re.ServiceError.Details) > 0 {
|
||||
return re.ServiceError.Details[0]["target"].(string), nil
|
||||
}
|
||||
return "", errors.New("provider was not found in the response")
|
||||
}
|
||||
|
||||
func register(client autorest.Client, originalReq *http.Request, re RequestError) error {
|
||||
subID := getSubscription(originalReq.URL.Path)
|
||||
if subID == "" {
|
||||
return errors.New("missing parameter subscriptionID to register resource provider")
|
||||
}
|
||||
providerName, err := getProvider(re)
|
||||
if err != nil {
|
||||
return fmt.Errorf("missing parameter provider to register resource provider: %s", err)
|
||||
}
|
||||
newURL := url.URL{
|
||||
Scheme: originalReq.URL.Scheme,
|
||||
Host: originalReq.URL.Host,
|
||||
}
|
||||
|
||||
// taken from the resources SDK
|
||||
// with almost identical code, this sections are easier to mantain
|
||||
// It is also not a good idea to import the SDK here
|
||||
// https://github.com/Azure/azure-sdk-for-go/blob/9f366792afa3e0ddaecdc860e793ba9d75e76c27/arm/resources/resources/providers.go#L252
|
||||
pathParameters := map[string]interface{}{
|
||||
"resourceProviderNamespace": autorest.Encode("path", providerName),
|
||||
"subscriptionId": autorest.Encode("path", subID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsPost(),
|
||||
autorest.WithBaseURL(newURL.String()),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}/register", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters),
|
||||
)
|
||||
|
||||
req, err := preparer.Prepare(&http.Request{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req = req.WithContext(originalReq.Context())
|
||||
|
||||
resp, err := autorest.SendWithSender(client, req,
|
||||
autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
type Provider struct {
|
||||
RegistrationState *string `json:"registrationState,omitempty"`
|
||||
}
|
||||
var provider Provider
|
||||
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&provider),
|
||||
autorest.ByClosing(),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// poll for registered provisioning state
|
||||
registrationStartTime := time.Now()
|
||||
for err == nil && (client.PollingDuration == 0 || (client.PollingDuration != 0 && time.Since(registrationStartTime) < client.PollingDuration)) {
|
||||
// taken from the resources SDK
|
||||
// https://github.com/Azure/azure-sdk-for-go/blob/9f366792afa3e0ddaecdc860e793ba9d75e76c27/arm/resources/resources/providers.go#L45
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsGet(),
|
||||
autorest.WithBaseURL(newURL.String()),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters),
|
||||
)
|
||||
req, err = preparer.Prepare(&http.Request{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req = req.WithContext(originalReq.Context())
|
||||
|
||||
resp, err := autorest.SendWithSender(client, req,
|
||||
autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&provider),
|
||||
autorest.ByClosing(),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if provider.RegistrationState != nil &&
|
||||
*provider.RegistrationState == "Registered" {
|
||||
break
|
||||
}
|
||||
|
||||
delayed := autorest.DelayWithRetryAfter(resp, originalReq.Context().Done())
|
||||
if !delayed && !autorest.DelayForBackoff(client.PollingDelay, 0, originalReq.Context().Done()) {
|
||||
return originalReq.Context().Err()
|
||||
}
|
||||
}
|
||||
if client.PollingDuration != 0 && !(time.Since(registrationStartTime) < client.PollingDuration) {
|
||||
return errors.New("polling for resource provider registration has exceeded the polling duration")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func getSubscription(path string) string {
|
||||
parts := strings.Split(path, "/")
|
||||
for i, v := range parts {
|
||||
if v == "subscriptions" && (i+1) < len(parts) {
|
||||
return parts[i+1]
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
268
vendor/github.com/Azure/go-autorest/autorest/client.go
generated
vendored
268
vendor/github.com/Azure/go-autorest/autorest/client.go
generated
vendored
@ -1,268 +0,0 @@
|
||||
package autorest
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/go-autorest/logger"
|
||||
"github.com/Azure/go-autorest/version"
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultPollingDelay is a reasonable delay between polling requests.
|
||||
DefaultPollingDelay = 60 * time.Second
|
||||
|
||||
// DefaultPollingDuration is a reasonable total polling duration.
|
||||
DefaultPollingDuration = 15 * time.Minute
|
||||
|
||||
// DefaultRetryAttempts is number of attempts for retry status codes (5xx).
|
||||
DefaultRetryAttempts = 3
|
||||
|
||||
// DefaultRetryDuration is the duration to wait between retries.
|
||||
DefaultRetryDuration = 30 * time.Second
|
||||
)
|
||||
|
||||
var (
|
||||
// StatusCodesForRetry are a defined group of status code for which the client will retry
|
||||
StatusCodesForRetry = []int{
|
||||
http.StatusRequestTimeout, // 408
|
||||
http.StatusTooManyRequests, // 429
|
||||
http.StatusInternalServerError, // 500
|
||||
http.StatusBadGateway, // 502
|
||||
http.StatusServiceUnavailable, // 503
|
||||
http.StatusGatewayTimeout, // 504
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
requestFormat = `HTTP Request Begin ===================================================
|
||||
%s
|
||||
===================================================== HTTP Request End
|
||||
`
|
||||
responseFormat = `HTTP Response Begin ===================================================
|
||||
%s
|
||||
===================================================== HTTP Response End
|
||||
`
|
||||
)
|
||||
|
||||
// Response serves as the base for all responses from generated clients. It provides access to the
|
||||
// last http.Response.
|
||||
type Response struct {
|
||||
*http.Response `json:"-"`
|
||||
}
|
||||
|
||||
// LoggingInspector implements request and response inspectors that log the full request and
|
||||
// response to a supplied log.
|
||||
type LoggingInspector struct {
|
||||
Logger *log.Logger
|
||||
}
|
||||
|
||||
// WithInspection returns a PrepareDecorator that emits the http.Request to the supplied logger. The
|
||||
// body is restored after being emitted.
|
||||
//
|
||||
// Note: Since it reads the entire Body, this decorator should not be used where body streaming is
|
||||
// important. It is best used to trace JSON or similar body values.
|
||||
func (li LoggingInspector) WithInspection() PrepareDecorator {
|
||||
return func(p Preparer) Preparer {
|
||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
var body, b bytes.Buffer
|
||||
|
||||
defer r.Body.Close()
|
||||
|
||||
r.Body = ioutil.NopCloser(io.TeeReader(r.Body, &body))
|
||||
if err := r.Write(&b); err != nil {
|
||||
return nil, fmt.Errorf("Failed to write response: %v", err)
|
||||
}
|
||||
|
||||
li.Logger.Printf(requestFormat, b.String())
|
||||
|
||||
r.Body = ioutil.NopCloser(&body)
|
||||
return p.Prepare(r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// ByInspecting returns a RespondDecorator that emits the http.Response to the supplied logger. The
|
||||
// body is restored after being emitted.
|
||||
//
|
||||
// Note: Since it reads the entire Body, this decorator should not be used where body streaming is
|
||||
// important. It is best used to trace JSON or similar body values.
|
||||
func (li LoggingInspector) ByInspecting() RespondDecorator {
|
||||
return func(r Responder) Responder {
|
||||
return ResponderFunc(func(resp *http.Response) error {
|
||||
var body, b bytes.Buffer
|
||||
defer resp.Body.Close()
|
||||
resp.Body = ioutil.NopCloser(io.TeeReader(resp.Body, &body))
|
||||
if err := resp.Write(&b); err != nil {
|
||||
return fmt.Errorf("Failed to write response: %v", err)
|
||||
}
|
||||
|
||||
li.Logger.Printf(responseFormat, b.String())
|
||||
|
||||
resp.Body = ioutil.NopCloser(&body)
|
||||
return r.Respond(resp)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Client is the base for autorest generated clients. It provides default, "do nothing"
|
||||
// implementations of an Authorizer, RequestInspector, and ResponseInspector. It also returns the
|
||||
// standard, undecorated http.Client as a default Sender.
|
||||
//
|
||||
// Generated clients should also use Error (see NewError and NewErrorWithError) for errors and
|
||||
// return responses that compose with Response.
|
||||
//
|
||||
// Most customization of generated clients is best achieved by supplying a custom Authorizer, custom
|
||||
// RequestInspector, and / or custom ResponseInspector. Users may log requests, implement circuit
|
||||
// breakers (see https://msdn.microsoft.com/en-us/library/dn589784.aspx) or otherwise influence
|
||||
// sending the request by providing a decorated Sender.
|
||||
type Client struct {
|
||||
Authorizer Authorizer
|
||||
Sender Sender
|
||||
RequestInspector PrepareDecorator
|
||||
ResponseInspector RespondDecorator
|
||||
|
||||
// PollingDelay sets the polling frequency used in absence of a Retry-After HTTP header
|
||||
PollingDelay time.Duration
|
||||
|
||||
// PollingDuration sets the maximum polling time after which an error is returned.
|
||||
// Setting this to zero will use the provided context to control the duration.
|
||||
PollingDuration time.Duration
|
||||
|
||||
// RetryAttempts sets the default number of retry attempts for client.
|
||||
RetryAttempts int
|
||||
|
||||
// RetryDuration sets the delay duration for retries.
|
||||
RetryDuration time.Duration
|
||||
|
||||
// UserAgent, if not empty, will be set as the HTTP User-Agent header on all requests sent
|
||||
// through the Do method.
|
||||
UserAgent string
|
||||
|
||||
Jar http.CookieJar
|
||||
|
||||
// Set to true to skip attempted registration of resource providers (false by default).
|
||||
SkipResourceProviderRegistration bool
|
||||
}
|
||||
|
||||
// NewClientWithUserAgent returns an instance of a Client with the UserAgent set to the passed
|
||||
// string.
|
||||
func NewClientWithUserAgent(ua string) Client {
|
||||
c := Client{
|
||||
PollingDelay: DefaultPollingDelay,
|
||||
PollingDuration: DefaultPollingDuration,
|
||||
RetryAttempts: DefaultRetryAttempts,
|
||||
RetryDuration: DefaultRetryDuration,
|
||||
UserAgent: version.UserAgent(),
|
||||
}
|
||||
c.Sender = c.sender()
|
||||
c.AddToUserAgent(ua)
|
||||
return c
|
||||
}
|
||||
|
||||
// AddToUserAgent adds an extension to the current user agent
|
||||
func (c *Client) AddToUserAgent(extension string) error {
|
||||
if extension != "" {
|
||||
c.UserAgent = fmt.Sprintf("%s %s", c.UserAgent, extension)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Extension was empty, User Agent stayed as %s", c.UserAgent)
|
||||
}
|
||||
|
||||
// Do implements the Sender interface by invoking the active Sender after applying authorization.
|
||||
// If Sender is not set, it uses a new instance of http.Client. In both cases it will, if UserAgent
|
||||
// is set, apply set the User-Agent header.
|
||||
func (c Client) Do(r *http.Request) (*http.Response, error) {
|
||||
if r.UserAgent() == "" {
|
||||
r, _ = Prepare(r,
|
||||
WithUserAgent(c.UserAgent))
|
||||
}
|
||||
// NOTE: c.WithInspection() must be last in the list so that it can inspect all preceding operations
|
||||
r, err := Prepare(r,
|
||||
c.WithAuthorization(),
|
||||
c.WithInspection())
|
||||
if err != nil {
|
||||
var resp *http.Response
|
||||
if detErr, ok := err.(DetailedError); ok {
|
||||
// if the authorization failed (e.g. invalid credentials) there will
|
||||
// be a response associated with the error, be sure to return it.
|
||||
resp = detErr.Response
|
||||
}
|
||||
return resp, NewErrorWithError(err, "autorest/Client", "Do", nil, "Preparing request failed")
|
||||
}
|
||||
logger.Instance.WriteRequest(r, logger.Filter{
|
||||
Header: func(k string, v []string) (bool, []string) {
|
||||
// remove the auth token from the log
|
||||
if strings.EqualFold(k, "Authorization") || strings.EqualFold(k, "Ocp-Apim-Subscription-Key") {
|
||||
v = []string{"**REDACTED**"}
|
||||
}
|
||||
return true, v
|
||||
},
|
||||
})
|
||||
resp, err := SendWithSender(c.sender(), r)
|
||||
logger.Instance.WriteResponse(resp, logger.Filter{})
|
||||
Respond(resp, c.ByInspecting())
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// sender returns the Sender to which to send requests.
|
||||
func (c Client) sender() Sender {
|
||||
if c.Sender == nil {
|
||||
j, _ := cookiejar.New(nil)
|
||||
return &http.Client{Jar: j}
|
||||
}
|
||||
return c.Sender
|
||||
}
|
||||
|
||||
// WithAuthorization is a convenience method that returns the WithAuthorization PrepareDecorator
|
||||
// from the current Authorizer. If not Authorizer is set, it uses the NullAuthorizer.
|
||||
func (c Client) WithAuthorization() PrepareDecorator {
|
||||
return c.authorizer().WithAuthorization()
|
||||
}
|
||||
|
||||
// authorizer returns the Authorizer to use.
|
||||
func (c Client) authorizer() Authorizer {
|
||||
if c.Authorizer == nil {
|
||||
return NullAuthorizer{}
|
||||
}
|
||||
return c.Authorizer
|
||||
}
|
||||
|
||||
// WithInspection is a convenience method that passes the request to the supplied RequestInspector,
|
||||
// if present, or returns the WithNothing PrepareDecorator otherwise.
|
||||
func (c Client) WithInspection() PrepareDecorator {
|
||||
if c.RequestInspector == nil {
|
||||
return WithNothing()
|
||||
}
|
||||
return c.RequestInspector
|
||||
}
|
||||
|
||||
// ByInspecting is a convenience method that passes the response to the supplied ResponseInspector,
|
||||
// if present, or returns the ByIgnoring RespondDecorator otherwise.
|
||||
func (c Client) ByInspecting() RespondDecorator {
|
||||
if c.ResponseInspector == nil {
|
||||
return ByIgnoring()
|
||||
}
|
||||
return c.ResponseInspector
|
||||
}
|
96
vendor/github.com/Azure/go-autorest/autorest/date/date.go
generated
vendored
96
vendor/github.com/Azure/go-autorest/autorest/date/date.go
generated
vendored
@ -1,96 +0,0 @@
|
||||
/*
|
||||
Package date provides time.Time derivatives that conform to the Swagger.io (https://swagger.io/)
|
||||
defined date formats: Date and DateTime. Both types may, in most cases, be used in lieu of
|
||||
time.Time types. And both convert to time.Time through a ToTime method.
|
||||
*/
|
||||
package date
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
fullDate = "2006-01-02"
|
||||
fullDateJSON = `"2006-01-02"`
|
||||
dateFormat = "%04d-%02d-%02d"
|
||||
jsonFormat = `"%04d-%02d-%02d"`
|
||||
)
|
||||
|
||||
// Date defines a type similar to time.Time but assumes a layout of RFC3339 full-date (i.e.,
|
||||
// 2006-01-02).
|
||||
type Date struct {
|
||||
time.Time
|
||||
}
|
||||
|
||||
// ParseDate create a new Date from the passed string.
|
||||
func ParseDate(date string) (d Date, err error) {
|
||||
return parseDate(date, fullDate)
|
||||
}
|
||||
|
||||
func parseDate(date string, format string) (Date, error) {
|
||||
d, err := time.Parse(format, date)
|
||||
return Date{Time: d}, err
|
||||
}
|
||||
|
||||
// MarshalBinary preserves the Date as a byte array conforming to RFC3339 full-date (i.e.,
|
||||
// 2006-01-02).
|
||||
func (d Date) MarshalBinary() ([]byte, error) {
|
||||
return d.MarshalText()
|
||||
}
|
||||
|
||||
// UnmarshalBinary reconstitutes a Date saved as a byte array conforming to RFC3339 full-date (i.e.,
|
||||
// 2006-01-02).
|
||||
func (d *Date) UnmarshalBinary(data []byte) error {
|
||||
return d.UnmarshalText(data)
|
||||
}
|
||||
|
||||
// MarshalJSON preserves the Date as a JSON string conforming to RFC3339 full-date (i.e.,
|
||||
// 2006-01-02).
|
||||
func (d Date) MarshalJSON() (json []byte, err error) {
|
||||
return []byte(fmt.Sprintf(jsonFormat, d.Year(), d.Month(), d.Day())), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON reconstitutes the Date from a JSON string conforming to RFC3339 full-date (i.e.,
|
||||
// 2006-01-02).
|
||||
func (d *Date) UnmarshalJSON(data []byte) (err error) {
|
||||
d.Time, err = time.Parse(fullDateJSON, string(data))
|
||||
return err
|
||||
}
|
||||
|
||||
// MarshalText preserves the Date as a byte array conforming to RFC3339 full-date (i.e.,
|
||||
// 2006-01-02).
|
||||
func (d Date) MarshalText() (text []byte, err error) {
|
||||
return []byte(fmt.Sprintf(dateFormat, d.Year(), d.Month(), d.Day())), nil
|
||||
}
|
||||
|
||||
// UnmarshalText reconstitutes a Date saved as a byte array conforming to RFC3339 full-date (i.e.,
|
||||
// 2006-01-02).
|
||||
func (d *Date) UnmarshalText(data []byte) (err error) {
|
||||
d.Time, err = time.Parse(fullDate, string(data))
|
||||
return err
|
||||
}
|
||||
|
||||
// String returns the Date formatted as an RFC3339 full-date string (i.e., 2006-01-02).
|
||||
func (d Date) String() string {
|
||||
return fmt.Sprintf(dateFormat, d.Year(), d.Month(), d.Day())
|
||||
}
|
||||
|
||||
// ToTime returns a Date as a time.Time
|
||||
func (d Date) ToTime() time.Time {
|
||||
return d.Time
|
||||
}
|
103
vendor/github.com/Azure/go-autorest/autorest/date/time.go
generated
vendored
103
vendor/github.com/Azure/go-autorest/autorest/date/time.go
generated
vendored
@ -1,103 +0,0 @@
|
||||
package date
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Azure reports time in UTC but it doesn't include the 'Z' time zone suffix in some cases.
|
||||
const (
|
||||
azureUtcFormatJSON = `"2006-01-02T15:04:05.999999999"`
|
||||
azureUtcFormat = "2006-01-02T15:04:05.999999999"
|
||||
rfc3339JSON = `"` + time.RFC3339Nano + `"`
|
||||
rfc3339 = time.RFC3339Nano
|
||||
tzOffsetRegex = `(Z|z|\+|-)(\d+:\d+)*"*$`
|
||||
)
|
||||
|
||||
// Time defines a type similar to time.Time but assumes a layout of RFC3339 date-time (i.e.,
|
||||
// 2006-01-02T15:04:05Z).
|
||||
type Time struct {
|
||||
time.Time
|
||||
}
|
||||
|
||||
// MarshalBinary preserves the Time as a byte array conforming to RFC3339 date-time (i.e.,
|
||||
// 2006-01-02T15:04:05Z).
|
||||
func (t Time) MarshalBinary() ([]byte, error) {
|
||||
return t.Time.MarshalText()
|
||||
}
|
||||
|
||||
// UnmarshalBinary reconstitutes a Time saved as a byte array conforming to RFC3339 date-time
|
||||
// (i.e., 2006-01-02T15:04:05Z).
|
||||
func (t *Time) UnmarshalBinary(data []byte) error {
|
||||
return t.UnmarshalText(data)
|
||||
}
|
||||
|
||||
// MarshalJSON preserves the Time as a JSON string conforming to RFC3339 date-time (i.e.,
|
||||
// 2006-01-02T15:04:05Z).
|
||||
func (t Time) MarshalJSON() (json []byte, err error) {
|
||||
return t.Time.MarshalJSON()
|
||||
}
|
||||
|
||||
// UnmarshalJSON reconstitutes the Time from a JSON string conforming to RFC3339 date-time
|
||||
// (i.e., 2006-01-02T15:04:05Z).
|
||||
func (t *Time) UnmarshalJSON(data []byte) (err error) {
|
||||
timeFormat := azureUtcFormatJSON
|
||||
match, err := regexp.Match(tzOffsetRegex, data)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if match {
|
||||
timeFormat = rfc3339JSON
|
||||
}
|
||||
t.Time, err = ParseTime(timeFormat, string(data))
|
||||
return err
|
||||
}
|
||||
|
||||
// MarshalText preserves the Time as a byte array conforming to RFC3339 date-time (i.e.,
|
||||
// 2006-01-02T15:04:05Z).
|
||||
func (t Time) MarshalText() (text []byte, err error) {
|
||||
return t.Time.MarshalText()
|
||||
}
|
||||
|
||||
// UnmarshalText reconstitutes a Time saved as a byte array conforming to RFC3339 date-time
|
||||
// (i.e., 2006-01-02T15:04:05Z).
|
||||
func (t *Time) UnmarshalText(data []byte) (err error) {
|
||||
timeFormat := azureUtcFormat
|
||||
match, err := regexp.Match(tzOffsetRegex, data)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if match {
|
||||
timeFormat = rfc3339
|
||||
}
|
||||
t.Time, err = ParseTime(timeFormat, string(data))
|
||||
return err
|
||||
}
|
||||
|
||||
// String returns the Time formatted as an RFC3339 date-time string (i.e.,
|
||||
// 2006-01-02T15:04:05Z).
|
||||
func (t Time) String() string {
|
||||
// Note: time.Time.String does not return an RFC3339 compliant string, time.Time.MarshalText does.
|
||||
b, err := t.MarshalText()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// ToTime returns a Time as a time.Time
|
||||
func (t Time) ToTime() time.Time {
|
||||
return t.Time
|
||||
}
|
100
vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go
generated
vendored
100
vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go
generated
vendored
@ -1,100 +0,0 @@
|
||||
package date
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
rfc1123JSON = `"` + time.RFC1123 + `"`
|
||||
rfc1123 = time.RFC1123
|
||||
)
|
||||
|
||||
// TimeRFC1123 defines a type similar to time.Time but assumes a layout of RFC1123 date-time (i.e.,
|
||||
// Mon, 02 Jan 2006 15:04:05 MST).
|
||||
type TimeRFC1123 struct {
|
||||
time.Time
|
||||
}
|
||||
|
||||
// UnmarshalJSON reconstitutes the Time from a JSON string conforming to RFC1123 date-time
|
||||
// (i.e., Mon, 02 Jan 2006 15:04:05 MST).
|
||||
func (t *TimeRFC1123) UnmarshalJSON(data []byte) (err error) {
|
||||
t.Time, err = ParseTime(rfc1123JSON, string(data))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON preserves the Time as a JSON string conforming to RFC1123 date-time (i.e.,
|
||||
// Mon, 02 Jan 2006 15:04:05 MST).
|
||||
func (t TimeRFC1123) MarshalJSON() ([]byte, error) {
|
||||
if y := t.Year(); y < 0 || y >= 10000 {
|
||||
return nil, errors.New("Time.MarshalJSON: year outside of range [0,9999]")
|
||||
}
|
||||
b := []byte(t.Format(rfc1123JSON))
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// MarshalText preserves the Time as a byte array conforming to RFC1123 date-time (i.e.,
|
||||
// Mon, 02 Jan 2006 15:04:05 MST).
|
||||
func (t TimeRFC1123) MarshalText() ([]byte, error) {
|
||||
if y := t.Year(); y < 0 || y >= 10000 {
|
||||
return nil, errors.New("Time.MarshalText: year outside of range [0,9999]")
|
||||
}
|
||||
|
||||
b := []byte(t.Format(rfc1123))
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// UnmarshalText reconstitutes a Time saved as a byte array conforming to RFC1123 date-time
|
||||
// (i.e., Mon, 02 Jan 2006 15:04:05 MST).
|
||||
func (t *TimeRFC1123) UnmarshalText(data []byte) (err error) {
|
||||
t.Time, err = ParseTime(rfc1123, string(data))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary preserves the Time as a byte array conforming to RFC1123 date-time (i.e.,
|
||||
// Mon, 02 Jan 2006 15:04:05 MST).
|
||||
func (t TimeRFC1123) MarshalBinary() ([]byte, error) {
|
||||
return t.MarshalText()
|
||||
}
|
||||
|
||||
// UnmarshalBinary reconstitutes a Time saved as a byte array conforming to RFC1123 date-time
|
||||
// (i.e., Mon, 02 Jan 2006 15:04:05 MST).
|
||||
func (t *TimeRFC1123) UnmarshalBinary(data []byte) error {
|
||||
return t.UnmarshalText(data)
|
||||
}
|
||||
|
||||
// ToTime returns a Time as a time.Time
|
||||
func (t TimeRFC1123) ToTime() time.Time {
|
||||
return t.Time
|
||||
}
|
||||
|
||||
// String returns the Time formatted as an RFC1123 date-time string (i.e.,
|
||||
// Mon, 02 Jan 2006 15:04:05 MST).
|
||||
func (t TimeRFC1123) String() string {
|
||||
// Note: time.Time.String does not return an RFC1123 compliant string, time.Time.MarshalText does.
|
||||
b, err := t.MarshalText()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return string(b)
|
||||
}
|
123
vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go
generated
vendored
123
vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go
generated
vendored
@ -1,123 +0,0 @@
|
||||
package date
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"time"
|
||||
)
|
||||
|
||||
// unixEpoch is the moment in time that should be treated as timestamp 0.
|
||||
var unixEpoch = time.Date(1970, time.January, 1, 0, 0, 0, 0, time.UTC)
|
||||
|
||||
// UnixTime marshals and unmarshals a time that is represented as the number
|
||||
// of seconds (ignoring skip-seconds) since the Unix Epoch.
|
||||
type UnixTime time.Time
|
||||
|
||||
// Duration returns the time as a Duration since the UnixEpoch.
|
||||
func (t UnixTime) Duration() time.Duration {
|
||||
return time.Time(t).Sub(unixEpoch)
|
||||
}
|
||||
|
||||
// NewUnixTimeFromSeconds creates a UnixTime as a number of seconds from the UnixEpoch.
|
||||
func NewUnixTimeFromSeconds(seconds float64) UnixTime {
|
||||
return NewUnixTimeFromDuration(time.Duration(seconds * float64(time.Second)))
|
||||
}
|
||||
|
||||
// NewUnixTimeFromNanoseconds creates a UnixTime as a number of nanoseconds from the UnixEpoch.
|
||||
func NewUnixTimeFromNanoseconds(nanoseconds int64) UnixTime {
|
||||
return NewUnixTimeFromDuration(time.Duration(nanoseconds))
|
||||
}
|
||||
|
||||
// NewUnixTimeFromDuration creates a UnixTime as a duration of time since the UnixEpoch.
|
||||
func NewUnixTimeFromDuration(dur time.Duration) UnixTime {
|
||||
return UnixTime(unixEpoch.Add(dur))
|
||||
}
|
||||
|
||||
// UnixEpoch retreives the moment considered the Unix Epoch. I.e. The time represented by '0'
|
||||
func UnixEpoch() time.Time {
|
||||
return unixEpoch
|
||||
}
|
||||
|
||||
// MarshalJSON preserves the UnixTime as a JSON number conforming to Unix Timestamp requirements.
|
||||
// (i.e. the number of seconds since midnight January 1st, 1970 not considering leap seconds.)
|
||||
func (t UnixTime) MarshalJSON() ([]byte, error) {
|
||||
buffer := &bytes.Buffer{}
|
||||
enc := json.NewEncoder(buffer)
|
||||
err := enc.Encode(float64(time.Time(t).UnixNano()) / 1e9)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buffer.Bytes(), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON reconstitures a UnixTime saved as a JSON number of the number of seconds since
|
||||
// midnight January 1st, 1970.
|
||||
func (t *UnixTime) UnmarshalJSON(text []byte) error {
|
||||
dec := json.NewDecoder(bytes.NewReader(text))
|
||||
|
||||
var secondsSinceEpoch float64
|
||||
if err := dec.Decode(&secondsSinceEpoch); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*t = NewUnixTimeFromSeconds(secondsSinceEpoch)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalText stores the number of seconds since the Unix Epoch as a textual floating point number.
|
||||
func (t UnixTime) MarshalText() ([]byte, error) {
|
||||
cast := time.Time(t)
|
||||
return cast.MarshalText()
|
||||
}
|
||||
|
||||
// UnmarshalText populates a UnixTime with a value stored textually as a floating point number of seconds since the Unix Epoch.
|
||||
func (t *UnixTime) UnmarshalText(raw []byte) error {
|
||||
var unmarshaled time.Time
|
||||
|
||||
if err := unmarshaled.UnmarshalText(raw); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*t = UnixTime(unmarshaled)
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary converts a UnixTime into a binary.LittleEndian float64 of nanoseconds since the epoch.
|
||||
func (t UnixTime) MarshalBinary() ([]byte, error) {
|
||||
buf := &bytes.Buffer{}
|
||||
|
||||
payload := int64(t.Duration())
|
||||
|
||||
if err := binary.Write(buf, binary.LittleEndian, &payload); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
// UnmarshalBinary converts a from a binary.LittleEndian float64 of nanoseconds since the epoch into a UnixTime.
|
||||
func (t *UnixTime) UnmarshalBinary(raw []byte) error {
|
||||
var nanosecondsSinceEpoch int64
|
||||
|
||||
if err := binary.Read(bytes.NewReader(raw), binary.LittleEndian, &nanosecondsSinceEpoch); err != nil {
|
||||
return err
|
||||
}
|
||||
*t = NewUnixTimeFromNanoseconds(nanosecondsSinceEpoch)
|
||||
return nil
|
||||
}
|
25
vendor/github.com/Azure/go-autorest/autorest/date/utility.go
generated
vendored
25
vendor/github.com/Azure/go-autorest/autorest/date/utility.go
generated
vendored
@ -1,25 +0,0 @@
|
||||
package date
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ParseTime to parse Time string to specified format.
|
||||
func ParseTime(format string, t string) (d time.Time, err error) {
|
||||
return time.Parse(format, strings.ToUpper(t))
|
||||
}
|
98
vendor/github.com/Azure/go-autorest/autorest/error.go
generated
vendored
98
vendor/github.com/Azure/go-autorest/autorest/error.go
generated
vendored
@ -1,98 +0,0 @@
|
||||
package autorest
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const (
|
||||
// UndefinedStatusCode is used when HTTP status code is not available for an error.
|
||||
UndefinedStatusCode = 0
|
||||
)
|
||||
|
||||
// DetailedError encloses a error with details of the package, method, and associated HTTP
|
||||
// status code (if any).
|
||||
type DetailedError struct {
|
||||
Original error
|
||||
|
||||
// PackageType is the package type of the object emitting the error. For types, the value
|
||||
// matches that produced the the '%T' format specifier of the fmt package. For other elements,
|
||||
// such as functions, it is just the package name (e.g., "autorest").
|
||||
PackageType string
|
||||
|
||||
// Method is the name of the method raising the error.
|
||||
Method string
|
||||
|
||||
// StatusCode is the HTTP Response StatusCode (if non-zero) that led to the error.
|
||||
StatusCode interface{}
|
||||
|
||||
// Message is the error message.
|
||||
Message string
|
||||
|
||||
// Service Error is the response body of failed API in bytes
|
||||
ServiceError []byte
|
||||
|
||||
// Response is the response object that was returned during failure if applicable.
|
||||
Response *http.Response
|
||||
}
|
||||
|
||||
// NewError creates a new Error conforming object from the passed packageType, method, and
|
||||
// message. message is treated as a format string to which the optional args apply.
|
||||
func NewError(packageType string, method string, message string, args ...interface{}) DetailedError {
|
||||
return NewErrorWithError(nil, packageType, method, nil, message, args...)
|
||||
}
|
||||
|
||||
// NewErrorWithResponse creates a new Error conforming object from the passed
|
||||
// packageType, method, statusCode of the given resp (UndefinedStatusCode if
|
||||
// resp is nil), and message. message is treated as a format string to which the
|
||||
// optional args apply.
|
||||
func NewErrorWithResponse(packageType string, method string, resp *http.Response, message string, args ...interface{}) DetailedError {
|
||||
return NewErrorWithError(nil, packageType, method, resp, message, args...)
|
||||
}
|
||||
|
||||
// NewErrorWithError creates a new Error conforming object from the
|
||||
// passed packageType, method, statusCode of the given resp (UndefinedStatusCode
|
||||
// if resp is nil), message, and original error. message is treated as a format
|
||||
// string to which the optional args apply.
|
||||
func NewErrorWithError(original error, packageType string, method string, resp *http.Response, message string, args ...interface{}) DetailedError {
|
||||
if v, ok := original.(DetailedError); ok {
|
||||
return v
|
||||
}
|
||||
|
||||
statusCode := UndefinedStatusCode
|
||||
if resp != nil {
|
||||
statusCode = resp.StatusCode
|
||||
}
|
||||
|
||||
return DetailedError{
|
||||
Original: original,
|
||||
PackageType: packageType,
|
||||
Method: method,
|
||||
StatusCode: statusCode,
|
||||
Message: fmt.Sprintf(message, args...),
|
||||
Response: resp,
|
||||
}
|
||||
}
|
||||
|
||||
// Error returns a formatted containing all available details (i.e., PackageType, Method,
|
||||
// StatusCode, Message, and original error (if any)).
|
||||
func (e DetailedError) Error() string {
|
||||
if e.Original == nil {
|
||||
return fmt.Sprintf("%s#%s: %s: StatusCode=%d", e.PackageType, e.Method, e.Message, e.StatusCode)
|
||||
}
|
||||
return fmt.Sprintf("%s#%s: %s: StatusCode=%d -- Original Error: %v", e.PackageType, e.Method, e.Message, e.StatusCode, e.Original)
|
||||
}
|
480
vendor/github.com/Azure/go-autorest/autorest/preparer.go
generated
vendored
480
vendor/github.com/Azure/go-autorest/autorest/preparer.go
generated
vendored
@ -1,480 +0,0 @@
|
||||
package autorest
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
mimeTypeJSON = "application/json"
|
||||
mimeTypeOctetStream = "application/octet-stream"
|
||||
mimeTypeFormPost = "application/x-www-form-urlencoded"
|
||||
|
||||
headerAuthorization = "Authorization"
|
||||
headerContentType = "Content-Type"
|
||||
headerUserAgent = "User-Agent"
|
||||
)
|
||||
|
||||
// Preparer is the interface that wraps the Prepare method.
|
||||
//
|
||||
// Prepare accepts and possibly modifies an http.Request (e.g., adding Headers). Implementations
|
||||
// must ensure to not share or hold per-invocation state since Preparers may be shared and re-used.
|
||||
type Preparer interface {
|
||||
Prepare(*http.Request) (*http.Request, error)
|
||||
}
|
||||
|
||||
// PreparerFunc is a method that implements the Preparer interface.
|
||||
type PreparerFunc func(*http.Request) (*http.Request, error)
|
||||
|
||||
// Prepare implements the Preparer interface on PreparerFunc.
|
||||
func (pf PreparerFunc) Prepare(r *http.Request) (*http.Request, error) {
|
||||
return pf(r)
|
||||
}
|
||||
|
||||
// PrepareDecorator takes and possibly decorates, by wrapping, a Preparer. Decorators may affect the
|
||||
// http.Request and pass it along or, first, pass the http.Request along then affect the result.
|
||||
type PrepareDecorator func(Preparer) Preparer
|
||||
|
||||
// CreatePreparer creates, decorates, and returns a Preparer.
|
||||
// Without decorators, the returned Preparer returns the passed http.Request unmodified.
|
||||
// Preparers are safe to share and re-use.
|
||||
func CreatePreparer(decorators ...PrepareDecorator) Preparer {
|
||||
return DecoratePreparer(
|
||||
Preparer(PreparerFunc(func(r *http.Request) (*http.Request, error) { return r, nil })),
|
||||
decorators...)
|
||||
}
|
||||
|
||||
// DecoratePreparer accepts a Preparer and a, possibly empty, set of PrepareDecorators, which it
|
||||
// applies to the Preparer. Decorators are applied in the order received, but their affect upon the
|
||||
// request depends on whether they are a pre-decorator (change the http.Request and then pass it
|
||||
// along) or a post-decorator (pass the http.Request along and alter it on return).
|
||||
func DecoratePreparer(p Preparer, decorators ...PrepareDecorator) Preparer {
|
||||
for _, decorate := range decorators {
|
||||
p = decorate(p)
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// Prepare accepts an http.Request and a, possibly empty, set of PrepareDecorators.
|
||||
// It creates a Preparer from the decorators which it then applies to the passed http.Request.
|
||||
func Prepare(r *http.Request, decorators ...PrepareDecorator) (*http.Request, error) {
|
||||
if r == nil {
|
||||
return nil, NewError("autorest", "Prepare", "Invoked without an http.Request")
|
||||
}
|
||||
return CreatePreparer(decorators...).Prepare(r)
|
||||
}
|
||||
|
||||
// WithNothing returns a "do nothing" PrepareDecorator that makes no changes to the passed
|
||||
// http.Request.
|
||||
func WithNothing() PrepareDecorator {
|
||||
return func(p Preparer) Preparer {
|
||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
return p.Prepare(r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// WithHeader returns a PrepareDecorator that sets the specified HTTP header of the http.Request to
|
||||
// the passed value. It canonicalizes the passed header name (via http.CanonicalHeaderKey) before
|
||||
// adding the header.
|
||||
func WithHeader(header string, value string) PrepareDecorator {
|
||||
return func(p Preparer) Preparer {
|
||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
r, err := p.Prepare(r)
|
||||
if err == nil {
|
||||
if r.Header == nil {
|
||||
r.Header = make(http.Header)
|
||||
}
|
||||
r.Header.Set(http.CanonicalHeaderKey(header), value)
|
||||
}
|
||||
return r, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// WithHeaders returns a PrepareDecorator that sets the specified HTTP headers of the http.Request to
|
||||
// the passed value. It canonicalizes the passed headers name (via http.CanonicalHeaderKey) before
|
||||
// adding them.
|
||||
func WithHeaders(headers map[string]interface{}) PrepareDecorator {
|
||||
h := ensureValueStrings(headers)
|
||||
return func(p Preparer) Preparer {
|
||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
r, err := p.Prepare(r)
|
||||
if err == nil {
|
||||
if r.Header == nil {
|
||||
r.Header = make(http.Header)
|
||||
}
|
||||
|
||||
for name, value := range h {
|
||||
r.Header.Set(http.CanonicalHeaderKey(name), value)
|
||||
}
|
||||
}
|
||||
return r, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// WithBearerAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose
|
||||
// value is "Bearer " followed by the supplied token.
|
||||
func WithBearerAuthorization(token string) PrepareDecorator {
|
||||
return WithHeader(headerAuthorization, fmt.Sprintf("Bearer %s", token))
|
||||
}
|
||||
|
||||
// AsContentType returns a PrepareDecorator that adds an HTTP Content-Type header whose value
|
||||
// is the passed contentType.
|
||||
func AsContentType(contentType string) PrepareDecorator {
|
||||
return WithHeader(headerContentType, contentType)
|
||||
}
|
||||
|
||||
// WithUserAgent returns a PrepareDecorator that adds an HTTP User-Agent header whose value is the
|
||||
// passed string.
|
||||
func WithUserAgent(ua string) PrepareDecorator {
|
||||
return WithHeader(headerUserAgent, ua)
|
||||
}
|
||||
|
||||
// AsFormURLEncoded returns a PrepareDecorator that adds an HTTP Content-Type header whose value is
|
||||
// "application/x-www-form-urlencoded".
|
||||
func AsFormURLEncoded() PrepareDecorator {
|
||||
return AsContentType(mimeTypeFormPost)
|
||||
}
|
||||
|
||||
// AsJSON returns a PrepareDecorator that adds an HTTP Content-Type header whose value is
|
||||
// "application/json".
|
||||
func AsJSON() PrepareDecorator {
|
||||
return AsContentType(mimeTypeJSON)
|
||||
}
|
||||
|
||||
// AsOctetStream returns a PrepareDecorator that adds the "application/octet-stream" Content-Type header.
|
||||
func AsOctetStream() PrepareDecorator {
|
||||
return AsContentType(mimeTypeOctetStream)
|
||||
}
|
||||
|
||||
// WithMethod returns a PrepareDecorator that sets the HTTP method of the passed request. The
|
||||
// decorator does not validate that the passed method string is a known HTTP method.
|
||||
func WithMethod(method string) PrepareDecorator {
|
||||
return func(p Preparer) Preparer {
|
||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
r.Method = method
|
||||
return p.Prepare(r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// AsDelete returns a PrepareDecorator that sets the HTTP method to DELETE.
|
||||
func AsDelete() PrepareDecorator { return WithMethod("DELETE") }
|
||||
|
||||
// AsGet returns a PrepareDecorator that sets the HTTP method to GET.
|
||||
func AsGet() PrepareDecorator { return WithMethod("GET") }
|
||||
|
||||
// AsHead returns a PrepareDecorator that sets the HTTP method to HEAD.
|
||||
func AsHead() PrepareDecorator { return WithMethod("HEAD") }
|
||||
|
||||
// AsOptions returns a PrepareDecorator that sets the HTTP method to OPTIONS.
|
||||
func AsOptions() PrepareDecorator { return WithMethod("OPTIONS") }
|
||||
|
||||
// AsPatch returns a PrepareDecorator that sets the HTTP method to PATCH.
|
||||
func AsPatch() PrepareDecorator { return WithMethod("PATCH") }
|
||||
|
||||
// AsPost returns a PrepareDecorator that sets the HTTP method to POST.
|
||||
func AsPost() PrepareDecorator { return WithMethod("POST") }
|
||||
|
||||
// AsPut returns a PrepareDecorator that sets the HTTP method to PUT.
|
||||
func AsPut() PrepareDecorator { return WithMethod("PUT") }
|
||||
|
||||
// WithBaseURL returns a PrepareDecorator that populates the http.Request with a url.URL constructed
|
||||
// from the supplied baseUrl.
|
||||
func WithBaseURL(baseURL string) PrepareDecorator {
|
||||
return func(p Preparer) Preparer {
|
||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
r, err := p.Prepare(r)
|
||||
if err == nil {
|
||||
var u *url.URL
|
||||
if u, err = url.Parse(baseURL); err != nil {
|
||||
return r, err
|
||||
}
|
||||
if u.Scheme == "" {
|
||||
err = fmt.Errorf("autorest: No scheme detected in URL %s", baseURL)
|
||||
}
|
||||
if err == nil {
|
||||
r.URL = u
|
||||
}
|
||||
}
|
||||
return r, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// WithCustomBaseURL returns a PrepareDecorator that replaces brace-enclosed keys within the
|
||||
// request base URL (i.e., http.Request.URL) with the corresponding values from the passed map.
|
||||
func WithCustomBaseURL(baseURL string, urlParameters map[string]interface{}) PrepareDecorator {
|
||||
parameters := ensureValueStrings(urlParameters)
|
||||
for key, value := range parameters {
|
||||
baseURL = strings.Replace(baseURL, "{"+key+"}", value, -1)
|
||||
}
|
||||
return WithBaseURL(baseURL)
|
||||
}
|
||||
|
||||
// WithFormData returns a PrepareDecoratore that "URL encodes" (e.g., bar=baz&foo=quux) into the
|
||||
// http.Request body.
|
||||
func WithFormData(v url.Values) PrepareDecorator {
|
||||
return func(p Preparer) Preparer {
|
||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
r, err := p.Prepare(r)
|
||||
if err == nil {
|
||||
s := v.Encode()
|
||||
|
||||
if r.Header == nil {
|
||||
r.Header = make(http.Header)
|
||||
}
|
||||
r.Header.Set(http.CanonicalHeaderKey(headerContentType), mimeTypeFormPost)
|
||||
r.ContentLength = int64(len(s))
|
||||
r.Body = ioutil.NopCloser(strings.NewReader(s))
|
||||
}
|
||||
return r, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// WithMultiPartFormData returns a PrepareDecoratore that "URL encodes" (e.g., bar=baz&foo=quux) form parameters
|
||||
// into the http.Request body.
|
||||
func WithMultiPartFormData(formDataParameters map[string]interface{}) PrepareDecorator {
|
||||
return func(p Preparer) Preparer {
|
||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
r, err := p.Prepare(r)
|
||||
if err == nil {
|
||||
var body bytes.Buffer
|
||||
writer := multipart.NewWriter(&body)
|
||||
for key, value := range formDataParameters {
|
||||
if rc, ok := value.(io.ReadCloser); ok {
|
||||
var fd io.Writer
|
||||
if fd, err = writer.CreateFormFile(key, key); err != nil {
|
||||
return r, err
|
||||
}
|
||||
if _, err = io.Copy(fd, rc); err != nil {
|
||||
return r, err
|
||||
}
|
||||
} else {
|
||||
if err = writer.WriteField(key, ensureValueString(value)); err != nil {
|
||||
return r, err
|
||||
}
|
||||
}
|
||||
}
|
||||
if err = writer.Close(); err != nil {
|
||||
return r, err
|
||||
}
|
||||
if r.Header == nil {
|
||||
r.Header = make(http.Header)
|
||||
}
|
||||
r.Header.Set(http.CanonicalHeaderKey(headerContentType), writer.FormDataContentType())
|
||||
r.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes()))
|
||||
r.ContentLength = int64(body.Len())
|
||||
return r, err
|
||||
}
|
||||
return r, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// WithFile returns a PrepareDecorator that sends file in request body.
|
||||
func WithFile(f io.ReadCloser) PrepareDecorator {
|
||||
return func(p Preparer) Preparer {
|
||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
r, err := p.Prepare(r)
|
||||
if err == nil {
|
||||
b, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
return r, err
|
||||
}
|
||||
r.Body = ioutil.NopCloser(bytes.NewReader(b))
|
||||
r.ContentLength = int64(len(b))
|
||||
}
|
||||
return r, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// WithBool returns a PrepareDecorator that encodes the passed bool into the body of the request
|
||||
// and sets the Content-Length header.
|
||||
func WithBool(v bool) PrepareDecorator {
|
||||
return WithString(fmt.Sprintf("%v", v))
|
||||
}
|
||||
|
||||
// WithFloat32 returns a PrepareDecorator that encodes the passed float32 into the body of the
|
||||
// request and sets the Content-Length header.
|
||||
func WithFloat32(v float32) PrepareDecorator {
|
||||
return WithString(fmt.Sprintf("%v", v))
|
||||
}
|
||||
|
||||
// WithFloat64 returns a PrepareDecorator that encodes the passed float64 into the body of the
|
||||
// request and sets the Content-Length header.
|
||||
func WithFloat64(v float64) PrepareDecorator {
|
||||
return WithString(fmt.Sprintf("%v", v))
|
||||
}
|
||||
|
||||
// WithInt32 returns a PrepareDecorator that encodes the passed int32 into the body of the request
|
||||
// and sets the Content-Length header.
|
||||
func WithInt32(v int32) PrepareDecorator {
|
||||
return WithString(fmt.Sprintf("%v", v))
|
||||
}
|
||||
|
||||
// WithInt64 returns a PrepareDecorator that encodes the passed int64 into the body of the request
|
||||
// and sets the Content-Length header.
|
||||
func WithInt64(v int64) PrepareDecorator {
|
||||
return WithString(fmt.Sprintf("%v", v))
|
||||
}
|
||||
|
||||
// WithString returns a PrepareDecorator that encodes the passed string into the body of the request
|
||||
// and sets the Content-Length header.
|
||||
func WithString(v string) PrepareDecorator {
|
||||
return func(p Preparer) Preparer {
|
||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
r, err := p.Prepare(r)
|
||||
if err == nil {
|
||||
r.ContentLength = int64(len(v))
|
||||
r.Body = ioutil.NopCloser(strings.NewReader(v))
|
||||
}
|
||||
return r, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// WithJSON returns a PrepareDecorator that encodes the data passed as JSON into the body of the
|
||||
// request and sets the Content-Length header.
|
||||
func WithJSON(v interface{}) PrepareDecorator {
|
||||
return func(p Preparer) Preparer {
|
||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
r, err := p.Prepare(r)
|
||||
if err == nil {
|
||||
b, err := json.Marshal(v)
|
||||
if err == nil {
|
||||
r.ContentLength = int64(len(b))
|
||||
r.Body = ioutil.NopCloser(bytes.NewReader(b))
|
||||
}
|
||||
}
|
||||
return r, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// WithPath returns a PrepareDecorator that adds the supplied path to the request URL. If the path
|
||||
// is absolute (that is, it begins with a "/"), it replaces the existing path.
|
||||
func WithPath(path string) PrepareDecorator {
|
||||
return func(p Preparer) Preparer {
|
||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
r, err := p.Prepare(r)
|
||||
if err == nil {
|
||||
if r.URL == nil {
|
||||
return r, NewError("autorest", "WithPath", "Invoked with a nil URL")
|
||||
}
|
||||
if r.URL, err = parseURL(r.URL, path); err != nil {
|
||||
return r, err
|
||||
}
|
||||
}
|
||||
return r, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// WithEscapedPathParameters returns a PrepareDecorator that replaces brace-enclosed keys within the
|
||||
// request path (i.e., http.Request.URL.Path) with the corresponding values from the passed map. The
|
||||
// values will be escaped (aka URL encoded) before insertion into the path.
|
||||
func WithEscapedPathParameters(path string, pathParameters map[string]interface{}) PrepareDecorator {
|
||||
parameters := escapeValueStrings(ensureValueStrings(pathParameters))
|
||||
return func(p Preparer) Preparer {
|
||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
r, err := p.Prepare(r)
|
||||
if err == nil {
|
||||
if r.URL == nil {
|
||||
return r, NewError("autorest", "WithEscapedPathParameters", "Invoked with a nil URL")
|
||||
}
|
||||
for key, value := range parameters {
|
||||
path = strings.Replace(path, "{"+key+"}", value, -1)
|
||||
}
|
||||
if r.URL, err = parseURL(r.URL, path); err != nil {
|
||||
return r, err
|
||||
}
|
||||
}
|
||||
return r, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// WithPathParameters returns a PrepareDecorator that replaces brace-enclosed keys within the
|
||||
// request path (i.e., http.Request.URL.Path) with the corresponding values from the passed map.
|
||||
func WithPathParameters(path string, pathParameters map[string]interface{}) PrepareDecorator {
|
||||
parameters := ensureValueStrings(pathParameters)
|
||||
return func(p Preparer) Preparer {
|
||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
r, err := p.Prepare(r)
|
||||
if err == nil {
|
||||
if r.URL == nil {
|
||||
return r, NewError("autorest", "WithPathParameters", "Invoked with a nil URL")
|
||||
}
|
||||
for key, value := range parameters {
|
||||
path = strings.Replace(path, "{"+key+"}", value, -1)
|
||||
}
|
||||
|
||||
if r.URL, err = parseURL(r.URL, path); err != nil {
|
||||
return r, err
|
||||
}
|
||||
}
|
||||
return r, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func parseURL(u *url.URL, path string) (*url.URL, error) {
|
||||
p := strings.TrimRight(u.String(), "/")
|
||||
if !strings.HasPrefix(path, "/") {
|
||||
path = "/" + path
|
||||
}
|
||||
return url.Parse(p + path)
|
||||
}
|
||||
|
||||
// WithQueryParameters returns a PrepareDecorators that encodes and applies the query parameters
|
||||
// given in the supplied map (i.e., key=value).
|
||||
func WithQueryParameters(queryParameters map[string]interface{}) PrepareDecorator {
|
||||
parameters := ensureValueStrings(queryParameters)
|
||||
return func(p Preparer) Preparer {
|
||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
r, err := p.Prepare(r)
|
||||
if err == nil {
|
||||
if r.URL == nil {
|
||||
return r, NewError("autorest", "WithQueryParameters", "Invoked with a nil URL")
|
||||
}
|
||||
|
||||
v := r.URL.Query()
|
||||
for key, value := range parameters {
|
||||
d, err := url.QueryUnescape(value)
|
||||
if err != nil {
|
||||
return r, err
|
||||
}
|
||||
v.Add(key, d)
|
||||
}
|
||||
r.URL.RawQuery = v.Encode()
|
||||
}
|
||||
return r, err
|
||||
})
|
||||
}
|
||||
}
|
250
vendor/github.com/Azure/go-autorest/autorest/responder.go
generated
vendored
250
vendor/github.com/Azure/go-autorest/autorest/responder.go
generated
vendored
@ -1,250 +0,0 @@
|
||||
package autorest
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Responder is the interface that wraps the Respond method.
|
||||
//
|
||||
// Respond accepts and reacts to an http.Response. Implementations must ensure to not share or hold
|
||||
// state since Responders may be shared and re-used.
|
||||
type Responder interface {
|
||||
Respond(*http.Response) error
|
||||
}
|
||||
|
||||
// ResponderFunc is a method that implements the Responder interface.
|
||||
type ResponderFunc func(*http.Response) error
|
||||
|
||||
// Respond implements the Responder interface on ResponderFunc.
|
||||
func (rf ResponderFunc) Respond(r *http.Response) error {
|
||||
return rf(r)
|
||||
}
|
||||
|
||||
// RespondDecorator takes and possibly decorates, by wrapping, a Responder. Decorators may react to
|
||||
// the http.Response and pass it along or, first, pass the http.Response along then react.
|
||||
type RespondDecorator func(Responder) Responder
|
||||
|
||||
// CreateResponder creates, decorates, and returns a Responder. Without decorators, the returned
|
||||
// Responder returns the passed http.Response unmodified. Responders may or may not be safe to share
|
||||
// and re-used: It depends on the applied decorators. For example, a standard decorator that closes
|
||||
// the response body is fine to share whereas a decorator that reads the body into a passed struct
|
||||
// is not.
|
||||
//
|
||||
// To prevent memory leaks, ensure that at least one Responder closes the response body.
|
||||
func CreateResponder(decorators ...RespondDecorator) Responder {
|
||||
return DecorateResponder(
|
||||
Responder(ResponderFunc(func(r *http.Response) error { return nil })),
|
||||
decorators...)
|
||||
}
|
||||
|
||||
// DecorateResponder accepts a Responder and a, possibly empty, set of RespondDecorators, which it
|
||||
// applies to the Responder. Decorators are applied in the order received, but their affect upon the
|
||||
// request depends on whether they are a pre-decorator (react to the http.Response and then pass it
|
||||
// along) or a post-decorator (pass the http.Response along and then react).
|
||||
func DecorateResponder(r Responder, decorators ...RespondDecorator) Responder {
|
||||
for _, decorate := range decorators {
|
||||
r = decorate(r)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// Respond accepts an http.Response and a, possibly empty, set of RespondDecorators.
|
||||
// It creates a Responder from the decorators it then applies to the passed http.Response.
|
||||
func Respond(r *http.Response, decorators ...RespondDecorator) error {
|
||||
if r == nil {
|
||||
return nil
|
||||
}
|
||||
return CreateResponder(decorators...).Respond(r)
|
||||
}
|
||||
|
||||
// ByIgnoring returns a RespondDecorator that ignores the passed http.Response passing it unexamined
|
||||
// to the next RespondDecorator.
|
||||
func ByIgnoring() RespondDecorator {
|
||||
return func(r Responder) Responder {
|
||||
return ResponderFunc(func(resp *http.Response) error {
|
||||
return r.Respond(resp)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// ByCopying copies the contents of the http.Response Body into the passed bytes.Buffer as
|
||||
// the Body is read.
|
||||
func ByCopying(b *bytes.Buffer) RespondDecorator {
|
||||
return func(r Responder) Responder {
|
||||
return ResponderFunc(func(resp *http.Response) error {
|
||||
err := r.Respond(resp)
|
||||
if err == nil && resp != nil && resp.Body != nil {
|
||||
resp.Body = TeeReadCloser(resp.Body, b)
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// ByDiscardingBody returns a RespondDecorator that first invokes the passed Responder after which
|
||||
// it copies the remaining bytes (if any) in the response body to ioutil.Discard. Since the passed
|
||||
// Responder is invoked prior to discarding the response body, the decorator may occur anywhere
|
||||
// within the set.
|
||||
func ByDiscardingBody() RespondDecorator {
|
||||
return func(r Responder) Responder {
|
||||
return ResponderFunc(func(resp *http.Response) error {
|
||||
err := r.Respond(resp)
|
||||
if err == nil && resp != nil && resp.Body != nil {
|
||||
if _, err := io.Copy(ioutil.Discard, resp.Body); err != nil {
|
||||
return fmt.Errorf("Error discarding the response body: %v", err)
|
||||
}
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// ByClosing returns a RespondDecorator that first invokes the passed Responder after which it
|
||||
// closes the response body. Since the passed Responder is invoked prior to closing the response
|
||||
// body, the decorator may occur anywhere within the set.
|
||||
func ByClosing() RespondDecorator {
|
||||
return func(r Responder) Responder {
|
||||
return ResponderFunc(func(resp *http.Response) error {
|
||||
err := r.Respond(resp)
|
||||
if resp != nil && resp.Body != nil {
|
||||
if err := resp.Body.Close(); err != nil {
|
||||
return fmt.Errorf("Error closing the response body: %v", err)
|
||||
}
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// ByClosingIfError returns a RespondDecorator that first invokes the passed Responder after which
|
||||
// it closes the response if the passed Responder returns an error and the response body exists.
|
||||
func ByClosingIfError() RespondDecorator {
|
||||
return func(r Responder) Responder {
|
||||
return ResponderFunc(func(resp *http.Response) error {
|
||||
err := r.Respond(resp)
|
||||
if err != nil && resp != nil && resp.Body != nil {
|
||||
if err := resp.Body.Close(); err != nil {
|
||||
return fmt.Errorf("Error closing the response body: %v", err)
|
||||
}
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// ByUnmarshallingJSON returns a RespondDecorator that decodes a JSON document returned in the
|
||||
// response Body into the value pointed to by v.
|
||||
func ByUnmarshallingJSON(v interface{}) RespondDecorator {
|
||||
return func(r Responder) Responder {
|
||||
return ResponderFunc(func(resp *http.Response) error {
|
||||
err := r.Respond(resp)
|
||||
if err == nil {
|
||||
b, errInner := ioutil.ReadAll(resp.Body)
|
||||
// Some responses might include a BOM, remove for successful unmarshalling
|
||||
b = bytes.TrimPrefix(b, []byte("\xef\xbb\xbf"))
|
||||
if errInner != nil {
|
||||
err = fmt.Errorf("Error occurred reading http.Response#Body - Error = '%v'", errInner)
|
||||
} else if len(strings.Trim(string(b), " ")) > 0 {
|
||||
errInner = json.Unmarshal(b, v)
|
||||
if errInner != nil {
|
||||
err = fmt.Errorf("Error occurred unmarshalling JSON - Error = '%v' JSON = '%s'", errInner, string(b))
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// ByUnmarshallingXML returns a RespondDecorator that decodes a XML document returned in the
|
||||
// response Body into the value pointed to by v.
|
||||
func ByUnmarshallingXML(v interface{}) RespondDecorator {
|
||||
return func(r Responder) Responder {
|
||||
return ResponderFunc(func(resp *http.Response) error {
|
||||
err := r.Respond(resp)
|
||||
if err == nil {
|
||||
b, errInner := ioutil.ReadAll(resp.Body)
|
||||
if errInner != nil {
|
||||
err = fmt.Errorf("Error occurred reading http.Response#Body - Error = '%v'", errInner)
|
||||
} else {
|
||||
errInner = xml.Unmarshal(b, v)
|
||||
if errInner != nil {
|
||||
err = fmt.Errorf("Error occurred unmarshalling Xml - Error = '%v' Xml = '%s'", errInner, string(b))
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// WithErrorUnlessStatusCode returns a RespondDecorator that emits an error unless the response
|
||||
// StatusCode is among the set passed. On error, response body is fully read into a buffer and
|
||||
// presented in the returned error, as well as in the response body.
|
||||
func WithErrorUnlessStatusCode(codes ...int) RespondDecorator {
|
||||
return func(r Responder) Responder {
|
||||
return ResponderFunc(func(resp *http.Response) error {
|
||||
err := r.Respond(resp)
|
||||
if err == nil && !ResponseHasStatusCode(resp, codes...) {
|
||||
derr := NewErrorWithResponse("autorest", "WithErrorUnlessStatusCode", resp, "%v %v failed with %s",
|
||||
resp.Request.Method,
|
||||
resp.Request.URL,
|
||||
resp.Status)
|
||||
if resp.Body != nil {
|
||||
defer resp.Body.Close()
|
||||
b, _ := ioutil.ReadAll(resp.Body)
|
||||
derr.ServiceError = b
|
||||
resp.Body = ioutil.NopCloser(bytes.NewReader(b))
|
||||
}
|
||||
err = derr
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// WithErrorUnlessOK returns a RespondDecorator that emits an error if the response StatusCode is
|
||||
// anything other than HTTP 200.
|
||||
func WithErrorUnlessOK() RespondDecorator {
|
||||
return WithErrorUnlessStatusCode(http.StatusOK)
|
||||
}
|
||||
|
||||
// ExtractHeader extracts all values of the specified header from the http.Response. It returns an
|
||||
// empty string slice if the passed http.Response is nil or the header does not exist.
|
||||
func ExtractHeader(header string, resp *http.Response) []string {
|
||||
if resp != nil && resp.Header != nil {
|
||||
return resp.Header[http.CanonicalHeaderKey(header)]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExtractHeaderValue extracts the first value of the specified header from the http.Response. It
|
||||
// returns an empty string if the passed http.Response is nil or the header does not exist.
|
||||
func ExtractHeaderValue(header string, resp *http.Response) string {
|
||||
h := ExtractHeader(header, resp)
|
||||
if len(h) > 0 {
|
||||
return h[0]
|
||||
}
|
||||
return ""
|
||||
}
|
52
vendor/github.com/Azure/go-autorest/autorest/retriablerequest.go
generated
vendored
52
vendor/github.com/Azure/go-autorest/autorest/retriablerequest.go
generated
vendored
@ -1,52 +0,0 @@
|
||||
package autorest
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// NewRetriableRequest returns a wrapper around an HTTP request that support retry logic.
|
||||
func NewRetriableRequest(req *http.Request) *RetriableRequest {
|
||||
return &RetriableRequest{req: req}
|
||||
}
|
||||
|
||||
// Request returns the wrapped HTTP request.
|
||||
func (rr *RetriableRequest) Request() *http.Request {
|
||||
return rr.req
|
||||
}
|
||||
|
||||
func (rr *RetriableRequest) prepareFromByteReader() (err error) {
|
||||
// fall back to making a copy (only do this once)
|
||||
b := []byte{}
|
||||
if rr.req.ContentLength > 0 {
|
||||
b = make([]byte, rr.req.ContentLength)
|
||||
_, err = io.ReadFull(rr.req.Body, b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
b, err = ioutil.ReadAll(rr.req.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
rr.br = bytes.NewReader(b)
|
||||
rr.req.Body = ioutil.NopCloser(rr.br)
|
||||
return err
|
||||
}
|
54
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go
generated
vendored
54
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go
generated
vendored
@ -1,54 +0,0 @@
|
||||
// +build !go1.8
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
package autorest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// RetriableRequest provides facilities for retrying an HTTP request.
|
||||
type RetriableRequest struct {
|
||||
req *http.Request
|
||||
br *bytes.Reader
|
||||
}
|
||||
|
||||
// Prepare signals that the request is about to be sent.
|
||||
func (rr *RetriableRequest) Prepare() (err error) {
|
||||
// preserve the request body; this is to support retry logic as
|
||||
// the underlying transport will always close the reqeust body
|
||||
if rr.req.Body != nil {
|
||||
if rr.br != nil {
|
||||
_, err = rr.br.Seek(0, 0 /*io.SeekStart*/)
|
||||
rr.req.Body = ioutil.NopCloser(rr.br)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rr.br == nil {
|
||||
// fall back to making a copy (only do this once)
|
||||
err = rr.prepareFromByteReader()
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func removeRequestBody(req *http.Request) {
|
||||
req.Body = nil
|
||||
req.ContentLength = 0
|
||||
}
|
66
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go
generated
vendored
66
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go
generated
vendored
@ -1,66 +0,0 @@
|
||||
// +build go1.8
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
package autorest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// RetriableRequest provides facilities for retrying an HTTP request.
|
||||
type RetriableRequest struct {
|
||||
req *http.Request
|
||||
rc io.ReadCloser
|
||||
br *bytes.Reader
|
||||
}
|
||||
|
||||
// Prepare signals that the request is about to be sent.
|
||||
func (rr *RetriableRequest) Prepare() (err error) {
|
||||
// preserve the request body; this is to support retry logic as
|
||||
// the underlying transport will always close the reqeust body
|
||||
if rr.req.Body != nil {
|
||||
if rr.rc != nil {
|
||||
rr.req.Body = rr.rc
|
||||
} else if rr.br != nil {
|
||||
_, err = rr.br.Seek(0, io.SeekStart)
|
||||
rr.req.Body = ioutil.NopCloser(rr.br)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rr.req.GetBody != nil {
|
||||
// this will allow us to preserve the body without having to
|
||||
// make a copy. note we need to do this on each iteration
|
||||
rr.rc, err = rr.req.GetBody()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if rr.br == nil {
|
||||
// fall back to making a copy (only do this once)
|
||||
err = rr.prepareFromByteReader()
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func removeRequestBody(req *http.Request) {
|
||||
req.Body = nil
|
||||
req.GetBody = nil
|
||||
req.ContentLength = 0
|
||||
}
|
325
vendor/github.com/Azure/go-autorest/autorest/sender.go
generated
vendored
325
vendor/github.com/Azure/go-autorest/autorest/sender.go
generated
vendored
@ -1,325 +0,0 @@
|
||||
package autorest
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Sender is the interface that wraps the Do method to send HTTP requests.
|
||||
//
|
||||
// The standard http.Client conforms to this interface.
|
||||
type Sender interface {
|
||||
Do(*http.Request) (*http.Response, error)
|
||||
}
|
||||
|
||||
// SenderFunc is a method that implements the Sender interface.
|
||||
type SenderFunc func(*http.Request) (*http.Response, error)
|
||||
|
||||
// Do implements the Sender interface on SenderFunc.
|
||||
func (sf SenderFunc) Do(r *http.Request) (*http.Response, error) {
|
||||
return sf(r)
|
||||
}
|
||||
|
||||
// SendDecorator takes and possibily decorates, by wrapping, a Sender. Decorators may affect the
|
||||
// http.Request and pass it along or, first, pass the http.Request along then react to the
|
||||
// http.Response result.
|
||||
type SendDecorator func(Sender) Sender
|
||||
|
||||
// CreateSender creates, decorates, and returns, as a Sender, the default http.Client.
|
||||
func CreateSender(decorators ...SendDecorator) Sender {
|
||||
return DecorateSender(&http.Client{}, decorators...)
|
||||
}
|
||||
|
||||
// DecorateSender accepts a Sender and a, possibly empty, set of SendDecorators, which is applies to
|
||||
// the Sender. Decorators are applied in the order received, but their affect upon the request
|
||||
// depends on whether they are a pre-decorator (change the http.Request and then pass it along) or a
|
||||
// post-decorator (pass the http.Request along and react to the results in http.Response).
|
||||
func DecorateSender(s Sender, decorators ...SendDecorator) Sender {
|
||||
for _, decorate := range decorators {
|
||||
s = decorate(s)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Send sends, by means of the default http.Client, the passed http.Request, returning the
|
||||
// http.Response and possible error. It also accepts a, possibly empty, set of SendDecorators which
|
||||
// it will apply the http.Client before invoking the Do method.
|
||||
//
|
||||
// Send is a convenience method and not recommended for production. Advanced users should use
|
||||
// SendWithSender, passing and sharing their own Sender (e.g., instance of http.Client).
|
||||
//
|
||||
// Send will not poll or retry requests.
|
||||
func Send(r *http.Request, decorators ...SendDecorator) (*http.Response, error) {
|
||||
return SendWithSender(&http.Client{}, r, decorators...)
|
||||
}
|
||||
|
||||
// SendWithSender sends the passed http.Request, through the provided Sender, returning the
|
||||
// http.Response and possible error. It also accepts a, possibly empty, set of SendDecorators which
|
||||
// it will apply the http.Client before invoking the Do method.
|
||||
//
|
||||
// SendWithSender will not poll or retry requests.
|
||||
func SendWithSender(s Sender, r *http.Request, decorators ...SendDecorator) (*http.Response, error) {
|
||||
return DecorateSender(s, decorators...).Do(r)
|
||||
}
|
||||
|
||||
// AfterDelay returns a SendDecorator that delays for the passed time.Duration before
|
||||
// invoking the Sender. The delay may be terminated by closing the optional channel on the
|
||||
// http.Request. If canceled, no further Senders are invoked.
|
||||
func AfterDelay(d time.Duration) SendDecorator {
|
||||
return func(s Sender) Sender {
|
||||
return SenderFunc(func(r *http.Request) (*http.Response, error) {
|
||||
if !DelayForBackoff(d, 0, r.Context().Done()) {
|
||||
return nil, fmt.Errorf("autorest: AfterDelay canceled before full delay")
|
||||
}
|
||||
return s.Do(r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// AsIs returns a SendDecorator that invokes the passed Sender without modifying the http.Request.
|
||||
func AsIs() SendDecorator {
|
||||
return func(s Sender) Sender {
|
||||
return SenderFunc(func(r *http.Request) (*http.Response, error) {
|
||||
return s.Do(r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// DoCloseIfError returns a SendDecorator that first invokes the passed Sender after which
|
||||
// it closes the response if the passed Sender returns an error and the response body exists.
|
||||
func DoCloseIfError() SendDecorator {
|
||||
return func(s Sender) Sender {
|
||||
return SenderFunc(func(r *http.Request) (*http.Response, error) {
|
||||
resp, err := s.Do(r)
|
||||
if err != nil {
|
||||
Respond(resp, ByDiscardingBody(), ByClosing())
|
||||
}
|
||||
return resp, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// DoErrorIfStatusCode returns a SendDecorator that emits an error if the response StatusCode is
|
||||
// among the set passed. Since these are artificial errors, the response body may still require
|
||||
// closing.
|
||||
func DoErrorIfStatusCode(codes ...int) SendDecorator {
|
||||
return func(s Sender) Sender {
|
||||
return SenderFunc(func(r *http.Request) (*http.Response, error) {
|
||||
resp, err := s.Do(r)
|
||||
if err == nil && ResponseHasStatusCode(resp, codes...) {
|
||||
err = NewErrorWithResponse("autorest", "DoErrorIfStatusCode", resp, "%v %v failed with %s",
|
||||
resp.Request.Method,
|
||||
resp.Request.URL,
|
||||
resp.Status)
|
||||
}
|
||||
return resp, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// DoErrorUnlessStatusCode returns a SendDecorator that emits an error unless the response
|
||||
// StatusCode is among the set passed. Since these are artificial errors, the response body
|
||||
// may still require closing.
|
||||
func DoErrorUnlessStatusCode(codes ...int) SendDecorator {
|
||||
return func(s Sender) Sender {
|
||||
return SenderFunc(func(r *http.Request) (*http.Response, error) {
|
||||
resp, err := s.Do(r)
|
||||
if err == nil && !ResponseHasStatusCode(resp, codes...) {
|
||||
err = NewErrorWithResponse("autorest", "DoErrorUnlessStatusCode", resp, "%v %v failed with %s",
|
||||
resp.Request.Method,
|
||||
resp.Request.URL,
|
||||
resp.Status)
|
||||
}
|
||||
return resp, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// DoPollForStatusCodes returns a SendDecorator that polls if the http.Response contains one of the
|
||||
// passed status codes. It expects the http.Response to contain a Location header providing the
|
||||
// URL at which to poll (using GET) and will poll until the time passed is equal to or greater than
|
||||
// the supplied duration. It will delay between requests for the duration specified in the
|
||||
// RetryAfter header or, if the header is absent, the passed delay. Polling may be canceled by
|
||||
// closing the optional channel on the http.Request.
|
||||
func DoPollForStatusCodes(duration time.Duration, delay time.Duration, codes ...int) SendDecorator {
|
||||
return func(s Sender) Sender {
|
||||
return SenderFunc(func(r *http.Request) (resp *http.Response, err error) {
|
||||
resp, err = s.Do(r)
|
||||
|
||||
if err == nil && ResponseHasStatusCode(resp, codes...) {
|
||||
r, err = NewPollingRequestWithContext(r.Context(), resp)
|
||||
|
||||
for err == nil && ResponseHasStatusCode(resp, codes...) {
|
||||
Respond(resp,
|
||||
ByDiscardingBody(),
|
||||
ByClosing())
|
||||
resp, err = SendWithSender(s, r,
|
||||
AfterDelay(GetRetryAfter(resp, delay)))
|
||||
}
|
||||
}
|
||||
|
||||
return resp, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// DoRetryForAttempts returns a SendDecorator that retries a failed request for up to the specified
|
||||
// number of attempts, exponentially backing off between requests using the supplied backoff
|
||||
// time.Duration (which may be zero). Retrying may be canceled by closing the optional channel on
|
||||
// the http.Request.
|
||||
func DoRetryForAttempts(attempts int, backoff time.Duration) SendDecorator {
|
||||
return func(s Sender) Sender {
|
||||
return SenderFunc(func(r *http.Request) (resp *http.Response, err error) {
|
||||
rr := NewRetriableRequest(r)
|
||||
for attempt := 0; attempt < attempts; attempt++ {
|
||||
err = rr.Prepare()
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
resp, err = s.Do(rr.Request())
|
||||
if err == nil {
|
||||
return resp, err
|
||||
}
|
||||
if !DelayForBackoff(backoff, attempt, r.Context().Done()) {
|
||||
return nil, r.Context().Err()
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// DoRetryForStatusCodes returns a SendDecorator that retries for specified statusCodes for up to the specified
|
||||
// number of attempts, exponentially backing off between requests using the supplied backoff
|
||||
// time.Duration (which may be zero). Retrying may be canceled by closing the optional channel on
|
||||
// the http.Request.
|
||||
func DoRetryForStatusCodes(attempts int, backoff time.Duration, codes ...int) SendDecorator {
|
||||
return func(s Sender) Sender {
|
||||
return SenderFunc(func(r *http.Request) (resp *http.Response, err error) {
|
||||
rr := NewRetriableRequest(r)
|
||||
// Increment to add the first call (attempts denotes number of retries)
|
||||
attempts++
|
||||
for attempt := 0; attempt < attempts; {
|
||||
err = rr.Prepare()
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
resp, err = s.Do(rr.Request())
|
||||
// if the error isn't temporary don't bother retrying
|
||||
if err != nil && !IsTemporaryNetworkError(err) {
|
||||
return nil, err
|
||||
}
|
||||
// we want to retry if err is not nil (e.g. transient network failure). note that for failed authentication
|
||||
// resp and err will both have a value, so in this case we don't want to retry as it will never succeed.
|
||||
if err == nil && !ResponseHasStatusCode(resp, codes...) || IsTokenRefreshError(err) {
|
||||
return resp, err
|
||||
}
|
||||
delayed := DelayWithRetryAfter(resp, r.Context().Done())
|
||||
if !delayed && !DelayForBackoff(backoff, attempt, r.Context().Done()) {
|
||||
return resp, r.Context().Err()
|
||||
}
|
||||
// don't count a 429 against the number of attempts
|
||||
// so that we continue to retry until it succeeds
|
||||
if resp == nil || resp.StatusCode != http.StatusTooManyRequests {
|
||||
attempt++
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// DelayWithRetryAfter invokes time.After for the duration specified in the "Retry-After" header in
|
||||
// responses with status code 429
|
||||
func DelayWithRetryAfter(resp *http.Response, cancel <-chan struct{}) bool {
|
||||
if resp == nil {
|
||||
return false
|
||||
}
|
||||
retryAfter, _ := strconv.Atoi(resp.Header.Get("Retry-After"))
|
||||
if resp.StatusCode == http.StatusTooManyRequests && retryAfter > 0 {
|
||||
select {
|
||||
case <-time.After(time.Duration(retryAfter) * time.Second):
|
||||
return true
|
||||
case <-cancel:
|
||||
return false
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// DoRetryForDuration returns a SendDecorator that retries the request until the total time is equal
|
||||
// to or greater than the specified duration, exponentially backing off between requests using the
|
||||
// supplied backoff time.Duration (which may be zero). Retrying may be canceled by closing the
|
||||
// optional channel on the http.Request.
|
||||
func DoRetryForDuration(d time.Duration, backoff time.Duration) SendDecorator {
|
||||
return func(s Sender) Sender {
|
||||
return SenderFunc(func(r *http.Request) (resp *http.Response, err error) {
|
||||
rr := NewRetriableRequest(r)
|
||||
end := time.Now().Add(d)
|
||||
for attempt := 0; time.Now().Before(end); attempt++ {
|
||||
err = rr.Prepare()
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
resp, err = s.Do(rr.Request())
|
||||
if err == nil {
|
||||
return resp, err
|
||||
}
|
||||
if !DelayForBackoff(backoff, attempt, r.Context().Done()) {
|
||||
return nil, r.Context().Err()
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// WithLogging returns a SendDecorator that implements simple before and after logging of the
|
||||
// request.
|
||||
func WithLogging(logger *log.Logger) SendDecorator {
|
||||
return func(s Sender) Sender {
|
||||
return SenderFunc(func(r *http.Request) (*http.Response, error) {
|
||||
logger.Printf("Sending %s %s", r.Method, r.URL)
|
||||
resp, err := s.Do(r)
|
||||
if err != nil {
|
||||
logger.Printf("%s %s received error '%v'", r.Method, r.URL, err)
|
||||
} else {
|
||||
logger.Printf("%s %s received %s", r.Method, r.URL, resp.Status)
|
||||
}
|
||||
return resp, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// DelayForBackoff invokes time.After for the supplied backoff duration raised to the power of
|
||||
// passed attempt (i.e., an exponential backoff delay). Backoff duration is in seconds and can set
|
||||
// to zero for no delay. The delay may be canceled by closing the passed channel. If terminated early,
|
||||
// returns false.
|
||||
// Note: Passing attempt 1 will result in doubling "backoff" duration. Treat this as a zero-based attempt
|
||||
// count.
|
||||
func DelayForBackoff(backoff time.Duration, attempt int, cancel <-chan struct{}) bool {
|
||||
select {
|
||||
case <-time.After(time.Duration(backoff.Seconds()*math.Pow(2, float64(attempt))) * time.Second):
|
||||
return true
|
||||
case <-cancel:
|
||||
return false
|
||||
}
|
||||
}
|
228
vendor/github.com/Azure/go-autorest/autorest/utility.go
generated
vendored
228
vendor/github.com/Azure/go-autorest/autorest/utility.go
generated
vendored
@ -1,228 +0,0 @@
|
||||
package autorest
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest/adal"
|
||||
)
|
||||
|
||||
// EncodedAs is a series of constants specifying various data encodings
|
||||
type EncodedAs string
|
||||
|
||||
const (
|
||||
// EncodedAsJSON states that data is encoded as JSON
|
||||
EncodedAsJSON EncodedAs = "JSON"
|
||||
|
||||
// EncodedAsXML states that data is encoded as Xml
|
||||
EncodedAsXML EncodedAs = "XML"
|
||||
)
|
||||
|
||||
// Decoder defines the decoding method json.Decoder and xml.Decoder share
|
||||
type Decoder interface {
|
||||
Decode(v interface{}) error
|
||||
}
|
||||
|
||||
// NewDecoder creates a new decoder appropriate to the passed encoding.
|
||||
// encodedAs specifies the type of encoding and r supplies the io.Reader containing the
|
||||
// encoded data.
|
||||
func NewDecoder(encodedAs EncodedAs, r io.Reader) Decoder {
|
||||
if encodedAs == EncodedAsJSON {
|
||||
return json.NewDecoder(r)
|
||||
} else if encodedAs == EncodedAsXML {
|
||||
return xml.NewDecoder(r)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CopyAndDecode decodes the data from the passed io.Reader while making a copy. Having a copy
|
||||
// is especially useful if there is a chance the data will fail to decode.
|
||||
// encodedAs specifies the expected encoding, r provides the io.Reader to the data, and v
|
||||
// is the decoding destination.
|
||||
func CopyAndDecode(encodedAs EncodedAs, r io.Reader, v interface{}) (bytes.Buffer, error) {
|
||||
b := bytes.Buffer{}
|
||||
return b, NewDecoder(encodedAs, io.TeeReader(r, &b)).Decode(v)
|
||||
}
|
||||
|
||||
// TeeReadCloser returns a ReadCloser that writes to w what it reads from rc.
|
||||
// It utilizes io.TeeReader to copy the data read and has the same behavior when reading.
|
||||
// Further, when it is closed, it ensures that rc is closed as well.
|
||||
func TeeReadCloser(rc io.ReadCloser, w io.Writer) io.ReadCloser {
|
||||
return &teeReadCloser{rc, io.TeeReader(rc, w)}
|
||||
}
|
||||
|
||||
type teeReadCloser struct {
|
||||
rc io.ReadCloser
|
||||
r io.Reader
|
||||
}
|
||||
|
||||
func (t *teeReadCloser) Read(p []byte) (int, error) {
|
||||
return t.r.Read(p)
|
||||
}
|
||||
|
||||
func (t *teeReadCloser) Close() error {
|
||||
return t.rc.Close()
|
||||
}
|
||||
|
||||
func containsInt(ints []int, n int) bool {
|
||||
for _, i := range ints {
|
||||
if i == n {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func escapeValueStrings(m map[string]string) map[string]string {
|
||||
for key, value := range m {
|
||||
m[key] = url.QueryEscape(value)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func ensureValueStrings(mapOfInterface map[string]interface{}) map[string]string {
|
||||
mapOfStrings := make(map[string]string)
|
||||
for key, value := range mapOfInterface {
|
||||
mapOfStrings[key] = ensureValueString(value)
|
||||
}
|
||||
return mapOfStrings
|
||||
}
|
||||
|
||||
func ensureValueString(value interface{}) string {
|
||||
if value == nil {
|
||||
return ""
|
||||
}
|
||||
switch v := value.(type) {
|
||||
case string:
|
||||
return v
|
||||
case []byte:
|
||||
return string(v)
|
||||
default:
|
||||
return fmt.Sprintf("%v", v)
|
||||
}
|
||||
}
|
||||
|
||||
// MapToValues method converts map[string]interface{} to url.Values.
|
||||
func MapToValues(m map[string]interface{}) url.Values {
|
||||
v := url.Values{}
|
||||
for key, value := range m {
|
||||
x := reflect.ValueOf(value)
|
||||
if x.Kind() == reflect.Array || x.Kind() == reflect.Slice {
|
||||
for i := 0; i < x.Len(); i++ {
|
||||
v.Add(key, ensureValueString(x.Index(i)))
|
||||
}
|
||||
} else {
|
||||
v.Add(key, ensureValueString(value))
|
||||
}
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// AsStringSlice method converts interface{} to []string. This expects a
|
||||
//that the parameter passed to be a slice or array of a type that has the underlying
|
||||
//type a string.
|
||||
func AsStringSlice(s interface{}) ([]string, error) {
|
||||
v := reflect.ValueOf(s)
|
||||
if v.Kind() != reflect.Slice && v.Kind() != reflect.Array {
|
||||
return nil, NewError("autorest", "AsStringSlice", "the value's type is not an array.")
|
||||
}
|
||||
stringSlice := make([]string, 0, v.Len())
|
||||
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
stringSlice = append(stringSlice, v.Index(i).String())
|
||||
}
|
||||
return stringSlice, nil
|
||||
}
|
||||
|
||||
// String method converts interface v to string. If interface is a list, it
|
||||
// joins list elements using the seperator. Note that only sep[0] will be used for
|
||||
// joining if any separator is specified.
|
||||
func String(v interface{}, sep ...string) string {
|
||||
if len(sep) == 0 {
|
||||
return ensureValueString(v)
|
||||
}
|
||||
stringSlice, ok := v.([]string)
|
||||
if ok == false {
|
||||
var err error
|
||||
stringSlice, err = AsStringSlice(v)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("autorest: Couldn't convert value to a string %s.", err))
|
||||
}
|
||||
}
|
||||
return ensureValueString(strings.Join(stringSlice, sep[0]))
|
||||
}
|
||||
|
||||
// Encode method encodes url path and query parameters.
|
||||
func Encode(location string, v interface{}, sep ...string) string {
|
||||
s := String(v, sep...)
|
||||
switch strings.ToLower(location) {
|
||||
case "path":
|
||||
return pathEscape(s)
|
||||
case "query":
|
||||
return queryEscape(s)
|
||||
default:
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
||||
func pathEscape(s string) string {
|
||||
return strings.Replace(url.QueryEscape(s), "+", "%20", -1)
|
||||
}
|
||||
|
||||
func queryEscape(s string) string {
|
||||
return url.QueryEscape(s)
|
||||
}
|
||||
|
||||
// ChangeToGet turns the specified http.Request into a GET (it assumes it wasn't).
|
||||
// This is mainly useful for long-running operations that use the Azure-AsyncOperation
|
||||
// header, so we change the initial PUT into a GET to retrieve the final result.
|
||||
func ChangeToGet(req *http.Request) *http.Request {
|
||||
req.Method = "GET"
|
||||
req.Body = nil
|
||||
req.ContentLength = 0
|
||||
req.Header.Del("Content-Length")
|
||||
return req
|
||||
}
|
||||
|
||||
// IsTokenRefreshError returns true if the specified error implements the TokenRefreshError
|
||||
// interface. If err is a DetailedError it will walk the chain of Original errors.
|
||||
func IsTokenRefreshError(err error) bool {
|
||||
if _, ok := err.(adal.TokenRefreshError); ok {
|
||||
return true
|
||||
}
|
||||
if de, ok := err.(DetailedError); ok {
|
||||
return IsTokenRefreshError(de.Original)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsTemporaryNetworkError returns true if the specified error is a temporary network error or false
|
||||
// if it's not. If the error doesn't implement the net.Error interface the return value is true.
|
||||
func IsTemporaryNetworkError(err error) bool {
|
||||
if netErr, ok := err.(net.Error); !ok || (ok && netErr.Temporary()) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
22
vendor/github.com/Azure/go-autorest/autorest/version.go
generated
vendored
22
vendor/github.com/Azure/go-autorest/autorest/version.go
generated
vendored
@ -1,22 +0,0 @@
|
||||
package autorest
|
||||
|
||||
import "github.com/Azure/go-autorest/version"
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
// Version returns the semantic version (see http://semver.org).
|
||||
func Version() string {
|
||||
return version.Number
|
||||
}
|
328
vendor/github.com/Azure/go-autorest/logger/logger.go
generated
vendored
328
vendor/github.com/Azure/go-autorest/logger/logger.go
generated
vendored
@ -1,328 +0,0 @@
|
||||
package logger
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// LevelType tells a logger the minimum level to log. When code reports a log entry,
|
||||
// the LogLevel indicates the level of the log entry. The logger only records entries
|
||||
// whose level is at least the level it was told to log. See the Log* constants.
|
||||
// For example, if a logger is configured with LogError, then LogError, LogPanic,
|
||||
// and LogFatal entries will be logged; lower level entries are ignored.
|
||||
type LevelType uint32
|
||||
|
||||
const (
|
||||
// LogNone tells a logger not to log any entries passed to it.
|
||||
LogNone LevelType = iota
|
||||
|
||||
// LogFatal tells a logger to log all LogFatal entries passed to it.
|
||||
LogFatal
|
||||
|
||||
// LogPanic tells a logger to log all LogPanic and LogFatal entries passed to it.
|
||||
LogPanic
|
||||
|
||||
// LogError tells a logger to log all LogError, LogPanic and LogFatal entries passed to it.
|
||||
LogError
|
||||
|
||||
// LogWarning tells a logger to log all LogWarning, LogError, LogPanic and LogFatal entries passed to it.
|
||||
LogWarning
|
||||
|
||||
// LogInfo tells a logger to log all LogInfo, LogWarning, LogError, LogPanic and LogFatal entries passed to it.
|
||||
LogInfo
|
||||
|
||||
// LogDebug tells a logger to log all LogDebug, LogInfo, LogWarning, LogError, LogPanic and LogFatal entries passed to it.
|
||||
LogDebug
|
||||
)
|
||||
|
||||
const (
|
||||
logNone = "NONE"
|
||||
logFatal = "FATAL"
|
||||
logPanic = "PANIC"
|
||||
logError = "ERROR"
|
||||
logWarning = "WARNING"
|
||||
logInfo = "INFO"
|
||||
logDebug = "DEBUG"
|
||||
logUnknown = "UNKNOWN"
|
||||
)
|
||||
|
||||
// ParseLevel converts the specified string into the corresponding LevelType.
|
||||
func ParseLevel(s string) (lt LevelType, err error) {
|
||||
switch strings.ToUpper(s) {
|
||||
case logFatal:
|
||||
lt = LogFatal
|
||||
case logPanic:
|
||||
lt = LogPanic
|
||||
case logError:
|
||||
lt = LogError
|
||||
case logWarning:
|
||||
lt = LogWarning
|
||||
case logInfo:
|
||||
lt = LogInfo
|
||||
case logDebug:
|
||||
lt = LogDebug
|
||||
default:
|
||||
err = fmt.Errorf("bad log level '%s'", s)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// String implements the stringer interface for LevelType.
|
||||
func (lt LevelType) String() string {
|
||||
switch lt {
|
||||
case LogNone:
|
||||
return logNone
|
||||
case LogFatal:
|
||||
return logFatal
|
||||
case LogPanic:
|
||||
return logPanic
|
||||
case LogError:
|
||||
return logError
|
||||
case LogWarning:
|
||||
return logWarning
|
||||
case LogInfo:
|
||||
return logInfo
|
||||
case LogDebug:
|
||||
return logDebug
|
||||
default:
|
||||
return logUnknown
|
||||
}
|
||||
}
|
||||
|
||||
// Filter defines functions for filtering HTTP request/response content.
|
||||
type Filter struct {
|
||||
// URL returns a potentially modified string representation of a request URL.
|
||||
URL func(u *url.URL) string
|
||||
|
||||
// Header returns a potentially modified set of values for the specified key.
|
||||
// To completely exclude the header key/values return false.
|
||||
Header func(key string, val []string) (bool, []string)
|
||||
|
||||
// Body returns a potentially modified request/response body.
|
||||
Body func(b []byte) []byte
|
||||
}
|
||||
|
||||
func (f Filter) processURL(u *url.URL) string {
|
||||
if f.URL == nil {
|
||||
return u.String()
|
||||
}
|
||||
return f.URL(u)
|
||||
}
|
||||
|
||||
func (f Filter) processHeader(k string, val []string) (bool, []string) {
|
||||
if f.Header == nil {
|
||||
return true, val
|
||||
}
|
||||
return f.Header(k, val)
|
||||
}
|
||||
|
||||
func (f Filter) processBody(b []byte) []byte {
|
||||
if f.Body == nil {
|
||||
return b
|
||||
}
|
||||
return f.Body(b)
|
||||
}
|
||||
|
||||
// Writer defines methods for writing to a logging facility.
|
||||
type Writer interface {
|
||||
// Writeln writes the specified message with the standard log entry header and new-line character.
|
||||
Writeln(level LevelType, message string)
|
||||
|
||||
// Writef writes the specified format specifier with the standard log entry header and no new-line character.
|
||||
Writef(level LevelType, format string, a ...interface{})
|
||||
|
||||
// WriteRequest writes the specified HTTP request to the logger if the log level is greater than
|
||||
// or equal to LogInfo. The request body, if set, is logged at level LogDebug or higher.
|
||||
// Custom filters can be specified to exclude URL, header, and/or body content from the log.
|
||||
// By default no request content is excluded.
|
||||
WriteRequest(req *http.Request, filter Filter)
|
||||
|
||||
// WriteResponse writes the specified HTTP response to the logger if the log level is greater than
|
||||
// or equal to LogInfo. The response body, if set, is logged at level LogDebug or higher.
|
||||
// Custom filters can be specified to exclude URL, header, and/or body content from the log.
|
||||
// By default no respone content is excluded.
|
||||
WriteResponse(resp *http.Response, filter Filter)
|
||||
}
|
||||
|
||||
// Instance is the default log writer initialized during package init.
|
||||
// This can be replaced with a custom implementation as required.
|
||||
var Instance Writer
|
||||
|
||||
// default log level
|
||||
var logLevel = LogNone
|
||||
|
||||
// Level returns the value specified in AZURE_GO_AUTOREST_LOG_LEVEL.
|
||||
// If no value was specified the default value is LogNone.
|
||||
// Custom loggers can call this to retrieve the configured log level.
|
||||
func Level() LevelType {
|
||||
return logLevel
|
||||
}
|
||||
|
||||
func init() {
|
||||
// separated for testing purposes
|
||||
initDefaultLogger()
|
||||
}
|
||||
|
||||
func initDefaultLogger() {
|
||||
// init with nilLogger so callers don't have to do a nil check on Default
|
||||
Instance = nilLogger{}
|
||||
llStr := strings.ToLower(os.Getenv("AZURE_GO_SDK_LOG_LEVEL"))
|
||||
if llStr == "" {
|
||||
return
|
||||
}
|
||||
var err error
|
||||
logLevel, err = ParseLevel(llStr)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "go-autorest: failed to parse log level: %s\n", err.Error())
|
||||
return
|
||||
}
|
||||
if logLevel == LogNone {
|
||||
return
|
||||
}
|
||||
// default to stderr
|
||||
dest := os.Stderr
|
||||
lfStr := os.Getenv("AZURE_GO_SDK_LOG_FILE")
|
||||
if strings.EqualFold(lfStr, "stdout") {
|
||||
dest = os.Stdout
|
||||
} else if lfStr != "" {
|
||||
lf, err := os.Create(lfStr)
|
||||
if err == nil {
|
||||
dest = lf
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, "go-autorest: failed to create log file, using stderr: %s\n", err.Error())
|
||||
}
|
||||
}
|
||||
Instance = fileLogger{
|
||||
logLevel: logLevel,
|
||||
mu: &sync.Mutex{},
|
||||
logFile: dest,
|
||||
}
|
||||
}
|
||||
|
||||
// the nil logger does nothing
|
||||
type nilLogger struct{}
|
||||
|
||||
func (nilLogger) Writeln(LevelType, string) {}
|
||||
|
||||
func (nilLogger) Writef(LevelType, string, ...interface{}) {}
|
||||
|
||||
func (nilLogger) WriteRequest(*http.Request, Filter) {}
|
||||
|
||||
func (nilLogger) WriteResponse(*http.Response, Filter) {}
|
||||
|
||||
// A File is used instead of a Logger so the stream can be flushed after every write.
|
||||
type fileLogger struct {
|
||||
logLevel LevelType
|
||||
mu *sync.Mutex // for synchronizing writes to logFile
|
||||
logFile *os.File
|
||||
}
|
||||
|
||||
func (fl fileLogger) Writeln(level LevelType, message string) {
|
||||
fl.Writef(level, "%s\n", message)
|
||||
}
|
||||
|
||||
func (fl fileLogger) Writef(level LevelType, format string, a ...interface{}) {
|
||||
if fl.logLevel >= level {
|
||||
fl.mu.Lock()
|
||||
defer fl.mu.Unlock()
|
||||
fmt.Fprintf(fl.logFile, "%s %s", entryHeader(level), fmt.Sprintf(format, a...))
|
||||
fl.logFile.Sync()
|
||||
}
|
||||
}
|
||||
|
||||
func (fl fileLogger) WriteRequest(req *http.Request, filter Filter) {
|
||||
if req == nil || fl.logLevel < LogInfo {
|
||||
return
|
||||
}
|
||||
b := &bytes.Buffer{}
|
||||
fmt.Fprintf(b, "%s REQUEST: %s %s\n", entryHeader(LogInfo), req.Method, filter.processURL(req.URL))
|
||||
// dump headers
|
||||
for k, v := range req.Header {
|
||||
if ok, mv := filter.processHeader(k, v); ok {
|
||||
fmt.Fprintf(b, "%s: %s\n", k, strings.Join(mv, ","))
|
||||
}
|
||||
}
|
||||
if fl.shouldLogBody(req.Header, req.Body) {
|
||||
// dump body
|
||||
body, err := ioutil.ReadAll(req.Body)
|
||||
if err == nil {
|
||||
fmt.Fprintln(b, string(filter.processBody(body)))
|
||||
if nc, ok := req.Body.(io.Seeker); ok {
|
||||
// rewind to the beginning
|
||||
nc.Seek(0, io.SeekStart)
|
||||
} else {
|
||||
// recreate the body
|
||||
req.Body = ioutil.NopCloser(bytes.NewReader(body))
|
||||
}
|
||||
} else {
|
||||
fmt.Fprintf(b, "failed to read body: %v\n", err)
|
||||
}
|
||||
}
|
||||
fl.mu.Lock()
|
||||
defer fl.mu.Unlock()
|
||||
fmt.Fprint(fl.logFile, b.String())
|
||||
fl.logFile.Sync()
|
||||
}
|
||||
|
||||
func (fl fileLogger) WriteResponse(resp *http.Response, filter Filter) {
|
||||
if resp == nil || fl.logLevel < LogInfo {
|
||||
return
|
||||
}
|
||||
b := &bytes.Buffer{}
|
||||
fmt.Fprintf(b, "%s RESPONSE: %d %s\n", entryHeader(LogInfo), resp.StatusCode, filter.processURL(resp.Request.URL))
|
||||
// dump headers
|
||||
for k, v := range resp.Header {
|
||||
if ok, mv := filter.processHeader(k, v); ok {
|
||||
fmt.Fprintf(b, "%s: %s\n", k, strings.Join(mv, ","))
|
||||
}
|
||||
}
|
||||
if fl.shouldLogBody(resp.Header, resp.Body) {
|
||||
// dump body
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err == nil {
|
||||
fmt.Fprintln(b, string(filter.processBody(body)))
|
||||
resp.Body = ioutil.NopCloser(bytes.NewReader(body))
|
||||
} else {
|
||||
fmt.Fprintf(b, "failed to read body: %v\n", err)
|
||||
}
|
||||
}
|
||||
fl.mu.Lock()
|
||||
defer fl.mu.Unlock()
|
||||
fmt.Fprint(fl.logFile, b.String())
|
||||
fl.logFile.Sync()
|
||||
}
|
||||
|
||||
// returns true if the provided body should be included in the log
|
||||
func (fl fileLogger) shouldLogBody(header http.Header, body io.ReadCloser) bool {
|
||||
ct := header.Get("Content-Type")
|
||||
return fl.logLevel >= LogDebug && body != nil && strings.Index(ct, "application/octet-stream") == -1
|
||||
}
|
||||
|
||||
// creates standard header for log entries, it contains a timestamp and the log level
|
||||
func entryHeader(level LevelType) string {
|
||||
// this format provides a fixed number of digits so the size of the timestamp is constant
|
||||
return fmt.Sprintf("(%s) %s:", time.Now().Format("2006-01-02T15:04:05.0000000Z07:00"), level.String())
|
||||
}
|
37
vendor/github.com/Azure/go-autorest/version/version.go
generated
vendored
37
vendor/github.com/Azure/go-autorest/version/version.go
generated
vendored
@ -1,37 +0,0 @@
|
||||
package version
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// Number contains the semantic version of this SDK.
|
||||
const Number = "v11.1.2"
|
||||
|
||||
var (
|
||||
userAgent = fmt.Sprintf("Go/%s (%s-%s) go-autorest/%s",
|
||||
runtime.Version(),
|
||||
runtime.GOARCH,
|
||||
runtime.GOOS,
|
||||
Number,
|
||||
)
|
||||
)
|
||||
|
||||
// UserAgent returns a string containing the Go version, system archityecture and OS, and the go-autorest version.
|
||||
func UserAgent() string {
|
||||
return userAgent
|
||||
}
|
21
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/LICENSE
generated
vendored
21
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/LICENSE
generated
vendored
@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
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
|
3393
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/build/client.go
generated
vendored
3393
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/build/client.go
generated
vendored
File diff suppressed because it is too large
Load Diff
2301
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/build/models.go
generated
vendored
2301
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/build/models.go
generated
vendored
File diff suppressed because it is too large
Load Diff
417
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/client.go
generated
vendored
417
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/client.go
generated
vendored
@ -1,417 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package azuredevops
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/google/uuid"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// header keys
|
||||
headerKeyAccept = "Accept"
|
||||
headerKeyAuthorization = "Authorization"
|
||||
headerKeyContentType = "Content-Type"
|
||||
HeaderKeyContinuationToken = "X-MS-ContinuationToken"
|
||||
headerKeyFedAuthRedirect = "X-TFS-FedAuthRedirect"
|
||||
headerKeyForceMsaPassThrough = "X-VSS-ForceMsaPassThrough"
|
||||
headerKeySession = "X-TFS-Session"
|
||||
headerUserAgent = "User-Agent"
|
||||
|
||||
// media types
|
||||
MediaTypeTextPlain = "text/plain"
|
||||
MediaTypeApplicationJson = "application/json"
|
||||
)
|
||||
|
||||
// Unique session id to be used by all requests of this session.
|
||||
var SessionId = uuid.New().String()
|
||||
|
||||
// ApiResourceLocation Cache by Url
|
||||
var apiResourceLocationCache = make(map[string]*map[uuid.UUID]ApiResourceLocation)
|
||||
var apiResourceLocationCacheLock = sync.RWMutex{}
|
||||
|
||||
// Base user agent string. The UserAgent set on the connection will be appended to this.
|
||||
var baseUserAgent = "go/" + runtime.Version() + " (" + runtime.GOOS + " " + runtime.GOARCH + ") azure-devops-go-api/0.0.0" // todo: get real version
|
||||
|
||||
func NewClient(connection *Connection, baseUrl string) *Client {
|
||||
client := &http.Client{}
|
||||
if connection.Timeout != nil {
|
||||
client.Timeout = *connection.Timeout
|
||||
}
|
||||
return &Client{
|
||||
baseUrl: baseUrl,
|
||||
client: client,
|
||||
authorization: connection.AuthorizationString,
|
||||
suppressFedAuthRedirect: connection.SuppressFedAuthRedirect,
|
||||
forceMsaPassThrough: connection.ForceMsaPassThrough,
|
||||
userAgent: connection.UserAgent,
|
||||
}
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
baseUrl string
|
||||
client *http.Client
|
||||
authorization string
|
||||
suppressFedAuthRedirect bool
|
||||
forceMsaPassThrough bool
|
||||
userAgent string
|
||||
}
|
||||
|
||||
func (client *Client) SendRequest(request *http.Request) (response *http.Response, err error) {
|
||||
resp, err := client.client.Do(request) // todo: add retry logic
|
||||
if resp != nil && (resp.StatusCode < 200 || resp.StatusCode >= 300) {
|
||||
err = client.UnwrapError(resp)
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (client *Client) Send(ctx context.Context,
|
||||
httpMethod string,
|
||||
locationId uuid.UUID,
|
||||
apiVersion string,
|
||||
routeValues map[string]string,
|
||||
queryParameters url.Values,
|
||||
body io.Reader,
|
||||
mediaType string,
|
||||
acceptMediaType string,
|
||||
additionalHeaders map[string]string) (response *http.Response, err error) {
|
||||
location, err := client.getResourceLocation(ctx, locationId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
generatedUrl := client.GenerateUrl(location, routeValues, queryParameters)
|
||||
fullUrl := combineUrl(client.baseUrl, generatedUrl)
|
||||
negotiatedVersion, err := negotiateRequestVersion(location, apiVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req, err := client.CreateRequestMessage(ctx, httpMethod, fullUrl, negotiatedVersion, body, mediaType, acceptMediaType, additionalHeaders)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := client.SendRequest(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Set session if one was supplied in the response.
|
||||
session, ok := resp.Header[headerKeySession]
|
||||
if ok && len(session) > 0 {
|
||||
SessionId = session[0]
|
||||
}
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (client *Client) GenerateUrl(apiResourceLocation *ApiResourceLocation, routeValues map[string]string, queryParameters url.Values) (request string) {
|
||||
builtUrl := *apiResourceLocation.RouteTemplate
|
||||
if routeValues == nil {
|
||||
routeValues = make(map[string]string)
|
||||
}
|
||||
routeValues["area"] = *apiResourceLocation.Area
|
||||
routeValues["resource"] = *apiResourceLocation.ResourceName
|
||||
builtUrl = transformRouteTemplate(builtUrl, routeValues)
|
||||
if queryParameters != nil && len(queryParameters) > 0 {
|
||||
builtUrl += "?" + queryParameters.Encode()
|
||||
}
|
||||
return builtUrl
|
||||
}
|
||||
|
||||
func (client *Client) CreateRequestMessage(ctx context.Context,
|
||||
httpMethod string,
|
||||
url string,
|
||||
apiVersion string,
|
||||
body io.Reader,
|
||||
mediaType string,
|
||||
acceptMediaType string,
|
||||
additionalHeaders map[string]string) (request *http.Request, err error) {
|
||||
req, err := http.NewRequest(httpMethod, url, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if ctx != nil {
|
||||
req = req.WithContext(ctx)
|
||||
}
|
||||
|
||||
if client.authorization != "" {
|
||||
req.Header.Add(headerKeyAuthorization, client.authorization)
|
||||
}
|
||||
accept := acceptMediaType
|
||||
if apiVersion != "" {
|
||||
accept += ";api-version=" + apiVersion
|
||||
}
|
||||
req.Header.Add(headerKeyAccept, accept)
|
||||
if mediaType != "" {
|
||||
req.Header.Add(headerKeyContentType, mediaType+";charset=utf-8")
|
||||
}
|
||||
if client.suppressFedAuthRedirect {
|
||||
req.Header.Add(headerKeyFedAuthRedirect, "Suppress")
|
||||
}
|
||||
if client.forceMsaPassThrough {
|
||||
req.Header.Add(headerKeyForceMsaPassThrough, "true")
|
||||
}
|
||||
|
||||
// set session if it has not already been set
|
||||
_, ok := req.Header[headerKeySession]
|
||||
if !ok {
|
||||
req.Header.Add(headerKeySession, SessionId)
|
||||
}
|
||||
|
||||
userAgent := baseUserAgent
|
||||
if client.userAgent != "" {
|
||||
userAgent += " " + client.userAgent
|
||||
}
|
||||
req.Header.Add(headerUserAgent, userAgent)
|
||||
|
||||
for key, value := range additionalHeaders {
|
||||
req.Header.Add(key, value)
|
||||
}
|
||||
|
||||
return req, err
|
||||
}
|
||||
|
||||
func (client *Client) getResourceLocation(ctx context.Context, locationId uuid.UUID) (*ApiResourceLocation, error) {
|
||||
locationsMap, ok := getApiResourceLocationCache(client.baseUrl)
|
||||
if !ok {
|
||||
locations, err := client.getResourceLocationsFromServer(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
newMap := make(map[uuid.UUID]ApiResourceLocation)
|
||||
locationsMap = &newMap
|
||||
for _, locationEntry := range locations {
|
||||
(*locationsMap)[*locationEntry.Id] = locationEntry
|
||||
}
|
||||
|
||||
setApiResourceLocationCache(client.baseUrl, locationsMap)
|
||||
}
|
||||
|
||||
location, ok := (*locationsMap)[locationId]
|
||||
if ok {
|
||||
return &location, nil
|
||||
}
|
||||
|
||||
return nil, &LocationIdNotRegisteredError{locationId, client.baseUrl}
|
||||
}
|
||||
|
||||
func getApiResourceLocationCache(url string) (*map[uuid.UUID]ApiResourceLocation, bool) {
|
||||
apiResourceLocationCacheLock.RLock()
|
||||
defer apiResourceLocationCacheLock.RUnlock()
|
||||
locationsMap, ok := apiResourceLocationCache[url]
|
||||
return locationsMap, ok
|
||||
}
|
||||
|
||||
func setApiResourceLocationCache(url string, locationsMap *map[uuid.UUID]ApiResourceLocation) {
|
||||
apiResourceLocationCacheLock.Lock()
|
||||
defer apiResourceLocationCacheLock.Unlock()
|
||||
apiResourceLocationCache[url] = locationsMap
|
||||
}
|
||||
|
||||
func (client *Client) getResourceLocationsFromServer(ctx context.Context) ([]ApiResourceLocation, error) {
|
||||
optionsUri := combineUrl(client.baseUrl, "_apis")
|
||||
request, err := client.CreateRequestMessage(ctx, http.MethodOptions, optionsUri, "", nil, "", MediaTypeApplicationJson, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := client.SendRequest(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Set session if one was supplied in the response.
|
||||
session, ok := resp.Header[headerKeySession]
|
||||
if ok && len(session) > 0 {
|
||||
SessionId = session[0]
|
||||
}
|
||||
|
||||
if resp != nil && (resp.StatusCode < 200 || resp.StatusCode >= 300) {
|
||||
return nil, client.UnwrapError(resp)
|
||||
}
|
||||
|
||||
var locations []ApiResourceLocation
|
||||
err = client.UnmarshalCollectionBody(resp, &locations)
|
||||
|
||||
return locations, err
|
||||
}
|
||||
|
||||
// Examples of api-version: 5.1, 5.1-preview, 5.1-preview.1
|
||||
var apiVersionRegEx = regexp.MustCompile(`(\d+(\.\d)?)(-preview(.(\d+))?)?`)
|
||||
|
||||
func combineUrl(part1 string, part2 string) string {
|
||||
return strings.TrimRight(part1, "/") + "/" + strings.TrimLeft(part2, "/")
|
||||
}
|
||||
|
||||
func transformRouteTemplate(routeTemplate string, routeValues map[string]string) string {
|
||||
newTemplate := ""
|
||||
routeTemplate = strings.Replace(routeTemplate, "{*", "{", -1)
|
||||
segments := strings.Split(routeTemplate, "/")
|
||||
for _, segment := range segments {
|
||||
length := len(segment)
|
||||
if length <= 2 || segment[0] != '{' || segment[length-1] != '}' {
|
||||
newTemplate += "/" + segment
|
||||
} else {
|
||||
value, ok := routeValues[segment[1:length-1]]
|
||||
if ok {
|
||||
newTemplate += "/" + url.PathEscape(value)
|
||||
}
|
||||
// else this is an optional parameter that has not been supplied, so don't add it back
|
||||
}
|
||||
}
|
||||
// following covers oddball templates with segments that include the token and additional constants
|
||||
for key, value := range routeValues {
|
||||
newTemplate = strings.Replace(newTemplate, "{"+key+"}", value, -1)
|
||||
}
|
||||
return newTemplate
|
||||
}
|
||||
|
||||
func (client *Client) UnmarshalBody(response *http.Response, v interface{}) (err error) {
|
||||
if response != nil && response.Body != nil {
|
||||
var err error
|
||||
defer func() {
|
||||
if closeError := response.Body.Close(); closeError != nil {
|
||||
err = closeError
|
||||
}
|
||||
}()
|
||||
body, err := ioutil.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
body = trimByteOrderMark(body)
|
||||
return json.Unmarshal(body, &v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (client *Client) UnmarshalCollectionBody(response *http.Response, v interface{}) (err error) {
|
||||
if response != nil && response.Body != nil {
|
||||
var err error
|
||||
defer func() {
|
||||
if closeError := response.Body.Close(); closeError != nil {
|
||||
err = closeError
|
||||
}
|
||||
}()
|
||||
body, err := ioutil.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
body = trimByteOrderMark(body)
|
||||
err = client.UnmarshalCollectionJson(body, v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (client *Client) UnmarshalCollectionJson(jsonValue []byte, v interface{}) (err error) {
|
||||
var wrappedResponse VssJsonCollectionWrapper
|
||||
err = json.Unmarshal(jsonValue, &wrappedResponse)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
value, err := json.Marshal(wrappedResponse.Value) // todo: investigate better way to do this.
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return json.Unmarshal(value, &v)
|
||||
}
|
||||
|
||||
// Returns slice of body without utf-8 byte order mark.
|
||||
// If BOM does not exist body is returned unchanged.
|
||||
func trimByteOrderMark(body []byte) []byte {
|
||||
return bytes.TrimPrefix(body, []byte("\xef\xbb\xbf"))
|
||||
}
|
||||
|
||||
func (client *Client) UnwrapError(response *http.Response) (err error) {
|
||||
if response.ContentLength == 0 {
|
||||
message := "Request returned status: " + response.Status
|
||||
return &WrappedError{
|
||||
Message: &message,
|
||||
StatusCode: &response.StatusCode,
|
||||
}
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if closeError := response.Body.Close(); closeError != nil {
|
||||
err = closeError
|
||||
}
|
||||
}()
|
||||
|
||||
body, err := ioutil.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
body = trimByteOrderMark(body)
|
||||
|
||||
contentType, ok := response.Header[headerKeyContentType]
|
||||
if ok && len(contentType) > 0 && strings.Index(contentType[0], MediaTypeTextPlain) >= 0 {
|
||||
message := string(body)
|
||||
statusCode := response.StatusCode
|
||||
return WrappedError{Message: &message, StatusCode: &statusCode}
|
||||
}
|
||||
|
||||
var wrappedError WrappedError
|
||||
err = json.Unmarshal(body, &wrappedError)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if wrappedError.Message == nil {
|
||||
var wrappedImproperError WrappedImproperError
|
||||
err = json.Unmarshal(body, &wrappedImproperError)
|
||||
if err == nil && wrappedImproperError.Value != nil && wrappedImproperError.Value.Message != nil {
|
||||
statusCode := response.StatusCode
|
||||
return &WrappedError{
|
||||
Message: wrappedImproperError.Value.Message,
|
||||
StatusCode: &statusCode,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return wrappedError
|
||||
}
|
||||
|
||||
func (client *Client) GetResourceAreas(ctx context.Context) (*[]ResourceAreaInfo, error) {
|
||||
queryParams := url.Values{}
|
||||
locationId, _ := uuid.Parse("e81700f7-3be2-46de-8624-2eb35882fcaa")
|
||||
resp, err := client.Send(ctx, http.MethodGet, locationId, "5.1-preview.1", nil, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue []ResourceAreaInfo
|
||||
err = client.UnmarshalCollectionBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
type LocationIdNotRegisteredError struct {
|
||||
LocationId uuid.UUID
|
||||
Url string
|
||||
}
|
||||
|
||||
func (e LocationIdNotRegisteredError) Error() string {
|
||||
return "API resource location " + e.LocationId.String() + " is not registered on " + e.Url + "."
|
||||
}
|
||||
|
||||
type InvalidApiVersion struct {
|
||||
ApiVersion string
|
||||
}
|
||||
|
||||
func (e InvalidApiVersion) Error() string {
|
||||
return "The requested api-version is not in a valid format: " + e.ApiVersion
|
||||
}
|
154
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/connection.go
generated
vendored
154
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/connection.go
generated
vendored
@ -1,154 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package azuredevops
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"github.com/google/uuid"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Creates a new Azure DevOps connection instance using a personal access token.
|
||||
func NewPatConnection(organizationUrl string, personalAccessToken string) *Connection {
|
||||
authorizationString := CreateBasicAuthHeaderValue("", personalAccessToken)
|
||||
organizationUrl = normalizeUrl(organizationUrl)
|
||||
return &Connection{
|
||||
AuthorizationString: authorizationString,
|
||||
BaseUrl: organizationUrl,
|
||||
SuppressFedAuthRedirect: true,
|
||||
}
|
||||
}
|
||||
|
||||
func NewAnonymousConnection(organizationUrl string) *Connection {
|
||||
organizationUrl = normalizeUrl(organizationUrl)
|
||||
return &Connection{
|
||||
BaseUrl: organizationUrl,
|
||||
SuppressFedAuthRedirect: true,
|
||||
}
|
||||
}
|
||||
|
||||
type Connection struct {
|
||||
AuthorizationString string
|
||||
BaseUrl string
|
||||
UserAgent string
|
||||
SuppressFedAuthRedirect bool
|
||||
ForceMsaPassThrough bool
|
||||
Timeout *time.Duration
|
||||
clientCache map[string]Client
|
||||
clientCacheLock sync.RWMutex
|
||||
resourceAreaCache map[uuid.UUID]ResourceAreaInfo
|
||||
resourceAreaCacheLock sync.RWMutex
|
||||
}
|
||||
|
||||
func CreateBasicAuthHeaderValue(username, password string) string {
|
||||
auth := username + ":" + password
|
||||
return "Basic " + base64.StdEncoding.EncodeToString([]byte(auth))
|
||||
}
|
||||
|
||||
func normalizeUrl(url string) string {
|
||||
return strings.ToLower(strings.TrimRight(url, "/"))
|
||||
}
|
||||
|
||||
func (connection *Connection) GetClientByResourceAreaId(ctx context.Context, resourceAreaID uuid.UUID) (*Client, error) {
|
||||
resourceAreaInfo, err := connection.getResourceAreaInfo(ctx, resourceAreaID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var client *Client
|
||||
if resourceAreaInfo != nil {
|
||||
client = connection.GetClientByUrl(*resourceAreaInfo.LocationUrl)
|
||||
} else {
|
||||
// resourceAreaInfo will be nil for on prem servers
|
||||
client = connection.GetClientByUrl(connection.BaseUrl)
|
||||
}
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func (connection *Connection) GetClientByUrl(baseUrl string) *Client {
|
||||
normalizedUrl := normalizeUrl(baseUrl)
|
||||
azureDevOpsClient, ok := connection.getClientCacheEntry(normalizedUrl)
|
||||
if !ok {
|
||||
azureDevOpsClient = NewClient(connection, normalizedUrl)
|
||||
connection.setClientCacheEntry(normalizedUrl, azureDevOpsClient)
|
||||
}
|
||||
return azureDevOpsClient
|
||||
}
|
||||
|
||||
func (connection *Connection) getResourceAreaInfo(ctx context.Context, resourceAreaId uuid.UUID) (*ResourceAreaInfo, error) {
|
||||
resourceAreaInfo, ok := connection.getResourceAreaCacheEntry(resourceAreaId)
|
||||
if !ok {
|
||||
client := connection.GetClientByUrl(connection.BaseUrl)
|
||||
resourceAreaInfos, err := client.GetResourceAreas(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(*resourceAreaInfos) > 0 {
|
||||
for _, resourceEntry := range *resourceAreaInfos {
|
||||
connection.setResourceAreaCacheEntry(*resourceEntry.Id, &resourceEntry)
|
||||
}
|
||||
resourceAreaInfo, ok = connection.getResourceAreaCacheEntry(resourceAreaId)
|
||||
} else {
|
||||
// on prem servers return an empty list
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
if ok {
|
||||
return resourceAreaInfo, nil
|
||||
}
|
||||
|
||||
return nil, &ResourceAreaIdNotRegisteredError{resourceAreaId, connection.BaseUrl}
|
||||
}
|
||||
|
||||
// Client Cache by Url
|
||||
func (connection *Connection) getClientCacheEntry(url string) (*Client, bool) {
|
||||
if connection.clientCache == nil {
|
||||
return nil, false
|
||||
}
|
||||
connection.clientCacheLock.RLock()
|
||||
defer connection.clientCacheLock.RUnlock()
|
||||
client, ok := connection.clientCache[url]
|
||||
return &client, ok
|
||||
}
|
||||
|
||||
func (connection *Connection) setClientCacheEntry(url string, client *Client) {
|
||||
connection.clientCacheLock.Lock()
|
||||
defer connection.clientCacheLock.Unlock()
|
||||
if connection.clientCache == nil {
|
||||
connection.clientCache = make(map[string]Client)
|
||||
}
|
||||
connection.clientCache[url] = *client
|
||||
}
|
||||
|
||||
func (connection *Connection) getResourceAreaCacheEntry(resourceAreaId uuid.UUID) (*ResourceAreaInfo, bool) {
|
||||
if connection.resourceAreaCache == nil {
|
||||
return nil, false
|
||||
}
|
||||
connection.resourceAreaCacheLock.RLock()
|
||||
defer connection.resourceAreaCacheLock.RUnlock()
|
||||
resourceAreaInfo, ok := connection.resourceAreaCache[resourceAreaId]
|
||||
return &resourceAreaInfo, ok
|
||||
}
|
||||
|
||||
func (connection *Connection) setResourceAreaCacheEntry(resourceAreaId uuid.UUID, resourceAreaInfo *ResourceAreaInfo) {
|
||||
connection.resourceAreaCacheLock.Lock()
|
||||
defer connection.resourceAreaCacheLock.Unlock()
|
||||
if connection.resourceAreaCache == nil {
|
||||
connection.resourceAreaCache = make(map[uuid.UUID]ResourceAreaInfo)
|
||||
}
|
||||
connection.resourceAreaCache[resourceAreaId] = *resourceAreaInfo
|
||||
}
|
||||
|
||||
type ResourceAreaIdNotRegisteredError struct {
|
||||
ResourceAreaId uuid.UUID
|
||||
Url string
|
||||
}
|
||||
|
||||
func (e ResourceAreaIdNotRegisteredError) Error() string {
|
||||
return "API resource area Id " + e.ResourceAreaId.String() + " is not registered on " + e.Url + "."
|
||||
}
|
918
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/core/client.go
generated
vendored
918
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/core/client.go
generated
vendored
@ -1,918 +0,0 @@
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Generated file, DO NOT EDIT
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/google/uuid"
|
||||
"github.com/microsoft/azure-devops-go-api/azuredevops"
|
||||
"github.com/microsoft/azure-devops-go-api/azuredevops/operations"
|
||||
"github.com/microsoft/azure-devops-go-api/azuredevops/webapi"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var ResourceAreaId, _ = uuid.Parse("79134c72-4a58-4b42-976c-04e7115f32bf")
|
||||
|
||||
type Client interface {
|
||||
// [Preview API]
|
||||
CreateConnectedService(context.Context, CreateConnectedServiceArgs) (*WebApiConnectedService, error)
|
||||
// [Preview API]
|
||||
CreateOrUpdateProxy(context.Context, CreateOrUpdateProxyArgs) (*Proxy, error)
|
||||
// Create a team in a team project.
|
||||
CreateTeam(context.Context, CreateTeamArgs) (*WebApiTeam, error)
|
||||
// [Preview API]
|
||||
DeleteProxy(context.Context, DeleteProxyArgs) error
|
||||
// Delete a team.
|
||||
DeleteTeam(context.Context, DeleteTeamArgs) error
|
||||
// [Preview API] Get a list of all teams.
|
||||
GetAllTeams(context.Context, GetAllTeamsArgs) (*[]WebApiTeam, error)
|
||||
// [Preview API]
|
||||
GetConnectedServiceDetails(context.Context, GetConnectedServiceDetailsArgs) (*WebApiConnectedServiceDetails, error)
|
||||
// [Preview API]
|
||||
GetConnectedServices(context.Context, GetConnectedServicesArgs) (*[]WebApiConnectedService, error)
|
||||
// Get a process by ID.
|
||||
GetProcessById(context.Context, GetProcessByIdArgs) (*Process, error)
|
||||
// Get a list of processes.
|
||||
GetProcesses(context.Context, GetProcessesArgs) (*[]Process, error)
|
||||
// Get project with the specified id or name, optionally including capabilities.
|
||||
GetProject(context.Context, GetProjectArgs) (*TeamProject, error)
|
||||
// Get project collection with the specified id or name.
|
||||
GetProjectCollection(context.Context, GetProjectCollectionArgs) (*TeamProjectCollection, error)
|
||||
// Get project collection references for this application.
|
||||
GetProjectCollections(context.Context, GetProjectCollectionsArgs) (*[]TeamProjectCollectionReference, error)
|
||||
// [Preview API] Get a collection of team project properties.
|
||||
GetProjectProperties(context.Context, GetProjectPropertiesArgs) (*[]ProjectProperty, error)
|
||||
// Get all projects in the organization that the authenticated user has access to.
|
||||
GetProjects(context.Context, GetProjectsArgs) (*GetProjectsResponseValue, error)
|
||||
// [Preview API]
|
||||
GetProxies(context.Context, GetProxiesArgs) (*[]Proxy, error)
|
||||
// Get a specific team.
|
||||
GetTeam(context.Context, GetTeamArgs) (*WebApiTeam, error)
|
||||
// Get a list of members for a specific team.
|
||||
GetTeamMembersWithExtendedProperties(context.Context, GetTeamMembersWithExtendedPropertiesArgs) (*[]webapi.TeamMember, error)
|
||||
// Get a list of teams.
|
||||
GetTeams(context.Context, GetTeamsArgs) (*[]WebApiTeam, error)
|
||||
// Queues a project to be created. Use the [GetOperation](../../operations/operations/get) to periodically check for create project status.
|
||||
QueueCreateProject(context.Context, QueueCreateProjectArgs) (*operations.OperationReference, error)
|
||||
// Queues a project to be deleted. Use the [GetOperation](../../operations/operations/get) to periodically check for delete project status.
|
||||
QueueDeleteProject(context.Context, QueueDeleteProjectArgs) (*operations.OperationReference, error)
|
||||
// [Preview API] Removes the avatar for the project.
|
||||
RemoveProjectAvatar(context.Context, RemoveProjectAvatarArgs) error
|
||||
// [Preview API] Sets the avatar for the project.
|
||||
SetProjectAvatar(context.Context, SetProjectAvatarArgs) error
|
||||
// [Preview API] Create, update, and delete team project properties.
|
||||
SetProjectProperties(context.Context, SetProjectPropertiesArgs) error
|
||||
// Update an existing project's name, abbreviation, description, or restore a project.
|
||||
UpdateProject(context.Context, UpdateProjectArgs) (*operations.OperationReference, error)
|
||||
// Update a team's name and/or description.
|
||||
UpdateTeam(context.Context, UpdateTeamArgs) (*WebApiTeam, error)
|
||||
}
|
||||
|
||||
type ClientImpl struct {
|
||||
Client azuredevops.Client
|
||||
}
|
||||
|
||||
func NewClient(ctx context.Context, connection *azuredevops.Connection) (Client, error) {
|
||||
client, err := connection.GetClientByResourceAreaId(ctx, ResourceAreaId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ClientImpl{
|
||||
Client: *client,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// [Preview API]
|
||||
func (client *ClientImpl) CreateConnectedService(ctx context.Context, args CreateConnectedServiceArgs) (*WebApiConnectedService, error) {
|
||||
if args.ConnectedServiceCreationData == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.ConnectedServiceCreationData"}
|
||||
}
|
||||
routeValues := make(map[string]string)
|
||||
if args.ProjectId == nil || *args.ProjectId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ProjectId"}
|
||||
}
|
||||
routeValues["projectId"] = *args.ProjectId
|
||||
|
||||
body, marshalErr := json.Marshal(*args.ConnectedServiceCreationData)
|
||||
if marshalErr != nil {
|
||||
return nil, marshalErr
|
||||
}
|
||||
locationId, _ := uuid.Parse("b4f70219-e18b-42c5-abe3-98b07d35525e")
|
||||
resp, err := client.Client.Send(ctx, http.MethodPost, locationId, "5.1-preview.1", routeValues, nil, bytes.NewReader(body), "application/json", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue WebApiConnectedService
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the CreateConnectedService function
|
||||
type CreateConnectedServiceArgs struct {
|
||||
// (required)
|
||||
ConnectedServiceCreationData *WebApiConnectedServiceDetails
|
||||
// (required)
|
||||
ProjectId *string
|
||||
}
|
||||
|
||||
// [Preview API]
|
||||
func (client *ClientImpl) CreateOrUpdateProxy(ctx context.Context, args CreateOrUpdateProxyArgs) (*Proxy, error) {
|
||||
if args.Proxy == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.Proxy"}
|
||||
}
|
||||
body, marshalErr := json.Marshal(*args.Proxy)
|
||||
if marshalErr != nil {
|
||||
return nil, marshalErr
|
||||
}
|
||||
locationId, _ := uuid.Parse("ec1f4311-f2b4-4c15-b2b8-8990b80d2908")
|
||||
resp, err := client.Client.Send(ctx, http.MethodPut, locationId, "5.1-preview.2", nil, nil, bytes.NewReader(body), "application/json", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue Proxy
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the CreateOrUpdateProxy function
|
||||
type CreateOrUpdateProxyArgs struct {
|
||||
// (required)
|
||||
Proxy *Proxy
|
||||
}
|
||||
|
||||
// Create a team in a team project.
|
||||
func (client *ClientImpl) CreateTeam(ctx context.Context, args CreateTeamArgs) (*WebApiTeam, error) {
|
||||
if args.Team == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.Team"}
|
||||
}
|
||||
routeValues := make(map[string]string)
|
||||
if args.ProjectId == nil || *args.ProjectId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ProjectId"}
|
||||
}
|
||||
routeValues["projectId"] = *args.ProjectId
|
||||
|
||||
body, marshalErr := json.Marshal(*args.Team)
|
||||
if marshalErr != nil {
|
||||
return nil, marshalErr
|
||||
}
|
||||
locationId, _ := uuid.Parse("d30a3dd1-f8ba-442a-b86a-bd0c0c383e59")
|
||||
resp, err := client.Client.Send(ctx, http.MethodPost, locationId, "5.1", routeValues, nil, bytes.NewReader(body), "application/json", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue WebApiTeam
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the CreateTeam function
|
||||
type CreateTeamArgs struct {
|
||||
// (required) The team data used to create the team.
|
||||
Team *WebApiTeam
|
||||
// (required) The name or ID (GUID) of the team project in which to create the team.
|
||||
ProjectId *string
|
||||
}
|
||||
|
||||
// [Preview API]
|
||||
func (client *ClientImpl) DeleteProxy(ctx context.Context, args DeleteProxyArgs) error {
|
||||
queryParams := url.Values{}
|
||||
if args.ProxyUrl == nil {
|
||||
return &azuredevops.ArgumentNilError{ArgumentName: "proxyUrl"}
|
||||
}
|
||||
queryParams.Add("proxyUrl", *args.ProxyUrl)
|
||||
if args.Site != nil {
|
||||
queryParams.Add("site", *args.Site)
|
||||
}
|
||||
locationId, _ := uuid.Parse("ec1f4311-f2b4-4c15-b2b8-8990b80d2908")
|
||||
_, err := client.Client.Send(ctx, http.MethodDelete, locationId, "5.1-preview.2", nil, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Arguments for the DeleteProxy function
|
||||
type DeleteProxyArgs struct {
|
||||
// (required)
|
||||
ProxyUrl *string
|
||||
// (optional)
|
||||
Site *string
|
||||
}
|
||||
|
||||
// Delete a team.
|
||||
func (client *ClientImpl) DeleteTeam(ctx context.Context, args DeleteTeamArgs) error {
|
||||
routeValues := make(map[string]string)
|
||||
if args.ProjectId == nil || *args.ProjectId == "" {
|
||||
return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ProjectId"}
|
||||
}
|
||||
routeValues["projectId"] = *args.ProjectId
|
||||
if args.TeamId == nil || *args.TeamId == "" {
|
||||
return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.TeamId"}
|
||||
}
|
||||
routeValues["teamId"] = *args.TeamId
|
||||
|
||||
locationId, _ := uuid.Parse("d30a3dd1-f8ba-442a-b86a-bd0c0c383e59")
|
||||
_, err := client.Client.Send(ctx, http.MethodDelete, locationId, "5.1", routeValues, nil, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Arguments for the DeleteTeam function
|
||||
type DeleteTeamArgs struct {
|
||||
// (required) The name or ID (GUID) of the team project containing the team to delete.
|
||||
ProjectId *string
|
||||
// (required) The name or ID of the team to delete.
|
||||
TeamId *string
|
||||
}
|
||||
|
||||
// [Preview API] Get a list of all teams.
|
||||
func (client *ClientImpl) GetAllTeams(ctx context.Context, args GetAllTeamsArgs) (*[]WebApiTeam, error) {
|
||||
queryParams := url.Values{}
|
||||
if args.Mine != nil {
|
||||
queryParams.Add("$mine", strconv.FormatBool(*args.Mine))
|
||||
}
|
||||
if args.Top != nil {
|
||||
queryParams.Add("$top", strconv.Itoa(*args.Top))
|
||||
}
|
||||
if args.Skip != nil {
|
||||
queryParams.Add("$skip", strconv.Itoa(*args.Skip))
|
||||
}
|
||||
if args.ExpandIdentity != nil {
|
||||
queryParams.Add("$expandIdentity", strconv.FormatBool(*args.ExpandIdentity))
|
||||
}
|
||||
locationId, _ := uuid.Parse("7a4d9ee9-3433-4347-b47a-7a80f1cf307e")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1-preview.3", nil, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue []WebApiTeam
|
||||
err = client.Client.UnmarshalCollectionBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetAllTeams function
|
||||
type GetAllTeamsArgs struct {
|
||||
// (optional) If true, then return all teams requesting user is member. Otherwise return all teams user has read access.
|
||||
Mine *bool
|
||||
// (optional) Maximum number of teams to return.
|
||||
Top *int
|
||||
// (optional) Number of teams to skip.
|
||||
Skip *int
|
||||
// (optional) A value indicating whether or not to expand Identity information in the result WebApiTeam object.
|
||||
ExpandIdentity *bool
|
||||
}
|
||||
|
||||
// [Preview API]
|
||||
func (client *ClientImpl) GetConnectedServiceDetails(ctx context.Context, args GetConnectedServiceDetailsArgs) (*WebApiConnectedServiceDetails, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.ProjectId == nil || *args.ProjectId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ProjectId"}
|
||||
}
|
||||
routeValues["projectId"] = *args.ProjectId
|
||||
if args.Name == nil || *args.Name == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.Name"}
|
||||
}
|
||||
routeValues["name"] = *args.Name
|
||||
|
||||
locationId, _ := uuid.Parse("b4f70219-e18b-42c5-abe3-98b07d35525e")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue WebApiConnectedServiceDetails
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetConnectedServiceDetails function
|
||||
type GetConnectedServiceDetailsArgs struct {
|
||||
// (required)
|
||||
ProjectId *string
|
||||
// (required)
|
||||
Name *string
|
||||
}
|
||||
|
||||
// [Preview API]
|
||||
func (client *ClientImpl) GetConnectedServices(ctx context.Context, args GetConnectedServicesArgs) (*[]WebApiConnectedService, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.ProjectId == nil || *args.ProjectId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ProjectId"}
|
||||
}
|
||||
routeValues["projectId"] = *args.ProjectId
|
||||
|
||||
queryParams := url.Values{}
|
||||
if args.Kind != nil {
|
||||
queryParams.Add("kind", string(*args.Kind))
|
||||
}
|
||||
locationId, _ := uuid.Parse("b4f70219-e18b-42c5-abe3-98b07d35525e")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1-preview.1", routeValues, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue []WebApiConnectedService
|
||||
err = client.Client.UnmarshalCollectionBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetConnectedServices function
|
||||
type GetConnectedServicesArgs struct {
|
||||
// (required)
|
||||
ProjectId *string
|
||||
// (optional)
|
||||
Kind *ConnectedServiceKind
|
||||
}
|
||||
|
||||
// Get a process by ID.
|
||||
func (client *ClientImpl) GetProcessById(ctx context.Context, args GetProcessByIdArgs) (*Process, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.ProcessId == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.ProcessId"}
|
||||
}
|
||||
routeValues["processId"] = (*args.ProcessId).String()
|
||||
|
||||
locationId, _ := uuid.Parse("93878975-88c5-4e6a-8abb-7ddd77a8a7d8")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1", routeValues, nil, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue Process
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetProcessById function
|
||||
type GetProcessByIdArgs struct {
|
||||
// (required) ID for a process.
|
||||
ProcessId *uuid.UUID
|
||||
}
|
||||
|
||||
// Get a list of processes.
|
||||
func (client *ClientImpl) GetProcesses(ctx context.Context, args GetProcessesArgs) (*[]Process, error) {
|
||||
locationId, _ := uuid.Parse("93878975-88c5-4e6a-8abb-7ddd77a8a7d8")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1", nil, nil, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue []Process
|
||||
err = client.Client.UnmarshalCollectionBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetProcesses function
|
||||
type GetProcessesArgs struct {
|
||||
}
|
||||
|
||||
// Get project with the specified id or name, optionally including capabilities.
|
||||
func (client *ClientImpl) GetProject(ctx context.Context, args GetProjectArgs) (*TeamProject, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.ProjectId == nil || *args.ProjectId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ProjectId"}
|
||||
}
|
||||
routeValues["projectId"] = *args.ProjectId
|
||||
|
||||
queryParams := url.Values{}
|
||||
if args.IncludeCapabilities != nil {
|
||||
queryParams.Add("includeCapabilities", strconv.FormatBool(*args.IncludeCapabilities))
|
||||
}
|
||||
if args.IncludeHistory != nil {
|
||||
queryParams.Add("includeHistory", strconv.FormatBool(*args.IncludeHistory))
|
||||
}
|
||||
locationId, _ := uuid.Parse("603fe2ac-9723-48b9-88ad-09305aa6c6e1")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1", routeValues, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue TeamProject
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetProject function
|
||||
type GetProjectArgs struct {
|
||||
// (required)
|
||||
ProjectId *string
|
||||
// (optional) Include capabilities (such as source control) in the team project result (default: false).
|
||||
IncludeCapabilities *bool
|
||||
// (optional) Search within renamed projects (that had such name in the past).
|
||||
IncludeHistory *bool
|
||||
}
|
||||
|
||||
// Get project collection with the specified id or name.
|
||||
func (client *ClientImpl) GetProjectCollection(ctx context.Context, args GetProjectCollectionArgs) (*TeamProjectCollection, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.CollectionId == nil || *args.CollectionId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.CollectionId"}
|
||||
}
|
||||
routeValues["collectionId"] = *args.CollectionId
|
||||
|
||||
locationId, _ := uuid.Parse("8031090f-ef1d-4af6-85fc-698cd75d42bf")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1", routeValues, nil, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue TeamProjectCollection
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetProjectCollection function
|
||||
type GetProjectCollectionArgs struct {
|
||||
// (required)
|
||||
CollectionId *string
|
||||
}
|
||||
|
||||
// Get project collection references for this application.
|
||||
func (client *ClientImpl) GetProjectCollections(ctx context.Context, args GetProjectCollectionsArgs) (*[]TeamProjectCollectionReference, error) {
|
||||
queryParams := url.Values{}
|
||||
if args.Top != nil {
|
||||
queryParams.Add("$top", strconv.Itoa(*args.Top))
|
||||
}
|
||||
if args.Skip != nil {
|
||||
queryParams.Add("$skip", strconv.Itoa(*args.Skip))
|
||||
}
|
||||
locationId, _ := uuid.Parse("8031090f-ef1d-4af6-85fc-698cd75d42bf")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1", nil, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue []TeamProjectCollectionReference
|
||||
err = client.Client.UnmarshalCollectionBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetProjectCollections function
|
||||
type GetProjectCollectionsArgs struct {
|
||||
// (optional)
|
||||
Top *int
|
||||
// (optional)
|
||||
Skip *int
|
||||
}
|
||||
|
||||
// [Preview API] Get a collection of team project properties.
|
||||
func (client *ClientImpl) GetProjectProperties(ctx context.Context, args GetProjectPropertiesArgs) (*[]ProjectProperty, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.ProjectId == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.ProjectId"}
|
||||
}
|
||||
routeValues["projectId"] = (*args.ProjectId).String()
|
||||
|
||||
queryParams := url.Values{}
|
||||
if args.Keys != nil {
|
||||
listAsString := strings.Join((*args.Keys)[:], ",")
|
||||
queryParams.Add("keys", listAsString)
|
||||
}
|
||||
locationId, _ := uuid.Parse("4976a71a-4487-49aa-8aab-a1eda469037a")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1-preview.1", routeValues, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue []ProjectProperty
|
||||
err = client.Client.UnmarshalCollectionBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetProjectProperties function
|
||||
type GetProjectPropertiesArgs struct {
|
||||
// (required) The team project ID.
|
||||
ProjectId *uuid.UUID
|
||||
// (optional) A comma-delimited string of team project property names. Wildcard characters ("?" and "*") are supported. If no key is specified, all properties will be returned.
|
||||
Keys *[]string
|
||||
}
|
||||
|
||||
// Get all projects in the organization that the authenticated user has access to.
|
||||
func (client *ClientImpl) GetProjects(ctx context.Context, args GetProjectsArgs) (*GetProjectsResponseValue, error) {
|
||||
queryParams := url.Values{}
|
||||
if args.StateFilter != nil {
|
||||
queryParams.Add("stateFilter", string(*args.StateFilter))
|
||||
}
|
||||
if args.Top != nil {
|
||||
queryParams.Add("$top", strconv.Itoa(*args.Top))
|
||||
}
|
||||
if args.Skip != nil {
|
||||
queryParams.Add("$skip", strconv.Itoa(*args.Skip))
|
||||
}
|
||||
if args.ContinuationToken != nil {
|
||||
queryParams.Add("continuationToken", *args.ContinuationToken)
|
||||
}
|
||||
if args.GetDefaultTeamImageUrl != nil {
|
||||
queryParams.Add("getDefaultTeamImageUrl", strconv.FormatBool(*args.GetDefaultTeamImageUrl))
|
||||
}
|
||||
locationId, _ := uuid.Parse("603fe2ac-9723-48b9-88ad-09305aa6c6e1")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1", nil, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue GetProjectsResponseValue
|
||||
responseValue.ContinuationToken = resp.Header.Get(azuredevops.HeaderKeyContinuationToken)
|
||||
err = client.Client.UnmarshalCollectionBody(resp, &responseValue.Value)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetProjects function
|
||||
type GetProjectsArgs struct {
|
||||
// (optional) Filter on team projects in a specific team project state (default: WellFormed).
|
||||
StateFilter *ProjectState
|
||||
// (optional)
|
||||
Top *int
|
||||
// (optional)
|
||||
Skip *int
|
||||
// (optional)
|
||||
ContinuationToken *string
|
||||
// (optional)
|
||||
GetDefaultTeamImageUrl *bool
|
||||
}
|
||||
|
||||
// Return type for the GetProjects function
|
||||
type GetProjectsResponseValue struct {
|
||||
Value []TeamProjectReference
|
||||
// The continuation token to be used to get the next page of results.
|
||||
ContinuationToken string
|
||||
}
|
||||
|
||||
// [Preview API]
|
||||
func (client *ClientImpl) GetProxies(ctx context.Context, args GetProxiesArgs) (*[]Proxy, error) {
|
||||
queryParams := url.Values{}
|
||||
if args.ProxyUrl != nil {
|
||||
queryParams.Add("proxyUrl", *args.ProxyUrl)
|
||||
}
|
||||
locationId, _ := uuid.Parse("ec1f4311-f2b4-4c15-b2b8-8990b80d2908")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1-preview.2", nil, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue []Proxy
|
||||
err = client.Client.UnmarshalCollectionBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetProxies function
|
||||
type GetProxiesArgs struct {
|
||||
// (optional)
|
||||
ProxyUrl *string
|
||||
}
|
||||
|
||||
// Get a specific team.
|
||||
func (client *ClientImpl) GetTeam(ctx context.Context, args GetTeamArgs) (*WebApiTeam, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.ProjectId == nil || *args.ProjectId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ProjectId"}
|
||||
}
|
||||
routeValues["projectId"] = *args.ProjectId
|
||||
if args.TeamId == nil || *args.TeamId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.TeamId"}
|
||||
}
|
||||
routeValues["teamId"] = *args.TeamId
|
||||
|
||||
queryParams := url.Values{}
|
||||
if args.ExpandIdentity != nil {
|
||||
queryParams.Add("$expandIdentity", strconv.FormatBool(*args.ExpandIdentity))
|
||||
}
|
||||
locationId, _ := uuid.Parse("d30a3dd1-f8ba-442a-b86a-bd0c0c383e59")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1", routeValues, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue WebApiTeam
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetTeam function
|
||||
type GetTeamArgs struct {
|
||||
// (required) The name or ID (GUID) of the team project containing the team.
|
||||
ProjectId *string
|
||||
// (required) The name or ID (GUID) of the team.
|
||||
TeamId *string
|
||||
// (optional) A value indicating whether or not to expand Identity information in the result WebApiTeam object.
|
||||
ExpandIdentity *bool
|
||||
}
|
||||
|
||||
// Get a list of members for a specific team.
|
||||
func (client *ClientImpl) GetTeamMembersWithExtendedProperties(ctx context.Context, args GetTeamMembersWithExtendedPropertiesArgs) (*[]webapi.TeamMember, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.ProjectId == nil || *args.ProjectId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ProjectId"}
|
||||
}
|
||||
routeValues["projectId"] = *args.ProjectId
|
||||
if args.TeamId == nil || *args.TeamId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.TeamId"}
|
||||
}
|
||||
routeValues["teamId"] = *args.TeamId
|
||||
|
||||
queryParams := url.Values{}
|
||||
if args.Top != nil {
|
||||
queryParams.Add("$top", strconv.Itoa(*args.Top))
|
||||
}
|
||||
if args.Skip != nil {
|
||||
queryParams.Add("$skip", strconv.Itoa(*args.Skip))
|
||||
}
|
||||
locationId, _ := uuid.Parse("294c494c-2600-4d7e-b76c-3dd50c3c95be")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1", routeValues, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue []webapi.TeamMember
|
||||
err = client.Client.UnmarshalCollectionBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetTeamMembersWithExtendedProperties function
|
||||
type GetTeamMembersWithExtendedPropertiesArgs struct {
|
||||
// (required) The name or ID (GUID) of the team project the team belongs to.
|
||||
ProjectId *string
|
||||
// (required) The name or ID (GUID) of the team .
|
||||
TeamId *string
|
||||
// (optional)
|
||||
Top *int
|
||||
// (optional)
|
||||
Skip *int
|
||||
}
|
||||
|
||||
// Get a list of teams.
|
||||
func (client *ClientImpl) GetTeams(ctx context.Context, args GetTeamsArgs) (*[]WebApiTeam, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.ProjectId == nil || *args.ProjectId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ProjectId"}
|
||||
}
|
||||
routeValues["projectId"] = *args.ProjectId
|
||||
|
||||
queryParams := url.Values{}
|
||||
if args.Mine != nil {
|
||||
queryParams.Add("$mine", strconv.FormatBool(*args.Mine))
|
||||
}
|
||||
if args.Top != nil {
|
||||
queryParams.Add("$top", strconv.Itoa(*args.Top))
|
||||
}
|
||||
if args.Skip != nil {
|
||||
queryParams.Add("$skip", strconv.Itoa(*args.Skip))
|
||||
}
|
||||
if args.ExpandIdentity != nil {
|
||||
queryParams.Add("$expandIdentity", strconv.FormatBool(*args.ExpandIdentity))
|
||||
}
|
||||
locationId, _ := uuid.Parse("d30a3dd1-f8ba-442a-b86a-bd0c0c383e59")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1", routeValues, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue []WebApiTeam
|
||||
err = client.Client.UnmarshalCollectionBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetTeams function
|
||||
type GetTeamsArgs struct {
|
||||
// (required)
|
||||
ProjectId *string
|
||||
// (optional) If true return all the teams requesting user is member, otherwise return all the teams user has read access.
|
||||
Mine *bool
|
||||
// (optional) Maximum number of teams to return.
|
||||
Top *int
|
||||
// (optional) Number of teams to skip.
|
||||
Skip *int
|
||||
// (optional) A value indicating whether or not to expand Identity information in the result WebApiTeam object.
|
||||
ExpandIdentity *bool
|
||||
}
|
||||
|
||||
// Queues a project to be created. Use the [GetOperation](../../operations/operations/get) to periodically check for create project status.
|
||||
func (client *ClientImpl) QueueCreateProject(ctx context.Context, args QueueCreateProjectArgs) (*operations.OperationReference, error) {
|
||||
if args.ProjectToCreate == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.ProjectToCreate"}
|
||||
}
|
||||
body, marshalErr := json.Marshal(*args.ProjectToCreate)
|
||||
if marshalErr != nil {
|
||||
return nil, marshalErr
|
||||
}
|
||||
locationId, _ := uuid.Parse("603fe2ac-9723-48b9-88ad-09305aa6c6e1")
|
||||
resp, err := client.Client.Send(ctx, http.MethodPost, locationId, "5.1", nil, nil, bytes.NewReader(body), "application/json", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue operations.OperationReference
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the QueueCreateProject function
|
||||
type QueueCreateProjectArgs struct {
|
||||
// (required) The project to create.
|
||||
ProjectToCreate *TeamProject
|
||||
}
|
||||
|
||||
// Queues a project to be deleted. Use the [GetOperation](../../operations/operations/get) to periodically check for delete project status.
|
||||
func (client *ClientImpl) QueueDeleteProject(ctx context.Context, args QueueDeleteProjectArgs) (*operations.OperationReference, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.ProjectId == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.ProjectId"}
|
||||
}
|
||||
routeValues["projectId"] = (*args.ProjectId).String()
|
||||
|
||||
locationId, _ := uuid.Parse("603fe2ac-9723-48b9-88ad-09305aa6c6e1")
|
||||
resp, err := client.Client.Send(ctx, http.MethodDelete, locationId, "5.1", routeValues, nil, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue operations.OperationReference
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the QueueDeleteProject function
|
||||
type QueueDeleteProjectArgs struct {
|
||||
// (required) The project id of the project to delete.
|
||||
ProjectId *uuid.UUID
|
||||
}
|
||||
|
||||
// [Preview API] Removes the avatar for the project.
|
||||
func (client *ClientImpl) RemoveProjectAvatar(ctx context.Context, args RemoveProjectAvatarArgs) error {
|
||||
routeValues := make(map[string]string)
|
||||
if args.ProjectId == nil || *args.ProjectId == "" {
|
||||
return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ProjectId"}
|
||||
}
|
||||
routeValues["projectId"] = *args.ProjectId
|
||||
|
||||
locationId, _ := uuid.Parse("54b2a2a0-859b-4d05-827c-ec4c862f641a")
|
||||
_, err := client.Client.Send(ctx, http.MethodDelete, locationId, "5.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Arguments for the RemoveProjectAvatar function
|
||||
type RemoveProjectAvatarArgs struct {
|
||||
// (required) The ID or name of the project.
|
||||
ProjectId *string
|
||||
}
|
||||
|
||||
// [Preview API] Sets the avatar for the project.
|
||||
func (client *ClientImpl) SetProjectAvatar(ctx context.Context, args SetProjectAvatarArgs) error {
|
||||
if args.AvatarBlob == nil {
|
||||
return &azuredevops.ArgumentNilError{ArgumentName: "args.AvatarBlob"}
|
||||
}
|
||||
routeValues := make(map[string]string)
|
||||
if args.ProjectId == nil || *args.ProjectId == "" {
|
||||
return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ProjectId"}
|
||||
}
|
||||
routeValues["projectId"] = *args.ProjectId
|
||||
|
||||
body, marshalErr := json.Marshal(*args.AvatarBlob)
|
||||
if marshalErr != nil {
|
||||
return marshalErr
|
||||
}
|
||||
locationId, _ := uuid.Parse("54b2a2a0-859b-4d05-827c-ec4c862f641a")
|
||||
_, err := client.Client.Send(ctx, http.MethodPut, locationId, "5.1-preview.1", routeValues, nil, bytes.NewReader(body), "application/json", "application/json", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Arguments for the SetProjectAvatar function
|
||||
type SetProjectAvatarArgs struct {
|
||||
// (required) The avatar blob data object to upload.
|
||||
AvatarBlob *ProjectAvatar
|
||||
// (required) The ID or name of the project.
|
||||
ProjectId *string
|
||||
}
|
||||
|
||||
// [Preview API] Create, update, and delete team project properties.
|
||||
func (client *ClientImpl) SetProjectProperties(ctx context.Context, args SetProjectPropertiesArgs) error {
|
||||
if args.PatchDocument == nil {
|
||||
return &azuredevops.ArgumentNilError{ArgumentName: "args.PatchDocument"}
|
||||
}
|
||||
routeValues := make(map[string]string)
|
||||
if args.ProjectId == nil {
|
||||
return &azuredevops.ArgumentNilError{ArgumentName: "args.ProjectId"}
|
||||
}
|
||||
routeValues["projectId"] = (*args.ProjectId).String()
|
||||
|
||||
body, marshalErr := json.Marshal(*args.PatchDocument)
|
||||
if marshalErr != nil {
|
||||
return marshalErr
|
||||
}
|
||||
locationId, _ := uuid.Parse("4976a71a-4487-49aa-8aab-a1eda469037a")
|
||||
_, err := client.Client.Send(ctx, http.MethodPatch, locationId, "5.1-preview.1", routeValues, nil, bytes.NewReader(body), "application/json-patch+json", "application/json", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Arguments for the SetProjectProperties function
|
||||
type SetProjectPropertiesArgs struct {
|
||||
// (required) The team project ID.
|
||||
ProjectId *uuid.UUID
|
||||
// (required) A JSON Patch document that represents an array of property operations. See RFC 6902 for more details on JSON Patch. The accepted operation verbs are Add and Remove, where Add is used for both creating and updating properties. The path consists of a forward slash and a property name.
|
||||
PatchDocument *[]webapi.JsonPatchOperation
|
||||
}
|
||||
|
||||
// Update an existing project's name, abbreviation, description, or restore a project.
|
||||
func (client *ClientImpl) UpdateProject(ctx context.Context, args UpdateProjectArgs) (*operations.OperationReference, error) {
|
||||
if args.ProjectUpdate == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.ProjectUpdate"}
|
||||
}
|
||||
routeValues := make(map[string]string)
|
||||
if args.ProjectId == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.ProjectId"}
|
||||
}
|
||||
routeValues["projectId"] = (*args.ProjectId).String()
|
||||
|
||||
body, marshalErr := json.Marshal(*args.ProjectUpdate)
|
||||
if marshalErr != nil {
|
||||
return nil, marshalErr
|
||||
}
|
||||
locationId, _ := uuid.Parse("603fe2ac-9723-48b9-88ad-09305aa6c6e1")
|
||||
resp, err := client.Client.Send(ctx, http.MethodPatch, locationId, "5.1", routeValues, nil, bytes.NewReader(body), "application/json", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue operations.OperationReference
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the UpdateProject function
|
||||
type UpdateProjectArgs struct {
|
||||
// (required) The updates for the project. The state must be set to wellFormed to restore the project.
|
||||
ProjectUpdate *TeamProject
|
||||
// (required) The project id of the project to update.
|
||||
ProjectId *uuid.UUID
|
||||
}
|
||||
|
||||
// Update a team's name and/or description.
|
||||
func (client *ClientImpl) UpdateTeam(ctx context.Context, args UpdateTeamArgs) (*WebApiTeam, error) {
|
||||
if args.TeamData == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.TeamData"}
|
||||
}
|
||||
routeValues := make(map[string]string)
|
||||
if args.ProjectId == nil || *args.ProjectId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ProjectId"}
|
||||
}
|
||||
routeValues["projectId"] = *args.ProjectId
|
||||
if args.TeamId == nil || *args.TeamId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.TeamId"}
|
||||
}
|
||||
routeValues["teamId"] = *args.TeamId
|
||||
|
||||
body, marshalErr := json.Marshal(*args.TeamData)
|
||||
if marshalErr != nil {
|
||||
return nil, marshalErr
|
||||
}
|
||||
locationId, _ := uuid.Parse("d30a3dd1-f8ba-442a-b86a-bd0c0c383e59")
|
||||
resp, err := client.Client.Send(ctx, http.MethodPatch, locationId, "5.1", routeValues, nil, bytes.NewReader(body), "application/json", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue WebApiTeam
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the UpdateTeam function
|
||||
type UpdateTeamArgs struct {
|
||||
// (required)
|
||||
TeamData *WebApiTeam
|
||||
// (required) The name or ID (GUID) of the team project containing the team to update.
|
||||
ProjectId *string
|
||||
// (required) The name of ID of the team to update.
|
||||
TeamId *string
|
||||
}
|
483
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/core/models.go
generated
vendored
483
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/core/models.go
generated
vendored
@ -1,483 +0,0 @@
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Generated file, DO NOT EDIT
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/microsoft/azure-devops-go-api/azuredevops"
|
||||
"github.com/microsoft/azure-devops-go-api/azuredevops/identity"
|
||||
"github.com/microsoft/azure-devops-go-api/azuredevops/webapi"
|
||||
)
|
||||
|
||||
type ConnectedServiceKind string
|
||||
|
||||
type connectedServiceKindValuesType struct {
|
||||
Custom ConnectedServiceKind
|
||||
AzureSubscription ConnectedServiceKind
|
||||
Chef ConnectedServiceKind
|
||||
Generic ConnectedServiceKind
|
||||
}
|
||||
|
||||
var ConnectedServiceKindValues = connectedServiceKindValuesType{
|
||||
// Custom or unknown service
|
||||
Custom: "custom",
|
||||
// Azure Subscription
|
||||
AzureSubscription: "azureSubscription",
|
||||
// Chef Connection
|
||||
Chef: "chef",
|
||||
// Generic Connection
|
||||
Generic: "generic",
|
||||
}
|
||||
|
||||
type IdentityData struct {
|
||||
IdentityIds *[]uuid.UUID `json:"identityIds,omitempty"`
|
||||
}
|
||||
|
||||
type Process struct {
|
||||
Name *string `json:"name,omitempty"`
|
||||
Url *string `json:"url,omitempty"`
|
||||
Links interface{} `json:"_links,omitempty"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
IsDefault *bool `json:"isDefault,omitempty"`
|
||||
Type *ProcessType `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
// Type of process customization on a collection.
|
||||
type ProcessCustomizationType string
|
||||
|
||||
type processCustomizationTypeValuesType struct {
|
||||
Xml ProcessCustomizationType
|
||||
Inherited ProcessCustomizationType
|
||||
}
|
||||
|
||||
var ProcessCustomizationTypeValues = processCustomizationTypeValuesType{
|
||||
// Customization based on project-scoped xml customization
|
||||
Xml: "xml",
|
||||
// Customization based on process inheritance
|
||||
Inherited: "inherited",
|
||||
}
|
||||
|
||||
type ProcessReference struct {
|
||||
Name *string `json:"name,omitempty"`
|
||||
Url *string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
type ProcessType string
|
||||
|
||||
type processTypeValuesType struct {
|
||||
System ProcessType
|
||||
Custom ProcessType
|
||||
Inherited ProcessType
|
||||
}
|
||||
|
||||
var ProcessTypeValues = processTypeValuesType{
|
||||
System: "system",
|
||||
Custom: "custom",
|
||||
Inherited: "inherited",
|
||||
}
|
||||
|
||||
// Contains the image data for project avatar.
|
||||
type ProjectAvatar struct {
|
||||
// The avatar image represented as a byte array.
|
||||
Image *[]byte `json:"image,omitempty"`
|
||||
}
|
||||
|
||||
type ProjectChangeType string
|
||||
|
||||
type projectChangeTypeValuesType struct {
|
||||
Modified ProjectChangeType
|
||||
Deleted ProjectChangeType
|
||||
Added ProjectChangeType
|
||||
}
|
||||
|
||||
var ProjectChangeTypeValues = projectChangeTypeValuesType{
|
||||
Modified: "modified",
|
||||
Deleted: "deleted",
|
||||
Added: "added",
|
||||
}
|
||||
|
||||
// Contains information describing a project.
|
||||
type ProjectInfo struct {
|
||||
// The abbreviated name of the project.
|
||||
Abbreviation *string `json:"abbreviation,omitempty"`
|
||||
// The description of the project.
|
||||
Description *string `json:"description,omitempty"`
|
||||
// The id of the project.
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
// The time that this project was last updated.
|
||||
LastUpdateTime *azuredevops.Time `json:"lastUpdateTime,omitempty"`
|
||||
// The name of the project.
|
||||
Name *string `json:"name,omitempty"`
|
||||
// A set of name-value pairs storing additional property data related to the project.
|
||||
Properties *[]ProjectProperty `json:"properties,omitempty"`
|
||||
// The current revision of the project.
|
||||
Revision *uint64 `json:"revision,omitempty"`
|
||||
// The current state of the project.
|
||||
State *ProjectState `json:"state,omitempty"`
|
||||
// A Uri that can be used to refer to this project.
|
||||
Uri *string `json:"uri,omitempty"`
|
||||
// The version number of the project.
|
||||
Version *uint64 `json:"version,omitempty"`
|
||||
// Indicates whom the project is visible to.
|
||||
Visibility *ProjectVisibility `json:"visibility,omitempty"`
|
||||
}
|
||||
|
||||
type ProjectMessage struct {
|
||||
Project *ProjectInfo `json:"project,omitempty"`
|
||||
ProjectChangeType *ProjectChangeType `json:"projectChangeType,omitempty"`
|
||||
ShouldInvalidateSystemStore *bool `json:"shouldInvalidateSystemStore,omitempty"`
|
||||
}
|
||||
|
||||
type ProjectProperties struct {
|
||||
// The team project Id
|
||||
ProjectId *uuid.UUID `json:"projectId,omitempty"`
|
||||
// The collection of team project properties
|
||||
Properties *[]ProjectProperty `json:"properties,omitempty"`
|
||||
}
|
||||
|
||||
// A named value associated with a project.
|
||||
type ProjectProperty struct {
|
||||
// The name of the property.
|
||||
Name *string `json:"name,omitempty"`
|
||||
// The value of the property.
|
||||
Value interface{} `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
type ProjectState string
|
||||
|
||||
type projectStateValuesType struct {
|
||||
Deleting ProjectState
|
||||
New ProjectState
|
||||
WellFormed ProjectState
|
||||
CreatePending ProjectState
|
||||
All ProjectState
|
||||
Unchanged ProjectState
|
||||
Deleted ProjectState
|
||||
}
|
||||
|
||||
var ProjectStateValues = projectStateValuesType{
|
||||
// Project is in the process of being deleted.
|
||||
Deleting: "deleting",
|
||||
// Project is in the process of being created.
|
||||
New: "new",
|
||||
// Project is completely created and ready to use.
|
||||
WellFormed: "wellFormed",
|
||||
// Project has been queued for creation, but the process has not yet started.
|
||||
CreatePending: "createPending",
|
||||
// All projects regardless of state.
|
||||
All: "all",
|
||||
// Project has not been changed.
|
||||
Unchanged: "unchanged",
|
||||
// Project has been deleted.
|
||||
Deleted: "deleted",
|
||||
}
|
||||
|
||||
type ProjectVisibility string
|
||||
|
||||
type projectVisibilityValuesType struct {
|
||||
Private ProjectVisibility
|
||||
Public ProjectVisibility
|
||||
}
|
||||
|
||||
var ProjectVisibilityValues = projectVisibilityValuesType{
|
||||
// The project is only visible to users with explicit access.
|
||||
Private: "private",
|
||||
// The project is visible to all.
|
||||
Public: "public",
|
||||
}
|
||||
|
||||
type Proxy struct {
|
||||
Authorization *ProxyAuthorization `json:"authorization,omitempty"`
|
||||
// This is a description string
|
||||
Description *string `json:"description,omitempty"`
|
||||
// The friendly name of the server
|
||||
FriendlyName *string `json:"friendlyName,omitempty"`
|
||||
GlobalDefault *bool `json:"globalDefault,omitempty"`
|
||||
// This is a string representation of the site that the proxy server is located in (e.g. "NA-WA-RED")
|
||||
Site *string `json:"site,omitempty"`
|
||||
SiteDefault *bool `json:"siteDefault,omitempty"`
|
||||
// The URL of the proxy server
|
||||
Url *string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
type ProxyAuthorization struct {
|
||||
// Gets or sets the endpoint used to obtain access tokens from the configured token service.
|
||||
AuthorizationUrl *string `json:"authorizationUrl,omitempty"`
|
||||
// Gets or sets the client identifier for this proxy.
|
||||
ClientId *uuid.UUID `json:"clientId,omitempty"`
|
||||
// Gets or sets the user identity to authorize for on-prem.
|
||||
Identity *string `json:"identity,omitempty"`
|
||||
// Gets or sets the public key used to verify the identity of this proxy. Only specify on hosted.
|
||||
PublicKey *webapi.PublicKey `json:"publicKey,omitempty"`
|
||||
}
|
||||
|
||||
type SourceControlTypes string
|
||||
|
||||
type sourceControlTypesValuesType struct {
|
||||
Tfvc SourceControlTypes
|
||||
Git SourceControlTypes
|
||||
}
|
||||
|
||||
var SourceControlTypesValues = sourceControlTypesValuesType{
|
||||
Tfvc: "tfvc",
|
||||
Git: "git",
|
||||
}
|
||||
|
||||
// The Team Context for an operation.
|
||||
type TeamContext struct {
|
||||
// The team project Id or name. Ignored if ProjectId is set.
|
||||
Project *string `json:"project,omitempty"`
|
||||
// The Team Project ID. Required if Project is not set.
|
||||
ProjectId *uuid.UUID `json:"projectId,omitempty"`
|
||||
// The Team Id or name. Ignored if TeamId is set.
|
||||
Team *string `json:"team,omitempty"`
|
||||
// The Team Id
|
||||
TeamId *uuid.UUID `json:"teamId,omitempty"`
|
||||
}
|
||||
|
||||
// Represents a Team Project object.
|
||||
type TeamProject struct {
|
||||
// Project abbreviation.
|
||||
Abbreviation *string `json:"abbreviation,omitempty"`
|
||||
// Url to default team identity image.
|
||||
DefaultTeamImageUrl *string `json:"defaultTeamImageUrl,omitempty"`
|
||||
// The project's description (if any).
|
||||
Description *string `json:"description,omitempty"`
|
||||
// Project identifier.
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
// Project last update time.
|
||||
LastUpdateTime *azuredevops.Time `json:"lastUpdateTime,omitempty"`
|
||||
// Project name.
|
||||
Name *string `json:"name,omitempty"`
|
||||
// Project revision.
|
||||
Revision *uint64 `json:"revision,omitempty"`
|
||||
// Project state.
|
||||
State *ProjectState `json:"state,omitempty"`
|
||||
// Url to the full version of the object.
|
||||
Url *string `json:"url,omitempty"`
|
||||
// Project visibility.
|
||||
Visibility *ProjectVisibility `json:"visibility,omitempty"`
|
||||
// The links to other objects related to this object.
|
||||
Links interface{} `json:"_links,omitempty"`
|
||||
// Set of capabilities this project has (such as process template & version control).
|
||||
Capabilities *map[string]map[string]string `json:"capabilities,omitempty"`
|
||||
// The shallow ref to the default team.
|
||||
DefaultTeam *WebApiTeamRef `json:"defaultTeam,omitempty"`
|
||||
}
|
||||
|
||||
// Data contract for a TeamProjectCollection.
|
||||
type TeamProjectCollection struct {
|
||||
// Collection Id.
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
// Collection Name.
|
||||
Name *string `json:"name,omitempty"`
|
||||
// Collection REST Url.
|
||||
Url *string `json:"url,omitempty"`
|
||||
// The links to other objects related to this object.
|
||||
Links interface{} `json:"_links,omitempty"`
|
||||
// Project collection description.
|
||||
Description *string `json:"description,omitempty"`
|
||||
// Process customization type on this collection. It can be Xml or Inherited.
|
||||
ProcessCustomizationType *ProcessCustomizationType `json:"processCustomizationType,omitempty"`
|
||||
// Project collection state.
|
||||
State *string `json:"state,omitempty"`
|
||||
}
|
||||
|
||||
// Reference object for a TeamProjectCollection.
|
||||
type TeamProjectCollectionReference struct {
|
||||
// Collection Id.
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
// Collection Name.
|
||||
Name *string `json:"name,omitempty"`
|
||||
// Collection REST Url.
|
||||
Url *string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
// Represents a shallow reference to a TeamProject.
|
||||
type TeamProjectReference struct {
|
||||
// Project abbreviation.
|
||||
Abbreviation *string `json:"abbreviation,omitempty"`
|
||||
// Url to default team identity image.
|
||||
DefaultTeamImageUrl *string `json:"defaultTeamImageUrl,omitempty"`
|
||||
// The project's description (if any).
|
||||
Description *string `json:"description,omitempty"`
|
||||
// Project identifier.
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
// Project last update time.
|
||||
LastUpdateTime *azuredevops.Time `json:"lastUpdateTime,omitempty"`
|
||||
// Project name.
|
||||
Name *string `json:"name,omitempty"`
|
||||
// Project revision.
|
||||
Revision *uint64 `json:"revision,omitempty"`
|
||||
// Project state.
|
||||
State *ProjectState `json:"state,omitempty"`
|
||||
// Url to the full version of the object.
|
||||
Url *string `json:"url,omitempty"`
|
||||
// Project visibility.
|
||||
Visibility *ProjectVisibility `json:"visibility,omitempty"`
|
||||
}
|
||||
|
||||
// A data transfer object that stores the metadata associated with the creation of temporary data.
|
||||
type TemporaryDataCreatedDTO struct {
|
||||
ExpirationSeconds *int `json:"expirationSeconds,omitempty"`
|
||||
Origin *string `json:"origin,omitempty"`
|
||||
Value interface{} `json:"value,omitempty"`
|
||||
ExpirationDate *azuredevops.Time `json:"expirationDate,omitempty"`
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
Url *string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
// A data transfer object that stores the metadata associated with the temporary data.
|
||||
type TemporaryDataDTO struct {
|
||||
ExpirationSeconds *int `json:"expirationSeconds,omitempty"`
|
||||
Origin *string `json:"origin,omitempty"`
|
||||
Value interface{} `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
// Updateable properties for a WebApiTeam.
|
||||
type UpdateTeam struct {
|
||||
// New description for the team.
|
||||
Description *string `json:"description,omitempty"`
|
||||
// New name for the team.
|
||||
Name *string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
type WebApiConnectedService struct {
|
||||
Url *string `json:"url,omitempty"`
|
||||
// The user who did the OAuth authentication to created this service
|
||||
AuthenticatedBy *webapi.IdentityRef `json:"authenticatedBy,omitempty"`
|
||||
// Extra description on the service.
|
||||
Description *string `json:"description,omitempty"`
|
||||
// Friendly Name of service connection
|
||||
FriendlyName *string `json:"friendlyName,omitempty"`
|
||||
// Id/Name of the connection service. For Ex: Subscription Id for Azure Connection
|
||||
Id *string `json:"id,omitempty"`
|
||||
// The kind of service.
|
||||
Kind *string `json:"kind,omitempty"`
|
||||
// The project associated with this service
|
||||
Project *TeamProjectReference `json:"project,omitempty"`
|
||||
// Optional uri to connect directly to the service such as https://windows.azure.com
|
||||
ServiceUri *string `json:"serviceUri,omitempty"`
|
||||
}
|
||||
|
||||
type WebApiConnectedServiceDetails struct {
|
||||
Id *string `json:"id,omitempty"`
|
||||
Url *string `json:"url,omitempty"`
|
||||
// Meta data for service connection
|
||||
ConnectedServiceMetaData *WebApiConnectedService `json:"connectedServiceMetaData,omitempty"`
|
||||
// Credential info
|
||||
CredentialsXml *string `json:"credentialsXml,omitempty"`
|
||||
// Optional uri to connect directly to the service such as https://windows.azure.com
|
||||
EndPoint *string `json:"endPoint,omitempty"`
|
||||
}
|
||||
|
||||
type WebApiConnectedServiceRef struct {
|
||||
Id *string `json:"id,omitempty"`
|
||||
Url *string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
// The representation of data needed to create a tag definition which is sent across the wire.
|
||||
type WebApiCreateTagRequestData struct {
|
||||
// Name of the tag definition that will be created.
|
||||
Name *string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
type WebApiProject struct {
|
||||
// Project abbreviation.
|
||||
Abbreviation *string `json:"abbreviation,omitempty"`
|
||||
// Url to default team identity image.
|
||||
DefaultTeamImageUrl *string `json:"defaultTeamImageUrl,omitempty"`
|
||||
// The project's description (if any).
|
||||
Description *string `json:"description,omitempty"`
|
||||
// Project identifier.
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
// Project last update time.
|
||||
LastUpdateTime *azuredevops.Time `json:"lastUpdateTime,omitempty"`
|
||||
// Project name.
|
||||
Name *string `json:"name,omitempty"`
|
||||
// Project revision.
|
||||
Revision *uint64 `json:"revision,omitempty"`
|
||||
// Project state.
|
||||
State *ProjectState `json:"state,omitempty"`
|
||||
// Url to the full version of the object.
|
||||
Url *string `json:"url,omitempty"`
|
||||
// Project visibility.
|
||||
Visibility *ProjectVisibility `json:"visibility,omitempty"`
|
||||
// Set of capabilities this project has
|
||||
Capabilities *map[string]map[string]string `json:"capabilities,omitempty"`
|
||||
// Reference to collection which contains this project
|
||||
Collection *WebApiProjectCollectionRef `json:"collection,omitempty"`
|
||||
// Default team for this project
|
||||
DefaultTeam *WebApiTeamRef `json:"defaultTeam,omitempty"`
|
||||
}
|
||||
|
||||
type WebApiProjectCollection struct {
|
||||
// Collection Tfs Url (Host Url)
|
||||
CollectionUrl *string `json:"collectionUrl,omitempty"`
|
||||
// Collection Guid
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
// Collection Name
|
||||
Name *string `json:"name,omitempty"`
|
||||
// Collection REST Url
|
||||
Url *string `json:"url,omitempty"`
|
||||
// Project collection description
|
||||
Description *string `json:"description,omitempty"`
|
||||
// Project collection state
|
||||
State *string `json:"state,omitempty"`
|
||||
}
|
||||
|
||||
type WebApiProjectCollectionRef struct {
|
||||
// Collection Tfs Url (Host Url)
|
||||
CollectionUrl *string `json:"collectionUrl,omitempty"`
|
||||
// Collection Guid
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
// Collection Name
|
||||
Name *string `json:"name,omitempty"`
|
||||
// Collection REST Url
|
||||
Url *string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
// The representation of a tag definition which is sent across the wire.
|
||||
type WebApiTagDefinition struct {
|
||||
// Whether or not the tag definition is active.
|
||||
Active *bool `json:"active,omitempty"`
|
||||
// ID of the tag definition.
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
// The name of the tag definition.
|
||||
Name *string `json:"name,omitempty"`
|
||||
// Resource URL for the Tag Definition.
|
||||
Url *string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
type WebApiTeam struct {
|
||||
// Team (Identity) Guid. A Team Foundation ID.
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
// Team name
|
||||
Name *string `json:"name,omitempty"`
|
||||
// Team REST API Url
|
||||
Url *string `json:"url,omitempty"`
|
||||
// Team description
|
||||
Description *string `json:"description,omitempty"`
|
||||
// Team identity.
|
||||
Identity *identity.Identity `json:"identity,omitempty"`
|
||||
// Identity REST API Url to this team
|
||||
IdentityUrl *string `json:"identityUrl,omitempty"`
|
||||
ProjectId *uuid.UUID `json:"projectId,omitempty"`
|
||||
ProjectName *string `json:"projectName,omitempty"`
|
||||
}
|
||||
|
||||
type WebApiTeamRef struct {
|
||||
// Team (Identity) Guid. A Team Foundation ID.
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
// Team name
|
||||
Name *string `json:"name,omitempty"`
|
||||
// Team REST API Url
|
||||
Url *string `json:"url,omitempty"`
|
||||
}
|
350
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/delegatedauthorization/models.go
generated
vendored
350
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/delegatedauthorization/models.go
generated
vendored
@ -1,350 +0,0 @@
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Generated file, DO NOT EDIT
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
package delegatedauthorization
|
||||
|
||||
import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/microsoft/azure-devops-go-api/azuredevops"
|
||||
"github.com/microsoft/azure-devops-go-api/azuredevops/webapi"
|
||||
)
|
||||
|
||||
type AccessTokenResult struct {
|
||||
AccessToken *webapi.JsonWebToken `json:"accessToken,omitempty"`
|
||||
AccessTokenError *TokenError `json:"accessTokenError,omitempty"`
|
||||
AuthorizationId *uuid.UUID `json:"authorizationId,omitempty"`
|
||||
ErrorDescription *string `json:"errorDescription,omitempty"`
|
||||
HasError *bool `json:"hasError,omitempty"`
|
||||
RefreshToken *RefreshTokenGrant `json:"refreshToken,omitempty"`
|
||||
TokenType *string `json:"tokenType,omitempty"`
|
||||
ValidTo *azuredevops.Time `json:"validTo,omitempty"`
|
||||
}
|
||||
|
||||
type Authorization struct {
|
||||
AccessIssued *azuredevops.Time `json:"accessIssued,omitempty"`
|
||||
Audience *string `json:"audience,omitempty"`
|
||||
AuthorizationId *uuid.UUID `json:"authorizationId,omitempty"`
|
||||
IdentityId *uuid.UUID `json:"identityId,omitempty"`
|
||||
IsAccessUsed *bool `json:"isAccessUsed,omitempty"`
|
||||
IsValid *bool `json:"isValid,omitempty"`
|
||||
RedirectUri *string `json:"redirectUri,omitempty"`
|
||||
RegistrationId *uuid.UUID `json:"registrationId,omitempty"`
|
||||
Scopes *string `json:"scopes,omitempty"`
|
||||
Source *string `json:"source,omitempty"`
|
||||
ValidFrom *azuredevops.Time `json:"validFrom,omitempty"`
|
||||
ValidTo *azuredevops.Time `json:"validTo,omitempty"`
|
||||
}
|
||||
|
||||
type AuthorizationDecision struct {
|
||||
Authorization *Authorization `json:"authorization,omitempty"`
|
||||
AuthorizationError *AuthorizationError `json:"authorizationError,omitempty"`
|
||||
AuthorizationGrant *AuthorizationGrant `json:"authorizationGrant,omitempty"`
|
||||
HasError *bool `json:"hasError,omitempty"`
|
||||
IsAuthorized *bool `json:"isAuthorized,omitempty"`
|
||||
}
|
||||
|
||||
type AuthorizationDescription struct {
|
||||
ClientRegistration *Registration `json:"clientRegistration,omitempty"`
|
||||
HasError *bool `json:"hasError,omitempty"`
|
||||
InitiationError *InitiationError `json:"initiationError,omitempty"`
|
||||
ScopeDescriptions *[]AuthorizationScopeDescription `json:"scopeDescriptions,omitempty"`
|
||||
}
|
||||
|
||||
type AuthorizationDetails struct {
|
||||
Authorization *Authorization `json:"authorization,omitempty"`
|
||||
ClientRegistration *Registration `json:"clientRegistration,omitempty"`
|
||||
ScopeDescriptions *[]AuthorizationScopeDescription `json:"scopeDescriptions,omitempty"`
|
||||
}
|
||||
|
||||
type AuthorizationError string
|
||||
|
||||
type authorizationErrorValuesType struct {
|
||||
None AuthorizationError
|
||||
ClientIdRequired AuthorizationError
|
||||
InvalidClientId AuthorizationError
|
||||
ResponseTypeRequired AuthorizationError
|
||||
ResponseTypeNotSupported AuthorizationError
|
||||
ScopeRequired AuthorizationError
|
||||
InvalidScope AuthorizationError
|
||||
RedirectUriRequired AuthorizationError
|
||||
InsecureRedirectUri AuthorizationError
|
||||
InvalidRedirectUri AuthorizationError
|
||||
InvalidUserId AuthorizationError
|
||||
InvalidUserType AuthorizationError
|
||||
AccessDenied AuthorizationError
|
||||
}
|
||||
|
||||
var AuthorizationErrorValues = authorizationErrorValuesType{
|
||||
None: "none",
|
||||
ClientIdRequired: "clientIdRequired",
|
||||
InvalidClientId: "invalidClientId",
|
||||
ResponseTypeRequired: "responseTypeRequired",
|
||||
ResponseTypeNotSupported: "responseTypeNotSupported",
|
||||
ScopeRequired: "scopeRequired",
|
||||
InvalidScope: "invalidScope",
|
||||
RedirectUriRequired: "redirectUriRequired",
|
||||
InsecureRedirectUri: "insecureRedirectUri",
|
||||
InvalidRedirectUri: "invalidRedirectUri",
|
||||
InvalidUserId: "invalidUserId",
|
||||
InvalidUserType: "invalidUserType",
|
||||
AccessDenied: "accessDenied",
|
||||
}
|
||||
|
||||
type AuthorizationGrant struct {
|
||||
GrantType *GrantType `json:"grantType,omitempty"`
|
||||
}
|
||||
|
||||
type AuthorizationScopeDescription struct {
|
||||
Description *string `json:"description,omitempty"`
|
||||
Market *string `json:"market,omitempty"`
|
||||
Title *string `json:"title,omitempty"`
|
||||
}
|
||||
|
||||
type ClientType string
|
||||
|
||||
type clientTypeValuesType struct {
|
||||
Confidential ClientType
|
||||
Public ClientType
|
||||
MediumTrust ClientType
|
||||
HighTrust ClientType
|
||||
FullTrust ClientType
|
||||
}
|
||||
|
||||
var ClientTypeValues = clientTypeValuesType{
|
||||
Confidential: "confidential",
|
||||
Public: "public",
|
||||
MediumTrust: "mediumTrust",
|
||||
HighTrust: "highTrust",
|
||||
FullTrust: "fullTrust",
|
||||
}
|
||||
|
||||
type GrantType string
|
||||
|
||||
type grantTypeValuesType struct {
|
||||
None GrantType
|
||||
JwtBearer GrantType
|
||||
RefreshToken GrantType
|
||||
Implicit GrantType
|
||||
ClientCredentials GrantType
|
||||
}
|
||||
|
||||
var GrantTypeValues = grantTypeValuesType{
|
||||
None: "none",
|
||||
JwtBearer: "jwtBearer",
|
||||
RefreshToken: "refreshToken",
|
||||
Implicit: "implicit",
|
||||
ClientCredentials: "clientCredentials",
|
||||
}
|
||||
|
||||
type HostAuthorization struct {
|
||||
HostId *uuid.UUID `json:"hostId,omitempty"`
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
IsValid *bool `json:"isValid,omitempty"`
|
||||
RegistrationId *uuid.UUID `json:"registrationId,omitempty"`
|
||||
}
|
||||
|
||||
type HostAuthorizationDecision struct {
|
||||
HasError *bool `json:"hasError,omitempty"`
|
||||
HostAuthorizationError *HostAuthorizationError `json:"hostAuthorizationError,omitempty"`
|
||||
HostAuthorizationId *uuid.UUID `json:"hostAuthorizationId,omitempty"`
|
||||
}
|
||||
|
||||
type HostAuthorizationError string
|
||||
|
||||
type hostAuthorizationErrorValuesType struct {
|
||||
None HostAuthorizationError
|
||||
ClientIdRequired HostAuthorizationError
|
||||
AccessDenied HostAuthorizationError
|
||||
FailedToAuthorizeHost HostAuthorizationError
|
||||
ClientIdNotFound HostAuthorizationError
|
||||
InvalidClientId HostAuthorizationError
|
||||
}
|
||||
|
||||
var HostAuthorizationErrorValues = hostAuthorizationErrorValuesType{
|
||||
None: "none",
|
||||
ClientIdRequired: "clientIdRequired",
|
||||
AccessDenied: "accessDenied",
|
||||
FailedToAuthorizeHost: "failedToAuthorizeHost",
|
||||
ClientIdNotFound: "clientIdNotFound",
|
||||
InvalidClientId: "invalidClientId",
|
||||
}
|
||||
|
||||
type InitiationError string
|
||||
|
||||
type initiationErrorValuesType struct {
|
||||
None InitiationError
|
||||
ClientIdRequired InitiationError
|
||||
InvalidClientId InitiationError
|
||||
ResponseTypeRequired InitiationError
|
||||
ResponseTypeNotSupported InitiationError
|
||||
ScopeRequired InitiationError
|
||||
InvalidScope InitiationError
|
||||
RedirectUriRequired InitiationError
|
||||
InsecureRedirectUri InitiationError
|
||||
InvalidRedirectUri InitiationError
|
||||
}
|
||||
|
||||
var InitiationErrorValues = initiationErrorValuesType{
|
||||
None: "none",
|
||||
ClientIdRequired: "clientIdRequired",
|
||||
InvalidClientId: "invalidClientId",
|
||||
ResponseTypeRequired: "responseTypeRequired",
|
||||
ResponseTypeNotSupported: "responseTypeNotSupported",
|
||||
ScopeRequired: "scopeRequired",
|
||||
InvalidScope: "invalidScope",
|
||||
RedirectUriRequired: "redirectUriRequired",
|
||||
InsecureRedirectUri: "insecureRedirectUri",
|
||||
InvalidRedirectUri: "invalidRedirectUri",
|
||||
}
|
||||
|
||||
type RefreshTokenGrant struct {
|
||||
GrantType *GrantType `json:"grantType,omitempty"`
|
||||
Jwt *webapi.JsonWebToken `json:"jwt,omitempty"`
|
||||
}
|
||||
|
||||
type Registration struct {
|
||||
ClientType *ClientType `json:"clientType,omitempty"`
|
||||
IdentityId *uuid.UUID `json:"identityId,omitempty"`
|
||||
Issuer *string `json:"issuer,omitempty"`
|
||||
IsValid *bool `json:"isValid,omitempty"`
|
||||
IsWellKnown *bool `json:"isWellKnown,omitempty"`
|
||||
OrganizationLocation *string `json:"organizationLocation,omitempty"`
|
||||
OrganizationName *string `json:"organizationName,omitempty"`
|
||||
// Raw cert data string from public key. This will be used for authenticating medium trust clients.
|
||||
PublicKey *string `json:"publicKey,omitempty"`
|
||||
RedirectUris *[]string `json:"redirectUris,omitempty"`
|
||||
RegistrationDescription *string `json:"registrationDescription,omitempty"`
|
||||
RegistrationId *uuid.UUID `json:"registrationId,omitempty"`
|
||||
RegistrationLocation *string `json:"registrationLocation,omitempty"`
|
||||
RegistrationLogoSecureLocation *string `json:"registrationLogoSecureLocation,omitempty"`
|
||||
RegistrationName *string `json:"registrationName,omitempty"`
|
||||
RegistrationPrivacyStatementLocation *string `json:"registrationPrivacyStatementLocation,omitempty"`
|
||||
RegistrationTermsOfServiceLocation *string `json:"registrationTermsOfServiceLocation,omitempty"`
|
||||
ResponseTypes *string `json:"responseTypes,omitempty"`
|
||||
Scopes *string `json:"scopes,omitempty"`
|
||||
Secret *string `json:"secret,omitempty"`
|
||||
SecretValidTo *azuredevops.Time `json:"secretValidTo,omitempty"`
|
||||
SecretVersionId *uuid.UUID `json:"secretVersionId,omitempty"`
|
||||
ValidFrom *azuredevops.Time `json:"validFrom,omitempty"`
|
||||
}
|
||||
|
||||
type ResponseType string
|
||||
|
||||
type responseTypeValuesType struct {
|
||||
None ResponseType
|
||||
Assertion ResponseType
|
||||
IdToken ResponseType
|
||||
TenantPicker ResponseType
|
||||
SignoutToken ResponseType
|
||||
AppToken ResponseType
|
||||
Code ResponseType
|
||||
}
|
||||
|
||||
var ResponseTypeValues = responseTypeValuesType{
|
||||
None: "none",
|
||||
Assertion: "assertion",
|
||||
IdToken: "idToken",
|
||||
TenantPicker: "tenantPicker",
|
||||
SignoutToken: "signoutToken",
|
||||
AppToken: "appToken",
|
||||
Code: "code",
|
||||
}
|
||||
|
||||
type SessionToken struct {
|
||||
AccessId *uuid.UUID `json:"accessId,omitempty"`
|
||||
// This is populated when user requests a compact token. The alternate token value is self describing token.
|
||||
AlternateToken *string `json:"alternateToken,omitempty"`
|
||||
AuthorizationId *uuid.UUID `json:"authorizationId,omitempty"`
|
||||
Claims *map[string]string `json:"claims,omitempty"`
|
||||
ClientId *uuid.UUID `json:"clientId,omitempty"`
|
||||
DisplayName *string `json:"displayName,omitempty"`
|
||||
HostAuthorizationId *uuid.UUID `json:"hostAuthorizationId,omitempty"`
|
||||
IsPublic *bool `json:"isPublic,omitempty"`
|
||||
IsValid *bool `json:"isValid,omitempty"`
|
||||
PublicData *string `json:"publicData,omitempty"`
|
||||
Scope *string `json:"scope,omitempty"`
|
||||
Source *string `json:"source,omitempty"`
|
||||
TargetAccounts *[]uuid.UUID `json:"targetAccounts,omitempty"`
|
||||
// This is computed and not returned in Get queries
|
||||
Token *string `json:"token,omitempty"`
|
||||
UserId *uuid.UUID `json:"userId,omitempty"`
|
||||
ValidFrom *azuredevops.Time `json:"validFrom,omitempty"`
|
||||
ValidTo *azuredevops.Time `json:"validTo,omitempty"`
|
||||
}
|
||||
|
||||
type TokenError string
|
||||
|
||||
type tokenErrorValuesType struct {
|
||||
None TokenError
|
||||
GrantTypeRequired TokenError
|
||||
AuthorizationGrantRequired TokenError
|
||||
ClientSecretRequired TokenError
|
||||
RedirectUriRequired TokenError
|
||||
InvalidAuthorizationGrant TokenError
|
||||
InvalidAuthorizationScopes TokenError
|
||||
InvalidRefreshToken TokenError
|
||||
AuthorizationNotFound TokenError
|
||||
AuthorizationGrantExpired TokenError
|
||||
AccessAlreadyIssued TokenError
|
||||
InvalidRedirectUri TokenError
|
||||
AccessTokenNotFound TokenError
|
||||
InvalidAccessToken TokenError
|
||||
AccessTokenAlreadyRefreshed TokenError
|
||||
InvalidClientSecret TokenError
|
||||
ClientSecretExpired TokenError
|
||||
ServerError TokenError
|
||||
AccessDenied TokenError
|
||||
AccessTokenKeyRequired TokenError
|
||||
InvalidAccessTokenKey TokenError
|
||||
FailedToGetAccessToken TokenError
|
||||
InvalidClientId TokenError
|
||||
InvalidClient TokenError
|
||||
InvalidValidTo TokenError
|
||||
InvalidUserId TokenError
|
||||
FailedToIssueAccessToken TokenError
|
||||
AuthorizationGrantScopeMissing TokenError
|
||||
InvalidPublicAccessTokenKey TokenError
|
||||
InvalidPublicAccessToken TokenError
|
||||
PublicFeatureFlagNotEnabled TokenError
|
||||
SshPolicyDisabled TokenError
|
||||
}
|
||||
|
||||
var TokenErrorValues = tokenErrorValuesType{
|
||||
None: "none",
|
||||
GrantTypeRequired: "grantTypeRequired",
|
||||
AuthorizationGrantRequired: "authorizationGrantRequired",
|
||||
ClientSecretRequired: "clientSecretRequired",
|
||||
RedirectUriRequired: "redirectUriRequired",
|
||||
InvalidAuthorizationGrant: "invalidAuthorizationGrant",
|
||||
InvalidAuthorizationScopes: "invalidAuthorizationScopes",
|
||||
InvalidRefreshToken: "invalidRefreshToken",
|
||||
AuthorizationNotFound: "authorizationNotFound",
|
||||
AuthorizationGrantExpired: "authorizationGrantExpired",
|
||||
AccessAlreadyIssued: "accessAlreadyIssued",
|
||||
InvalidRedirectUri: "invalidRedirectUri",
|
||||
AccessTokenNotFound: "accessTokenNotFound",
|
||||
InvalidAccessToken: "invalidAccessToken",
|
||||
AccessTokenAlreadyRefreshed: "accessTokenAlreadyRefreshed",
|
||||
InvalidClientSecret: "invalidClientSecret",
|
||||
ClientSecretExpired: "clientSecretExpired",
|
||||
ServerError: "serverError",
|
||||
AccessDenied: "accessDenied",
|
||||
AccessTokenKeyRequired: "accessTokenKeyRequired",
|
||||
InvalidAccessTokenKey: "invalidAccessTokenKey",
|
||||
FailedToGetAccessToken: "failedToGetAccessToken",
|
||||
InvalidClientId: "invalidClientId",
|
||||
InvalidClient: "invalidClient",
|
||||
InvalidValidTo: "invalidValidTo",
|
||||
InvalidUserId: "invalidUserId",
|
||||
FailedToIssueAccessToken: "failedToIssueAccessToken",
|
||||
AuthorizationGrantScopeMissing: "authorizationGrantScopeMissing",
|
||||
InvalidPublicAccessTokenKey: "invalidPublicAccessTokenKey",
|
||||
InvalidPublicAccessToken: "invalidPublicAccessToken",
|
||||
PublicFeatureFlagNotEnabled: "publicFeatureFlagNotEnabled",
|
||||
SshPolicyDisabled: "sshPolicyDisabled",
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Generated file, DO NOT EDIT
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
package distributedtaskcommon
|
||||
|
||||
type AuthorizationHeader struct {
|
||||
Name *string `json:"name,omitempty"`
|
||||
Value *string `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
// Represents binding of data source for the service endpoint request.
|
||||
type DataSourceBindingBase struct {
|
||||
// Pagination format supported by this data source(ContinuationToken/SkipTop).
|
||||
CallbackContextTemplate *string `json:"callbackContextTemplate,omitempty"`
|
||||
// Subsequent calls needed?
|
||||
CallbackRequiredTemplate *string `json:"callbackRequiredTemplate,omitempty"`
|
||||
// Gets or sets the name of the data source.
|
||||
DataSourceName *string `json:"dataSourceName,omitempty"`
|
||||
// Gets or sets the endpoint Id.
|
||||
EndpointId *string `json:"endpointId,omitempty"`
|
||||
// Gets or sets the url of the service endpoint.
|
||||
EndpointUrl *string `json:"endpointUrl,omitempty"`
|
||||
// Gets or sets the authorization headers.
|
||||
Headers *[]AuthorizationHeader `json:"headers,omitempty"`
|
||||
// Defines the initial value of the query params
|
||||
InitialContextTemplate *string `json:"initialContextTemplate,omitempty"`
|
||||
// Gets or sets the parameters for the data source.
|
||||
Parameters *map[string]string `json:"parameters,omitempty"`
|
||||
// Gets or sets http request body
|
||||
RequestContent *string `json:"requestContent,omitempty"`
|
||||
// Gets or sets http request verb
|
||||
RequestVerb *string `json:"requestVerb,omitempty"`
|
||||
// Gets or sets the result selector.
|
||||
ResultSelector *string `json:"resultSelector,omitempty"`
|
||||
// Gets or sets the result template.
|
||||
ResultTemplate *string `json:"resultTemplate,omitempty"`
|
||||
// Gets or sets the target of the data source.
|
||||
Target *string `json:"target,omitempty"`
|
||||
}
|
||||
|
||||
type ProcessParameters struct {
|
||||
DataSourceBindings *[]DataSourceBindingBase `json:"dataSourceBindings,omitempty"`
|
||||
Inputs *[]TaskInputDefinitionBase `json:"inputs,omitempty"`
|
||||
SourceDefinitions *[]TaskSourceDefinitionBase `json:"sourceDefinitions,omitempty"`
|
||||
}
|
||||
|
||||
type TaskInputDefinitionBase struct {
|
||||
Aliases *[]string `json:"aliases,omitempty"`
|
||||
DefaultValue *string `json:"defaultValue,omitempty"`
|
||||
GroupName *string `json:"groupName,omitempty"`
|
||||
HelpMarkDown *string `json:"helpMarkDown,omitempty"`
|
||||
Label *string `json:"label,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
Options *map[string]string `json:"options,omitempty"`
|
||||
Properties *map[string]string `json:"properties,omitempty"`
|
||||
Required *bool `json:"required,omitempty"`
|
||||
Type *string `json:"type,omitempty"`
|
||||
Validation *TaskInputValidation `json:"validation,omitempty"`
|
||||
VisibleRule *string `json:"visibleRule,omitempty"`
|
||||
}
|
||||
|
||||
type TaskInputValidation struct {
|
||||
// Conditional expression
|
||||
Expression *string `json:"expression,omitempty"`
|
||||
// Message explaining how user can correct if validation fails
|
||||
Message *string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
type TaskSourceDefinitionBase struct {
|
||||
AuthKey *string `json:"authKey,omitempty"`
|
||||
Endpoint *string `json:"endpoint,omitempty"`
|
||||
KeySelector *string `json:"keySelector,omitempty"`
|
||||
Selector *string `json:"selector,omitempty"`
|
||||
Target *string `json:"target,omitempty"`
|
||||
}
|
17
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/errors.go
generated
vendored
17
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/errors.go
generated
vendored
@ -1,17 +0,0 @@
|
||||
package azuredevops
|
||||
|
||||
type ArgumentNilError struct {
|
||||
ArgumentName string
|
||||
}
|
||||
|
||||
func (e ArgumentNilError) Error() string {
|
||||
return "Argument " + e.ArgumentName + " can not be nil"
|
||||
}
|
||||
|
||||
type ArgumentNilOrEmptyError struct {
|
||||
ArgumentName string
|
||||
}
|
||||
|
||||
func (e ArgumentNilOrEmptyError) Error() string {
|
||||
return "Argument " + e.ArgumentName + " can not be nil or empty"
|
||||
}
|
5702
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/git/client.go
generated
vendored
5702
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/git/client.go
generated
vendored
File diff suppressed because it is too large
Load Diff
3129
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/git/models.go
generated
vendored
3129
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/git/models.go
generated
vendored
File diff suppressed because it is too large
Load Diff
5
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/go.mod
generated
vendored
5
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/go.mod
generated
vendored
@ -1,5 +0,0 @@
|
||||
module github.com/microsoft/azure-devops-go-api/azuredevops
|
||||
|
||||
go 1.12
|
||||
|
||||
require github.com/google/uuid v1.1.1
|
2
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/go.sum
generated
vendored
2
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/go.sum
generated
vendored
@ -1,2 +0,0 @@
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
996
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/identity/client.go
generated
vendored
996
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/identity/client.go
generated
vendored
@ -1,996 +0,0 @@
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Generated file, DO NOT EDIT
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
package identity
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/google/uuid"
|
||||
"github.com/microsoft/azure-devops-go-api/azuredevops"
|
||||
"github.com/microsoft/azure-devops-go-api/azuredevops/delegatedauthorization"
|
||||
"github.com/microsoft/azure-devops-go-api/azuredevops/webapi"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
var ResourceAreaId, _ = uuid.Parse("8a3d49b8-91f0-46ef-b33d-dda338c25db3")
|
||||
|
||||
type Client interface {
|
||||
// [Preview API]
|
||||
AddMember(context.Context, AddMemberArgs) (*bool, error)
|
||||
CreateGroups(context.Context, CreateGroupsArgs) (*[]Identity, error)
|
||||
CreateIdentity(context.Context, CreateIdentityArgs) (*Identity, error)
|
||||
// [Preview API]
|
||||
CreateOrBindWithClaims(context.Context, CreateOrBindWithClaimsArgs) (*Identity, error)
|
||||
// [Preview API]
|
||||
CreateScope(context.Context, CreateScopeArgs) (*IdentityScope, error)
|
||||
DeleteGroup(context.Context, DeleteGroupArgs) error
|
||||
// [Preview API]
|
||||
DeleteScope(context.Context, DeleteScopeArgs) error
|
||||
// [Preview API]
|
||||
GetDescriptorById(context.Context, GetDescriptorByIdArgs) (*string, error)
|
||||
GetIdentityChanges(context.Context, GetIdentityChangesArgs) (*ChangedIdentities, error)
|
||||
// [Preview API]
|
||||
GetIdentitySnapshot(context.Context, GetIdentitySnapshotArgs) (*IdentitySnapshot, error)
|
||||
// Read the max sequence id of all the identities.
|
||||
GetMaxSequenceId(context.Context, GetMaxSequenceIdArgs) (*uint64, error)
|
||||
// [Preview API]
|
||||
GetScopeById(context.Context, GetScopeByIdArgs) (*IdentityScope, error)
|
||||
// [Preview API]
|
||||
GetScopeByName(context.Context, GetScopeByNameArgs) (*IdentityScope, error)
|
||||
// Read identity of the home tenant request user.
|
||||
GetSelf(context.Context, GetSelfArgs) (*IdentitySelf, error)
|
||||
// [Preview API]
|
||||
GetSignedInToken(context.Context, GetSignedInTokenArgs) (*delegatedauthorization.AccessTokenResult, error)
|
||||
// [Preview API]
|
||||
GetSignoutToken(context.Context, GetSignoutTokenArgs) (*delegatedauthorization.AccessTokenResult, error)
|
||||
// [Preview API]
|
||||
GetTenant(context.Context, GetTenantArgs) (*TenantInfo, error)
|
||||
GetUserIdentityIdsByDomainId(context.Context, GetUserIdentityIdsByDomainIdArgs) (*[]uuid.UUID, error)
|
||||
ListGroups(context.Context, ListGroupsArgs) (*[]Identity, error)
|
||||
ReadIdentities(context.Context, ReadIdentitiesArgs) (*[]Identity, error)
|
||||
ReadIdentitiesByScope(context.Context, ReadIdentitiesByScopeArgs) (*[]Identity, error)
|
||||
ReadIdentity(context.Context, ReadIdentityArgs) (*Identity, error)
|
||||
// [Preview API]
|
||||
ReadIdentityBatch(context.Context, ReadIdentityBatchArgs) (*[]Identity, error)
|
||||
// [Preview API]
|
||||
ReadMember(context.Context, ReadMemberArgs) (*string, error)
|
||||
// [Preview API]
|
||||
ReadMemberOf(context.Context, ReadMemberOfArgs) (*string, error)
|
||||
// [Preview API]
|
||||
ReadMembers(context.Context, ReadMembersArgs) (*[]string, error)
|
||||
// [Preview API]
|
||||
ReadMembersOf(context.Context, ReadMembersOfArgs) (*[]string, error)
|
||||
// [Preview API]
|
||||
RemoveMember(context.Context, RemoveMemberArgs) (*bool, error)
|
||||
UpdateIdentities(context.Context, UpdateIdentitiesArgs) (*[]IdentityUpdateData, error)
|
||||
UpdateIdentity(context.Context, UpdateIdentityArgs) error
|
||||
// [Preview API]
|
||||
UpdateScope(context.Context, UpdateScopeArgs) error
|
||||
}
|
||||
|
||||
type ClientImpl struct {
|
||||
Client azuredevops.Client
|
||||
}
|
||||
|
||||
func NewClient(ctx context.Context, connection *azuredevops.Connection) (Client, error) {
|
||||
client, err := connection.GetClientByResourceAreaId(ctx, ResourceAreaId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ClientImpl{
|
||||
Client: *client,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// [Preview API]
|
||||
func (client *ClientImpl) AddMember(ctx context.Context, args AddMemberArgs) (*bool, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.ContainerId == nil || *args.ContainerId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ContainerId"}
|
||||
}
|
||||
routeValues["containerId"] = *args.ContainerId
|
||||
if args.MemberId == nil || *args.MemberId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.MemberId"}
|
||||
}
|
||||
routeValues["memberId"] = *args.MemberId
|
||||
|
||||
locationId, _ := uuid.Parse("8ba35978-138e-41f8-8963-7b1ea2c5f775")
|
||||
resp, err := client.Client.Send(ctx, http.MethodPut, locationId, "5.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue bool
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the AddMember function
|
||||
type AddMemberArgs struct {
|
||||
// (required)
|
||||
ContainerId *string
|
||||
// (required)
|
||||
MemberId *string
|
||||
}
|
||||
|
||||
func (client *ClientImpl) CreateGroups(ctx context.Context, args CreateGroupsArgs) (*[]Identity, error) {
|
||||
if args.Container == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.Container"}
|
||||
}
|
||||
body, marshalErr := json.Marshal(args.Container)
|
||||
if marshalErr != nil {
|
||||
return nil, marshalErr
|
||||
}
|
||||
locationId, _ := uuid.Parse("5966283b-4196-4d57-9211-1b68f41ec1c2")
|
||||
resp, err := client.Client.Send(ctx, http.MethodPost, locationId, "5.1", nil, nil, bytes.NewReader(body), "application/json", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue []Identity
|
||||
err = client.Client.UnmarshalCollectionBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the CreateGroups function
|
||||
type CreateGroupsArgs struct {
|
||||
// (required)
|
||||
Container interface{}
|
||||
}
|
||||
|
||||
func (client *ClientImpl) CreateIdentity(ctx context.Context, args CreateIdentityArgs) (*Identity, error) {
|
||||
if args.FrameworkIdentityInfo == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.FrameworkIdentityInfo"}
|
||||
}
|
||||
body, marshalErr := json.Marshal(*args.FrameworkIdentityInfo)
|
||||
if marshalErr != nil {
|
||||
return nil, marshalErr
|
||||
}
|
||||
locationId, _ := uuid.Parse("dd55f0eb-6ea2-4fe4-9ebe-919e7dd1dfb4")
|
||||
resp, err := client.Client.Send(ctx, http.MethodPut, locationId, "5.1", nil, nil, bytes.NewReader(body), "application/json", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue Identity
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the CreateIdentity function
|
||||
type CreateIdentityArgs struct {
|
||||
// (required)
|
||||
FrameworkIdentityInfo *FrameworkIdentityInfo
|
||||
}
|
||||
|
||||
// [Preview API]
|
||||
func (client *ClientImpl) CreateOrBindWithClaims(ctx context.Context, args CreateOrBindWithClaimsArgs) (*Identity, error) {
|
||||
if args.SourceIdentity == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.SourceIdentity"}
|
||||
}
|
||||
body, marshalErr := json.Marshal(*args.SourceIdentity)
|
||||
if marshalErr != nil {
|
||||
return nil, marshalErr
|
||||
}
|
||||
locationId, _ := uuid.Parse("90ddfe71-171c-446c-bf3b-b597cd562afd")
|
||||
resp, err := client.Client.Send(ctx, http.MethodPut, locationId, "5.1-preview.1", nil, nil, bytes.NewReader(body), "application/json", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue Identity
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the CreateOrBindWithClaims function
|
||||
type CreateOrBindWithClaimsArgs struct {
|
||||
// (required)
|
||||
SourceIdentity *Identity
|
||||
}
|
||||
|
||||
// [Preview API]
|
||||
func (client *ClientImpl) CreateScope(ctx context.Context, args CreateScopeArgs) (*IdentityScope, error) {
|
||||
if args.Info == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.Info"}
|
||||
}
|
||||
routeValues := make(map[string]string)
|
||||
if args.ScopeId == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.ScopeId"}
|
||||
}
|
||||
routeValues["scopeId"] = (*args.ScopeId).String()
|
||||
|
||||
body, marshalErr := json.Marshal(*args.Info)
|
||||
if marshalErr != nil {
|
||||
return nil, marshalErr
|
||||
}
|
||||
locationId, _ := uuid.Parse("4e11e2bf-1e79-4eb5-8f34-a6337bd0de38")
|
||||
resp, err := client.Client.Send(ctx, http.MethodPut, locationId, "5.1-preview.2", routeValues, nil, bytes.NewReader(body), "application/json", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue IdentityScope
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the CreateScope function
|
||||
type CreateScopeArgs struct {
|
||||
// (required)
|
||||
Info *CreateScopeInfo
|
||||
// (required)
|
||||
ScopeId *uuid.UUID
|
||||
}
|
||||
|
||||
func (client *ClientImpl) DeleteGroup(ctx context.Context, args DeleteGroupArgs) error {
|
||||
routeValues := make(map[string]string)
|
||||
if args.GroupId == nil || *args.GroupId == "" {
|
||||
return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.GroupId"}
|
||||
}
|
||||
routeValues["groupId"] = *args.GroupId
|
||||
|
||||
locationId, _ := uuid.Parse("5966283b-4196-4d57-9211-1b68f41ec1c2")
|
||||
_, err := client.Client.Send(ctx, http.MethodDelete, locationId, "5.1", routeValues, nil, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Arguments for the DeleteGroup function
|
||||
type DeleteGroupArgs struct {
|
||||
// (required)
|
||||
GroupId *string
|
||||
}
|
||||
|
||||
// [Preview API]
|
||||
func (client *ClientImpl) DeleteScope(ctx context.Context, args DeleteScopeArgs) error {
|
||||
routeValues := make(map[string]string)
|
||||
if args.ScopeId == nil {
|
||||
return &azuredevops.ArgumentNilError{ArgumentName: "args.ScopeId"}
|
||||
}
|
||||
routeValues["scopeId"] = (*args.ScopeId).String()
|
||||
|
||||
locationId, _ := uuid.Parse("4e11e2bf-1e79-4eb5-8f34-a6337bd0de38")
|
||||
_, err := client.Client.Send(ctx, http.MethodDelete, locationId, "5.1-preview.2", routeValues, nil, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Arguments for the DeleteScope function
|
||||
type DeleteScopeArgs struct {
|
||||
// (required)
|
||||
ScopeId *uuid.UUID
|
||||
}
|
||||
|
||||
// [Preview API]
|
||||
func (client *ClientImpl) GetDescriptorById(ctx context.Context, args GetDescriptorByIdArgs) (*string, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.Id == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.Id"}
|
||||
}
|
||||
routeValues["id"] = (*args.Id).String()
|
||||
|
||||
queryParams := url.Values{}
|
||||
if args.IsMasterId != nil {
|
||||
queryParams.Add("isMasterId", strconv.FormatBool(*args.IsMasterId))
|
||||
}
|
||||
locationId, _ := uuid.Parse("a230389a-94f2-496c-839f-c929787496dd")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1-preview.1", routeValues, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue string
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetDescriptorById function
|
||||
type GetDescriptorByIdArgs struct {
|
||||
// (required)
|
||||
Id *uuid.UUID
|
||||
// (optional)
|
||||
IsMasterId *bool
|
||||
}
|
||||
|
||||
func (client *ClientImpl) GetIdentityChanges(ctx context.Context, args GetIdentityChangesArgs) (*ChangedIdentities, error) {
|
||||
queryParams := url.Values{}
|
||||
if args.IdentitySequenceId == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "identitySequenceId"}
|
||||
}
|
||||
queryParams.Add("identitySequenceId", strconv.Itoa(*args.IdentitySequenceId))
|
||||
if args.GroupSequenceId == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "groupSequenceId"}
|
||||
}
|
||||
queryParams.Add("groupSequenceId", strconv.Itoa(*args.GroupSequenceId))
|
||||
if args.OrganizationIdentitySequenceId != nil {
|
||||
queryParams.Add("organizationIdentitySequenceId", strconv.Itoa(*args.OrganizationIdentitySequenceId))
|
||||
}
|
||||
if args.PageSize != nil {
|
||||
queryParams.Add("pageSize", strconv.Itoa(*args.PageSize))
|
||||
}
|
||||
if args.ScopeId != nil {
|
||||
queryParams.Add("scopeId", (*args.ScopeId).String())
|
||||
}
|
||||
locationId, _ := uuid.Parse("28010c54-d0c0-4c89-a5b0-1c9e188b9fb7")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1", nil, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue ChangedIdentities
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetIdentityChanges function
|
||||
type GetIdentityChangesArgs struct {
|
||||
// (required)
|
||||
IdentitySequenceId *int
|
||||
// (required)
|
||||
GroupSequenceId *int
|
||||
// (optional)
|
||||
OrganizationIdentitySequenceId *int
|
||||
// (optional)
|
||||
PageSize *int
|
||||
// (optional)
|
||||
ScopeId *uuid.UUID
|
||||
}
|
||||
|
||||
// [Preview API]
|
||||
func (client *ClientImpl) GetIdentitySnapshot(ctx context.Context, args GetIdentitySnapshotArgs) (*IdentitySnapshot, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.ScopeId == nil || *args.ScopeId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ScopeId"}
|
||||
}
|
||||
routeValues["scopeId"] = *args.ScopeId
|
||||
|
||||
locationId, _ := uuid.Parse("d56223df-8ccd-45c9-89b4-eddf692400d7")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue IdentitySnapshot
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetIdentitySnapshot function
|
||||
type GetIdentitySnapshotArgs struct {
|
||||
// (required)
|
||||
ScopeId *string
|
||||
}
|
||||
|
||||
// Read the max sequence id of all the identities.
|
||||
func (client *ClientImpl) GetMaxSequenceId(ctx context.Context, args GetMaxSequenceIdArgs) (*uint64, error) {
|
||||
locationId, _ := uuid.Parse("e4a70778-cb2c-4e85-b7cc-3f3c7ae2d408")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1", nil, nil, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue uint64
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetMaxSequenceId function
|
||||
type GetMaxSequenceIdArgs struct {
|
||||
}
|
||||
|
||||
// [Preview API]
|
||||
func (client *ClientImpl) GetScopeById(ctx context.Context, args GetScopeByIdArgs) (*IdentityScope, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.ScopeId == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.ScopeId"}
|
||||
}
|
||||
routeValues["scopeId"] = (*args.ScopeId).String()
|
||||
|
||||
locationId, _ := uuid.Parse("4e11e2bf-1e79-4eb5-8f34-a6337bd0de38")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1-preview.2", routeValues, nil, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue IdentityScope
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetScopeById function
|
||||
type GetScopeByIdArgs struct {
|
||||
// (required)
|
||||
ScopeId *uuid.UUID
|
||||
}
|
||||
|
||||
// [Preview API]
|
||||
func (client *ClientImpl) GetScopeByName(ctx context.Context, args GetScopeByNameArgs) (*IdentityScope, error) {
|
||||
queryParams := url.Values{}
|
||||
if args.ScopeName == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "scopeName"}
|
||||
}
|
||||
queryParams.Add("scopeName", *args.ScopeName)
|
||||
locationId, _ := uuid.Parse("4e11e2bf-1e79-4eb5-8f34-a6337bd0de38")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1-preview.2", nil, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue IdentityScope
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetScopeByName function
|
||||
type GetScopeByNameArgs struct {
|
||||
// (required)
|
||||
ScopeName *string
|
||||
}
|
||||
|
||||
// Read identity of the home tenant request user.
|
||||
func (client *ClientImpl) GetSelf(ctx context.Context, args GetSelfArgs) (*IdentitySelf, error) {
|
||||
locationId, _ := uuid.Parse("4bb02b5b-c120-4be2-b68e-21f7c50a4b82")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1", nil, nil, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue IdentitySelf
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetSelf function
|
||||
type GetSelfArgs struct {
|
||||
}
|
||||
|
||||
// [Preview API]
|
||||
func (client *ClientImpl) GetSignedInToken(ctx context.Context, args GetSignedInTokenArgs) (*delegatedauthorization.AccessTokenResult, error) {
|
||||
locationId, _ := uuid.Parse("6074ff18-aaad-4abb-a41e-5c75f6178057")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1-preview.1", nil, nil, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue delegatedauthorization.AccessTokenResult
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetSignedInToken function
|
||||
type GetSignedInTokenArgs struct {
|
||||
}
|
||||
|
||||
// [Preview API]
|
||||
func (client *ClientImpl) GetSignoutToken(ctx context.Context, args GetSignoutTokenArgs) (*delegatedauthorization.AccessTokenResult, error) {
|
||||
locationId, _ := uuid.Parse("be39e83c-7529-45e9-9c67-0410885880da")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1-preview.1", nil, nil, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue delegatedauthorization.AccessTokenResult
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetSignoutToken function
|
||||
type GetSignoutTokenArgs struct {
|
||||
}
|
||||
|
||||
// [Preview API]
|
||||
func (client *ClientImpl) GetTenant(ctx context.Context, args GetTenantArgs) (*TenantInfo, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.TenantId == nil || *args.TenantId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.TenantId"}
|
||||
}
|
||||
routeValues["tenantId"] = *args.TenantId
|
||||
|
||||
locationId, _ := uuid.Parse("5f0a1723-2e2c-4c31-8cae-002d01bdd592")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue TenantInfo
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetTenant function
|
||||
type GetTenantArgs struct {
|
||||
// (required)
|
||||
TenantId *string
|
||||
}
|
||||
|
||||
func (client *ClientImpl) GetUserIdentityIdsByDomainId(ctx context.Context, args GetUserIdentityIdsByDomainIdArgs) (*[]uuid.UUID, error) {
|
||||
queryParams := url.Values{}
|
||||
if args.DomainId == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "domainId"}
|
||||
}
|
||||
queryParams.Add("domainId", (*args.DomainId).String())
|
||||
locationId, _ := uuid.Parse("28010c54-d0c0-4c89-a5b0-1c9e188b9fb7")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1", nil, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue []uuid.UUID
|
||||
err = client.Client.UnmarshalCollectionBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetUserIdentityIdsByDomainId function
|
||||
type GetUserIdentityIdsByDomainIdArgs struct {
|
||||
// (required)
|
||||
DomainId *uuid.UUID
|
||||
}
|
||||
|
||||
func (client *ClientImpl) ListGroups(ctx context.Context, args ListGroupsArgs) (*[]Identity, error) {
|
||||
queryParams := url.Values{}
|
||||
if args.ScopeIds != nil {
|
||||
queryParams.Add("scopeIds", *args.ScopeIds)
|
||||
}
|
||||
if args.Recurse != nil {
|
||||
queryParams.Add("recurse", strconv.FormatBool(*args.Recurse))
|
||||
}
|
||||
if args.Deleted != nil {
|
||||
queryParams.Add("deleted", strconv.FormatBool(*args.Deleted))
|
||||
}
|
||||
if args.Properties != nil {
|
||||
queryParams.Add("properties", *args.Properties)
|
||||
}
|
||||
locationId, _ := uuid.Parse("5966283b-4196-4d57-9211-1b68f41ec1c2")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1", nil, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue []Identity
|
||||
err = client.Client.UnmarshalCollectionBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the ListGroups function
|
||||
type ListGroupsArgs struct {
|
||||
// (optional)
|
||||
ScopeIds *string
|
||||
// (optional)
|
||||
Recurse *bool
|
||||
// (optional)
|
||||
Deleted *bool
|
||||
// (optional)
|
||||
Properties *string
|
||||
}
|
||||
|
||||
func (client *ClientImpl) ReadIdentities(ctx context.Context, args ReadIdentitiesArgs) (*[]Identity, error) {
|
||||
queryParams := url.Values{}
|
||||
if args.Descriptors != nil {
|
||||
queryParams.Add("descriptors", *args.Descriptors)
|
||||
}
|
||||
if args.IdentityIds != nil {
|
||||
queryParams.Add("identityIds", *args.IdentityIds)
|
||||
}
|
||||
if args.SubjectDescriptors != nil {
|
||||
queryParams.Add("subjectDescriptors", *args.SubjectDescriptors)
|
||||
}
|
||||
if args.SocialDescriptors != nil {
|
||||
queryParams.Add("socialDescriptors", *args.SocialDescriptors)
|
||||
}
|
||||
if args.SearchFilter != nil {
|
||||
queryParams.Add("searchFilter", *args.SearchFilter)
|
||||
}
|
||||
if args.FilterValue != nil {
|
||||
queryParams.Add("filterValue", *args.FilterValue)
|
||||
}
|
||||
if args.QueryMembership != nil {
|
||||
queryParams.Add("queryMembership", string(*args.QueryMembership))
|
||||
}
|
||||
if args.Properties != nil {
|
||||
queryParams.Add("properties", *args.Properties)
|
||||
}
|
||||
if args.IncludeRestrictedVisibility != nil {
|
||||
queryParams.Add("includeRestrictedVisibility", strconv.FormatBool(*args.IncludeRestrictedVisibility))
|
||||
}
|
||||
if args.Options != nil {
|
||||
queryParams.Add("options", string(*args.Options))
|
||||
}
|
||||
locationId, _ := uuid.Parse("28010c54-d0c0-4c89-a5b0-1c9e188b9fb7")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1", nil, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue []Identity
|
||||
err = client.Client.UnmarshalCollectionBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the ReadIdentities function
|
||||
type ReadIdentitiesArgs struct {
|
||||
// (optional)
|
||||
Descriptors *string
|
||||
// (optional)
|
||||
IdentityIds *string
|
||||
// (optional)
|
||||
SubjectDescriptors *string
|
||||
// (optional)
|
||||
SocialDescriptors *string
|
||||
// (optional)
|
||||
SearchFilter *string
|
||||
// (optional)
|
||||
FilterValue *string
|
||||
// (optional)
|
||||
QueryMembership *QueryMembership
|
||||
// (optional)
|
||||
Properties *string
|
||||
// (optional)
|
||||
IncludeRestrictedVisibility *bool
|
||||
// (optional)
|
||||
Options *ReadIdentitiesOptions
|
||||
}
|
||||
|
||||
func (client *ClientImpl) ReadIdentitiesByScope(ctx context.Context, args ReadIdentitiesByScopeArgs) (*[]Identity, error) {
|
||||
queryParams := url.Values{}
|
||||
if args.ScopeId == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "scopeId"}
|
||||
}
|
||||
queryParams.Add("scopeId", (*args.ScopeId).String())
|
||||
if args.QueryMembership != nil {
|
||||
queryParams.Add("queryMembership", string(*args.QueryMembership))
|
||||
}
|
||||
if args.Properties != nil {
|
||||
queryParams.Add("properties", *args.Properties)
|
||||
}
|
||||
locationId, _ := uuid.Parse("28010c54-d0c0-4c89-a5b0-1c9e188b9fb7")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1", nil, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue []Identity
|
||||
err = client.Client.UnmarshalCollectionBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the ReadIdentitiesByScope function
|
||||
type ReadIdentitiesByScopeArgs struct {
|
||||
// (required)
|
||||
ScopeId *uuid.UUID
|
||||
// (optional)
|
||||
QueryMembership *QueryMembership
|
||||
// (optional)
|
||||
Properties *string
|
||||
}
|
||||
|
||||
func (client *ClientImpl) ReadIdentity(ctx context.Context, args ReadIdentityArgs) (*Identity, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.IdentityId == nil || *args.IdentityId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.IdentityId"}
|
||||
}
|
||||
routeValues["identityId"] = *args.IdentityId
|
||||
|
||||
queryParams := url.Values{}
|
||||
if args.QueryMembership != nil {
|
||||
queryParams.Add("queryMembership", string(*args.QueryMembership))
|
||||
}
|
||||
if args.Properties != nil {
|
||||
queryParams.Add("properties", *args.Properties)
|
||||
}
|
||||
locationId, _ := uuid.Parse("28010c54-d0c0-4c89-a5b0-1c9e188b9fb7")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1", routeValues, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue Identity
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the ReadIdentity function
|
||||
type ReadIdentityArgs struct {
|
||||
// (required)
|
||||
IdentityId *string
|
||||
// (optional)
|
||||
QueryMembership *QueryMembership
|
||||
// (optional)
|
||||
Properties *string
|
||||
}
|
||||
|
||||
// [Preview API]
|
||||
func (client *ClientImpl) ReadIdentityBatch(ctx context.Context, args ReadIdentityBatchArgs) (*[]Identity, error) {
|
||||
if args.BatchInfo == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.BatchInfo"}
|
||||
}
|
||||
body, marshalErr := json.Marshal(*args.BatchInfo)
|
||||
if marshalErr != nil {
|
||||
return nil, marshalErr
|
||||
}
|
||||
locationId, _ := uuid.Parse("299e50df-fe45-4d3a-8b5b-a5836fac74dc")
|
||||
resp, err := client.Client.Send(ctx, http.MethodPost, locationId, "5.1-preview.1", nil, nil, bytes.NewReader(body), "application/json", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue []Identity
|
||||
err = client.Client.UnmarshalCollectionBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the ReadIdentityBatch function
|
||||
type ReadIdentityBatchArgs struct {
|
||||
// (required)
|
||||
BatchInfo *IdentityBatchInfo
|
||||
}
|
||||
|
||||
// [Preview API]
|
||||
func (client *ClientImpl) ReadMember(ctx context.Context, args ReadMemberArgs) (*string, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.ContainerId == nil || *args.ContainerId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ContainerId"}
|
||||
}
|
||||
routeValues["containerId"] = *args.ContainerId
|
||||
if args.MemberId == nil || *args.MemberId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.MemberId"}
|
||||
}
|
||||
routeValues["memberId"] = *args.MemberId
|
||||
|
||||
queryParams := url.Values{}
|
||||
if args.QueryMembership != nil {
|
||||
queryParams.Add("queryMembership", string(*args.QueryMembership))
|
||||
}
|
||||
locationId, _ := uuid.Parse("8ba35978-138e-41f8-8963-7b1ea2c5f775")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1-preview.1", routeValues, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue string
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the ReadMember function
|
||||
type ReadMemberArgs struct {
|
||||
// (required)
|
||||
ContainerId *string
|
||||
// (required)
|
||||
MemberId *string
|
||||
// (optional)
|
||||
QueryMembership *QueryMembership
|
||||
}
|
||||
|
||||
// [Preview API]
|
||||
func (client *ClientImpl) ReadMemberOf(ctx context.Context, args ReadMemberOfArgs) (*string, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.MemberId == nil || *args.MemberId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.MemberId"}
|
||||
}
|
||||
routeValues["memberId"] = *args.MemberId
|
||||
if args.ContainerId == nil || *args.ContainerId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ContainerId"}
|
||||
}
|
||||
routeValues["containerId"] = *args.ContainerId
|
||||
|
||||
queryParams := url.Values{}
|
||||
if args.QueryMembership != nil {
|
||||
queryParams.Add("queryMembership", string(*args.QueryMembership))
|
||||
}
|
||||
locationId, _ := uuid.Parse("22865b02-9e4a-479e-9e18-e35b8803b8a0")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1-preview.1", routeValues, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue string
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the ReadMemberOf function
|
||||
type ReadMemberOfArgs struct {
|
||||
// (required)
|
||||
MemberId *string
|
||||
// (required)
|
||||
ContainerId *string
|
||||
// (optional)
|
||||
QueryMembership *QueryMembership
|
||||
}
|
||||
|
||||
// [Preview API]
|
||||
func (client *ClientImpl) ReadMembers(ctx context.Context, args ReadMembersArgs) (*[]string, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.ContainerId == nil || *args.ContainerId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ContainerId"}
|
||||
}
|
||||
routeValues["containerId"] = *args.ContainerId
|
||||
|
||||
queryParams := url.Values{}
|
||||
if args.QueryMembership != nil {
|
||||
queryParams.Add("queryMembership", string(*args.QueryMembership))
|
||||
}
|
||||
locationId, _ := uuid.Parse("8ba35978-138e-41f8-8963-7b1ea2c5f775")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1-preview.1", routeValues, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue []string
|
||||
err = client.Client.UnmarshalCollectionBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the ReadMembers function
|
||||
type ReadMembersArgs struct {
|
||||
// (required)
|
||||
ContainerId *string
|
||||
// (optional)
|
||||
QueryMembership *QueryMembership
|
||||
}
|
||||
|
||||
// [Preview API]
|
||||
func (client *ClientImpl) ReadMembersOf(ctx context.Context, args ReadMembersOfArgs) (*[]string, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.MemberId == nil || *args.MemberId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.MemberId"}
|
||||
}
|
||||
routeValues["memberId"] = *args.MemberId
|
||||
|
||||
queryParams := url.Values{}
|
||||
if args.QueryMembership != nil {
|
||||
queryParams.Add("queryMembership", string(*args.QueryMembership))
|
||||
}
|
||||
locationId, _ := uuid.Parse("22865b02-9e4a-479e-9e18-e35b8803b8a0")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1-preview.1", routeValues, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue []string
|
||||
err = client.Client.UnmarshalCollectionBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the ReadMembersOf function
|
||||
type ReadMembersOfArgs struct {
|
||||
// (required)
|
||||
MemberId *string
|
||||
// (optional)
|
||||
QueryMembership *QueryMembership
|
||||
}
|
||||
|
||||
// [Preview API]
|
||||
func (client *ClientImpl) RemoveMember(ctx context.Context, args RemoveMemberArgs) (*bool, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.ContainerId == nil || *args.ContainerId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ContainerId"}
|
||||
}
|
||||
routeValues["containerId"] = *args.ContainerId
|
||||
if args.MemberId == nil || *args.MemberId == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.MemberId"}
|
||||
}
|
||||
routeValues["memberId"] = *args.MemberId
|
||||
|
||||
locationId, _ := uuid.Parse("8ba35978-138e-41f8-8963-7b1ea2c5f775")
|
||||
resp, err := client.Client.Send(ctx, http.MethodDelete, locationId, "5.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue bool
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the RemoveMember function
|
||||
type RemoveMemberArgs struct {
|
||||
// (required)
|
||||
ContainerId *string
|
||||
// (required)
|
||||
MemberId *string
|
||||
}
|
||||
|
||||
func (client *ClientImpl) UpdateIdentities(ctx context.Context, args UpdateIdentitiesArgs) (*[]IdentityUpdateData, error) {
|
||||
if args.Identities == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.Identities"}
|
||||
}
|
||||
body, marshalErr := json.Marshal(*args.Identities)
|
||||
if marshalErr != nil {
|
||||
return nil, marshalErr
|
||||
}
|
||||
locationId, _ := uuid.Parse("28010c54-d0c0-4c89-a5b0-1c9e188b9fb7")
|
||||
resp, err := client.Client.Send(ctx, http.MethodPut, locationId, "5.1", nil, nil, bytes.NewReader(body), "application/json", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue []IdentityUpdateData
|
||||
err = client.Client.UnmarshalCollectionBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the UpdateIdentities function
|
||||
type UpdateIdentitiesArgs struct {
|
||||
// (required)
|
||||
Identities *azuredevops.VssJsonCollectionWrapper
|
||||
}
|
||||
|
||||
func (client *ClientImpl) UpdateIdentity(ctx context.Context, args UpdateIdentityArgs) error {
|
||||
if args.Identity == nil {
|
||||
return &azuredevops.ArgumentNilError{ArgumentName: "args.Identity"}
|
||||
}
|
||||
routeValues := make(map[string]string)
|
||||
if args.IdentityId == nil {
|
||||
return &azuredevops.ArgumentNilError{ArgumentName: "args.IdentityId"}
|
||||
}
|
||||
routeValues["identityId"] = (*args.IdentityId).String()
|
||||
|
||||
body, marshalErr := json.Marshal(*args.Identity)
|
||||
if marshalErr != nil {
|
||||
return marshalErr
|
||||
}
|
||||
locationId, _ := uuid.Parse("28010c54-d0c0-4c89-a5b0-1c9e188b9fb7")
|
||||
_, err := client.Client.Send(ctx, http.MethodPut, locationId, "5.1", routeValues, nil, bytes.NewReader(body), "application/json", "application/json", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Arguments for the UpdateIdentity function
|
||||
type UpdateIdentityArgs struct {
|
||||
// (required)
|
||||
Identity *Identity
|
||||
// (required)
|
||||
IdentityId *uuid.UUID
|
||||
}
|
||||
|
||||
// [Preview API]
|
||||
func (client *ClientImpl) UpdateScope(ctx context.Context, args UpdateScopeArgs) error {
|
||||
if args.PatchDocument == nil {
|
||||
return &azuredevops.ArgumentNilError{ArgumentName: "args.PatchDocument"}
|
||||
}
|
||||
routeValues := make(map[string]string)
|
||||
if args.ScopeId == nil {
|
||||
return &azuredevops.ArgumentNilError{ArgumentName: "args.ScopeId"}
|
||||
}
|
||||
routeValues["scopeId"] = (*args.ScopeId).String()
|
||||
|
||||
body, marshalErr := json.Marshal(*args.PatchDocument)
|
||||
if marshalErr != nil {
|
||||
return marshalErr
|
||||
}
|
||||
locationId, _ := uuid.Parse("4e11e2bf-1e79-4eb5-8f34-a6337bd0de38")
|
||||
_, err := client.Client.Send(ctx, http.MethodPatch, locationId, "5.1-preview.2", routeValues, nil, bytes.NewReader(body), "application/json-patch+json", "application/json", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Arguments for the UpdateScope function
|
||||
type UpdateScopeArgs struct {
|
||||
// (required)
|
||||
PatchDocument *[]webapi.JsonPatchOperation
|
||||
// (required)
|
||||
ScopeId *uuid.UUID
|
||||
}
|
234
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/identity/models.go
generated
vendored
234
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/identity/models.go
generated
vendored
@ -1,234 +0,0 @@
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Generated file, DO NOT EDIT
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
package identity
|
||||
|
||||
import (
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// Container class for changed identities
|
||||
type ChangedIdentities struct {
|
||||
// Changed Identities
|
||||
Identities *[]Identity `json:"identities,omitempty"`
|
||||
// More data available, set to true if pagesize is specified.
|
||||
MoreData *bool `json:"moreData,omitempty"`
|
||||
// Last Identity SequenceId
|
||||
SequenceContext *ChangedIdentitiesContext `json:"sequenceContext,omitempty"`
|
||||
}
|
||||
|
||||
// Context class for changed identities
|
||||
type ChangedIdentitiesContext struct {
|
||||
// Last Group SequenceId
|
||||
GroupSequenceId *int `json:"groupSequenceId,omitempty"`
|
||||
// Last Identity SequenceId
|
||||
IdentitySequenceId *int `json:"identitySequenceId,omitempty"`
|
||||
// Last Group OrganizationIdentitySequenceId
|
||||
OrganizationIdentitySequenceId *int `json:"organizationIdentitySequenceId,omitempty"`
|
||||
// Page size
|
||||
PageSize *int `json:"pageSize,omitempty"`
|
||||
}
|
||||
|
||||
type CreateScopeInfo struct {
|
||||
AdminGroupDescription *string `json:"adminGroupDescription,omitempty"`
|
||||
AdminGroupName *string `json:"adminGroupName,omitempty"`
|
||||
CreatorId *uuid.UUID `json:"creatorId,omitempty"`
|
||||
ParentScopeId *uuid.UUID `json:"parentScopeId,omitempty"`
|
||||
ScopeName *string `json:"scopeName,omitempty"`
|
||||
ScopeType *GroupScopeType `json:"scopeType,omitempty"`
|
||||
}
|
||||
|
||||
type FrameworkIdentityInfo struct {
|
||||
DisplayName *string `json:"displayName,omitempty"`
|
||||
Identifier *string `json:"identifier,omitempty"`
|
||||
IdentityType *FrameworkIdentityType `json:"identityType,omitempty"`
|
||||
Role *string `json:"role,omitempty"`
|
||||
}
|
||||
|
||||
type FrameworkIdentityType string
|
||||
|
||||
type frameworkIdentityTypeValuesType struct {
|
||||
None FrameworkIdentityType
|
||||
ServiceIdentity FrameworkIdentityType
|
||||
AggregateIdentity FrameworkIdentityType
|
||||
ImportedIdentity FrameworkIdentityType
|
||||
}
|
||||
|
||||
var FrameworkIdentityTypeValues = frameworkIdentityTypeValuesType{
|
||||
None: "none",
|
||||
ServiceIdentity: "serviceIdentity",
|
||||
AggregateIdentity: "aggregateIdentity",
|
||||
ImportedIdentity: "importedIdentity",
|
||||
}
|
||||
|
||||
type GroupMembership struct {
|
||||
Active *bool `json:"active,omitempty"`
|
||||
Descriptor *string `json:"descriptor,omitempty"`
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
QueriedId *uuid.UUID `json:"queriedId,omitempty"`
|
||||
}
|
||||
|
||||
type GroupScopeType string
|
||||
|
||||
type groupScopeTypeValuesType struct {
|
||||
Generic GroupScopeType
|
||||
ServiceHost GroupScopeType
|
||||
TeamProject GroupScopeType
|
||||
}
|
||||
|
||||
var GroupScopeTypeValues = groupScopeTypeValuesType{
|
||||
Generic: "generic",
|
||||
ServiceHost: "serviceHost",
|
||||
TeamProject: "teamProject",
|
||||
}
|
||||
|
||||
type Identity struct {
|
||||
// The custom display name for the identity (if any). Setting this property to an empty string will clear the existing custom display name. Setting this property to null will not affect the existing persisted value (since null values do not get sent over the wire or to the database)
|
||||
CustomDisplayName *string `json:"customDisplayName,omitempty"`
|
||||
Descriptor *string `json:"descriptor,omitempty"`
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
IsActive *bool `json:"isActive,omitempty"`
|
||||
IsContainer *bool `json:"isContainer,omitempty"`
|
||||
MasterId *uuid.UUID `json:"masterId,omitempty"`
|
||||
MemberIds *[]uuid.UUID `json:"memberIds,omitempty"`
|
||||
MemberOf *[]string `json:"memberOf,omitempty"`
|
||||
Members *[]string `json:"members,omitempty"`
|
||||
MetaTypeId *int `json:"metaTypeId,omitempty"`
|
||||
Properties interface{} `json:"properties,omitempty"`
|
||||
// The display name for the identity as specified by the source identity provider.
|
||||
ProviderDisplayName *string `json:"providerDisplayName,omitempty"`
|
||||
ResourceVersion *int `json:"resourceVersion,omitempty"`
|
||||
SocialDescriptor *string `json:"socialDescriptor,omitempty"`
|
||||
SubjectDescriptor *string `json:"subjectDescriptor,omitempty"`
|
||||
UniqueUserId *int `json:"uniqueUserId,omitempty"`
|
||||
}
|
||||
|
||||
// Base Identity class to allow "trimmed" identity class in the GetConnectionData API Makes sure that on-the-wire representations of the derived classes are compatible with each other (e.g. Server responds with PublicIdentity object while client deserializes it as Identity object) Derived classes should not have additional [DataMember] properties
|
||||
type IdentityBase struct {
|
||||
// The custom display name for the identity (if any). Setting this property to an empty string will clear the existing custom display name. Setting this property to null will not affect the existing persisted value (since null values do not get sent over the wire or to the database)
|
||||
CustomDisplayName *string `json:"customDisplayName,omitempty"`
|
||||
Descriptor *string `json:"descriptor,omitempty"`
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
IsActive *bool `json:"isActive,omitempty"`
|
||||
IsContainer *bool `json:"isContainer,omitempty"`
|
||||
MasterId *uuid.UUID `json:"masterId,omitempty"`
|
||||
MemberIds *[]uuid.UUID `json:"memberIds,omitempty"`
|
||||
MemberOf *[]string `json:"memberOf,omitempty"`
|
||||
Members *[]string `json:"members,omitempty"`
|
||||
MetaTypeId *int `json:"metaTypeId,omitempty"`
|
||||
Properties interface{} `json:"properties,omitempty"`
|
||||
// The display name for the identity as specified by the source identity provider.
|
||||
ProviderDisplayName *string `json:"providerDisplayName,omitempty"`
|
||||
ResourceVersion *int `json:"resourceVersion,omitempty"`
|
||||
SocialDescriptor *string `json:"socialDescriptor,omitempty"`
|
||||
SubjectDescriptor *string `json:"subjectDescriptor,omitempty"`
|
||||
UniqueUserId *int `json:"uniqueUserId,omitempty"`
|
||||
}
|
||||
|
||||
type IdentityBatchInfo struct {
|
||||
Descriptors *[]string `json:"descriptors,omitempty"`
|
||||
IdentityIds *[]uuid.UUID `json:"identityIds,omitempty"`
|
||||
IncludeRestrictedVisibility *bool `json:"includeRestrictedVisibility,omitempty"`
|
||||
PropertyNames *[]string `json:"propertyNames,omitempty"`
|
||||
QueryMembership *QueryMembership `json:"queryMembership,omitempty"`
|
||||
SocialDescriptors *[]string `json:"socialDescriptors,omitempty"`
|
||||
SubjectDescriptors *[]string `json:"subjectDescriptors,omitempty"`
|
||||
}
|
||||
|
||||
type IdentityScope struct {
|
||||
Administrators *string `json:"administrators,omitempty"`
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
IsActive *bool `json:"isActive,omitempty"`
|
||||
IsGlobal *bool `json:"isGlobal,omitempty"`
|
||||
LocalScopeId *uuid.UUID `json:"localScopeId,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
ParentId *uuid.UUID `json:"parentId,omitempty"`
|
||||
ScopeType *GroupScopeType `json:"scopeType,omitempty"`
|
||||
SecuringHostId *uuid.UUID `json:"securingHostId,omitempty"`
|
||||
SubjectDescriptor *string `json:"subjectDescriptor,omitempty"`
|
||||
}
|
||||
|
||||
// Identity information.
|
||||
type IdentitySelf struct {
|
||||
// The UserPrincipalName (UPN) of the account. This value comes from the source provider.
|
||||
AccountName *string `json:"accountName,omitempty"`
|
||||
// The display name. For AAD accounts with multiple tenants this is the display name of the profile in the home tenant.
|
||||
DisplayName *string `json:"displayName,omitempty"`
|
||||
// This represents the name of the container of origin. For AAD accounts this is the tenantID of the home tenant. For MSA accounts this is the string "Windows Live ID".
|
||||
Domain *string `json:"domain,omitempty"`
|
||||
// This is the VSID of the home tenant profile. If the profile is signed into the home tenant or if the profile has no tenants then this Id is the same as the Id returned by the profile/profiles/me endpoint. Going forward it is recommended that you use the combined values of Origin, OriginId and Domain to uniquely identify a user rather than this Id.
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
// The type of source provider for the origin identifier. For MSA accounts this is "msa". For AAD accounts this is "aad".
|
||||
Origin *string `json:"origin,omitempty"`
|
||||
// The unique identifier from the system of origin. If there are multiple tenants this is the unique identifier of the account in the home tenant. (For MSA this is the PUID in hex notation, for AAD this is the object id.)
|
||||
OriginId *string `json:"originId,omitempty"`
|
||||
// For AAD accounts this is all of the tenants that this account is a member of.
|
||||
Tenants *[]TenantInfo `json:"tenants,omitempty"`
|
||||
}
|
||||
|
||||
type IdentitySnapshot struct {
|
||||
Groups *[]Identity `json:"groups,omitempty"`
|
||||
IdentityIds *[]uuid.UUID `json:"identityIds,omitempty"`
|
||||
Memberships *[]GroupMembership `json:"memberships,omitempty"`
|
||||
ScopeId *uuid.UUID `json:"scopeId,omitempty"`
|
||||
Scopes *[]IdentityScope `json:"scopes,omitempty"`
|
||||
}
|
||||
|
||||
type IdentityUpdateData struct {
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
Index *int `json:"index,omitempty"`
|
||||
Updated *bool `json:"updated,omitempty"`
|
||||
}
|
||||
|
||||
type QueryMembership string
|
||||
|
||||
type queryMembershipValuesType struct {
|
||||
None QueryMembership
|
||||
Direct QueryMembership
|
||||
Expanded QueryMembership
|
||||
ExpandedUp QueryMembership
|
||||
ExpandedDown QueryMembership
|
||||
}
|
||||
|
||||
var QueryMembershipValues = queryMembershipValuesType{
|
||||
// Query will not return any membership data
|
||||
None: "none",
|
||||
// Query will return only direct membership data
|
||||
Direct: "direct",
|
||||
// Query will return expanded membership data
|
||||
Expanded: "expanded",
|
||||
// Query will return expanded up membership data (parents only)
|
||||
ExpandedUp: "expandedUp",
|
||||
// Query will return expanded down membership data (children only)
|
||||
ExpandedDown: "expandedDown",
|
||||
}
|
||||
|
||||
// [Flags]
|
||||
type ReadIdentitiesOptions string
|
||||
|
||||
type readIdentitiesOptionsValuesType struct {
|
||||
None ReadIdentitiesOptions
|
||||
FilterIllegalMemberships ReadIdentitiesOptions
|
||||
}
|
||||
|
||||
var ReadIdentitiesOptionsValues = readIdentitiesOptionsValuesType{
|
||||
None: "none",
|
||||
FilterIllegalMemberships: "filterIllegalMemberships",
|
||||
}
|
||||
|
||||
type SwapIdentityInfo struct {
|
||||
Id1 *uuid.UUID `json:"id1,omitempty"`
|
||||
Id2 *uuid.UUID `json:"id2,omitempty"`
|
||||
}
|
||||
|
||||
type TenantInfo struct {
|
||||
HomeTenant *bool `json:"homeTenant,omitempty"`
|
||||
TenantId *uuid.UUID `json:"tenantId,omitempty"`
|
||||
TenantName *string `json:"tenantName,omitempty"`
|
||||
VerifiedDomains *[]string `json:"verifiedDomains,omitempty"`
|
||||
}
|
130
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/models.go
generated
vendored
130
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/models.go
generated
vendored
@ -1,130 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package azuredevops
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/google/uuid"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ApiResourceLocation Information about the location of a REST API resource
|
||||
type ApiResourceLocation struct {
|
||||
// Area name for this resource
|
||||
Area *string `json:"area,omitempty"`
|
||||
// Unique Identifier for this location
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
// Maximum api version that this resource supports (current server version for this resource)
|
||||
MaxVersion *string `json:"maxVersion,omitempty"`
|
||||
// Minimum api version that this resource supports
|
||||
MinVersion *string `json:"minVersion,omitempty"`
|
||||
// The latest version of this resource location that is in "Release" (non-preview) mode
|
||||
ReleasedVersion *string `json:"releasedVersion,omitempty"`
|
||||
// Resource name
|
||||
ResourceName *string `json:"resourceName,omitempty"`
|
||||
// The current resource version supported by this resource location
|
||||
ResourceVersion *int `json:"resourceVersion,omitempty"`
|
||||
// This location's route template (templated relative path)
|
||||
RouteTemplate *string `json:"routeTemplate,omitempty"`
|
||||
}
|
||||
|
||||
// WrappedImproperError
|
||||
type WrappedImproperError struct {
|
||||
Count *int `json:"count,omitEmpty"`
|
||||
Value *ImproperError `json:"value,omitEmpty"`
|
||||
}
|
||||
|
||||
// ImproperError
|
||||
type ImproperError struct {
|
||||
Message *string `json:"Message,omitEmpty"`
|
||||
}
|
||||
|
||||
// KeyValuePair
|
||||
type KeyValuePair struct {
|
||||
Key *interface{} `json:"key,omitEmpty"`
|
||||
Value *interface{} `json:"value,omitEmpty"`
|
||||
}
|
||||
|
||||
// ResourceAreaInfo
|
||||
type ResourceAreaInfo struct {
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
LocationUrl *string `json:"locationUrl,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
type Time struct {
|
||||
Time time.Time
|
||||
}
|
||||
|
||||
func (t *Time) UnmarshalJSON(b []byte) error {
|
||||
t2 := time.Time{}
|
||||
err := json.Unmarshal(b, &t2)
|
||||
|
||||
// ignore errors for 0001-01-01T00:00:00 dates. The Azure DevOps service
|
||||
// returns default dates in a format that is invalid for a time.Time. The
|
||||
// correct value would have a 'z' at the end to represent utc. We are going
|
||||
// to ignore this error, and set the value to the default time.Time value.
|
||||
// https://github.com/microsoft/azure-devops-go-api/issues/17
|
||||
if err != nil {
|
||||
if parseError, ok := err.(*time.ParseError); ok && parseError.Value == "\"0001-01-01T00:00:00\"" {
|
||||
err = nil
|
||||
}
|
||||
}
|
||||
|
||||
t.Time = t2
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *Time) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(t.Time)
|
||||
}
|
||||
|
||||
func (t Time) String() string {
|
||||
return t.Time.String()
|
||||
}
|
||||
|
||||
func (t Time) Equal(u Time) bool {
|
||||
return t.Time.Equal(u.Time)
|
||||
}
|
||||
|
||||
// ServerSystemError
|
||||
type ServerSystemError struct {
|
||||
ClassName *string `json:"className,omitempty"`
|
||||
InnerException *ServerSystemError `json:"innerException,omitempty"`
|
||||
Message *string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
func (e ServerSystemError) Error() string {
|
||||
return *e.Message
|
||||
}
|
||||
|
||||
// VssJsonCollectionWrapper -
|
||||
type VssJsonCollectionWrapper struct {
|
||||
Count *int `json:"count"`
|
||||
Value *[]interface{} `json:"value"`
|
||||
}
|
||||
|
||||
// WrappedError
|
||||
type WrappedError struct {
|
||||
ExceptionId *string `json:"$id,omitempty"`
|
||||
InnerError *WrappedError `json:"innerException,omitempty"`
|
||||
Message *string `json:"message,omitempty"`
|
||||
TypeName *string `json:"typeName,omitempty"`
|
||||
TypeKey *string `json:"typeKey,omitempty"`
|
||||
ErrorCode *int `json:"errorCode,omitempty"`
|
||||
EventId *int `json:"eventId,omitempty"`
|
||||
CustomProperties *map[string]interface{} `json:"customProperties,omitempty"`
|
||||
StatusCode *int
|
||||
}
|
||||
|
||||
func (e WrappedError) Error() string {
|
||||
if e.Message == nil {
|
||||
if e.StatusCode != nil {
|
||||
return "REST call returned status code " + strconv.Itoa(*e.StatusCode)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
return *e.Message
|
||||
}
|
64
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/operations/client.go
generated
vendored
64
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/operations/client.go
generated
vendored
@ -1,64 +0,0 @@
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Generated file, DO NOT EDIT
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
package operations
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/google/uuid"
|
||||
"github.com/microsoft/azure-devops-go-api/azuredevops"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
type Client interface {
|
||||
// Gets an operation from the the operationId using the given pluginId.
|
||||
GetOperation(context.Context, GetOperationArgs) (*Operation, error)
|
||||
}
|
||||
|
||||
type ClientImpl struct {
|
||||
Client azuredevops.Client
|
||||
}
|
||||
|
||||
func NewClient(ctx context.Context, connection *azuredevops.Connection) Client {
|
||||
client := connection.GetClientByUrl(connection.BaseUrl)
|
||||
return &ClientImpl{
|
||||
Client: *client,
|
||||
}
|
||||
}
|
||||
|
||||
// Gets an operation from the the operationId using the given pluginId.
|
||||
func (client *ClientImpl) GetOperation(ctx context.Context, args GetOperationArgs) (*Operation, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.OperationId == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.OperationId"}
|
||||
}
|
||||
routeValues["operationId"] = (*args.OperationId).String()
|
||||
|
||||
queryParams := url.Values{}
|
||||
if args.PluginId != nil {
|
||||
queryParams.Add("pluginId", (*args.PluginId).String())
|
||||
}
|
||||
locationId, _ := uuid.Parse("9a1b74b4-2ca8-4a9f-8470-c2f2e6fdc949")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1", routeValues, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue Operation
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetOperation function
|
||||
type GetOperationArgs struct {
|
||||
// (required) The ID for the operation.
|
||||
OperationId *uuid.UUID
|
||||
// (optional) The ID for the plugin.
|
||||
PluginId *uuid.UUID
|
||||
}
|
77
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/operations/models.go
generated
vendored
77
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/operations/models.go
generated
vendored
@ -1,77 +0,0 @@
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Generated file, DO NOT EDIT
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
package operations
|
||||
|
||||
import (
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// Contains information about the progress or result of an async operation.
|
||||
type Operation struct {
|
||||
// Unique identifier for the operation.
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
// Unique identifier for the plugin.
|
||||
PluginId *uuid.UUID `json:"pluginId,omitempty"`
|
||||
// The current status of the operation.
|
||||
Status *OperationStatus `json:"status,omitempty"`
|
||||
// URL to get the full operation object.
|
||||
Url *string `json:"url,omitempty"`
|
||||
// Links to other related objects.
|
||||
Links interface{} `json:"_links,omitempty"`
|
||||
// Detailed messaged about the status of an operation.
|
||||
DetailedMessage *string `json:"detailedMessage,omitempty"`
|
||||
// Result message for an operation.
|
||||
ResultMessage *string `json:"resultMessage,omitempty"`
|
||||
// URL to the operation result.
|
||||
ResultUrl *OperationResultReference `json:"resultUrl,omitempty"`
|
||||
}
|
||||
|
||||
// Reference for an async operation.
|
||||
type OperationReference struct {
|
||||
// Unique identifier for the operation.
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
// Unique identifier for the plugin.
|
||||
PluginId *uuid.UUID `json:"pluginId,omitempty"`
|
||||
// The current status of the operation.
|
||||
Status *OperationStatus `json:"status,omitempty"`
|
||||
// URL to get the full operation object.
|
||||
Url *string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
type OperationResultReference struct {
|
||||
// URL to the operation result.
|
||||
ResultUrl *string `json:"resultUrl,omitempty"`
|
||||
}
|
||||
|
||||
// The status of an operation.
|
||||
type OperationStatus string
|
||||
|
||||
type operationStatusValuesType struct {
|
||||
NotSet OperationStatus
|
||||
Queued OperationStatus
|
||||
InProgress OperationStatus
|
||||
Cancelled OperationStatus
|
||||
Succeeded OperationStatus
|
||||
Failed OperationStatus
|
||||
}
|
||||
|
||||
var OperationStatusValues = operationStatusValuesType{
|
||||
// The operation does not have a status set.
|
||||
NotSet: "notSet",
|
||||
// The operation has been queued.
|
||||
Queued: "queued",
|
||||
// The operation is in progress.
|
||||
InProgress: "inProgress",
|
||||
// The operation was cancelled by the user.
|
||||
Cancelled: "cancelled",
|
||||
// The operation completed successfully.
|
||||
Succeeded: "succeeded",
|
||||
// The operation completed with a failure.
|
||||
Failed: "failed",
|
||||
}
|
500
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/policy/client.go
generated
vendored
500
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/policy/client.go
generated
vendored
@ -1,500 +0,0 @@
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Generated file, DO NOT EDIT
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
package policy
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/google/uuid"
|
||||
"github.com/microsoft/azure-devops-go-api/azuredevops"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
var ResourceAreaId, _ = uuid.Parse("fb13a388-40dd-4a04-b530-013a739c72ef")
|
||||
|
||||
type Client interface {
|
||||
// Create a policy configuration of a given policy type.
|
||||
CreatePolicyConfiguration(context.Context, CreatePolicyConfigurationArgs) (*PolicyConfiguration, error)
|
||||
// Delete a policy configuration by its ID.
|
||||
DeletePolicyConfiguration(context.Context, DeletePolicyConfigurationArgs) error
|
||||
// Get a policy configuration by its ID.
|
||||
GetPolicyConfiguration(context.Context, GetPolicyConfigurationArgs) (*PolicyConfiguration, error)
|
||||
// Retrieve a specific revision of a given policy by ID.
|
||||
GetPolicyConfigurationRevision(context.Context, GetPolicyConfigurationRevisionArgs) (*PolicyConfiguration, error)
|
||||
// Retrieve all revisions for a given policy.
|
||||
GetPolicyConfigurationRevisions(context.Context, GetPolicyConfigurationRevisionsArgs) (*[]PolicyConfiguration, error)
|
||||
// Get a list of policy configurations in a project.
|
||||
GetPolicyConfigurations(context.Context, GetPolicyConfigurationsArgs) (*GetPolicyConfigurationsResponseValue, error)
|
||||
// [Preview API] Gets the present evaluation state of a policy.
|
||||
GetPolicyEvaluation(context.Context, GetPolicyEvaluationArgs) (*PolicyEvaluationRecord, error)
|
||||
// [Preview API] Retrieves a list of all the policy evaluation statuses for a specific pull request.
|
||||
GetPolicyEvaluations(context.Context, GetPolicyEvaluationsArgs) (*[]PolicyEvaluationRecord, error)
|
||||
// Retrieve a specific policy type by ID.
|
||||
GetPolicyType(context.Context, GetPolicyTypeArgs) (*PolicyType, error)
|
||||
// Retrieve all available policy types.
|
||||
GetPolicyTypes(context.Context, GetPolicyTypesArgs) (*[]PolicyType, error)
|
||||
// [Preview API] Requeue the policy evaluation.
|
||||
RequeuePolicyEvaluation(context.Context, RequeuePolicyEvaluationArgs) (*PolicyEvaluationRecord, error)
|
||||
// Update a policy configuration by its ID.
|
||||
UpdatePolicyConfiguration(context.Context, UpdatePolicyConfigurationArgs) (*PolicyConfiguration, error)
|
||||
}
|
||||
|
||||
type ClientImpl struct {
|
||||
Client azuredevops.Client
|
||||
}
|
||||
|
||||
func NewClient(ctx context.Context, connection *azuredevops.Connection) (Client, error) {
|
||||
client, err := connection.GetClientByResourceAreaId(ctx, ResourceAreaId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ClientImpl{
|
||||
Client: *client,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Create a policy configuration of a given policy type.
|
||||
func (client *ClientImpl) CreatePolicyConfiguration(ctx context.Context, args CreatePolicyConfigurationArgs) (*PolicyConfiguration, error) {
|
||||
if args.Configuration == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.Configuration"}
|
||||
}
|
||||
routeValues := make(map[string]string)
|
||||
if args.Project == nil || *args.Project == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.Project"}
|
||||
}
|
||||
routeValues["project"] = *args.Project
|
||||
if args.ConfigurationId != nil {
|
||||
routeValues["configurationId"] = strconv.Itoa(*args.ConfigurationId)
|
||||
}
|
||||
|
||||
body, marshalErr := json.Marshal(*args.Configuration)
|
||||
if marshalErr != nil {
|
||||
return nil, marshalErr
|
||||
}
|
||||
locationId, _ := uuid.Parse("dad91cbe-d183-45f8-9c6e-9c1164472121")
|
||||
resp, err := client.Client.Send(ctx, http.MethodPost, locationId, "5.1", routeValues, nil, bytes.NewReader(body), "application/json", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue PolicyConfiguration
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the CreatePolicyConfiguration function
|
||||
type CreatePolicyConfigurationArgs struct {
|
||||
// (required) The policy configuration to create.
|
||||
Configuration *PolicyConfiguration
|
||||
// (required) Project ID or project name
|
||||
Project *string
|
||||
// (optional)
|
||||
ConfigurationId *int
|
||||
}
|
||||
|
||||
// Delete a policy configuration by its ID.
|
||||
func (client *ClientImpl) DeletePolicyConfiguration(ctx context.Context, args DeletePolicyConfigurationArgs) error {
|
||||
routeValues := make(map[string]string)
|
||||
if args.Project == nil || *args.Project == "" {
|
||||
return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.Project"}
|
||||
}
|
||||
routeValues["project"] = *args.Project
|
||||
if args.ConfigurationId == nil {
|
||||
return &azuredevops.ArgumentNilError{ArgumentName: "args.ConfigurationId"}
|
||||
}
|
||||
routeValues["configurationId"] = strconv.Itoa(*args.ConfigurationId)
|
||||
|
||||
locationId, _ := uuid.Parse("dad91cbe-d183-45f8-9c6e-9c1164472121")
|
||||
_, err := client.Client.Send(ctx, http.MethodDelete, locationId, "5.1", routeValues, nil, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Arguments for the DeletePolicyConfiguration function
|
||||
type DeletePolicyConfigurationArgs struct {
|
||||
// (required) Project ID or project name
|
||||
Project *string
|
||||
// (required) ID of the policy configuration to delete.
|
||||
ConfigurationId *int
|
||||
}
|
||||
|
||||
// Get a policy configuration by its ID.
|
||||
func (client *ClientImpl) GetPolicyConfiguration(ctx context.Context, args GetPolicyConfigurationArgs) (*PolicyConfiguration, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.Project == nil || *args.Project == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.Project"}
|
||||
}
|
||||
routeValues["project"] = *args.Project
|
||||
if args.ConfigurationId == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.ConfigurationId"}
|
||||
}
|
||||
routeValues["configurationId"] = strconv.Itoa(*args.ConfigurationId)
|
||||
|
||||
locationId, _ := uuid.Parse("dad91cbe-d183-45f8-9c6e-9c1164472121")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1", routeValues, nil, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue PolicyConfiguration
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetPolicyConfiguration function
|
||||
type GetPolicyConfigurationArgs struct {
|
||||
// (required) Project ID or project name
|
||||
Project *string
|
||||
// (required) ID of the policy configuration
|
||||
ConfigurationId *int
|
||||
}
|
||||
|
||||
// Retrieve a specific revision of a given policy by ID.
|
||||
func (client *ClientImpl) GetPolicyConfigurationRevision(ctx context.Context, args GetPolicyConfigurationRevisionArgs) (*PolicyConfiguration, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.Project == nil || *args.Project == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.Project"}
|
||||
}
|
||||
routeValues["project"] = *args.Project
|
||||
if args.ConfigurationId == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.ConfigurationId"}
|
||||
}
|
||||
routeValues["configurationId"] = strconv.Itoa(*args.ConfigurationId)
|
||||
if args.RevisionId == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.RevisionId"}
|
||||
}
|
||||
routeValues["revisionId"] = strconv.Itoa(*args.RevisionId)
|
||||
|
||||
locationId, _ := uuid.Parse("fe1e68a2-60d3-43cb-855b-85e41ae97c95")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1", routeValues, nil, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue PolicyConfiguration
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetPolicyConfigurationRevision function
|
||||
type GetPolicyConfigurationRevisionArgs struct {
|
||||
// (required) Project ID or project name
|
||||
Project *string
|
||||
// (required) The policy configuration ID.
|
||||
ConfigurationId *int
|
||||
// (required) The revision ID.
|
||||
RevisionId *int
|
||||
}
|
||||
|
||||
// Retrieve all revisions for a given policy.
|
||||
func (client *ClientImpl) GetPolicyConfigurationRevisions(ctx context.Context, args GetPolicyConfigurationRevisionsArgs) (*[]PolicyConfiguration, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.Project == nil || *args.Project == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.Project"}
|
||||
}
|
||||
routeValues["project"] = *args.Project
|
||||
if args.ConfigurationId == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.ConfigurationId"}
|
||||
}
|
||||
routeValues["configurationId"] = strconv.Itoa(*args.ConfigurationId)
|
||||
|
||||
queryParams := url.Values{}
|
||||
if args.Top != nil {
|
||||
queryParams.Add("$top", strconv.Itoa(*args.Top))
|
||||
}
|
||||
if args.Skip != nil {
|
||||
queryParams.Add("$skip", strconv.Itoa(*args.Skip))
|
||||
}
|
||||
locationId, _ := uuid.Parse("fe1e68a2-60d3-43cb-855b-85e41ae97c95")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1", routeValues, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue []PolicyConfiguration
|
||||
err = client.Client.UnmarshalCollectionBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetPolicyConfigurationRevisions function
|
||||
type GetPolicyConfigurationRevisionsArgs struct {
|
||||
// (required) Project ID or project name
|
||||
Project *string
|
||||
// (required) The policy configuration ID.
|
||||
ConfigurationId *int
|
||||
// (optional) The number of revisions to retrieve.
|
||||
Top *int
|
||||
// (optional) The number of revisions to ignore. For example, to retrieve results 101-150, set top to 50 and skip to 100.
|
||||
Skip *int
|
||||
}
|
||||
|
||||
// Get a list of policy configurations in a project.
|
||||
func (client *ClientImpl) GetPolicyConfigurations(ctx context.Context, args GetPolicyConfigurationsArgs) (*GetPolicyConfigurationsResponseValue, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.Project == nil || *args.Project == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.Project"}
|
||||
}
|
||||
routeValues["project"] = *args.Project
|
||||
|
||||
queryParams := url.Values{}
|
||||
if args.Scope != nil {
|
||||
queryParams.Add("scope", *args.Scope)
|
||||
}
|
||||
if args.Top != nil {
|
||||
queryParams.Add("$top", strconv.Itoa(*args.Top))
|
||||
}
|
||||
if args.ContinuationToken != nil {
|
||||
queryParams.Add("continuationToken", *args.ContinuationToken)
|
||||
}
|
||||
if args.PolicyType != nil {
|
||||
queryParams.Add("policyType", (*args.PolicyType).String())
|
||||
}
|
||||
locationId, _ := uuid.Parse("dad91cbe-d183-45f8-9c6e-9c1164472121")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1", routeValues, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue GetPolicyConfigurationsResponseValue
|
||||
responseValue.ContinuationToken = resp.Header.Get(azuredevops.HeaderKeyContinuationToken)
|
||||
err = client.Client.UnmarshalCollectionBody(resp, &responseValue.Value)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetPolicyConfigurations function
|
||||
type GetPolicyConfigurationsArgs struct {
|
||||
// (required) Project ID or project name
|
||||
Project *string
|
||||
// (optional) [Provided for legacy reasons] The scope on which a subset of policies is defined.
|
||||
Scope *string
|
||||
// (optional) Maximum number of policies to return.
|
||||
Top *int
|
||||
// (optional) The continuation token used for pagination.
|
||||
ContinuationToken *string
|
||||
// (optional) Filter returned policies to only this type
|
||||
PolicyType *uuid.UUID
|
||||
}
|
||||
|
||||
// Return type for the GetPolicyConfigurations function
|
||||
type GetPolicyConfigurationsResponseValue struct {
|
||||
Value []PolicyConfiguration
|
||||
// The continuation token to be used to get the next page of results.
|
||||
ContinuationToken string
|
||||
}
|
||||
|
||||
// [Preview API] Gets the present evaluation state of a policy.
|
||||
func (client *ClientImpl) GetPolicyEvaluation(ctx context.Context, args GetPolicyEvaluationArgs) (*PolicyEvaluationRecord, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.Project == nil || *args.Project == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.Project"}
|
||||
}
|
||||
routeValues["project"] = *args.Project
|
||||
if args.EvaluationId == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.EvaluationId"}
|
||||
}
|
||||
routeValues["evaluationId"] = (*args.EvaluationId).String()
|
||||
|
||||
locationId, _ := uuid.Parse("46aecb7a-5d2c-4647-897b-0209505a9fe4")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue PolicyEvaluationRecord
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetPolicyEvaluation function
|
||||
type GetPolicyEvaluationArgs struct {
|
||||
// (required) Project ID or project name
|
||||
Project *string
|
||||
// (required) ID of the policy evaluation to be retrieved.
|
||||
EvaluationId *uuid.UUID
|
||||
}
|
||||
|
||||
// [Preview API] Retrieves a list of all the policy evaluation statuses for a specific pull request.
|
||||
func (client *ClientImpl) GetPolicyEvaluations(ctx context.Context, args GetPolicyEvaluationsArgs) (*[]PolicyEvaluationRecord, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.Project == nil || *args.Project == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.Project"}
|
||||
}
|
||||
routeValues["project"] = *args.Project
|
||||
|
||||
queryParams := url.Values{}
|
||||
if args.ArtifactId == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "artifactId"}
|
||||
}
|
||||
queryParams.Add("artifactId", *args.ArtifactId)
|
||||
if args.IncludeNotApplicable != nil {
|
||||
queryParams.Add("includeNotApplicable", strconv.FormatBool(*args.IncludeNotApplicable))
|
||||
}
|
||||
if args.Top != nil {
|
||||
queryParams.Add("$top", strconv.Itoa(*args.Top))
|
||||
}
|
||||
if args.Skip != nil {
|
||||
queryParams.Add("$skip", strconv.Itoa(*args.Skip))
|
||||
}
|
||||
locationId, _ := uuid.Parse("c23ddff5-229c-4d04-a80b-0fdce9f360c8")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1-preview.1", routeValues, queryParams, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue []PolicyEvaluationRecord
|
||||
err = client.Client.UnmarshalCollectionBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetPolicyEvaluations function
|
||||
type GetPolicyEvaluationsArgs struct {
|
||||
// (required) Project ID or project name
|
||||
Project *string
|
||||
// (required) A string which uniquely identifies the target of a policy evaluation.
|
||||
ArtifactId *string
|
||||
// (optional) Some policies might determine that they do not apply to a specific pull request. Setting this parameter to true will return evaluation records even for policies which don't apply to this pull request.
|
||||
IncludeNotApplicable *bool
|
||||
// (optional) The number of policy evaluation records to retrieve.
|
||||
Top *int
|
||||
// (optional) The number of policy evaluation records to ignore. For example, to retrieve results 101-150, set top to 50 and skip to 100.
|
||||
Skip *int
|
||||
}
|
||||
|
||||
// Retrieve a specific policy type by ID.
|
||||
func (client *ClientImpl) GetPolicyType(ctx context.Context, args GetPolicyTypeArgs) (*PolicyType, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.Project == nil || *args.Project == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.Project"}
|
||||
}
|
||||
routeValues["project"] = *args.Project
|
||||
if args.TypeId == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.TypeId"}
|
||||
}
|
||||
routeValues["typeId"] = (*args.TypeId).String()
|
||||
|
||||
locationId, _ := uuid.Parse("44096322-2d3d-466a-bb30-d1b7de69f61f")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1", routeValues, nil, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue PolicyType
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetPolicyType function
|
||||
type GetPolicyTypeArgs struct {
|
||||
// (required) Project ID or project name
|
||||
Project *string
|
||||
// (required) The policy ID.
|
||||
TypeId *uuid.UUID
|
||||
}
|
||||
|
||||
// Retrieve all available policy types.
|
||||
func (client *ClientImpl) GetPolicyTypes(ctx context.Context, args GetPolicyTypesArgs) (*[]PolicyType, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.Project == nil || *args.Project == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.Project"}
|
||||
}
|
||||
routeValues["project"] = *args.Project
|
||||
|
||||
locationId, _ := uuid.Parse("44096322-2d3d-466a-bb30-d1b7de69f61f")
|
||||
resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "5.1", routeValues, nil, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue []PolicyType
|
||||
err = client.Client.UnmarshalCollectionBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the GetPolicyTypes function
|
||||
type GetPolicyTypesArgs struct {
|
||||
// (required) Project ID or project name
|
||||
Project *string
|
||||
}
|
||||
|
||||
// [Preview API] Requeue the policy evaluation.
|
||||
func (client *ClientImpl) RequeuePolicyEvaluation(ctx context.Context, args RequeuePolicyEvaluationArgs) (*PolicyEvaluationRecord, error) {
|
||||
routeValues := make(map[string]string)
|
||||
if args.Project == nil || *args.Project == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.Project"}
|
||||
}
|
||||
routeValues["project"] = *args.Project
|
||||
if args.EvaluationId == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.EvaluationId"}
|
||||
}
|
||||
routeValues["evaluationId"] = (*args.EvaluationId).String()
|
||||
|
||||
locationId, _ := uuid.Parse("46aecb7a-5d2c-4647-897b-0209505a9fe4")
|
||||
resp, err := client.Client.Send(ctx, http.MethodPatch, locationId, "5.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue PolicyEvaluationRecord
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the RequeuePolicyEvaluation function
|
||||
type RequeuePolicyEvaluationArgs struct {
|
||||
// (required) Project ID or project name
|
||||
Project *string
|
||||
// (required) ID of the policy evaluation to be retrieved.
|
||||
EvaluationId *uuid.UUID
|
||||
}
|
||||
|
||||
// Update a policy configuration by its ID.
|
||||
func (client *ClientImpl) UpdatePolicyConfiguration(ctx context.Context, args UpdatePolicyConfigurationArgs) (*PolicyConfiguration, error) {
|
||||
if args.Configuration == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.Configuration"}
|
||||
}
|
||||
routeValues := make(map[string]string)
|
||||
if args.Project == nil || *args.Project == "" {
|
||||
return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.Project"}
|
||||
}
|
||||
routeValues["project"] = *args.Project
|
||||
if args.ConfigurationId == nil {
|
||||
return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.ConfigurationId"}
|
||||
}
|
||||
routeValues["configurationId"] = strconv.Itoa(*args.ConfigurationId)
|
||||
|
||||
body, marshalErr := json.Marshal(*args.Configuration)
|
||||
if marshalErr != nil {
|
||||
return nil, marshalErr
|
||||
}
|
||||
locationId, _ := uuid.Parse("dad91cbe-d183-45f8-9c6e-9c1164472121")
|
||||
resp, err := client.Client.Send(ctx, http.MethodPut, locationId, "5.1", routeValues, nil, bytes.NewReader(body), "application/json", "application/json", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var responseValue PolicyConfiguration
|
||||
err = client.Client.UnmarshalBody(resp, &responseValue)
|
||||
return &responseValue, err
|
||||
}
|
||||
|
||||
// Arguments for the UpdatePolicyConfiguration function
|
||||
type UpdatePolicyConfigurationArgs struct {
|
||||
// (required) The policy configuration to update.
|
||||
Configuration *PolicyConfiguration
|
||||
// (required) Project ID or project name
|
||||
Project *string
|
||||
// (required) ID of the existing policy configuration to be updated.
|
||||
ConfigurationId *int
|
||||
}
|
134
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/policy/models.go
generated
vendored
134
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/policy/models.go
generated
vendored
@ -1,134 +0,0 @@
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Generated file, DO NOT EDIT
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
package policy
|
||||
|
||||
import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/microsoft/azure-devops-go-api/azuredevops"
|
||||
"github.com/microsoft/azure-devops-go-api/azuredevops/webapi"
|
||||
)
|
||||
|
||||
// The full policy configuration with settings.
|
||||
type PolicyConfiguration struct {
|
||||
// The policy configuration ID.
|
||||
Id *int `json:"id,omitempty"`
|
||||
// The policy configuration type.
|
||||
Type *PolicyTypeRef `json:"type,omitempty"`
|
||||
// The URL where the policy configuration can be retrieved.
|
||||
Url *string `json:"url,omitempty"`
|
||||
// The policy configuration revision ID.
|
||||
Revision *int `json:"revision,omitempty"`
|
||||
// The links to other objects related to this object.
|
||||
Links interface{} `json:"_links,omitempty"`
|
||||
// A reference to the identity that created the policy.
|
||||
CreatedBy *webapi.IdentityRef `json:"createdBy,omitempty"`
|
||||
// The date and time when the policy was created.
|
||||
CreatedDate *azuredevops.Time `json:"createdDate,omitempty"`
|
||||
// Indicates whether the policy is blocking.
|
||||
IsBlocking *bool `json:"isBlocking,omitempty"`
|
||||
// Indicates whether the policy has been (soft) deleted.
|
||||
IsDeleted *bool `json:"isDeleted,omitempty"`
|
||||
// Indicates whether the policy is enabled.
|
||||
IsEnabled *bool `json:"isEnabled,omitempty"`
|
||||
// The policy configuration settings.
|
||||
Settings interface{} `json:"settings,omitempty"`
|
||||
}
|
||||
|
||||
// Policy configuration reference.
|
||||
type PolicyConfigurationRef struct {
|
||||
// The policy configuration ID.
|
||||
Id *int `json:"id,omitempty"`
|
||||
// The policy configuration type.
|
||||
Type *PolicyTypeRef `json:"type,omitempty"`
|
||||
// The URL where the policy configuration can be retrieved.
|
||||
Url *string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
// This record encapsulates the current state of a policy as it applies to one specific pull request. Each pull request has a unique PolicyEvaluationRecord for each pull request which the policy applies to.
|
||||
type PolicyEvaluationRecord struct {
|
||||
// Links to other related objects
|
||||
Links interface{} `json:"_links,omitempty"`
|
||||
// A string which uniquely identifies the target of a policy evaluation.
|
||||
ArtifactId *string `json:"artifactId,omitempty"`
|
||||
// Time when this policy finished evaluating on this pull request.
|
||||
CompletedDate *azuredevops.Time `json:"completedDate,omitempty"`
|
||||
// Contains all configuration data for the policy which is being evaluated.
|
||||
Configuration *PolicyConfiguration `json:"configuration,omitempty"`
|
||||
// Internal context data of this policy evaluation.
|
||||
Context interface{} `json:"context,omitempty"`
|
||||
// Guid which uniquely identifies this evaluation record (one policy running on one pull request).
|
||||
EvaluationId *uuid.UUID `json:"evaluationId,omitempty"`
|
||||
// Time when this policy was first evaluated on this pull request.
|
||||
StartedDate *azuredevops.Time `json:"startedDate,omitempty"`
|
||||
// Status of the policy (Running, Approved, Failed, etc.)
|
||||
Status *PolicyEvaluationStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// Status of a policy which is running against a specific pull request.
|
||||
type PolicyEvaluationStatus string
|
||||
|
||||
type policyEvaluationStatusValuesType struct {
|
||||
Queued PolicyEvaluationStatus
|
||||
Running PolicyEvaluationStatus
|
||||
Approved PolicyEvaluationStatus
|
||||
Rejected PolicyEvaluationStatus
|
||||
NotApplicable PolicyEvaluationStatus
|
||||
Broken PolicyEvaluationStatus
|
||||
}
|
||||
|
||||
var PolicyEvaluationStatusValues = policyEvaluationStatusValuesType{
|
||||
// The policy is either queued to run, or is waiting for some event before progressing.
|
||||
Queued: "queued",
|
||||
// The policy is currently running.
|
||||
Running: "running",
|
||||
// The policy has been fulfilled for this pull request.
|
||||
Approved: "approved",
|
||||
// The policy has rejected this pull request.
|
||||
Rejected: "rejected",
|
||||
// The policy does not apply to this pull request.
|
||||
NotApplicable: "notApplicable",
|
||||
// The policy has encountered an unexpected error.
|
||||
Broken: "broken",
|
||||
}
|
||||
|
||||
// User-friendly policy type with description (used for querying policy types).
|
||||
type PolicyType struct {
|
||||
// Display name of the policy type.
|
||||
DisplayName *string `json:"displayName,omitempty"`
|
||||
// The policy type ID.
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
// The URL where the policy type can be retrieved.
|
||||
Url *string `json:"url,omitempty"`
|
||||
// The links to other objects related to this object.
|
||||
Links interface{} `json:"_links,omitempty"`
|
||||
// Detailed description of the policy type.
|
||||
Description *string `json:"description,omitempty"`
|
||||
}
|
||||
|
||||
// Policy type reference.
|
||||
type PolicyTypeRef struct {
|
||||
// Display name of the policy type.
|
||||
DisplayName *string `json:"displayName,omitempty"`
|
||||
// The policy type ID.
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
// The URL where the policy type can be retrieved.
|
||||
Url *string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
// A particular revision for a policy configuration.
|
||||
type VersionedPolicyConfigurationRef struct {
|
||||
// The policy configuration ID.
|
||||
Id *int `json:"id,omitempty"`
|
||||
// The policy configuration type.
|
||||
Type *PolicyTypeRef `json:"type,omitempty"`
|
||||
// The URL where the policy configuration can be retrieved.
|
||||
Url *string `json:"url,omitempty"`
|
||||
// The policy configuration revision ID.
|
||||
Revision *int `json:"revision,omitempty"`
|
||||
}
|
97
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/system/models.go
generated
vendored
97
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/system/models.go
generated
vendored
@ -1,97 +0,0 @@
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Generated file, DO NOT EDIT
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
package system
|
||||
|
||||
type SqlDbType string
|
||||
|
||||
type sqlDbTypeValuesType struct {
|
||||
BigInt SqlDbType
|
||||
Binary SqlDbType
|
||||
Bit SqlDbType
|
||||
Char SqlDbType
|
||||
DateTime SqlDbType
|
||||
Decimal SqlDbType
|
||||
Float SqlDbType
|
||||
Image SqlDbType
|
||||
Int SqlDbType
|
||||
Money SqlDbType
|
||||
NChar SqlDbType
|
||||
NText SqlDbType
|
||||
NVarChar SqlDbType
|
||||
Real SqlDbType
|
||||
UniqueIdentifier SqlDbType
|
||||
SmallDateTime SqlDbType
|
||||
SmallInt SqlDbType
|
||||
SmallMoney SqlDbType
|
||||
Text SqlDbType
|
||||
Timestamp SqlDbType
|
||||
TinyInt SqlDbType
|
||||
VarBinary SqlDbType
|
||||
VarChar SqlDbType
|
||||
Variant SqlDbType
|
||||
Xml SqlDbType
|
||||
Udt SqlDbType
|
||||
Structured SqlDbType
|
||||
Date SqlDbType
|
||||
Time SqlDbType
|
||||
DateTime2 SqlDbType
|
||||
DateTimeOffset SqlDbType
|
||||
}
|
||||
|
||||
var SqlDbTypeValues = sqlDbTypeValuesType{
|
||||
BigInt: "bigInt",
|
||||
Binary: "binary",
|
||||
Bit: "bit",
|
||||
Char: "char",
|
||||
DateTime: "dateTime",
|
||||
Decimal: "decimal",
|
||||
Float: "float",
|
||||
Image: "image",
|
||||
Int: "int",
|
||||
Money: "money",
|
||||
NChar: "nChar",
|
||||
NText: "nText",
|
||||
NVarChar: "nVarChar",
|
||||
Real: "real",
|
||||
UniqueIdentifier: "uniqueIdentifier",
|
||||
SmallDateTime: "smallDateTime",
|
||||
SmallInt: "smallInt",
|
||||
SmallMoney: "smallMoney",
|
||||
Text: "text",
|
||||
Timestamp: "timestamp",
|
||||
TinyInt: "tinyInt",
|
||||
VarBinary: "varBinary",
|
||||
VarChar: "varChar",
|
||||
Variant: "variant",
|
||||
Xml: "xml",
|
||||
Udt: "udt",
|
||||
Structured: "structured",
|
||||
Date: "date",
|
||||
Time: "time",
|
||||
DateTime2: "dateTime2",
|
||||
DateTimeOffset: "dateTimeOffset",
|
||||
}
|
||||
|
||||
type TraceLevel string
|
||||
|
||||
type traceLevelValuesType struct {
|
||||
Off TraceLevel
|
||||
Error TraceLevel
|
||||
Warning TraceLevel
|
||||
Info TraceLevel
|
||||
Verbose TraceLevel
|
||||
}
|
||||
|
||||
var TraceLevelValues = traceLevelValuesType{
|
||||
Off: "off",
|
||||
Error: "error",
|
||||
Warning: "warning",
|
||||
Info: "info",
|
||||
Verbose: "verbose",
|
||||
}
|
2159
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/test/client.go
generated
vendored
2159
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/test/client.go
generated
vendored
File diff suppressed because it is too large
Load Diff
3564
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/test/models.go
generated
vendored
3564
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/test/models.go
generated
vendored
File diff suppressed because it is too large
Load Diff
58
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/version.go
generated
vendored
58
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/version.go
generated
vendored
@ -1,58 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package azuredevops
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Version struct {
|
||||
Major int
|
||||
Minor int
|
||||
}
|
||||
|
||||
func NewVersion(version string) (*Version, error) {
|
||||
split := strings.Split(version, ".")
|
||||
if len(split) > 1 {
|
||||
major, err := strconv.Atoi(split[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
minor, err := strconv.Atoi(split[1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Version{
|
||||
Major: major,
|
||||
Minor: minor,
|
||||
}, nil
|
||||
}
|
||||
return nil, &InvalidVersionStringError{version: version}
|
||||
}
|
||||
|
||||
func (version Version) CompareTo(compareToVersion Version) int {
|
||||
if version.Major > compareToVersion.Major {
|
||||
return 1
|
||||
} else if version.Major < compareToVersion.Major {
|
||||
return -1
|
||||
} else if version.Minor > compareToVersion.Minor {
|
||||
return 1
|
||||
} else if version.Minor < compareToVersion.Minor {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (version Version) String() string {
|
||||
return strconv.Itoa(version.Major) + "." + strconv.Itoa(version.Minor)
|
||||
}
|
||||
|
||||
type InvalidVersionStringError struct {
|
||||
version string
|
||||
}
|
||||
|
||||
func (e *InvalidVersionStringError) Error() string {
|
||||
return "The version string was invalid: " + e.version
|
||||
}
|
72
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/versionnegotiation.go
generated
vendored
72
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/versionnegotiation.go
generated
vendored
@ -1,72 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package azuredevops
|
||||
|
||||
import "strconv"
|
||||
|
||||
func negotiateRequestVersion(location *ApiResourceLocation, apiVersion string) (string, error) {
|
||||
if apiVersion == "" {
|
||||
// if no api-version is sent to the server, the server will decide the version. The server uses the latest
|
||||
// released version if the endpoint has been released, otherwise it will use the latest preview version.
|
||||
return apiVersion, nil
|
||||
}
|
||||
|
||||
matches := apiVersionRegEx.FindStringSubmatch(apiVersion)
|
||||
if len(matches) == 0 && matches[0] != "" {
|
||||
return apiVersion, &InvalidApiVersion{apiVersion}
|
||||
}
|
||||
|
||||
requestedApiVersion, err := NewVersion(matches[1])
|
||||
if err != nil {
|
||||
return apiVersion, err
|
||||
}
|
||||
locationMinVersion, err := NewVersion(*location.MinVersion)
|
||||
if err != nil {
|
||||
return apiVersion, err
|
||||
}
|
||||
if locationMinVersion.CompareTo(*requestedApiVersion) > 0 {
|
||||
// Client is older than the server. The server no longer supports this
|
||||
// resource (deprecated).
|
||||
return apiVersion, nil
|
||||
} else {
|
||||
locationMaxVersion, err := NewVersion(*location.MaxVersion)
|
||||
if err != nil {
|
||||
return apiVersion, err
|
||||
}
|
||||
if locationMaxVersion.CompareTo(*requestedApiVersion) < 0 {
|
||||
// Client is newer than the server. Negotiate down to the latest version
|
||||
// on the server
|
||||
negotiatedVersion := string(*location.MaxVersion)
|
||||
if *location.ReleasedVersion < *location.MaxVersion {
|
||||
negotiatedVersion += "-preview"
|
||||
}
|
||||
return negotiatedVersion, nil
|
||||
} else {
|
||||
// We can send at the requested api version. Make sure the resource version
|
||||
// is not bigger than what the server supports
|
||||
negotiatedVersion := matches[1]
|
||||
if len(matches) > 3 && matches[3] != "" { // matches '-preview'
|
||||
negotiatedVersion += "-preview"
|
||||
if len(matches) > 5 && matches[5] != "" { // has a resource version
|
||||
requestedResourceVersion, _ := strconv.Atoi(matches[5])
|
||||
if *location.ResourceVersion < requestedResourceVersion {
|
||||
negotiatedVersion += "." + strconv.Itoa(*location.ResourceVersion)
|
||||
} else {
|
||||
negotiatedVersion += "." + matches[5]
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// requesting released version, ensure server supports a released version, and if not append '-preview'
|
||||
locationReleasedVersion, err := NewVersion(*location.ReleasedVersion)
|
||||
if err != nil {
|
||||
return apiVersion, err
|
||||
}
|
||||
if (locationReleasedVersion.Major == 0 && locationReleasedVersion.Minor == 0) || locationReleasedVersion.CompareTo(*requestedApiVersion) < 0 {
|
||||
negotiatedVersion += "-preview"
|
||||
}
|
||||
}
|
||||
return negotiatedVersion, nil
|
||||
}
|
||||
}
|
||||
}
|
315
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/webapi/models.go
generated
vendored
315
vendor/github.com/Microsoft/azure-devops-go-api/azuredevops/webapi/models.go
generated
vendored
@ -1,315 +0,0 @@
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Generated file, DO NOT EDIT
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
package webapi
|
||||
|
||||
import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/microsoft/azure-devops-go-api/azuredevops"
|
||||
"github.com/microsoft/azure-devops-go-api/azuredevops/system"
|
||||
)
|
||||
|
||||
// Information about the location of a REST API resource
|
||||
type ApiResourceLocation struct {
|
||||
// Area name for this resource
|
||||
Area *string `json:"area,omitempty"`
|
||||
// Unique Identifier for this location
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
// Maximum api version that this resource supports (current server version for this resource)
|
||||
MaxVersion *string `json:"maxVersion,omitempty"`
|
||||
// Minimum api version that this resource supports
|
||||
MinVersion *string `json:"minVersion,omitempty"`
|
||||
// The latest version of this resource location that is in "Release" (non-preview) mode
|
||||
ReleasedVersion *string `json:"releasedVersion,omitempty"`
|
||||
// Resource name
|
||||
ResourceName *string `json:"resourceName,omitempty"`
|
||||
// The current resource version supported by this resource location
|
||||
ResourceVersion *int `json:"resourceVersion,omitempty"`
|
||||
// This location's route template (templated relative path)
|
||||
RouteTemplate *string `json:"routeTemplate,omitempty"`
|
||||
}
|
||||
|
||||
// [Flags] Enumeration of the options that can be passed in on Connect.
|
||||
type ConnectOptions string
|
||||
|
||||
type connectOptionsValuesType struct {
|
||||
None ConnectOptions
|
||||
IncludeServices ConnectOptions
|
||||
IncludeLastUserAccess ConnectOptions
|
||||
IncludeInheritedDefinitionsOnly ConnectOptions
|
||||
IncludeNonInheritedDefinitionsOnly ConnectOptions
|
||||
}
|
||||
|
||||
var ConnectOptionsValues = connectOptionsValuesType{
|
||||
// Retrieve no optional data.
|
||||
None: "none",
|
||||
// Includes information about AccessMappings and ServiceDefinitions.
|
||||
IncludeServices: "includeServices",
|
||||
// Includes the last user access for this host.
|
||||
IncludeLastUserAccess: "includeLastUserAccess",
|
||||
// This is only valid on the deployment host and when true. Will only return inherited definitions.
|
||||
IncludeInheritedDefinitionsOnly: "includeInheritedDefinitionsOnly",
|
||||
// When true will only return non inherited definitions. Only valid at non-deployment host.
|
||||
IncludeNonInheritedDefinitionsOnly: "includeNonInheritedDefinitionsOnly",
|
||||
}
|
||||
|
||||
// [Flags]
|
||||
type DeploymentFlags string
|
||||
|
||||
type deploymentFlagsValuesType struct {
|
||||
None DeploymentFlags
|
||||
Hosted DeploymentFlags
|
||||
OnPremises DeploymentFlags
|
||||
}
|
||||
|
||||
var DeploymentFlagsValues = deploymentFlagsValuesType{
|
||||
None: "none",
|
||||
Hosted: "hosted",
|
||||
OnPremises: "onPremises",
|
||||
}
|
||||
|
||||
// Defines an "actor" for an event.
|
||||
type EventActor struct {
|
||||
// Required: This is the identity of the user for the specified role.
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
// Required: The event specific name of a role.
|
||||
Role *string `json:"role,omitempty"`
|
||||
}
|
||||
|
||||
// Defines a scope for an event.
|
||||
type EventScope struct {
|
||||
// Required: This is the identity of the scope for the type.
|
||||
Id *uuid.UUID `json:"id,omitempty"`
|
||||
// Optional: The display name of the scope
|
||||
Name *string `json:"name,omitempty"`
|
||||
// Required: The event specific type of a scope.
|
||||
Type *string `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
type IdentityRef struct {
|
||||
// Deprecated - Can be retrieved by querying the Graph user referenced in the "self" entry of the IdentityRef "_links" dictionary
|
||||
DirectoryAlias *string `json:"directoryAlias,omitempty"`
|
||||
Id *string `json:"id,omitempty"`
|
||||
// Deprecated - Available in the "avatar" entry of the IdentityRef "_links" dictionary
|
||||
ImageUrl *string `json:"imageUrl,omitempty"`
|
||||
// Deprecated - Can be retrieved by querying the Graph membership state referenced in the "membershipState" entry of the GraphUser "_links" dictionary
|
||||
Inactive *bool `json:"inactive,omitempty"`
|
||||
// Deprecated - Can be inferred from the subject type of the descriptor (Descriptor.IsAadUserType/Descriptor.IsAadGroupType)
|
||||
IsAadIdentity *bool `json:"isAadIdentity,omitempty"`
|
||||
// Deprecated - Can be inferred from the subject type of the descriptor (Descriptor.IsGroupType)
|
||||
IsContainer *bool `json:"isContainer,omitempty"`
|
||||
IsDeletedInOrigin *bool `json:"isDeletedInOrigin,omitempty"`
|
||||
// Deprecated - not in use in most preexisting implementations of ToIdentityRef
|
||||
ProfileUrl *string `json:"profileUrl,omitempty"`
|
||||
// Deprecated - use Domain+PrincipalName instead
|
||||
UniqueName *string `json:"uniqueName,omitempty"`
|
||||
}
|
||||
|
||||
type IdentityRefWithEmail struct {
|
||||
// Deprecated - Can be retrieved by querying the Graph user referenced in the "self" entry of the IdentityRef "_links" dictionary
|
||||
DirectoryAlias *string `json:"directoryAlias,omitempty"`
|
||||
Id *string `json:"id,omitempty"`
|
||||
// Deprecated - Available in the "avatar" entry of the IdentityRef "_links" dictionary
|
||||
ImageUrl *string `json:"imageUrl,omitempty"`
|
||||
// Deprecated - Can be retrieved by querying the Graph membership state referenced in the "membershipState" entry of the GraphUser "_links" dictionary
|
||||
Inactive *bool `json:"inactive,omitempty"`
|
||||
// Deprecated - Can be inferred from the subject type of the descriptor (Descriptor.IsAadUserType/Descriptor.IsAadGroupType)
|
||||
IsAadIdentity *bool `json:"isAadIdentity,omitempty"`
|
||||
// Deprecated - Can be inferred from the subject type of the descriptor (Descriptor.IsGroupType)
|
||||
IsContainer *bool `json:"isContainer,omitempty"`
|
||||
IsDeletedInOrigin *bool `json:"isDeletedInOrigin,omitempty"`
|
||||
// Deprecated - not in use in most preexisting implementations of ToIdentityRef
|
||||
ProfileUrl *string `json:"profileUrl,omitempty"`
|
||||
// Deprecated - use Domain+PrincipalName instead
|
||||
UniqueName *string `json:"uniqueName,omitempty"`
|
||||
PreferredEmailAddress *string `json:"preferredEmailAddress,omitempty"`
|
||||
}
|
||||
|
||||
// The JSON model for a JSON Patch operation
|
||||
type JsonPatchOperation struct {
|
||||
// The path to copy from for the Move/Copy operation.
|
||||
From *string `json:"from,omitempty"`
|
||||
// The patch operation
|
||||
Op *Operation `json:"op,omitempty"`
|
||||
// The path for the operation. In the case of an array, a zero based index can be used to specify the position in the array (e.g. /biscuits/0/name). The "-" character can be used instead of an index to insert at the end of the array (e.g. /biscuits/-).
|
||||
Path *string `json:"path,omitempty"`
|
||||
// The value for the operation. This is either a primitive or a JToken.
|
||||
Value interface{} `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
type JsonWebToken struct {
|
||||
}
|
||||
|
||||
type JWTAlgorithm string
|
||||
|
||||
type jwtAlgorithmValuesType struct {
|
||||
None JWTAlgorithm
|
||||
HS256 JWTAlgorithm
|
||||
RS256 JWTAlgorithm
|
||||
}
|
||||
|
||||
var JWTAlgorithmValues = jwtAlgorithmValuesType{
|
||||
None: "none",
|
||||
HS256: "hS256",
|
||||
RS256: "rS256",
|
||||
}
|
||||
|
||||
type Operation string
|
||||
|
||||
type operationValuesType struct {
|
||||
Add Operation
|
||||
Remove Operation
|
||||
Replace Operation
|
||||
Move Operation
|
||||
Copy Operation
|
||||
Test Operation
|
||||
}
|
||||
|
||||
var OperationValues = operationValuesType{
|
||||
Add: "add",
|
||||
Remove: "remove",
|
||||
Replace: "replace",
|
||||
Move: "move",
|
||||
Copy: "copy",
|
||||
Test: "test",
|
||||
}
|
||||
|
||||
// Represents the public key portion of an RSA asymmetric key.
|
||||
type PublicKey struct {
|
||||
// Gets or sets the exponent for the public key.
|
||||
Exponent *[]byte `json:"exponent,omitempty"`
|
||||
// Gets or sets the modulus for the public key.
|
||||
Modulus *[]byte `json:"modulus,omitempty"`
|
||||
}
|
||||
|
||||
type Publisher struct {
|
||||
// Name of the publishing service.
|
||||
Name *string `json:"name,omitempty"`
|
||||
// Service Owner Guid Eg. Tfs : 00025394-6065-48CA-87D9-7F5672854EF7
|
||||
ServiceOwnerId *uuid.UUID `json:"serviceOwnerId,omitempty"`
|
||||
}
|
||||
|
||||
// The class to represent a REST reference link. RFC: http://tools.ietf.org/html/draft-kelly-json-hal-06 The RFC is not fully implemented, additional properties are allowed on the reference link but as of yet we don't have a need for them.
|
||||
type ReferenceLink struct {
|
||||
Href *string `json:"href,omitempty"`
|
||||
}
|
||||
|
||||
type ResourceRef struct {
|
||||
Id *string `json:"id,omitempty"`
|
||||
Url *string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
type ServiceEvent struct {
|
||||
// This is the id of the type. Constants that will be used by subscribers to identify/filter events being published on a topic.
|
||||
EventType *string `json:"eventType,omitempty"`
|
||||
// This is the service that published this event.
|
||||
Publisher *Publisher `json:"publisher,omitempty"`
|
||||
// The resource object that carries specific information about the event. The object must have the ServiceEventObject applied for serialization/deserialization to work.
|
||||
Resource interface{} `json:"resource,omitempty"`
|
||||
// This dictionary carries the context descriptors along with their ids.
|
||||
ResourceContainers *map[string]interface{} `json:"resourceContainers,omitempty"`
|
||||
// This is the version of the resource.
|
||||
ResourceVersion *string `json:"resourceVersion,omitempty"`
|
||||
}
|
||||
|
||||
// A signed url allowing limited-time anonymous access to private resources.
|
||||
type SignedUrl struct {
|
||||
SignatureExpires *azuredevops.Time `json:"signatureExpires,omitempty"`
|
||||
Url *string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
type TeamMember struct {
|
||||
Identity *IdentityRef `json:"identity,omitempty"`
|
||||
IsTeamAdmin *bool `json:"isTeamAdmin,omitempty"`
|
||||
}
|
||||
|
||||
// A single secured timing consisting of a duration and start time
|
||||
type TimingEntry struct {
|
||||
// Duration of the entry in ticks
|
||||
ElapsedTicks *uint64 `json:"elapsedTicks,omitempty"`
|
||||
// Properties to distinguish timings within the same group or to provide data to send with telemetry
|
||||
Properties *map[string]interface{} `json:"properties,omitempty"`
|
||||
// Offset from Server Request Context start time in microseconds
|
||||
StartOffset *uint64 `json:"startOffset,omitempty"`
|
||||
}
|
||||
|
||||
// A set of secured performance timings all keyed off of the same string
|
||||
type TimingGroup struct {
|
||||
// The total number of timing entries associated with this group
|
||||
Count *int `json:"count,omitempty"`
|
||||
// Overall duration of all entries in this group in ticks
|
||||
ElapsedTicks *uint64 `json:"elapsedTicks,omitempty"`
|
||||
// A list of timing entries in this group. Only the first few entries in each group are collected.
|
||||
Timings *[]TimingEntry `json:"timings,omitempty"`
|
||||
}
|
||||
|
||||
// This class describes a trace filter, i.e. a set of criteria on whether or not a trace event should be emitted
|
||||
type TraceFilter struct {
|
||||
Area *string `json:"area,omitempty"`
|
||||
ExceptionType *string `json:"exceptionType,omitempty"`
|
||||
IsEnabled *bool `json:"isEnabled,omitempty"`
|
||||
Layer *string `json:"layer,omitempty"`
|
||||
Level *system.TraceLevel `json:"level,omitempty"`
|
||||
Method *string `json:"method,omitempty"`
|
||||
// Used to serialize additional identity information (display name, etc) to clients. Not set by default. Server-side callers should use OwnerId.
|
||||
Owner *IdentityRef `json:"owner,omitempty"`
|
||||
OwnerId *uuid.UUID `json:"ownerId,omitempty"`
|
||||
Path *string `json:"path,omitempty"`
|
||||
ProcessName *string `json:"processName,omitempty"`
|
||||
Service *string `json:"service,omitempty"`
|
||||
ServiceHost *uuid.UUID `json:"serviceHost,omitempty"`
|
||||
TimeCreated *azuredevops.Time `json:"timeCreated,omitempty"`
|
||||
TraceId *uuid.UUID `json:"traceId,omitempty"`
|
||||
Tracepoint *int `json:"tracepoint,omitempty"`
|
||||
Uri *string `json:"uri,omitempty"`
|
||||
UserAgent *string `json:"userAgent,omitempty"`
|
||||
UserLogin *string `json:"userLogin,omitempty"`
|
||||
}
|
||||
|
||||
type VssJsonCollectionWrapper struct {
|
||||
Count *int `json:"count,omitempty"`
|
||||
Value *[]interface{} `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
type VssJsonCollectionWrapperBase struct {
|
||||
Count *int `json:"count,omitempty"`
|
||||
}
|
||||
|
||||
// This is the type used for firing notifications intended for the subsystem in the Notifications SDK. For components that can't take a dependency on the Notifications SDK directly, they can use ITeamFoundationEventService.PublishNotification and the Notifications SDK ISubscriber implementation will get it.
|
||||
type VssNotificationEvent struct {
|
||||
// Optional: A list of actors which are additional identities with corresponding roles that are relevant to the event.
|
||||
Actors *[]EventActor `json:"actors,omitempty"`
|
||||
// Optional: A list of artifacts referenced or impacted by this event.
|
||||
ArtifactUris *[]string `json:"artifactUris,omitempty"`
|
||||
// Required: The event payload. If Data is a string, it must be in Json or XML format. Otherwise it must have a serialization format attribute.
|
||||
Data interface{} `json:"data,omitempty"`
|
||||
// Required: The name of the event. This event must be registered in the context it is being fired.
|
||||
EventType *string `json:"eventType,omitempty"`
|
||||
// How long before the event expires and will be cleaned up. The default is to use the system default.
|
||||
ExpiresIn interface{} `json:"expiresIn,omitempty"`
|
||||
// The id of the item, artifact, extension, project, etc.
|
||||
ItemId *string `json:"itemId,omitempty"`
|
||||
// How long to wait before processing this event. The default is to process immediately.
|
||||
ProcessDelay interface{} `json:"processDelay,omitempty"`
|
||||
// Optional: A list of scopes which are are relevant to the event.
|
||||
Scopes *[]EventScope `json:"scopes,omitempty"`
|
||||
// This is the time the original source event for this VssNotificationEvent was created. For example, for something like a build completion notification SourceEventCreatedTime should be the time the build finished not the time this event was raised.
|
||||
SourceEventCreatedTime *azuredevops.Time `json:"sourceEventCreatedTime,omitempty"`
|
||||
}
|
||||
|
||||
type WrappedException struct {
|
||||
CustomProperties *map[string]interface{} `json:"customProperties,omitempty"`
|
||||
ErrorCode *int `json:"errorCode,omitempty"`
|
||||
EventId *int `json:"eventId,omitempty"`
|
||||
HelpLink *string `json:"helpLink,omitempty"`
|
||||
InnerException *WrappedException `json:"innerException,omitempty"`
|
||||
Message *string `json:"message,omitempty"`
|
||||
StackTrace *string `json:"stackTrace,omitempty"`
|
||||
TypeKey *string `json:"typeKey,omitempty"`
|
||||
TypeName *string `json:"typeName,omitempty"`
|
||||
}
|
1
vendor/github.com/Microsoft/go-winio/.gitignore
generated
vendored
1
vendor/github.com/Microsoft/go-winio/.gitignore
generated
vendored
@ -1 +0,0 @@
|
||||
*.exe
|
22
vendor/github.com/Microsoft/go-winio/LICENSE
generated
vendored
22
vendor/github.com/Microsoft/go-winio/LICENSE
generated
vendored
@ -1,22 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Microsoft
|
||||
|
||||
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.
|
||||
|
22
vendor/github.com/Microsoft/go-winio/README.md
generated
vendored
22
vendor/github.com/Microsoft/go-winio/README.md
generated
vendored
@ -1,22 +0,0 @@
|
||||
# go-winio
|
||||
|
||||
This repository contains utilities for efficiently performing Win32 IO operations in
|
||||
Go. Currently, this is focused on accessing named pipes and other file handles, and
|
||||
for using named pipes as a net transport.
|
||||
|
||||
This code relies on IO completion ports to avoid blocking IO on system threads, allowing Go
|
||||
to reuse the thread to schedule another goroutine. This limits support to Windows Vista and
|
||||
newer operating systems. This is similar to the implementation of network sockets in Go's net
|
||||
package.
|
||||
|
||||
Please see the LICENSE file for licensing information.
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of
|
||||
Conduct](https://opensource.microsoft.com/codeofconduct/). For more information
|
||||
see the [Code of Conduct
|
||||
FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact
|
||||
[opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional
|
||||
questions or comments.
|
||||
|
||||
Thanks to natefinch for the inspiration for this library. See https://github.com/natefinch/npipe
|
||||
for another named pipe implementation.
|
280
vendor/github.com/Microsoft/go-winio/backup.go
generated
vendored
280
vendor/github.com/Microsoft/go-winio/backup.go
generated
vendored
@ -1,280 +0,0 @@
|
||||
// +build windows
|
||||
|
||||
package winio
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"unicode/utf16"
|
||||
)
|
||||
|
||||
//sys backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupRead
|
||||
//sys backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupWrite
|
||||
|
||||
const (
|
||||
BackupData = uint32(iota + 1)
|
||||
BackupEaData
|
||||
BackupSecurity
|
||||
BackupAlternateData
|
||||
BackupLink
|
||||
BackupPropertyData
|
||||
BackupObjectId
|
||||
BackupReparseData
|
||||
BackupSparseBlock
|
||||
BackupTxfsData
|
||||
)
|
||||
|
||||
const (
|
||||
StreamSparseAttributes = uint32(8)
|
||||
)
|
||||
|
||||
const (
|
||||
WRITE_DAC = 0x40000
|
||||
WRITE_OWNER = 0x80000
|
||||
ACCESS_SYSTEM_SECURITY = 0x1000000
|
||||
)
|
||||
|
||||
// BackupHeader represents a backup stream of a file.
|
||||
type BackupHeader struct {
|
||||
Id uint32 // The backup stream ID
|
||||
Attributes uint32 // Stream attributes
|
||||
Size int64 // The size of the stream in bytes
|
||||
Name string // The name of the stream (for BackupAlternateData only).
|
||||
Offset int64 // The offset of the stream in the file (for BackupSparseBlock only).
|
||||
}
|
||||
|
||||
type win32StreamId struct {
|
||||
StreamId uint32
|
||||
Attributes uint32
|
||||
Size uint64
|
||||
NameSize uint32
|
||||
}
|
||||
|
||||
// BackupStreamReader reads from a stream produced by the BackupRead Win32 API and produces a series
|
||||
// of BackupHeader values.
|
||||
type BackupStreamReader struct {
|
||||
r io.Reader
|
||||
bytesLeft int64
|
||||
}
|
||||
|
||||
// NewBackupStreamReader produces a BackupStreamReader from any io.Reader.
|
||||
func NewBackupStreamReader(r io.Reader) *BackupStreamReader {
|
||||
return &BackupStreamReader{r, 0}
|
||||
}
|
||||
|
||||
// Next returns the next backup stream and prepares for calls to Read(). It skips the remainder of the current stream if
|
||||
// it was not completely read.
|
||||
func (r *BackupStreamReader) Next() (*BackupHeader, error) {
|
||||
if r.bytesLeft > 0 {
|
||||
if s, ok := r.r.(io.Seeker); ok {
|
||||
// Make sure Seek on io.SeekCurrent sometimes succeeds
|
||||
// before trying the actual seek.
|
||||
if _, err := s.Seek(0, io.SeekCurrent); err == nil {
|
||||
if _, err = s.Seek(r.bytesLeft, io.SeekCurrent); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r.bytesLeft = 0
|
||||
}
|
||||
}
|
||||
if _, err := io.Copy(ioutil.Discard, r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
var wsi win32StreamId
|
||||
if err := binary.Read(r.r, binary.LittleEndian, &wsi); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hdr := &BackupHeader{
|
||||
Id: wsi.StreamId,
|
||||
Attributes: wsi.Attributes,
|
||||
Size: int64(wsi.Size),
|
||||
}
|
||||
if wsi.NameSize != 0 {
|
||||
name := make([]uint16, int(wsi.NameSize/2))
|
||||
if err := binary.Read(r.r, binary.LittleEndian, name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hdr.Name = syscall.UTF16ToString(name)
|
||||
}
|
||||
if wsi.StreamId == BackupSparseBlock {
|
||||
if err := binary.Read(r.r, binary.LittleEndian, &hdr.Offset); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hdr.Size -= 8
|
||||
}
|
||||
r.bytesLeft = hdr.Size
|
||||
return hdr, nil
|
||||
}
|
||||
|
||||
// Read reads from the current backup stream.
|
||||
func (r *BackupStreamReader) Read(b []byte) (int, error) {
|
||||
if r.bytesLeft == 0 {
|
||||
return 0, io.EOF
|
||||
}
|
||||
if int64(len(b)) > r.bytesLeft {
|
||||
b = b[:r.bytesLeft]
|
||||
}
|
||||
n, err := r.r.Read(b)
|
||||
r.bytesLeft -= int64(n)
|
||||
if err == io.EOF {
|
||||
err = io.ErrUnexpectedEOF
|
||||
} else if r.bytesLeft == 0 && err == nil {
|
||||
err = io.EOF
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
// BackupStreamWriter writes a stream compatible with the BackupWrite Win32 API.
|
||||
type BackupStreamWriter struct {
|
||||
w io.Writer
|
||||
bytesLeft int64
|
||||
}
|
||||
|
||||
// NewBackupStreamWriter produces a BackupStreamWriter on top of an io.Writer.
|
||||
func NewBackupStreamWriter(w io.Writer) *BackupStreamWriter {
|
||||
return &BackupStreamWriter{w, 0}
|
||||
}
|
||||
|
||||
// WriteHeader writes the next backup stream header and prepares for calls to Write().
|
||||
func (w *BackupStreamWriter) WriteHeader(hdr *BackupHeader) error {
|
||||
if w.bytesLeft != 0 {
|
||||
return fmt.Errorf("missing %d bytes", w.bytesLeft)
|
||||
}
|
||||
name := utf16.Encode([]rune(hdr.Name))
|
||||
wsi := win32StreamId{
|
||||
StreamId: hdr.Id,
|
||||
Attributes: hdr.Attributes,
|
||||
Size: uint64(hdr.Size),
|
||||
NameSize: uint32(len(name) * 2),
|
||||
}
|
||||
if hdr.Id == BackupSparseBlock {
|
||||
// Include space for the int64 block offset
|
||||
wsi.Size += 8
|
||||
}
|
||||
if err := binary.Write(w.w, binary.LittleEndian, &wsi); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(name) != 0 {
|
||||
if err := binary.Write(w.w, binary.LittleEndian, name); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if hdr.Id == BackupSparseBlock {
|
||||
if err := binary.Write(w.w, binary.LittleEndian, hdr.Offset); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
w.bytesLeft = hdr.Size
|
||||
return nil
|
||||
}
|
||||
|
||||
// Write writes to the current backup stream.
|
||||
func (w *BackupStreamWriter) Write(b []byte) (int, error) {
|
||||
if w.bytesLeft < int64(len(b)) {
|
||||
return 0, fmt.Errorf("too many bytes by %d", int64(len(b))-w.bytesLeft)
|
||||
}
|
||||
n, err := w.w.Write(b)
|
||||
w.bytesLeft -= int64(n)
|
||||
return n, err
|
||||
}
|
||||
|
||||
// BackupFileReader provides an io.ReadCloser interface on top of the BackupRead Win32 API.
|
||||
type BackupFileReader struct {
|
||||
f *os.File
|
||||
includeSecurity bool
|
||||
ctx uintptr
|
||||
}
|
||||
|
||||
// NewBackupFileReader returns a new BackupFileReader from a file handle. If includeSecurity is true,
|
||||
// Read will attempt to read the security descriptor of the file.
|
||||
func NewBackupFileReader(f *os.File, includeSecurity bool) *BackupFileReader {
|
||||
r := &BackupFileReader{f, includeSecurity, 0}
|
||||
return r
|
||||
}
|
||||
|
||||
// Read reads a backup stream from the file by calling the Win32 API BackupRead().
|
||||
func (r *BackupFileReader) Read(b []byte) (int, error) {
|
||||
var bytesRead uint32
|
||||
err := backupRead(syscall.Handle(r.f.Fd()), b, &bytesRead, false, r.includeSecurity, &r.ctx)
|
||||
if err != nil {
|
||||
return 0, &os.PathError{"BackupRead", r.f.Name(), err}
|
||||
}
|
||||
runtime.KeepAlive(r.f)
|
||||
if bytesRead == 0 {
|
||||
return 0, io.EOF
|
||||
}
|
||||
return int(bytesRead), nil
|
||||
}
|
||||
|
||||
// Close frees Win32 resources associated with the BackupFileReader. It does not close
|
||||
// the underlying file.
|
||||
func (r *BackupFileReader) Close() error {
|
||||
if r.ctx != 0 {
|
||||
backupRead(syscall.Handle(r.f.Fd()), nil, nil, true, false, &r.ctx)
|
||||
runtime.KeepAlive(r.f)
|
||||
r.ctx = 0
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// BackupFileWriter provides an io.WriteCloser interface on top of the BackupWrite Win32 API.
|
||||
type BackupFileWriter struct {
|
||||
f *os.File
|
||||
includeSecurity bool
|
||||
ctx uintptr
|
||||
}
|
||||
|
||||
// NewBackupFileWriter returns a new BackupFileWriter from a file handle. If includeSecurity is true,
|
||||
// Write() will attempt to restore the security descriptor from the stream.
|
||||
func NewBackupFileWriter(f *os.File, includeSecurity bool) *BackupFileWriter {
|
||||
w := &BackupFileWriter{f, includeSecurity, 0}
|
||||
return w
|
||||
}
|
||||
|
||||
// Write restores a portion of the file using the provided backup stream.
|
||||
func (w *BackupFileWriter) Write(b []byte) (int, error) {
|
||||
var bytesWritten uint32
|
||||
err := backupWrite(syscall.Handle(w.f.Fd()), b, &bytesWritten, false, w.includeSecurity, &w.ctx)
|
||||
if err != nil {
|
||||
return 0, &os.PathError{"BackupWrite", w.f.Name(), err}
|
||||
}
|
||||
runtime.KeepAlive(w.f)
|
||||
if int(bytesWritten) != len(b) {
|
||||
return int(bytesWritten), errors.New("not all bytes could be written")
|
||||
}
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
// Close frees Win32 resources associated with the BackupFileWriter. It does not
|
||||
// close the underlying file.
|
||||
func (w *BackupFileWriter) Close() error {
|
||||
if w.ctx != 0 {
|
||||
backupWrite(syscall.Handle(w.f.Fd()), nil, nil, true, false, &w.ctx)
|
||||
runtime.KeepAlive(w.f)
|
||||
w.ctx = 0
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// OpenForBackup opens a file or directory, potentially skipping access checks if the backup
|
||||
// or restore privileges have been acquired.
|
||||
//
|
||||
// If the file opened was a directory, it cannot be used with Readdir().
|
||||
func OpenForBackup(path string, access uint32, share uint32, createmode uint32) (*os.File, error) {
|
||||
winPath, err := syscall.UTF16FromString(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
h, err := syscall.CreateFile(&winPath[0], access, share, nil, createmode, syscall.FILE_FLAG_BACKUP_SEMANTICS|syscall.FILE_FLAG_OPEN_REPARSE_POINT, 0)
|
||||
if err != nil {
|
||||
err = &os.PathError{Op: "open", Path: path, Err: err}
|
||||
return nil, err
|
||||
}
|
||||
return os.NewFile(uintptr(h), path), nil
|
||||
}
|
137
vendor/github.com/Microsoft/go-winio/ea.go
generated
vendored
137
vendor/github.com/Microsoft/go-winio/ea.go
generated
vendored
@ -1,137 +0,0 @@
|
||||
package winio
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
)
|
||||
|
||||
type fileFullEaInformation struct {
|
||||
NextEntryOffset uint32
|
||||
Flags uint8
|
||||
NameLength uint8
|
||||
ValueLength uint16
|
||||
}
|
||||
|
||||
var (
|
||||
fileFullEaInformationSize = binary.Size(&fileFullEaInformation{})
|
||||
|
||||
errInvalidEaBuffer = errors.New("invalid extended attribute buffer")
|
||||
errEaNameTooLarge = errors.New("extended attribute name too large")
|
||||
errEaValueTooLarge = errors.New("extended attribute value too large")
|
||||
)
|
||||
|
||||
// ExtendedAttribute represents a single Windows EA.
|
||||
type ExtendedAttribute struct {
|
||||
Name string
|
||||
Value []byte
|
||||
Flags uint8
|
||||
}
|
||||
|
||||
func parseEa(b []byte) (ea ExtendedAttribute, nb []byte, err error) {
|
||||
var info fileFullEaInformation
|
||||
err = binary.Read(bytes.NewReader(b), binary.LittleEndian, &info)
|
||||
if err != nil {
|
||||
err = errInvalidEaBuffer
|
||||
return
|
||||
}
|
||||
|
||||
nameOffset := fileFullEaInformationSize
|
||||
nameLen := int(info.NameLength)
|
||||
valueOffset := nameOffset + int(info.NameLength) + 1
|
||||
valueLen := int(info.ValueLength)
|
||||
nextOffset := int(info.NextEntryOffset)
|
||||
if valueLen+valueOffset > len(b) || nextOffset < 0 || nextOffset > len(b) {
|
||||
err = errInvalidEaBuffer
|
||||
return
|
||||
}
|
||||
|
||||
ea.Name = string(b[nameOffset : nameOffset+nameLen])
|
||||
ea.Value = b[valueOffset : valueOffset+valueLen]
|
||||
ea.Flags = info.Flags
|
||||
if info.NextEntryOffset != 0 {
|
||||
nb = b[info.NextEntryOffset:]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DecodeExtendedAttributes decodes a list of EAs from a FILE_FULL_EA_INFORMATION
|
||||
// buffer retrieved from BackupRead, ZwQueryEaFile, etc.
|
||||
func DecodeExtendedAttributes(b []byte) (eas []ExtendedAttribute, err error) {
|
||||
for len(b) != 0 {
|
||||
ea, nb, err := parseEa(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
eas = append(eas, ea)
|
||||
b = nb
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func writeEa(buf *bytes.Buffer, ea *ExtendedAttribute, last bool) error {
|
||||
if int(uint8(len(ea.Name))) != len(ea.Name) {
|
||||
return errEaNameTooLarge
|
||||
}
|
||||
if int(uint16(len(ea.Value))) != len(ea.Value) {
|
||||
return errEaValueTooLarge
|
||||
}
|
||||
entrySize := uint32(fileFullEaInformationSize + len(ea.Name) + 1 + len(ea.Value))
|
||||
withPadding := (entrySize + 3) &^ 3
|
||||
nextOffset := uint32(0)
|
||||
if !last {
|
||||
nextOffset = withPadding
|
||||
}
|
||||
info := fileFullEaInformation{
|
||||
NextEntryOffset: nextOffset,
|
||||
Flags: ea.Flags,
|
||||
NameLength: uint8(len(ea.Name)),
|
||||
ValueLength: uint16(len(ea.Value)),
|
||||
}
|
||||
|
||||
err := binary.Write(buf, binary.LittleEndian, &info)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = buf.Write([]byte(ea.Name))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = buf.WriteByte(0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = buf.Write(ea.Value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = buf.Write([]byte{0, 0, 0}[0 : withPadding-entrySize])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// EncodeExtendedAttributes encodes a list of EAs into a FILE_FULL_EA_INFORMATION
|
||||
// buffer for use with BackupWrite, ZwSetEaFile, etc.
|
||||
func EncodeExtendedAttributes(eas []ExtendedAttribute) ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
for i := range eas {
|
||||
last := false
|
||||
if i == len(eas)-1 {
|
||||
last = true
|
||||
}
|
||||
|
||||
err := writeEa(&buf, &eas[i], last)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
323
vendor/github.com/Microsoft/go-winio/file.go
generated
vendored
323
vendor/github.com/Microsoft/go-winio/file.go
generated
vendored
@ -1,323 +0,0 @@
|
||||
// +build windows
|
||||
|
||||
package winio
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"runtime"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
//sys cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) = CancelIoEx
|
||||
//sys createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) = CreateIoCompletionPort
|
||||
//sys getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) = GetQueuedCompletionStatus
|
||||
//sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes
|
||||
//sys wsaGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) = ws2_32.WSAGetOverlappedResult
|
||||
|
||||
type atomicBool int32
|
||||
|
||||
func (b *atomicBool) isSet() bool { return atomic.LoadInt32((*int32)(b)) != 0 }
|
||||
func (b *atomicBool) setFalse() { atomic.StoreInt32((*int32)(b), 0) }
|
||||
func (b *atomicBool) setTrue() { atomic.StoreInt32((*int32)(b), 1) }
|
||||
func (b *atomicBool) swap(new bool) bool {
|
||||
var newInt int32
|
||||
if new {
|
||||
newInt = 1
|
||||
}
|
||||
return atomic.SwapInt32((*int32)(b), newInt) == 1
|
||||
}
|
||||
|
||||
const (
|
||||
cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1
|
||||
cFILE_SKIP_SET_EVENT_ON_HANDLE = 2
|
||||
)
|
||||
|
||||
var (
|
||||
ErrFileClosed = errors.New("file has already been closed")
|
||||
ErrTimeout = &timeoutError{}
|
||||
)
|
||||
|
||||
type timeoutError struct{}
|
||||
|
||||
func (e *timeoutError) Error() string { return "i/o timeout" }
|
||||
func (e *timeoutError) Timeout() bool { return true }
|
||||
func (e *timeoutError) Temporary() bool { return true }
|
||||
|
||||
type timeoutChan chan struct{}
|
||||
|
||||
var ioInitOnce sync.Once
|
||||
var ioCompletionPort syscall.Handle
|
||||
|
||||
// ioResult contains the result of an asynchronous IO operation
|
||||
type ioResult struct {
|
||||
bytes uint32
|
||||
err error
|
||||
}
|
||||
|
||||
// ioOperation represents an outstanding asynchronous Win32 IO
|
||||
type ioOperation struct {
|
||||
o syscall.Overlapped
|
||||
ch chan ioResult
|
||||
}
|
||||
|
||||
func initIo() {
|
||||
h, err := createIoCompletionPort(syscall.InvalidHandle, 0, 0, 0xffffffff)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ioCompletionPort = h
|
||||
go ioCompletionProcessor(h)
|
||||
}
|
||||
|
||||
// win32File implements Reader, Writer, and Closer on a Win32 handle without blocking in a syscall.
|
||||
// It takes ownership of this handle and will close it if it is garbage collected.
|
||||
type win32File struct {
|
||||
handle syscall.Handle
|
||||
wg sync.WaitGroup
|
||||
wgLock sync.RWMutex
|
||||
closing atomicBool
|
||||
socket bool
|
||||
readDeadline deadlineHandler
|
||||
writeDeadline deadlineHandler
|
||||
}
|
||||
|
||||
type deadlineHandler struct {
|
||||
setLock sync.Mutex
|
||||
channel timeoutChan
|
||||
channelLock sync.RWMutex
|
||||
timer *time.Timer
|
||||
timedout atomicBool
|
||||
}
|
||||
|
||||
// makeWin32File makes a new win32File from an existing file handle
|
||||
func makeWin32File(h syscall.Handle) (*win32File, error) {
|
||||
f := &win32File{handle: h}
|
||||
ioInitOnce.Do(initIo)
|
||||
_, err := createIoCompletionPort(h, ioCompletionPort, 0, 0xffffffff)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = setFileCompletionNotificationModes(h, cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS|cFILE_SKIP_SET_EVENT_ON_HANDLE)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f.readDeadline.channel = make(timeoutChan)
|
||||
f.writeDeadline.channel = make(timeoutChan)
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func MakeOpenFile(h syscall.Handle) (io.ReadWriteCloser, error) {
|
||||
// If we return the result of makeWin32File directly, it can result in an
|
||||
// interface-wrapped nil, rather than a nil interface value.
|
||||
f, err := makeWin32File(h)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
// closeHandle closes the resources associated with a Win32 handle
|
||||
func (f *win32File) closeHandle() {
|
||||
f.wgLock.Lock()
|
||||
// Atomically set that we are closing, releasing the resources only once.
|
||||
if !f.closing.swap(true) {
|
||||
f.wgLock.Unlock()
|
||||
// cancel all IO and wait for it to complete
|
||||
cancelIoEx(f.handle, nil)
|
||||
f.wg.Wait()
|
||||
// at this point, no new IO can start
|
||||
syscall.Close(f.handle)
|
||||
f.handle = 0
|
||||
} else {
|
||||
f.wgLock.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
// Close closes a win32File.
|
||||
func (f *win32File) Close() error {
|
||||
f.closeHandle()
|
||||
return nil
|
||||
}
|
||||
|
||||
// prepareIo prepares for a new IO operation.
|
||||
// The caller must call f.wg.Done() when the IO is finished, prior to Close() returning.
|
||||
func (f *win32File) prepareIo() (*ioOperation, error) {
|
||||
f.wgLock.RLock()
|
||||
if f.closing.isSet() {
|
||||
f.wgLock.RUnlock()
|
||||
return nil, ErrFileClosed
|
||||
}
|
||||
f.wg.Add(1)
|
||||
f.wgLock.RUnlock()
|
||||
c := &ioOperation{}
|
||||
c.ch = make(chan ioResult)
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// ioCompletionProcessor processes completed async IOs forever
|
||||
func ioCompletionProcessor(h syscall.Handle) {
|
||||
for {
|
||||
var bytes uint32
|
||||
var key uintptr
|
||||
var op *ioOperation
|
||||
err := getQueuedCompletionStatus(h, &bytes, &key, &op, syscall.INFINITE)
|
||||
if op == nil {
|
||||
panic(err)
|
||||
}
|
||||
op.ch <- ioResult{bytes, err}
|
||||
}
|
||||
}
|
||||
|
||||
// asyncIo processes the return value from ReadFile or WriteFile, blocking until
|
||||
// the operation has actually completed.
|
||||
func (f *win32File) asyncIo(c *ioOperation, d *deadlineHandler, bytes uint32, err error) (int, error) {
|
||||
if err != syscall.ERROR_IO_PENDING {
|
||||
return int(bytes), err
|
||||
}
|
||||
|
||||
if f.closing.isSet() {
|
||||
cancelIoEx(f.handle, &c.o)
|
||||
}
|
||||
|
||||
var timeout timeoutChan
|
||||
if d != nil {
|
||||
d.channelLock.Lock()
|
||||
timeout = d.channel
|
||||
d.channelLock.Unlock()
|
||||
}
|
||||
|
||||
var r ioResult
|
||||
select {
|
||||
case r = <-c.ch:
|
||||
err = r.err
|
||||
if err == syscall.ERROR_OPERATION_ABORTED {
|
||||
if f.closing.isSet() {
|
||||
err = ErrFileClosed
|
||||
}
|
||||
} else if err != nil && f.socket {
|
||||
// err is from Win32. Query the overlapped structure to get the winsock error.
|
||||
var bytes, flags uint32
|
||||
err = wsaGetOverlappedResult(f.handle, &c.o, &bytes, false, &flags)
|
||||
}
|
||||
case <-timeout:
|
||||
cancelIoEx(f.handle, &c.o)
|
||||
r = <-c.ch
|
||||
err = r.err
|
||||
if err == syscall.ERROR_OPERATION_ABORTED {
|
||||
err = ErrTimeout
|
||||
}
|
||||
}
|
||||
|
||||
// runtime.KeepAlive is needed, as c is passed via native
|
||||
// code to ioCompletionProcessor, c must remain alive
|
||||
// until the channel read is complete.
|
||||
runtime.KeepAlive(c)
|
||||
return int(r.bytes), err
|
||||
}
|
||||
|
||||
// Read reads from a file handle.
|
||||
func (f *win32File) Read(b []byte) (int, error) {
|
||||
c, err := f.prepareIo()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer f.wg.Done()
|
||||
|
||||
if f.readDeadline.timedout.isSet() {
|
||||
return 0, ErrTimeout
|
||||
}
|
||||
|
||||
var bytes uint32
|
||||
err = syscall.ReadFile(f.handle, b, &bytes, &c.o)
|
||||
n, err := f.asyncIo(c, &f.readDeadline, bytes, err)
|
||||
runtime.KeepAlive(b)
|
||||
|
||||
// Handle EOF conditions.
|
||||
if err == nil && n == 0 && len(b) != 0 {
|
||||
return 0, io.EOF
|
||||
} else if err == syscall.ERROR_BROKEN_PIPE {
|
||||
return 0, io.EOF
|
||||
} else {
|
||||
return n, err
|
||||
}
|
||||
}
|
||||
|
||||
// Write writes to a file handle.
|
||||
func (f *win32File) Write(b []byte) (int, error) {
|
||||
c, err := f.prepareIo()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer f.wg.Done()
|
||||
|
||||
if f.writeDeadline.timedout.isSet() {
|
||||
return 0, ErrTimeout
|
||||
}
|
||||
|
||||
var bytes uint32
|
||||
err = syscall.WriteFile(f.handle, b, &bytes, &c.o)
|
||||
n, err := f.asyncIo(c, &f.writeDeadline, bytes, err)
|
||||
runtime.KeepAlive(b)
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (f *win32File) SetReadDeadline(deadline time.Time) error {
|
||||
return f.readDeadline.set(deadline)
|
||||
}
|
||||
|
||||
func (f *win32File) SetWriteDeadline(deadline time.Time) error {
|
||||
return f.writeDeadline.set(deadline)
|
||||
}
|
||||
|
||||
func (f *win32File) Flush() error {
|
||||
return syscall.FlushFileBuffers(f.handle)
|
||||
}
|
||||
|
||||
func (f *win32File) Fd() uintptr {
|
||||
return uintptr(f.handle)
|
||||
}
|
||||
|
||||
func (d *deadlineHandler) set(deadline time.Time) error {
|
||||
d.setLock.Lock()
|
||||
defer d.setLock.Unlock()
|
||||
|
||||
if d.timer != nil {
|
||||
if !d.timer.Stop() {
|
||||
<-d.channel
|
||||
}
|
||||
d.timer = nil
|
||||
}
|
||||
d.timedout.setFalse()
|
||||
|
||||
select {
|
||||
case <-d.channel:
|
||||
d.channelLock.Lock()
|
||||
d.channel = make(chan struct{})
|
||||
d.channelLock.Unlock()
|
||||
default:
|
||||
}
|
||||
|
||||
if deadline.IsZero() {
|
||||
return nil
|
||||
}
|
||||
|
||||
timeoutIO := func() {
|
||||
d.timedout.setTrue()
|
||||
close(d.channel)
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
duration := deadline.Sub(now)
|
||||
if deadline.After(now) {
|
||||
// Deadline is in the future, set a timer to wait
|
||||
d.timer = time.AfterFunc(duration, timeoutIO)
|
||||
} else {
|
||||
// Deadline is in the past. Cancel all pending IO now.
|
||||
timeoutIO()
|
||||
}
|
||||
return nil
|
||||
}
|
61
vendor/github.com/Microsoft/go-winio/fileinfo.go
generated
vendored
61
vendor/github.com/Microsoft/go-winio/fileinfo.go
generated
vendored
@ -1,61 +0,0 @@
|
||||
// +build windows
|
||||
|
||||
package winio
|
||||
|
||||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
//sys getFileInformationByHandleEx(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) = GetFileInformationByHandleEx
|
||||
//sys setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) = SetFileInformationByHandle
|
||||
|
||||
const (
|
||||
fileBasicInfo = 0
|
||||
fileIDInfo = 0x12
|
||||
)
|
||||
|
||||
// FileBasicInfo contains file access time and file attributes information.
|
||||
type FileBasicInfo struct {
|
||||
CreationTime, LastAccessTime, LastWriteTime, ChangeTime syscall.Filetime
|
||||
FileAttributes uint32
|
||||
pad uint32 // padding
|
||||
}
|
||||
|
||||
// GetFileBasicInfo retrieves times and attributes for a file.
|
||||
func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) {
|
||||
bi := &FileBasicInfo{}
|
||||
if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
|
||||
return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
|
||||
}
|
||||
runtime.KeepAlive(f)
|
||||
return bi, nil
|
||||
}
|
||||
|
||||
// SetFileBasicInfo sets times and attributes for a file.
|
||||
func SetFileBasicInfo(f *os.File, bi *FileBasicInfo) error {
|
||||
if err := setFileInformationByHandle(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
|
||||
return &os.PathError{Op: "SetFileInformationByHandle", Path: f.Name(), Err: err}
|
||||
}
|
||||
runtime.KeepAlive(f)
|
||||
return nil
|
||||
}
|
||||
|
||||
// FileIDInfo contains the volume serial number and file ID for a file. This pair should be
|
||||
// unique on a system.
|
||||
type FileIDInfo struct {
|
||||
VolumeSerialNumber uint64
|
||||
FileID [16]byte
|
||||
}
|
||||
|
||||
// GetFileID retrieves the unique (volume, file ID) pair for a file.
|
||||
func GetFileID(f *os.File) (*FileIDInfo, error) {
|
||||
fileID := &FileIDInfo{}
|
||||
if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileIDInfo, (*byte)(unsafe.Pointer(fileID)), uint32(unsafe.Sizeof(*fileID))); err != nil {
|
||||
return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
|
||||
}
|
||||
runtime.KeepAlive(f)
|
||||
return fileID, nil
|
||||
}
|
9
vendor/github.com/Microsoft/go-winio/go.mod
generated
vendored
9
vendor/github.com/Microsoft/go-winio/go.mod
generated
vendored
@ -1,9 +0,0 @@
|
||||
module github.com/Microsoft/go-winio
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/sirupsen/logrus v1.4.1
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b
|
||||
)
|
16
vendor/github.com/Microsoft/go-winio/go.sum
generated
vendored
16
vendor/github.com/Microsoft/go-winio/go.sum
generated
vendored
@ -1,16 +0,0 @@
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b h1:ag/x1USPSsqHud38I9BAC88qdNLDHHtQ4mlgQIZPPNA=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
305
vendor/github.com/Microsoft/go-winio/hvsock.go
generated
vendored
305
vendor/github.com/Microsoft/go-winio/hvsock.go
generated
vendored
@ -1,305 +0,0 @@
|
||||
package winio
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Microsoft/go-winio/pkg/guid"
|
||||
)
|
||||
|
||||
//sys bind(s syscall.Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socketError] = ws2_32.bind
|
||||
|
||||
const (
|
||||
afHvSock = 34 // AF_HYPERV
|
||||
|
||||
socketError = ^uintptr(0)
|
||||
)
|
||||
|
||||
// An HvsockAddr is an address for a AF_HYPERV socket.
|
||||
type HvsockAddr struct {
|
||||
VMID guid.GUID
|
||||
ServiceID guid.GUID
|
||||
}
|
||||
|
||||
type rawHvsockAddr struct {
|
||||
Family uint16
|
||||
_ uint16
|
||||
VMID guid.GUID
|
||||
ServiceID guid.GUID
|
||||
}
|
||||
|
||||
// Network returns the address's network name, "hvsock".
|
||||
func (addr *HvsockAddr) Network() string {
|
||||
return "hvsock"
|
||||
}
|
||||
|
||||
func (addr *HvsockAddr) String() string {
|
||||
return fmt.Sprintf("%s:%s", &addr.VMID, &addr.ServiceID)
|
||||
}
|
||||
|
||||
// VsockServiceID returns an hvsock service ID corresponding to the specified AF_VSOCK port.
|
||||
func VsockServiceID(port uint32) guid.GUID {
|
||||
g, _ := guid.FromString("00000000-facb-11e6-bd58-64006a7986d3")
|
||||
g.Data1 = port
|
||||
return g
|
||||
}
|
||||
|
||||
func (addr *HvsockAddr) raw() rawHvsockAddr {
|
||||
return rawHvsockAddr{
|
||||
Family: afHvSock,
|
||||
VMID: addr.VMID,
|
||||
ServiceID: addr.ServiceID,
|
||||
}
|
||||
}
|
||||
|
||||
func (addr *HvsockAddr) fromRaw(raw *rawHvsockAddr) {
|
||||
addr.VMID = raw.VMID
|
||||
addr.ServiceID = raw.ServiceID
|
||||
}
|
||||
|
||||
// HvsockListener is a socket listener for the AF_HYPERV address family.
|
||||
type HvsockListener struct {
|
||||
sock *win32File
|
||||
addr HvsockAddr
|
||||
}
|
||||
|
||||
// HvsockConn is a connected socket of the AF_HYPERV address family.
|
||||
type HvsockConn struct {
|
||||
sock *win32File
|
||||
local, remote HvsockAddr
|
||||
}
|
||||
|
||||
func newHvSocket() (*win32File, error) {
|
||||
fd, err := syscall.Socket(afHvSock, syscall.SOCK_STREAM, 1)
|
||||
if err != nil {
|
||||
return nil, os.NewSyscallError("socket", err)
|
||||
}
|
||||
f, err := makeWin32File(fd)
|
||||
if err != nil {
|
||||
syscall.Close(fd)
|
||||
return nil, err
|
||||
}
|
||||
f.socket = true
|
||||
return f, nil
|
||||
}
|
||||
|
||||
// ListenHvsock listens for connections on the specified hvsock address.
|
||||
func ListenHvsock(addr *HvsockAddr) (_ *HvsockListener, err error) {
|
||||
l := &HvsockListener{addr: *addr}
|
||||
sock, err := newHvSocket()
|
||||
if err != nil {
|
||||
return nil, l.opErr("listen", err)
|
||||
}
|
||||
sa := addr.raw()
|
||||
err = bind(sock.handle, unsafe.Pointer(&sa), int32(unsafe.Sizeof(sa)))
|
||||
if err != nil {
|
||||
return nil, l.opErr("listen", os.NewSyscallError("socket", err))
|
||||
}
|
||||
err = syscall.Listen(sock.handle, 16)
|
||||
if err != nil {
|
||||
return nil, l.opErr("listen", os.NewSyscallError("listen", err))
|
||||
}
|
||||
return &HvsockListener{sock: sock, addr: *addr}, nil
|
||||
}
|
||||
|
||||
func (l *HvsockListener) opErr(op string, err error) error {
|
||||
return &net.OpError{Op: op, Net: "hvsock", Addr: &l.addr, Err: err}
|
||||
}
|
||||
|
||||
// Addr returns the listener's network address.
|
||||
func (l *HvsockListener) Addr() net.Addr {
|
||||
return &l.addr
|
||||
}
|
||||
|
||||
// Accept waits for the next connection and returns it.
|
||||
func (l *HvsockListener) Accept() (_ net.Conn, err error) {
|
||||
sock, err := newHvSocket()
|
||||
if err != nil {
|
||||
return nil, l.opErr("accept", err)
|
||||
}
|
||||
defer func() {
|
||||
if sock != nil {
|
||||
sock.Close()
|
||||
}
|
||||
}()
|
||||
c, err := l.sock.prepareIo()
|
||||
if err != nil {
|
||||
return nil, l.opErr("accept", err)
|
||||
}
|
||||
defer l.sock.wg.Done()
|
||||
|
||||
// AcceptEx, per documentation, requires an extra 16 bytes per address.
|
||||
const addrlen = uint32(16 + unsafe.Sizeof(rawHvsockAddr{}))
|
||||
var addrbuf [addrlen * 2]byte
|
||||
|
||||
var bytes uint32
|
||||
err = syscall.AcceptEx(l.sock.handle, sock.handle, &addrbuf[0], 0, addrlen, addrlen, &bytes, &c.o)
|
||||
_, err = l.sock.asyncIo(c, nil, bytes, err)
|
||||
if err != nil {
|
||||
return nil, l.opErr("accept", os.NewSyscallError("acceptex", err))
|
||||
}
|
||||
conn := &HvsockConn{
|
||||
sock: sock,
|
||||
}
|
||||
conn.local.fromRaw((*rawHvsockAddr)(unsafe.Pointer(&addrbuf[0])))
|
||||
conn.remote.fromRaw((*rawHvsockAddr)(unsafe.Pointer(&addrbuf[addrlen])))
|
||||
sock = nil
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// Close closes the listener, causing any pending Accept calls to fail.
|
||||
func (l *HvsockListener) Close() error {
|
||||
return l.sock.Close()
|
||||
}
|
||||
|
||||
/* Need to finish ConnectEx handling
|
||||
func DialHvsock(ctx context.Context, addr *HvsockAddr) (*HvsockConn, error) {
|
||||
sock, err := newHvSocket()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
if sock != nil {
|
||||
sock.Close()
|
||||
}
|
||||
}()
|
||||
c, err := sock.prepareIo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer sock.wg.Done()
|
||||
var bytes uint32
|
||||
err = windows.ConnectEx(windows.Handle(sock.handle), sa, nil, 0, &bytes, &c.o)
|
||||
_, err = sock.asyncIo(ctx, c, nil, bytes, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
conn := &HvsockConn{
|
||||
sock: sock,
|
||||
remote: *addr,
|
||||
}
|
||||
sock = nil
|
||||
return conn, nil
|
||||
}
|
||||
*/
|
||||
|
||||
func (conn *HvsockConn) opErr(op string, err error) error {
|
||||
return &net.OpError{Op: op, Net: "hvsock", Source: &conn.local, Addr: &conn.remote, Err: err}
|
||||
}
|
||||
|
||||
func (conn *HvsockConn) Read(b []byte) (int, error) {
|
||||
c, err := conn.sock.prepareIo()
|
||||
if err != nil {
|
||||
return 0, conn.opErr("read", err)
|
||||
}
|
||||
defer conn.sock.wg.Done()
|
||||
buf := syscall.WSABuf{Buf: &b[0], Len: uint32(len(b))}
|
||||
var flags, bytes uint32
|
||||
err = syscall.WSARecv(conn.sock.handle, &buf, 1, &bytes, &flags, &c.o, nil)
|
||||
n, err := conn.sock.asyncIo(c, &conn.sock.readDeadline, bytes, err)
|
||||
if err != nil {
|
||||
if _, ok := err.(syscall.Errno); ok {
|
||||
err = os.NewSyscallError("wsarecv", err)
|
||||
}
|
||||
return 0, conn.opErr("read", err)
|
||||
} else if n == 0 {
|
||||
err = io.EOF
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (conn *HvsockConn) Write(b []byte) (int, error) {
|
||||
t := 0
|
||||
for len(b) != 0 {
|
||||
n, err := conn.write(b)
|
||||
if err != nil {
|
||||
return t + n, err
|
||||
}
|
||||
t += n
|
||||
b = b[n:]
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func (conn *HvsockConn) write(b []byte) (int, error) {
|
||||
c, err := conn.sock.prepareIo()
|
||||
if err != nil {
|
||||
return 0, conn.opErr("write", err)
|
||||
}
|
||||
defer conn.sock.wg.Done()
|
||||
buf := syscall.WSABuf{Buf: &b[0], Len: uint32(len(b))}
|
||||
var bytes uint32
|
||||
err = syscall.WSASend(conn.sock.handle, &buf, 1, &bytes, 0, &c.o, nil)
|
||||
n, err := conn.sock.asyncIo(c, &conn.sock.writeDeadline, bytes, err)
|
||||
if err != nil {
|
||||
if _, ok := err.(syscall.Errno); ok {
|
||||
err = os.NewSyscallError("wsasend", err)
|
||||
}
|
||||
return 0, conn.opErr("write", err)
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
// Close closes the socket connection, failing any pending read or write calls.
|
||||
func (conn *HvsockConn) Close() error {
|
||||
return conn.sock.Close()
|
||||
}
|
||||
|
||||
func (conn *HvsockConn) shutdown(how int) error {
|
||||
err := syscall.Shutdown(conn.sock.handle, syscall.SHUT_RD)
|
||||
if err != nil {
|
||||
return os.NewSyscallError("shutdown", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CloseRead shuts down the read end of the socket.
|
||||
func (conn *HvsockConn) CloseRead() error {
|
||||
err := conn.shutdown(syscall.SHUT_RD)
|
||||
if err != nil {
|
||||
return conn.opErr("close", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CloseWrite shuts down the write end of the socket, notifying the other endpoint that
|
||||
// no more data will be written.
|
||||
func (conn *HvsockConn) CloseWrite() error {
|
||||
err := conn.shutdown(syscall.SHUT_WR)
|
||||
if err != nil {
|
||||
return conn.opErr("close", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LocalAddr returns the local address of the connection.
|
||||
func (conn *HvsockConn) LocalAddr() net.Addr {
|
||||
return &conn.local
|
||||
}
|
||||
|
||||
// RemoteAddr returns the remote address of the connection.
|
||||
func (conn *HvsockConn) RemoteAddr() net.Addr {
|
||||
return &conn.remote
|
||||
}
|
||||
|
||||
// SetDeadline implements the net.Conn SetDeadline method.
|
||||
func (conn *HvsockConn) SetDeadline(t time.Time) error {
|
||||
conn.SetReadDeadline(t)
|
||||
conn.SetWriteDeadline(t)
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetReadDeadline implements the net.Conn SetReadDeadline method.
|
||||
func (conn *HvsockConn) SetReadDeadline(t time.Time) error {
|
||||
return conn.sock.SetReadDeadline(t)
|
||||
}
|
||||
|
||||
// SetWriteDeadline implements the net.Conn SetWriteDeadline method.
|
||||
func (conn *HvsockConn) SetWriteDeadline(t time.Time) error {
|
||||
return conn.sock.SetWriteDeadline(t)
|
||||
}
|
510
vendor/github.com/Microsoft/go-winio/pipe.go
generated
vendored
510
vendor/github.com/Microsoft/go-winio/pipe.go
generated
vendored
@ -1,510 +0,0 @@
|
||||
// +build windows
|
||||
|
||||
package winio
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
//sys connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) = ConnectNamedPipe
|
||||
//sys createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateNamedPipeW
|
||||
//sys createFile(name string, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateFileW
|
||||
//sys getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo
|
||||
//sys getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW
|
||||
//sys localAlloc(uFlags uint32, length uint32) (ptr uintptr) = LocalAlloc
|
||||
//sys ntCreateNamedPipeFile(pipe *syscall.Handle, access uint32, oa *objectAttributes, iosb *ioStatusBlock, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntstatus) = ntdll.NtCreateNamedPipeFile
|
||||
//sys rtlNtStatusToDosError(status ntstatus) (winerr error) = ntdll.RtlNtStatusToDosErrorNoTeb
|
||||
//sys rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntstatus) = ntdll.RtlDosPathNameToNtPathName_U
|
||||
//sys rtlDefaultNpAcl(dacl *uintptr) (status ntstatus) = ntdll.RtlDefaultNpAcl
|
||||
|
||||
type ioStatusBlock struct {
|
||||
Status, Information uintptr
|
||||
}
|
||||
|
||||
type objectAttributes struct {
|
||||
Length uintptr
|
||||
RootDirectory uintptr
|
||||
ObjectName *unicodeString
|
||||
Attributes uintptr
|
||||
SecurityDescriptor *securityDescriptor
|
||||
SecurityQoS uintptr
|
||||
}
|
||||
|
||||
type unicodeString struct {
|
||||
Length uint16
|
||||
MaximumLength uint16
|
||||
Buffer uintptr
|
||||
}
|
||||
|
||||
type securityDescriptor struct {
|
||||
Revision byte
|
||||
Sbz1 byte
|
||||
Control uint16
|
||||
Owner uintptr
|
||||
Group uintptr
|
||||
Sacl uintptr
|
||||
Dacl uintptr
|
||||
}
|
||||
|
||||
type ntstatus int32
|
||||
|
||||
func (status ntstatus) Err() error {
|
||||
if status >= 0 {
|
||||
return nil
|
||||
}
|
||||
return rtlNtStatusToDosError(status)
|
||||
}
|
||||
|
||||
const (
|
||||
cERROR_PIPE_BUSY = syscall.Errno(231)
|
||||
cERROR_NO_DATA = syscall.Errno(232)
|
||||
cERROR_PIPE_CONNECTED = syscall.Errno(535)
|
||||
cERROR_SEM_TIMEOUT = syscall.Errno(121)
|
||||
|
||||
cSECURITY_SQOS_PRESENT = 0x100000
|
||||
cSECURITY_ANONYMOUS = 0
|
||||
|
||||
cPIPE_TYPE_MESSAGE = 4
|
||||
|
||||
cPIPE_READMODE_MESSAGE = 2
|
||||
|
||||
cFILE_OPEN = 1
|
||||
cFILE_CREATE = 2
|
||||
|
||||
cFILE_PIPE_MESSAGE_TYPE = 1
|
||||
cFILE_PIPE_REJECT_REMOTE_CLIENTS = 2
|
||||
|
||||
cSE_DACL_PRESENT = 4
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrPipeListenerClosed is returned for pipe operations on listeners that have been closed.
|
||||
// This error should match net.errClosing since docker takes a dependency on its text.
|
||||
ErrPipeListenerClosed = errors.New("use of closed network connection")
|
||||
|
||||
errPipeWriteClosed = errors.New("pipe has been closed for write")
|
||||
)
|
||||
|
||||
type win32Pipe struct {
|
||||
*win32File
|
||||
path string
|
||||
}
|
||||
|
||||
type win32MessageBytePipe struct {
|
||||
win32Pipe
|
||||
writeClosed bool
|
||||
readEOF bool
|
||||
}
|
||||
|
||||
type pipeAddress string
|
||||
|
||||
func (f *win32Pipe) LocalAddr() net.Addr {
|
||||
return pipeAddress(f.path)
|
||||
}
|
||||
|
||||
func (f *win32Pipe) RemoteAddr() net.Addr {
|
||||
return pipeAddress(f.path)
|
||||
}
|
||||
|
||||
func (f *win32Pipe) SetDeadline(t time.Time) error {
|
||||
f.SetReadDeadline(t)
|
||||
f.SetWriteDeadline(t)
|
||||
return nil
|
||||
}
|
||||
|
||||
// CloseWrite closes the write side of a message pipe in byte mode.
|
||||
func (f *win32MessageBytePipe) CloseWrite() error {
|
||||
if f.writeClosed {
|
||||
return errPipeWriteClosed
|
||||
}
|
||||
err := f.win32File.Flush()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = f.win32File.Write(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.writeClosed = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// Write writes bytes to a message pipe in byte mode. Zero-byte writes are ignored, since
|
||||
// they are used to implement CloseWrite().
|
||||
func (f *win32MessageBytePipe) Write(b []byte) (int, error) {
|
||||
if f.writeClosed {
|
||||
return 0, errPipeWriteClosed
|
||||
}
|
||||
if len(b) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
return f.win32File.Write(b)
|
||||
}
|
||||
|
||||
// Read reads bytes from a message pipe in byte mode. A read of a zero-byte message on a message
|
||||
// mode pipe will return io.EOF, as will all subsequent reads.
|
||||
func (f *win32MessageBytePipe) Read(b []byte) (int, error) {
|
||||
if f.readEOF {
|
||||
return 0, io.EOF
|
||||
}
|
||||
n, err := f.win32File.Read(b)
|
||||
if err == io.EOF {
|
||||
// If this was the result of a zero-byte read, then
|
||||
// it is possible that the read was due to a zero-size
|
||||
// message. Since we are simulating CloseWrite with a
|
||||
// zero-byte message, ensure that all future Read() calls
|
||||
// also return EOF.
|
||||
f.readEOF = true
|
||||
} else if err == syscall.ERROR_MORE_DATA {
|
||||
// ERROR_MORE_DATA indicates that the pipe's read mode is message mode
|
||||
// and the message still has more bytes. Treat this as a success, since
|
||||
// this package presents all named pipes as byte streams.
|
||||
err = nil
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (s pipeAddress) Network() string {
|
||||
return "pipe"
|
||||
}
|
||||
|
||||
func (s pipeAddress) String() string {
|
||||
return string(s)
|
||||
}
|
||||
|
||||
// tryDialPipe attempts to dial the pipe at `path` until `ctx` cancellation or timeout.
|
||||
func tryDialPipe(ctx context.Context, path *string) (syscall.Handle, error) {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return syscall.Handle(0), ctx.Err()
|
||||
default:
|
||||
h, err := createFile(*path, syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_OVERLAPPED|cSECURITY_SQOS_PRESENT|cSECURITY_ANONYMOUS, 0)
|
||||
if err == nil {
|
||||
return h, nil
|
||||
}
|
||||
if err != cERROR_PIPE_BUSY {
|
||||
return h, &os.PathError{Err: err, Op: "open", Path: *path}
|
||||
}
|
||||
// Wait 10 msec and try again. This is a rather simplistic
|
||||
// view, as we always try each 10 milliseconds.
|
||||
time.Sleep(time.Millisecond * 10)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DialPipe connects to a named pipe by path, timing out if the connection
|
||||
// takes longer than the specified duration. If timeout is nil, then we use
|
||||
// a default timeout of 2 seconds. (We do not use WaitNamedPipe.)
|
||||
func DialPipe(path string, timeout *time.Duration) (net.Conn, error) {
|
||||
var absTimeout time.Time
|
||||
if timeout != nil {
|
||||
absTimeout = time.Now().Add(*timeout)
|
||||
} else {
|
||||
absTimeout = time.Now().Add(time.Second * 2)
|
||||
}
|
||||
ctx, _ := context.WithDeadline(context.Background(), absTimeout)
|
||||
conn, err := DialPipeContext(ctx, path)
|
||||
if err == context.DeadlineExceeded {
|
||||
return nil, ErrTimeout
|
||||
}
|
||||
return conn, err
|
||||
}
|
||||
|
||||
// DialPipeContext attempts to connect to a named pipe by `path` until `ctx`
|
||||
// cancellation or timeout.
|
||||
func DialPipeContext(ctx context.Context, path string) (net.Conn, error) {
|
||||
var err error
|
||||
var h syscall.Handle
|
||||
h, err = tryDialPipe(ctx, &path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var flags uint32
|
||||
err = getNamedPipeInfo(h, &flags, nil, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
f, err := makeWin32File(h)
|
||||
if err != nil {
|
||||
syscall.Close(h)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If the pipe is in message mode, return a message byte pipe, which
|
||||
// supports CloseWrite().
|
||||
if flags&cPIPE_TYPE_MESSAGE != 0 {
|
||||
return &win32MessageBytePipe{
|
||||
win32Pipe: win32Pipe{win32File: f, path: path},
|
||||
}, nil
|
||||
}
|
||||
return &win32Pipe{win32File: f, path: path}, nil
|
||||
}
|
||||
|
||||
type acceptResponse struct {
|
||||
f *win32File
|
||||
err error
|
||||
}
|
||||
|
||||
type win32PipeListener struct {
|
||||
firstHandle syscall.Handle
|
||||
path string
|
||||
config PipeConfig
|
||||
acceptCh chan (chan acceptResponse)
|
||||
closeCh chan int
|
||||
doneCh chan int
|
||||
}
|
||||
|
||||
func makeServerPipeHandle(path string, sd []byte, c *PipeConfig, first bool) (syscall.Handle, error) {
|
||||
path16, err := syscall.UTF16FromString(path)
|
||||
if err != nil {
|
||||
return 0, &os.PathError{Op: "open", Path: path, Err: err}
|
||||
}
|
||||
|
||||
var oa objectAttributes
|
||||
oa.Length = unsafe.Sizeof(oa)
|
||||
|
||||
var ntPath unicodeString
|
||||
if err := rtlDosPathNameToNtPathName(&path16[0], &ntPath, 0, 0).Err(); err != nil {
|
||||
return 0, &os.PathError{Op: "open", Path: path, Err: err}
|
||||
}
|
||||
defer localFree(ntPath.Buffer)
|
||||
oa.ObjectName = &ntPath
|
||||
|
||||
// The security descriptor is only needed for the first pipe.
|
||||
if first {
|
||||
if sd != nil {
|
||||
len := uint32(len(sd))
|
||||
sdb := localAlloc(0, len)
|
||||
defer localFree(sdb)
|
||||
copy((*[0xffff]byte)(unsafe.Pointer(sdb))[:], sd)
|
||||
oa.SecurityDescriptor = (*securityDescriptor)(unsafe.Pointer(sdb))
|
||||
} else {
|
||||
// Construct the default named pipe security descriptor.
|
||||
var dacl uintptr
|
||||
if err := rtlDefaultNpAcl(&dacl).Err(); err != nil {
|
||||
return 0, fmt.Errorf("getting default named pipe ACL: %s", err)
|
||||
}
|
||||
defer localFree(dacl)
|
||||
|
||||
sdb := &securityDescriptor{
|
||||
Revision: 1,
|
||||
Control: cSE_DACL_PRESENT,
|
||||
Dacl: dacl,
|
||||
}
|
||||
oa.SecurityDescriptor = sdb
|
||||
}
|
||||
}
|
||||
|
||||
typ := uint32(cFILE_PIPE_REJECT_REMOTE_CLIENTS)
|
||||
if c.MessageMode {
|
||||
typ |= cFILE_PIPE_MESSAGE_TYPE
|
||||
}
|
||||
|
||||
disposition := uint32(cFILE_OPEN)
|
||||
access := uint32(syscall.GENERIC_READ | syscall.GENERIC_WRITE | syscall.SYNCHRONIZE)
|
||||
if first {
|
||||
disposition = cFILE_CREATE
|
||||
// By not asking for read or write access, the named pipe file system
|
||||
// will put this pipe into an initially disconnected state, blocking
|
||||
// client connections until the next call with first == false.
|
||||
access = syscall.SYNCHRONIZE
|
||||
}
|
||||
|
||||
timeout := int64(-50 * 10000) // 50ms
|
||||
|
||||
var (
|
||||
h syscall.Handle
|
||||
iosb ioStatusBlock
|
||||
)
|
||||
err = ntCreateNamedPipeFile(&h, access, &oa, &iosb, syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE, disposition, 0, typ, 0, 0, 0xffffffff, uint32(c.InputBufferSize), uint32(c.OutputBufferSize), &timeout).Err()
|
||||
if err != nil {
|
||||
return 0, &os.PathError{Op: "open", Path: path, Err: err}
|
||||
}
|
||||
|
||||
runtime.KeepAlive(ntPath)
|
||||
return h, nil
|
||||
}
|
||||
|
||||
func (l *win32PipeListener) makeServerPipe() (*win32File, error) {
|
||||
h, err := makeServerPipeHandle(l.path, nil, &l.config, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f, err := makeWin32File(h)
|
||||
if err != nil {
|
||||
syscall.Close(h)
|
||||
return nil, err
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (l *win32PipeListener) makeConnectedServerPipe() (*win32File, error) {
|
||||
p, err := l.makeServerPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Wait for the client to connect.
|
||||
ch := make(chan error)
|
||||
go func(p *win32File) {
|
||||
ch <- connectPipe(p)
|
||||
}(p)
|
||||
|
||||
select {
|
||||
case err = <-ch:
|
||||
if err != nil {
|
||||
p.Close()
|
||||
p = nil
|
||||
}
|
||||
case <-l.closeCh:
|
||||
// Abort the connect request by closing the handle.
|
||||
p.Close()
|
||||
p = nil
|
||||
err = <-ch
|
||||
if err == nil || err == ErrFileClosed {
|
||||
err = ErrPipeListenerClosed
|
||||
}
|
||||
}
|
||||
return p, err
|
||||
}
|
||||
|
||||
func (l *win32PipeListener) listenerRoutine() {
|
||||
closed := false
|
||||
for !closed {
|
||||
select {
|
||||
case <-l.closeCh:
|
||||
closed = true
|
||||
case responseCh := <-l.acceptCh:
|
||||
var (
|
||||
p *win32File
|
||||
err error
|
||||
)
|
||||
for {
|
||||
p, err = l.makeConnectedServerPipe()
|
||||
// If the connection was immediately closed by the client, try
|
||||
// again.
|
||||
if err != cERROR_NO_DATA {
|
||||
break
|
||||
}
|
||||
}
|
||||
responseCh <- acceptResponse{p, err}
|
||||
closed = err == ErrPipeListenerClosed
|
||||
}
|
||||
}
|
||||
syscall.Close(l.firstHandle)
|
||||
l.firstHandle = 0
|
||||
// Notify Close() and Accept() callers that the handle has been closed.
|
||||
close(l.doneCh)
|
||||
}
|
||||
|
||||
// PipeConfig contain configuration for the pipe listener.
|
||||
type PipeConfig struct {
|
||||
// SecurityDescriptor contains a Windows security descriptor in SDDL format.
|
||||
SecurityDescriptor string
|
||||
|
||||
// MessageMode determines whether the pipe is in byte or message mode. In either
|
||||
// case the pipe is read in byte mode by default. The only practical difference in
|
||||
// this implementation is that CloseWrite() is only supported for message mode pipes;
|
||||
// CloseWrite() is implemented as a zero-byte write, but zero-byte writes are only
|
||||
// transferred to the reader (and returned as io.EOF in this implementation)
|
||||
// when the pipe is in message mode.
|
||||
MessageMode bool
|
||||
|
||||
// InputBufferSize specifies the size the input buffer, in bytes.
|
||||
InputBufferSize int32
|
||||
|
||||
// OutputBufferSize specifies the size the input buffer, in bytes.
|
||||
OutputBufferSize int32
|
||||
}
|
||||
|
||||
// ListenPipe creates a listener on a Windows named pipe path, e.g. \\.\pipe\mypipe.
|
||||
// The pipe must not already exist.
|
||||
func ListenPipe(path string, c *PipeConfig) (net.Listener, error) {
|
||||
var (
|
||||
sd []byte
|
||||
err error
|
||||
)
|
||||
if c == nil {
|
||||
c = &PipeConfig{}
|
||||
}
|
||||
if c.SecurityDescriptor != "" {
|
||||
sd, err = SddlToSecurityDescriptor(c.SecurityDescriptor)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
h, err := makeServerPipeHandle(path, sd, c, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
l := &win32PipeListener{
|
||||
firstHandle: h,
|
||||
path: path,
|
||||
config: *c,
|
||||
acceptCh: make(chan (chan acceptResponse)),
|
||||
closeCh: make(chan int),
|
||||
doneCh: make(chan int),
|
||||
}
|
||||
go l.listenerRoutine()
|
||||
return l, nil
|
||||
}
|
||||
|
||||
func connectPipe(p *win32File) error {
|
||||
c, err := p.prepareIo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer p.wg.Done()
|
||||
|
||||
err = connectNamedPipe(p.handle, &c.o)
|
||||
_, err = p.asyncIo(c, nil, 0, err)
|
||||
if err != nil && err != cERROR_PIPE_CONNECTED {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *win32PipeListener) Accept() (net.Conn, error) {
|
||||
ch := make(chan acceptResponse)
|
||||
select {
|
||||
case l.acceptCh <- ch:
|
||||
response := <-ch
|
||||
err := response.err
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if l.config.MessageMode {
|
||||
return &win32MessageBytePipe{
|
||||
win32Pipe: win32Pipe{win32File: response.f, path: l.path},
|
||||
}, nil
|
||||
}
|
||||
return &win32Pipe{win32File: response.f, path: l.path}, nil
|
||||
case <-l.doneCh:
|
||||
return nil, ErrPipeListenerClosed
|
||||
}
|
||||
}
|
||||
|
||||
func (l *win32PipeListener) Close() error {
|
||||
select {
|
||||
case l.closeCh <- 1:
|
||||
<-l.doneCh
|
||||
case <-l.doneCh:
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *win32PipeListener) Addr() net.Addr {
|
||||
return pipeAddress(l.path)
|
||||
}
|
235
vendor/github.com/Microsoft/go-winio/pkg/guid/guid.go
generated
vendored
235
vendor/github.com/Microsoft/go-winio/pkg/guid/guid.go
generated
vendored
@ -1,235 +0,0 @@
|
||||
// Package guid provides a GUID type. The backing structure for a GUID is
|
||||
// identical to that used by the golang.org/x/sys/windows GUID type.
|
||||
// There are two main binary encodings used for a GUID, the big-endian encoding,
|
||||
// and the Windows (mixed-endian) encoding. See here for details:
|
||||
// https://en.wikipedia.org/wiki/Universally_unique_identifier#Encoding
|
||||
package guid
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/sha1"
|
||||
"encoding"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// Variant specifies which GUID variant (or "type") of the GUID. It determines
|
||||
// how the entirety of the rest of the GUID is interpreted.
|
||||
type Variant uint8
|
||||
|
||||
// The variants specified by RFC 4122.
|
||||
const (
|
||||
// VariantUnknown specifies a GUID variant which does not conform to one of
|
||||
// the variant encodings specified in RFC 4122.
|
||||
VariantUnknown Variant = iota
|
||||
VariantNCS
|
||||
VariantRFC4122
|
||||
VariantMicrosoft
|
||||
VariantFuture
|
||||
)
|
||||
|
||||
// Version specifies how the bits in the GUID were generated. For instance, a
|
||||
// version 4 GUID is randomly generated, and a version 5 is generated from the
|
||||
// hash of an input string.
|
||||
type Version uint8
|
||||
|
||||
var _ = (encoding.TextMarshaler)(GUID{})
|
||||
var _ = (encoding.TextUnmarshaler)(&GUID{})
|
||||
|
||||
// GUID represents a GUID/UUID. It has the same structure as
|
||||
// golang.org/x/sys/windows.GUID so that it can be used with functions expecting
|
||||
// that type. It is defined as its own type so that stringification and
|
||||
// marshaling can be supported. The representation matches that used by native
|
||||
// Windows code.
|
||||
type GUID windows.GUID
|
||||
|
||||
// NewV4 returns a new version 4 (pseudorandom) GUID, as defined by RFC 4122.
|
||||
func NewV4() (GUID, error) {
|
||||
var b [16]byte
|
||||
if _, err := rand.Read(b[:]); err != nil {
|
||||
return GUID{}, err
|
||||
}
|
||||
|
||||
g := FromArray(b)
|
||||
g.setVersion(4) // Version 4 means randomly generated.
|
||||
g.setVariant(VariantRFC4122)
|
||||
|
||||
return g, nil
|
||||
}
|
||||
|
||||
// NewV5 returns a new version 5 (generated from a string via SHA-1 hashing)
|
||||
// GUID, as defined by RFC 4122. The RFC is unclear on the encoding of the name,
|
||||
// and the sample code treats it as a series of bytes, so we do the same here.
|
||||
//
|
||||
// Some implementations, such as those found on Windows, treat the name as a
|
||||
// big-endian UTF16 stream of bytes. If that is desired, the string can be
|
||||
// encoded as such before being passed to this function.
|
||||
func NewV5(namespace GUID, name []byte) (GUID, error) {
|
||||
b := sha1.New()
|
||||
namespaceBytes := namespace.ToArray()
|
||||
b.Write(namespaceBytes[:])
|
||||
b.Write(name)
|
||||
|
||||
a := [16]byte{}
|
||||
copy(a[:], b.Sum(nil))
|
||||
|
||||
g := FromArray(a)
|
||||
g.setVersion(5) // Version 5 means generated from a string.
|
||||
g.setVariant(VariantRFC4122)
|
||||
|
||||
return g, nil
|
||||
}
|
||||
|
||||
func fromArray(b [16]byte, order binary.ByteOrder) GUID {
|
||||
var g GUID
|
||||
g.Data1 = order.Uint32(b[0:4])
|
||||
g.Data2 = order.Uint16(b[4:6])
|
||||
g.Data3 = order.Uint16(b[6:8])
|
||||
copy(g.Data4[:], b[8:16])
|
||||
return g
|
||||
}
|
||||
|
||||
func (g GUID) toArray(order binary.ByteOrder) [16]byte {
|
||||
b := [16]byte{}
|
||||
order.PutUint32(b[0:4], g.Data1)
|
||||
order.PutUint16(b[4:6], g.Data2)
|
||||
order.PutUint16(b[6:8], g.Data3)
|
||||
copy(b[8:16], g.Data4[:])
|
||||
return b
|
||||
}
|
||||
|
||||
// FromArray constructs a GUID from a big-endian encoding array of 16 bytes.
|
||||
func FromArray(b [16]byte) GUID {
|
||||
return fromArray(b, binary.BigEndian)
|
||||
}
|
||||
|
||||
// ToArray returns an array of 16 bytes representing the GUID in big-endian
|
||||
// encoding.
|
||||
func (g GUID) ToArray() [16]byte {
|
||||
return g.toArray(binary.BigEndian)
|
||||
}
|
||||
|
||||
// FromWindowsArray constructs a GUID from a Windows encoding array of bytes.
|
||||
func FromWindowsArray(b [16]byte) GUID {
|
||||
return fromArray(b, binary.LittleEndian)
|
||||
}
|
||||
|
||||
// ToWindowsArray returns an array of 16 bytes representing the GUID in Windows
|
||||
// encoding.
|
||||
func (g GUID) ToWindowsArray() [16]byte {
|
||||
return g.toArray(binary.LittleEndian)
|
||||
}
|
||||
|
||||
func (g GUID) String() string {
|
||||
return fmt.Sprintf(
|
||||
"%08x-%04x-%04x-%04x-%012x",
|
||||
g.Data1,
|
||||
g.Data2,
|
||||
g.Data3,
|
||||
g.Data4[:2],
|
||||
g.Data4[2:])
|
||||
}
|
||||
|
||||
// FromString parses a string containing a GUID and returns the GUID. The only
|
||||
// format currently supported is the `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
|
||||
// format.
|
||||
func FromString(s string) (GUID, error) {
|
||||
if len(s) != 36 {
|
||||
return GUID{}, fmt.Errorf("invalid GUID %q", s)
|
||||
}
|
||||
if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
|
||||
return GUID{}, fmt.Errorf("invalid GUID %q", s)
|
||||
}
|
||||
|
||||
var g GUID
|
||||
|
||||
data1, err := strconv.ParseUint(s[0:8], 16, 32)
|
||||
if err != nil {
|
||||
return GUID{}, fmt.Errorf("invalid GUID %q", s)
|
||||
}
|
||||
g.Data1 = uint32(data1)
|
||||
|
||||
data2, err := strconv.ParseUint(s[9:13], 16, 16)
|
||||
if err != nil {
|
||||
return GUID{}, fmt.Errorf("invalid GUID %q", s)
|
||||
}
|
||||
g.Data2 = uint16(data2)
|
||||
|
||||
data3, err := strconv.ParseUint(s[14:18], 16, 16)
|
||||
if err != nil {
|
||||
return GUID{}, fmt.Errorf("invalid GUID %q", s)
|
||||
}
|
||||
g.Data3 = uint16(data3)
|
||||
|
||||
for i, x := range []int{19, 21, 24, 26, 28, 30, 32, 34} {
|
||||
v, err := strconv.ParseUint(s[x:x+2], 16, 8)
|
||||
if err != nil {
|
||||
return GUID{}, fmt.Errorf("invalid GUID %q", s)
|
||||
}
|
||||
g.Data4[i] = uint8(v)
|
||||
}
|
||||
|
||||
return g, nil
|
||||
}
|
||||
|
||||
func (g *GUID) setVariant(v Variant) {
|
||||
d := g.Data4[0]
|
||||
switch v {
|
||||
case VariantNCS:
|
||||
d = (d & 0x7f)
|
||||
case VariantRFC4122:
|
||||
d = (d & 0x3f) | 0x80
|
||||
case VariantMicrosoft:
|
||||
d = (d & 0x1f) | 0xc0
|
||||
case VariantFuture:
|
||||
d = (d & 0x0f) | 0xe0
|
||||
case VariantUnknown:
|
||||
fallthrough
|
||||
default:
|
||||
panic(fmt.Sprintf("invalid variant: %d", v))
|
||||
}
|
||||
g.Data4[0] = d
|
||||
}
|
||||
|
||||
// Variant returns the GUID variant, as defined in RFC 4122.
|
||||
func (g GUID) Variant() Variant {
|
||||
b := g.Data4[0]
|
||||
if b&0x80 == 0 {
|
||||
return VariantNCS
|
||||
} else if b&0xc0 == 0x80 {
|
||||
return VariantRFC4122
|
||||
} else if b&0xe0 == 0xc0 {
|
||||
return VariantMicrosoft
|
||||
} else if b&0xe0 == 0xe0 {
|
||||
return VariantFuture
|
||||
}
|
||||
return VariantUnknown
|
||||
}
|
||||
|
||||
func (g *GUID) setVersion(v Version) {
|
||||
g.Data3 = (g.Data3 & 0x0fff) | (uint16(v) << 12)
|
||||
}
|
||||
|
||||
// Version returns the GUID version, as defined in RFC 4122.
|
||||
func (g GUID) Version() Version {
|
||||
return Version((g.Data3 & 0xF000) >> 12)
|
||||
}
|
||||
|
||||
// MarshalText returns the textual representation of the GUID.
|
||||
func (g GUID) MarshalText() ([]byte, error) {
|
||||
return []byte(g.String()), nil
|
||||
}
|
||||
|
||||
// UnmarshalText takes the textual representation of a GUID, and unmarhals it
|
||||
// into this GUID.
|
||||
func (g *GUID) UnmarshalText(text []byte) error {
|
||||
g2, err := FromString(string(text))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*g = g2
|
||||
return nil
|
||||
}
|
202
vendor/github.com/Microsoft/go-winio/privilege.go
generated
vendored
202
vendor/github.com/Microsoft/go-winio/privilege.go
generated
vendored
@ -1,202 +0,0 @@
|
||||
// +build windows
|
||||
|
||||
package winio
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"sync"
|
||||
"syscall"
|
||||
"unicode/utf16"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
//sys adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) [true] = advapi32.AdjustTokenPrivileges
|
||||
//sys impersonateSelf(level uint32) (err error) = advapi32.ImpersonateSelf
|
||||
//sys revertToSelf() (err error) = advapi32.RevertToSelf
|
||||
//sys openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) = advapi32.OpenThreadToken
|
||||
//sys getCurrentThread() (h syscall.Handle) = GetCurrentThread
|
||||
//sys lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) = advapi32.LookupPrivilegeValueW
|
||||
//sys lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) = advapi32.LookupPrivilegeNameW
|
||||
//sys lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) = advapi32.LookupPrivilegeDisplayNameW
|
||||
|
||||
const (
|
||||
SE_PRIVILEGE_ENABLED = 2
|
||||
|
||||
ERROR_NOT_ALL_ASSIGNED syscall.Errno = 1300
|
||||
|
||||
SeBackupPrivilege = "SeBackupPrivilege"
|
||||
SeRestorePrivilege = "SeRestorePrivilege"
|
||||
)
|
||||
|
||||
const (
|
||||
securityAnonymous = iota
|
||||
securityIdentification
|
||||
securityImpersonation
|
||||
securityDelegation
|
||||
)
|
||||
|
||||
var (
|
||||
privNames = make(map[string]uint64)
|
||||
privNameMutex sync.Mutex
|
||||
)
|
||||
|
||||
// PrivilegeError represents an error enabling privileges.
|
||||
type PrivilegeError struct {
|
||||
privileges []uint64
|
||||
}
|
||||
|
||||
func (e *PrivilegeError) Error() string {
|
||||
s := ""
|
||||
if len(e.privileges) > 1 {
|
||||
s = "Could not enable privileges "
|
||||
} else {
|
||||
s = "Could not enable privilege "
|
||||
}
|
||||
for i, p := range e.privileges {
|
||||
if i != 0 {
|
||||
s += ", "
|
||||
}
|
||||
s += `"`
|
||||
s += getPrivilegeName(p)
|
||||
s += `"`
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// RunWithPrivilege enables a single privilege for a function call.
|
||||
func RunWithPrivilege(name string, fn func() error) error {
|
||||
return RunWithPrivileges([]string{name}, fn)
|
||||
}
|
||||
|
||||
// RunWithPrivileges enables privileges for a function call.
|
||||
func RunWithPrivileges(names []string, fn func() error) error {
|
||||
privileges, err := mapPrivileges(names)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
token, err := newThreadToken()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer releaseThreadToken(token)
|
||||
err = adjustPrivileges(token, privileges, SE_PRIVILEGE_ENABLED)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return fn()
|
||||
}
|
||||
|
||||
func mapPrivileges(names []string) ([]uint64, error) {
|
||||
var privileges []uint64
|
||||
privNameMutex.Lock()
|
||||
defer privNameMutex.Unlock()
|
||||
for _, name := range names {
|
||||
p, ok := privNames[name]
|
||||
if !ok {
|
||||
err := lookupPrivilegeValue("", name, &p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
privNames[name] = p
|
||||
}
|
||||
privileges = append(privileges, p)
|
||||
}
|
||||
return privileges, nil
|
||||
}
|
||||
|
||||
// EnableProcessPrivileges enables privileges globally for the process.
|
||||
func EnableProcessPrivileges(names []string) error {
|
||||
return enableDisableProcessPrivilege(names, SE_PRIVILEGE_ENABLED)
|
||||
}
|
||||
|
||||
// DisableProcessPrivileges disables privileges globally for the process.
|
||||
func DisableProcessPrivileges(names []string) error {
|
||||
return enableDisableProcessPrivilege(names, 0)
|
||||
}
|
||||
|
||||
func enableDisableProcessPrivilege(names []string, action uint32) error {
|
||||
privileges, err := mapPrivileges(names)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p, _ := windows.GetCurrentProcess()
|
||||
var token windows.Token
|
||||
err = windows.OpenProcessToken(p, windows.TOKEN_ADJUST_PRIVILEGES|windows.TOKEN_QUERY, &token)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer token.Close()
|
||||
return adjustPrivileges(token, privileges, action)
|
||||
}
|
||||
|
||||
func adjustPrivileges(token windows.Token, privileges []uint64, action uint32) error {
|
||||
var b bytes.Buffer
|
||||
binary.Write(&b, binary.LittleEndian, uint32(len(privileges)))
|
||||
for _, p := range privileges {
|
||||
binary.Write(&b, binary.LittleEndian, p)
|
||||
binary.Write(&b, binary.LittleEndian, action)
|
||||
}
|
||||
prevState := make([]byte, b.Len())
|
||||
reqSize := uint32(0)
|
||||
success, err := adjustTokenPrivileges(token, false, &b.Bytes()[0], uint32(len(prevState)), &prevState[0], &reqSize)
|
||||
if !success {
|
||||
return err
|
||||
}
|
||||
if err == ERROR_NOT_ALL_ASSIGNED {
|
||||
return &PrivilegeError{privileges}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getPrivilegeName(luid uint64) string {
|
||||
var nameBuffer [256]uint16
|
||||
bufSize := uint32(len(nameBuffer))
|
||||
err := lookupPrivilegeName("", &luid, &nameBuffer[0], &bufSize)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("<unknown privilege %d>", luid)
|
||||
}
|
||||
|
||||
var displayNameBuffer [256]uint16
|
||||
displayBufSize := uint32(len(displayNameBuffer))
|
||||
var langID uint32
|
||||
err = lookupPrivilegeDisplayName("", &nameBuffer[0], &displayNameBuffer[0], &displayBufSize, &langID)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("<unknown privilege %s>", string(utf16.Decode(nameBuffer[:bufSize])))
|
||||
}
|
||||
|
||||
return string(utf16.Decode(displayNameBuffer[:displayBufSize]))
|
||||
}
|
||||
|
||||
func newThreadToken() (windows.Token, error) {
|
||||
err := impersonateSelf(securityImpersonation)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
var token windows.Token
|
||||
err = openThreadToken(getCurrentThread(), syscall.TOKEN_ADJUST_PRIVILEGES|syscall.TOKEN_QUERY, false, &token)
|
||||
if err != nil {
|
||||
rerr := revertToSelf()
|
||||
if rerr != nil {
|
||||
panic(rerr)
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func releaseThreadToken(h windows.Token) {
|
||||
err := revertToSelf()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
h.Close()
|
||||
}
|
128
vendor/github.com/Microsoft/go-winio/reparse.go
generated
vendored
128
vendor/github.com/Microsoft/go-winio/reparse.go
generated
vendored
@ -1,128 +0,0 @@
|
||||
package winio
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode/utf16"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
reparseTagMountPoint = 0xA0000003
|
||||
reparseTagSymlink = 0xA000000C
|
||||
)
|
||||
|
||||
type reparseDataBuffer struct {
|
||||
ReparseTag uint32
|
||||
ReparseDataLength uint16
|
||||
Reserved uint16
|
||||
SubstituteNameOffset uint16
|
||||
SubstituteNameLength uint16
|
||||
PrintNameOffset uint16
|
||||
PrintNameLength uint16
|
||||
}
|
||||
|
||||
// ReparsePoint describes a Win32 symlink or mount point.
|
||||
type ReparsePoint struct {
|
||||
Target string
|
||||
IsMountPoint bool
|
||||
}
|
||||
|
||||
// UnsupportedReparsePointError is returned when trying to decode a non-symlink or
|
||||
// mount point reparse point.
|
||||
type UnsupportedReparsePointError struct {
|
||||
Tag uint32
|
||||
}
|
||||
|
||||
func (e *UnsupportedReparsePointError) Error() string {
|
||||
return fmt.Sprintf("unsupported reparse point %x", e.Tag)
|
||||
}
|
||||
|
||||
// DecodeReparsePoint decodes a Win32 REPARSE_DATA_BUFFER structure containing either a symlink
|
||||
// or a mount point.
|
||||
func DecodeReparsePoint(b []byte) (*ReparsePoint, error) {
|
||||
tag := binary.LittleEndian.Uint32(b[0:4])
|
||||
return DecodeReparsePointData(tag, b[8:])
|
||||
}
|
||||
|
||||
func DecodeReparsePointData(tag uint32, b []byte) (*ReparsePoint, error) {
|
||||
isMountPoint := false
|
||||
switch tag {
|
||||
case reparseTagMountPoint:
|
||||
isMountPoint = true
|
||||
case reparseTagSymlink:
|
||||
default:
|
||||
return nil, &UnsupportedReparsePointError{tag}
|
||||
}
|
||||
nameOffset := 8 + binary.LittleEndian.Uint16(b[4:6])
|
||||
if !isMountPoint {
|
||||
nameOffset += 4
|
||||
}
|
||||
nameLength := binary.LittleEndian.Uint16(b[6:8])
|
||||
name := make([]uint16, nameLength/2)
|
||||
err := binary.Read(bytes.NewReader(b[nameOffset:nameOffset+nameLength]), binary.LittleEndian, &name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ReparsePoint{string(utf16.Decode(name)), isMountPoint}, nil
|
||||
}
|
||||
|
||||
func isDriveLetter(c byte) bool {
|
||||
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
|
||||
}
|
||||
|
||||
// EncodeReparsePoint encodes a Win32 REPARSE_DATA_BUFFER structure describing a symlink or
|
||||
// mount point.
|
||||
func EncodeReparsePoint(rp *ReparsePoint) []byte {
|
||||
// Generate an NT path and determine if this is a relative path.
|
||||
var ntTarget string
|
||||
relative := false
|
||||
if strings.HasPrefix(rp.Target, `\\?\`) {
|
||||
ntTarget = `\??\` + rp.Target[4:]
|
||||
} else if strings.HasPrefix(rp.Target, `\\`) {
|
||||
ntTarget = `\??\UNC\` + rp.Target[2:]
|
||||
} else if len(rp.Target) >= 2 && isDriveLetter(rp.Target[0]) && rp.Target[1] == ':' {
|
||||
ntTarget = `\??\` + rp.Target
|
||||
} else {
|
||||
ntTarget = rp.Target
|
||||
relative = true
|
||||
}
|
||||
|
||||
// The paths must be NUL-terminated even though they are counted strings.
|
||||
target16 := utf16.Encode([]rune(rp.Target + "\x00"))
|
||||
ntTarget16 := utf16.Encode([]rune(ntTarget + "\x00"))
|
||||
|
||||
size := int(unsafe.Sizeof(reparseDataBuffer{})) - 8
|
||||
size += len(ntTarget16)*2 + len(target16)*2
|
||||
|
||||
tag := uint32(reparseTagMountPoint)
|
||||
if !rp.IsMountPoint {
|
||||
tag = reparseTagSymlink
|
||||
size += 4 // Add room for symlink flags
|
||||
}
|
||||
|
||||
data := reparseDataBuffer{
|
||||
ReparseTag: tag,
|
||||
ReparseDataLength: uint16(size),
|
||||
SubstituteNameOffset: 0,
|
||||
SubstituteNameLength: uint16((len(ntTarget16) - 1) * 2),
|
||||
PrintNameOffset: uint16(len(ntTarget16) * 2),
|
||||
PrintNameLength: uint16((len(target16) - 1) * 2),
|
||||
}
|
||||
|
||||
var b bytes.Buffer
|
||||
binary.Write(&b, binary.LittleEndian, &data)
|
||||
if !rp.IsMountPoint {
|
||||
flags := uint32(0)
|
||||
if relative {
|
||||
flags |= 1
|
||||
}
|
||||
binary.Write(&b, binary.LittleEndian, flags)
|
||||
}
|
||||
|
||||
binary.Write(&b, binary.LittleEndian, ntTarget16)
|
||||
binary.Write(&b, binary.LittleEndian, target16)
|
||||
return b.Bytes()
|
||||
}
|
98
vendor/github.com/Microsoft/go-winio/sd.go
generated
vendored
98
vendor/github.com/Microsoft/go-winio/sd.go
generated
vendored
@ -1,98 +0,0 @@
|
||||
// +build windows
|
||||
|
||||
package winio
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
//sys lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) = advapi32.LookupAccountNameW
|
||||
//sys convertSidToStringSid(sid *byte, str **uint16) (err error) = advapi32.ConvertSidToStringSidW
|
||||
//sys convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd *uintptr, size *uint32) (err error) = advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorW
|
||||
//sys convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) = advapi32.ConvertSecurityDescriptorToStringSecurityDescriptorW
|
||||
//sys localFree(mem uintptr) = LocalFree
|
||||
//sys getSecurityDescriptorLength(sd uintptr) (len uint32) = advapi32.GetSecurityDescriptorLength
|
||||
|
||||
const (
|
||||
cERROR_NONE_MAPPED = syscall.Errno(1332)
|
||||
)
|
||||
|
||||
type AccountLookupError struct {
|
||||
Name string
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e *AccountLookupError) Error() string {
|
||||
if e.Name == "" {
|
||||
return "lookup account: empty account name specified"
|
||||
}
|
||||
var s string
|
||||
switch e.Err {
|
||||
case cERROR_NONE_MAPPED:
|
||||
s = "not found"
|
||||
default:
|
||||
s = e.Err.Error()
|
||||
}
|
||||
return "lookup account " + e.Name + ": " + s
|
||||
}
|
||||
|
||||
type SddlConversionError struct {
|
||||
Sddl string
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e *SddlConversionError) Error() string {
|
||||
return "convert " + e.Sddl + ": " + e.Err.Error()
|
||||
}
|
||||
|
||||
// LookupSidByName looks up the SID of an account by name
|
||||
func LookupSidByName(name string) (sid string, err error) {
|
||||
if name == "" {
|
||||
return "", &AccountLookupError{name, cERROR_NONE_MAPPED}
|
||||
}
|
||||
|
||||
var sidSize, sidNameUse, refDomainSize uint32
|
||||
err = lookupAccountName(nil, name, nil, &sidSize, nil, &refDomainSize, &sidNameUse)
|
||||
if err != nil && err != syscall.ERROR_INSUFFICIENT_BUFFER {
|
||||
return "", &AccountLookupError{name, err}
|
||||
}
|
||||
sidBuffer := make([]byte, sidSize)
|
||||
refDomainBuffer := make([]uint16, refDomainSize)
|
||||
err = lookupAccountName(nil, name, &sidBuffer[0], &sidSize, &refDomainBuffer[0], &refDomainSize, &sidNameUse)
|
||||
if err != nil {
|
||||
return "", &AccountLookupError{name, err}
|
||||
}
|
||||
var strBuffer *uint16
|
||||
err = convertSidToStringSid(&sidBuffer[0], &strBuffer)
|
||||
if err != nil {
|
||||
return "", &AccountLookupError{name, err}
|
||||
}
|
||||
sid = syscall.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(strBuffer))[:])
|
||||
localFree(uintptr(unsafe.Pointer(strBuffer)))
|
||||
return sid, nil
|
||||
}
|
||||
|
||||
func SddlToSecurityDescriptor(sddl string) ([]byte, error) {
|
||||
var sdBuffer uintptr
|
||||
err := convertStringSecurityDescriptorToSecurityDescriptor(sddl, 1, &sdBuffer, nil)
|
||||
if err != nil {
|
||||
return nil, &SddlConversionError{sddl, err}
|
||||
}
|
||||
defer localFree(sdBuffer)
|
||||
sd := make([]byte, getSecurityDescriptorLength(sdBuffer))
|
||||
copy(sd, (*[0xffff]byte)(unsafe.Pointer(sdBuffer))[:len(sd)])
|
||||
return sd, nil
|
||||
}
|
||||
|
||||
func SecurityDescriptorToSddl(sd []byte) (string, error) {
|
||||
var sddl *uint16
|
||||
// The returned string length seems to including an aribtrary number of terminating NULs.
|
||||
// Don't use it.
|
||||
err := convertSecurityDescriptorToStringSecurityDescriptor(&sd[0], 1, 0xff, &sddl, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer localFree(uintptr(unsafe.Pointer(sddl)))
|
||||
return syscall.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(sddl))[:]), nil
|
||||
}
|
3
vendor/github.com/Microsoft/go-winio/syscall.go
generated
vendored
3
vendor/github.com/Microsoft/go-winio/syscall.go
generated
vendored
@ -1,3 +0,0 @@
|
||||
package winio
|
||||
|
||||
//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go file.go pipe.go sd.go fileinfo.go privilege.go backup.go hvsock.go
|
562
vendor/github.com/Microsoft/go-winio/zsyscall_windows.go
generated
vendored
562
vendor/github.com/Microsoft/go-winio/zsyscall_windows.go
generated
vendored
@ -1,562 +0,0 @@
|
||||
// Code generated by 'go generate'; DO NOT EDIT.
|
||||
|
||||
package winio
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var _ unsafe.Pointer
|
||||
|
||||
// Do the interface allocations only once for common
|
||||
// Errno values.
|
||||
const (
|
||||
errnoERROR_IO_PENDING = 997
|
||||
)
|
||||
|
||||
var (
|
||||
errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
|
||||
)
|
||||
|
||||
// errnoErr returns common boxed Errno values, to prevent
|
||||
// allocations at runtime.
|
||||
func errnoErr(e syscall.Errno) error {
|
||||
switch e {
|
||||
case 0:
|
||||
return nil
|
||||
case errnoERROR_IO_PENDING:
|
||||
return errERROR_IO_PENDING
|
||||
}
|
||||
// TODO: add more here, after collecting data on the common
|
||||
// error values see on Windows. (perhaps when running
|
||||
// all.bat?)
|
||||
return e
|
||||
}
|
||||
|
||||
var (
|
||||
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||
modws2_32 = windows.NewLazySystemDLL("ws2_32.dll")
|
||||
modntdll = windows.NewLazySystemDLL("ntdll.dll")
|
||||
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
|
||||
|
||||
procCancelIoEx = modkernel32.NewProc("CancelIoEx")
|
||||
procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort")
|
||||
procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus")
|
||||
procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes")
|
||||
procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult")
|
||||
procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe")
|
||||
procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW")
|
||||
procCreateFileW = modkernel32.NewProc("CreateFileW")
|
||||
procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo")
|
||||
procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW")
|
||||
procLocalAlloc = modkernel32.NewProc("LocalAlloc")
|
||||
procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile")
|
||||
procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb")
|
||||
procRtlDosPathNameToNtPathName_U = modntdll.NewProc("RtlDosPathNameToNtPathName_U")
|
||||
procRtlDefaultNpAcl = modntdll.NewProc("RtlDefaultNpAcl")
|
||||
procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW")
|
||||
procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW")
|
||||
procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW")
|
||||
procConvertSecurityDescriptorToStringSecurityDescriptorW = modadvapi32.NewProc("ConvertSecurityDescriptorToStringSecurityDescriptorW")
|
||||
procLocalFree = modkernel32.NewProc("LocalFree")
|
||||
procGetSecurityDescriptorLength = modadvapi32.NewProc("GetSecurityDescriptorLength")
|
||||
procGetFileInformationByHandleEx = modkernel32.NewProc("GetFileInformationByHandleEx")
|
||||
procSetFileInformationByHandle = modkernel32.NewProc("SetFileInformationByHandle")
|
||||
procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges")
|
||||
procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf")
|
||||
procRevertToSelf = modadvapi32.NewProc("RevertToSelf")
|
||||
procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken")
|
||||
procGetCurrentThread = modkernel32.NewProc("GetCurrentThread")
|
||||
procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW")
|
||||
procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW")
|
||||
procLookupPrivilegeDisplayNameW = modadvapi32.NewProc("LookupPrivilegeDisplayNameW")
|
||||
procBackupRead = modkernel32.NewProc("BackupRead")
|
||||
procBackupWrite = modkernel32.NewProc("BackupWrite")
|
||||
procbind = modws2_32.NewProc("bind")
|
||||
)
|
||||
|
||||
func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) {
|
||||
r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount), 0, 0)
|
||||
newport = syscall.Handle(r0)
|
||||
if newport == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func wsaGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) {
|
||||
var _p0 uint32
|
||||
if wait {
|
||||
_p0 = 1
|
||||
} else {
|
||||
_p0 = 0
|
||||
}
|
||||
r1, _, e1 := syscall.Syscall6(procWSAGetOverlappedResult.Addr(), 5, uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags)), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _createNamedPipe(_p0, flags, pipeMode, maxInstances, outSize, inSize, defaultTimeout, sa)
|
||||
}
|
||||
|
||||
func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) {
|
||||
r0, _, e1 := syscall.Syscall9(procCreateNamedPipeW.Addr(), 8, uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)), 0)
|
||||
handle = syscall.Handle(r0)
|
||||
if handle == syscall.InvalidHandle {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func createFile(name string, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _createFile(_p0, access, mode, sa, createmode, attrs, templatefile)
|
||||
}
|
||||
|
||||
func _createFile(name *uint16, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
|
||||
r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0)
|
||||
handle = syscall.Handle(r0)
|
||||
if handle == syscall.InvalidHandle {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func localAlloc(uFlags uint32, length uint32) (ptr uintptr) {
|
||||
r0, _, _ := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(uFlags), uintptr(length), 0)
|
||||
ptr = uintptr(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func ntCreateNamedPipeFile(pipe *syscall.Handle, access uint32, oa *objectAttributes, iosb *ioStatusBlock, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntstatus) {
|
||||
r0, _, _ := syscall.Syscall15(procNtCreateNamedPipeFile.Addr(), 14, uintptr(unsafe.Pointer(pipe)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(share), uintptr(disposition), uintptr(options), uintptr(typ), uintptr(readMode), uintptr(completionMode), uintptr(maxInstances), uintptr(inboundQuota), uintptr(outputQuota), uintptr(unsafe.Pointer(timeout)), 0)
|
||||
status = ntstatus(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func rtlNtStatusToDosError(status ntstatus) (winerr error) {
|
||||
r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(status), 0, 0)
|
||||
if r0 != 0 {
|
||||
winerr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntstatus) {
|
||||
r0, _, _ := syscall.Syscall6(procRtlDosPathNameToNtPathName_U.Addr(), 4, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(ntName)), uintptr(filePart), uintptr(reserved), 0, 0)
|
||||
status = ntstatus(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func rtlDefaultNpAcl(dacl *uintptr) (status ntstatus) {
|
||||
r0, _, _ := syscall.Syscall(procRtlDefaultNpAcl.Addr(), 1, uintptr(unsafe.Pointer(dacl)), 0, 0)
|
||||
status = ntstatus(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(accountName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _lookupAccountName(systemName, _p0, sid, sidSize, refDomain, refDomainSize, sidNameUse)
|
||||
}
|
||||
|
||||
func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func convertSidToStringSid(sid *byte, str **uint16) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str)), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd *uintptr, size *uint32) (err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(str)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _convertStringSecurityDescriptorToSecurityDescriptor(_p0, revision, sd, size)
|
||||
}
|
||||
|
||||
func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision uint32, sd *uintptr, size *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(secInfo), uintptr(unsafe.Pointer(sddl)), uintptr(unsafe.Pointer(sddlSize)), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func localFree(mem uintptr) {
|
||||
syscall.Syscall(procLocalFree.Addr(), 1, uintptr(mem), 0, 0)
|
||||
return
|
||||
}
|
||||
|
||||
func getSecurityDescriptorLength(sd uintptr) (len uint32) {
|
||||
r0, _, _ := syscall.Syscall(procGetSecurityDescriptorLength.Addr(), 1, uintptr(sd), 0, 0)
|
||||
len = uint32(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func getFileInformationByHandleEx(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procSetFileInformationByHandle.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) {
|
||||
var _p0 uint32
|
||||
if releaseAll {
|
||||
_p0 = 1
|
||||
} else {
|
||||
_p0 = 0
|
||||
}
|
||||
r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize)))
|
||||
success = r0 != 0
|
||||
if true {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func impersonateSelf(level uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(level), 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func revertToSelf() (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) {
|
||||
var _p0 uint32
|
||||
if openAsSelf {
|
||||
_p0 = 1
|
||||
} else {
|
||||
_p0 = 0
|
||||
}
|
||||
r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getCurrentThread() (h syscall.Handle) {
|
||||
r0, _, _ := syscall.Syscall(procGetCurrentThread.Addr(), 0, 0, 0, 0)
|
||||
h = syscall.Handle(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(systemName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var _p1 *uint16
|
||||
_p1, err = syscall.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _lookupPrivilegeValue(_p0, _p1, luid)
|
||||
}
|
||||
|
||||
func _lookupPrivilegeValue(systemName *uint16, name *uint16, luid *uint64) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid)))
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(systemName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _lookupPrivilegeName(_p0, luid, buffer, size)
|
||||
}
|
||||
|
||||
func _lookupPrivilegeName(systemName *uint16, luid *uint64, buffer *uint16, size *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(systemName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _lookupPrivilegeDisplayName(_p0, name, buffer, size, languageId)
|
||||
}
|
||||
|
||||
func _lookupPrivilegeDisplayName(systemName *uint16, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procLookupPrivilegeDisplayNameW.Addr(), 5, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId)), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) {
|
||||
var _p0 *byte
|
||||
if len(b) > 0 {
|
||||
_p0 = &b[0]
|
||||
}
|
||||
var _p1 uint32
|
||||
if abort {
|
||||
_p1 = 1
|
||||
} else {
|
||||
_p1 = 0
|
||||
}
|
||||
var _p2 uint32
|
||||
if processSecurity {
|
||||
_p2 = 1
|
||||
} else {
|
||||
_p2 = 0
|
||||
}
|
||||
r1, _, e1 := syscall.Syscall9(procBackupRead.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesRead)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) {
|
||||
var _p0 *byte
|
||||
if len(b) > 0 {
|
||||
_p0 = &b[0]
|
||||
}
|
||||
var _p1 uint32
|
||||
if abort {
|
||||
_p1 = 1
|
||||
} else {
|
||||
_p1 = 0
|
||||
}
|
||||
var _p2 uint32
|
||||
if processSecurity {
|
||||
_p2 = 1
|
||||
} else {
|
||||
_p2 = 0
|
||||
}
|
||||
r1, _, e1 := syscall.Syscall9(procBackupWrite.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesWritten)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func bind(s syscall.Handle, name unsafe.Pointer, namelen int32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
|
||||
if r1 == socketError {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
2
vendor/github.com/PagerDuty/go-pagerduty/.gitignore
generated
vendored
2
vendor/github.com/PagerDuty/go-pagerduty/.gitignore
generated
vendored
@ -1,2 +0,0 @@
|
||||
bin/*
|
||||
*.swp
|
33
vendor/github.com/PagerDuty/go-pagerduty/.goreleaser.yml
generated
vendored
33
vendor/github.com/PagerDuty/go-pagerduty/.goreleaser.yml
generated
vendored
@ -1,33 +0,0 @@
|
||||
project_name: go-pagerduty
|
||||
release:
|
||||
github:
|
||||
owner: PagerDuty
|
||||
name: go-pagerduty
|
||||
draft: false
|
||||
prerelease: true
|
||||
name_template: "{{.ProjectName}}-v{{.Version}}"
|
||||
builds:
|
||||
- goos:
|
||||
- linux
|
||||
- darwin
|
||||
- windows
|
||||
goarch:
|
||||
- amd64
|
||||
- 386
|
||||
main: ./command/*.go
|
||||
binary: pd
|
||||
archive:
|
||||
format: tar.gz
|
||||
format_overrides:
|
||||
- goos: windows
|
||||
format: zip
|
||||
replacements:
|
||||
amd64: 64-bit
|
||||
darwin: macOS
|
||||
linux: Tux
|
||||
name_template: "{{.Binary}}_{{.Version}}_{{.Os}}-{{.Arch}}"
|
||||
files:
|
||||
- LICENSE.txt
|
||||
- README.md
|
||||
- examples/*
|
||||
- CHANGELOG.md
|
89
vendor/github.com/PagerDuty/go-pagerduty/CHANGELOG.md
generated
vendored
89
vendor/github.com/PagerDuty/go-pagerduty/CHANGELOG.md
generated
vendored
@ -1,89 +0,0 @@
|
||||
# Change Log
|
||||
|
||||
## [1.0.0](https://github.com/PagerDuty/go-pagerduty/tree/1.0.0) (2018-05-28)
|
||||
**Fixed bugs:**
|
||||
|
||||
- Escalation Policy's repeat\_enabled Is Ignored [\#57](https://github.com/PagerDuty/go-pagerduty/issues/57)
|
||||
- Problems running freshly built pd utility [\#39](https://github.com/PagerDuty/go-pagerduty/issues/39)
|
||||
- Manage Incident gives error [\#32](https://github.com/PagerDuty/go-pagerduty/issues/32)
|
||||
- Added missing slash to delete integration method url [\#59](https://github.com/PagerDuty/go-pagerduty/pull/59) ([jescochu](https://github.com/jescochu))
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- Trouble creating an integration [\#102](https://github.com/PagerDuty/go-pagerduty/issues/102)
|
||||
- Client does not trigger events [\#101](https://github.com/PagerDuty/go-pagerduty/issues/101)
|
||||
- Paging help [\#94](https://github.com/PagerDuty/go-pagerduty/issues/94)
|
||||
- Help with incident creation API [\#89](https://github.com/PagerDuty/go-pagerduty/issues/89)
|
||||
- Memory leak because of response body is not closed [\#66](https://github.com/PagerDuty/go-pagerduty/issues/66)
|
||||
- Since and Until don't work for log\_entries [\#61](https://github.com/PagerDuty/go-pagerduty/issues/61)
|
||||
- service: auto\_resolve\_timeout & acknowledgement\_timeout cannot be set to null [\#51](https://github.com/PagerDuty/go-pagerduty/issues/51)
|
||||
- Possible to create new service and integration together [\#42](https://github.com/PagerDuty/go-pagerduty/issues/42)
|
||||
- Documentation does not match code [\#16](https://github.com/PagerDuty/go-pagerduty/issues/16)
|
||||
- Typo in repo description [\#15](https://github.com/PagerDuty/go-pagerduty/issues/15)
|
||||
- Webhook decoder [\#14](https://github.com/PagerDuty/go-pagerduty/issues/14)
|
||||
- incident\_key for create\_event [\#13](https://github.com/PagerDuty/go-pagerduty/issues/13)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Fix pagination for ListOnCalls [\#90](https://github.com/PagerDuty/go-pagerduty/pull/90) ([IainCole](https://github.com/IainCole))
|
||||
- Revert "Fix inconsistency with some REST Options objects passed by reference …" [\#88](https://github.com/PagerDuty/go-pagerduty/pull/88) ([mimato](https://github.com/mimato))
|
||||
- Adding travis config, fixup Makefile [\#87](https://github.com/PagerDuty/go-pagerduty/pull/87) ([mimato](https://github.com/mimato))
|
||||
- Fixed invalid JSON descriptor for FirstTriggerLogEntry [\#86](https://github.com/PagerDuty/go-pagerduty/pull/86) ([mwisniewski0](https://github.com/mwisniewski0))
|
||||
- \[incidents\] fix entries typo in a few places [\#85](https://github.com/PagerDuty/go-pagerduty/pull/85) ([joeyparsons](https://github.com/joeyparsons))
|
||||
- Fix inconsistency with some REST Options objects passed by reference … [\#79](https://github.com/PagerDuty/go-pagerduty/pull/79) ([lowesoftware](https://github.com/lowesoftware))
|
||||
- Explicit JSON reference to schedules [\#77](https://github.com/PagerDuty/go-pagerduty/pull/77) ([domudall](https://github.com/domudall))
|
||||
- Adding AlertCreation to Service struct [\#76](https://github.com/PagerDuty/go-pagerduty/pull/76) ([domudall](https://github.com/domudall))
|
||||
- Add support for escalation rules [\#71](https://github.com/PagerDuty/go-pagerduty/pull/71) ([heimweh](https://github.com/heimweh))
|
||||
- Fix maintenance window JSON [\#69](https://github.com/PagerDuty/go-pagerduty/pull/69) ([domudall](https://github.com/domudall))
|
||||
- Fixing Maintenance typo [\#68](https://github.com/PagerDuty/go-pagerduty/pull/68) ([domudall](https://github.com/domudall))
|
||||
- Update event.go - fix a memory leak [\#65](https://github.com/PagerDuty/go-pagerduty/pull/65) ([AngelRefael](https://github.com/AngelRefael))
|
||||
- Add query to vendor [\#64](https://github.com/PagerDuty/go-pagerduty/pull/64) ([heimweh](https://github.com/heimweh))
|
||||
- Fix JSON decode \(errorObject\) [\#63](https://github.com/PagerDuty/go-pagerduty/pull/63) ([heimweh](https://github.com/heimweh))
|
||||
- fix since and until by adding them to url scheme [\#60](https://github.com/PagerDuty/go-pagerduty/pull/60) ([ethansommer](https://github.com/ethansommer))
|
||||
- fix webhook struct member name [\#58](https://github.com/PagerDuty/go-pagerduty/pull/58) ([pgray](https://github.com/pgray))
|
||||
- Incident - Add status field to incident [\#56](https://github.com/PagerDuty/go-pagerduty/pull/56) ([heimweh](https://github.com/heimweh))
|
||||
- enable fetch log entries via incident api [\#55](https://github.com/PagerDuty/go-pagerduty/pull/55) ([flyinprogrammer](https://github.com/flyinprogrammer))
|
||||
- Allow service timeouts to be disabled [\#53](https://github.com/PagerDuty/go-pagerduty/pull/53) ([heimweh](https://github.com/heimweh))
|
||||
- Schedule restriction - Add support for start\_day\_of\_week [\#52](https://github.com/PagerDuty/go-pagerduty/pull/52) ([heimweh](https://github.com/heimweh))
|
||||
- Add vendor support [\#49](https://github.com/PagerDuty/go-pagerduty/pull/49) ([heimweh](https://github.com/heimweh))
|
||||
- Add schedules listing [\#46](https://github.com/PagerDuty/go-pagerduty/pull/46) ([Marc-Morata-Fite](https://github.com/Marc-Morata-Fite))
|
||||
- dont declare main twice in examples [\#45](https://github.com/PagerDuty/go-pagerduty/pull/45) ([ranjib](https://github.com/ranjib))
|
||||
- add service show [\#44](https://github.com/PagerDuty/go-pagerduty/pull/44) ([cmluciano](https://github.com/cmluciano))
|
||||
- \(feat\)implement integration creation [\#43](https://github.com/PagerDuty/go-pagerduty/pull/43) ([ranjib](https://github.com/ranjib))
|
||||
- \(chore\)add create event example [\#41](https://github.com/PagerDuty/go-pagerduty/pull/41) ([ranjib](https://github.com/ranjib))
|
||||
- \(bug\)Add test. fix version issue [\#40](https://github.com/PagerDuty/go-pagerduty/pull/40) ([ranjib](https://github.com/ranjib))
|
||||
- Remove subdomain argument from escalation\_policy example. [\#38](https://github.com/PagerDuty/go-pagerduty/pull/38) ([cmluciano](https://github.com/cmluciano))
|
||||
- Skip JSON encoding if no payload was given [\#37](https://github.com/PagerDuty/go-pagerduty/pull/37) ([heimweh](https://github.com/heimweh))
|
||||
- \(feat\)add ability API and CLI [\#36](https://github.com/PagerDuty/go-pagerduty/pull/36) ([ranjib](https://github.com/ranjib))
|
||||
- Make updates to Escalation Policies work [\#35](https://github.com/PagerDuty/go-pagerduty/pull/35) ([heimweh](https://github.com/heimweh))
|
||||
- Fix misspelling in User struct and add JSON tags [\#34](https://github.com/PagerDuty/go-pagerduty/pull/34) ([heimweh](https://github.com/heimweh))
|
||||
- \(bug\)allow passing headers in http do call. fix manage incident call [\#33](https://github.com/PagerDuty/go-pagerduty/pull/33) ([ranjib](https://github.com/ranjib))
|
||||
- \(chore\)get rid of logrus from all core structs except CLI entries. fix schedule override command [\#31](https://github.com/PagerDuty/go-pagerduty/pull/31) ([ranjib](https://github.com/ranjib))
|
||||
- \(bug\)rename override struct [\#30](https://github.com/PagerDuty/go-pagerduty/pull/30) ([ranjib](https://github.com/ranjib))
|
||||
- \(bug\)implement schedule override [\#29](https://github.com/PagerDuty/go-pagerduty/pull/29) ([ranjib](https://github.com/ranjib))
|
||||
- fix misspelling in trigger\_summary\_data's JSON key. [\#28](https://github.com/PagerDuty/go-pagerduty/pull/28) ([tomwans](https://github.com/tomwans))
|
||||
- Correctly set meta flag for incident list [\#26](https://github.com/PagerDuty/go-pagerduty/pull/26) ([afirth](https://github.com/afirth))
|
||||
- Add \*.swp to gitignore [\#25](https://github.com/PagerDuty/go-pagerduty/pull/25) ([afirth](https://github.com/afirth))
|
||||
- Support the /oncalls endpoint in the CLI [\#24](https://github.com/PagerDuty/go-pagerduty/pull/24) ([afirth](https://github.com/afirth))
|
||||
- Refactor to work correctly with V2 API [\#23](https://github.com/PagerDuty/go-pagerduty/pull/23) ([dthagard](https://github.com/dthagard))
|
||||
- \(feat\)Add webhook decoding capability [\#22](https://github.com/PagerDuty/go-pagerduty/pull/22) ([ranjib](https://github.com/ranjib))
|
||||
- \(chore\)Decode event API response. [\#21](https://github.com/PagerDuty/go-pagerduty/pull/21) ([ranjib](https://github.com/ranjib))
|
||||
- \(bug\)add incident\_key field in event api client [\#20](https://github.com/PagerDuty/go-pagerduty/pull/20) ([ranjib](https://github.com/ranjib))
|
||||
- \(chore\)nuke sub domain, v2 api does not need one [\#19](https://github.com/PagerDuty/go-pagerduty/pull/19) ([ranjib](https://github.com/ranjib))
|
||||
- Implement list users CLI [\#17](https://github.com/PagerDuty/go-pagerduty/pull/17) ([ranjib](https://github.com/ranjib))
|
||||
- Add team\_ids\[\] query string arg [\#12](https://github.com/PagerDuty/go-pagerduty/pull/12) ([marklap](https://github.com/marklap))
|
||||
- Incidents fix [\#11](https://github.com/PagerDuty/go-pagerduty/pull/11) ([jareksm](https://github.com/jareksm))
|
||||
- Added APIListObject to Option types to allow setting offset and [\#10](https://github.com/PagerDuty/go-pagerduty/pull/10) ([jareksm](https://github.com/jareksm))
|
||||
- fix typo [\#9](https://github.com/PagerDuty/go-pagerduty/pull/9) ([sjansen](https://github.com/sjansen))
|
||||
- implement incident list cli. event posting api [\#8](https://github.com/PagerDuty/go-pagerduty/pull/8) ([ranjib](https://github.com/ranjib))
|
||||
- CLI for create escalation policy, maintainenance window , schedule ov… [\#7](https://github.com/PagerDuty/go-pagerduty/pull/7) ([ranjib](https://github.com/ranjib))
|
||||
- \(feat\)implement create service cli [\#6](https://github.com/PagerDuty/go-pagerduty/pull/6) ([ranjib](https://github.com/ranjib))
|
||||
- \(feat\)list service cli [\#5](https://github.com/PagerDuty/go-pagerduty/pull/5) ([ranjib](https://github.com/ranjib))
|
||||
- \(feat\)implement addon update/delete [\#4](https://github.com/PagerDuty/go-pagerduty/pull/4) ([ranjib](https://github.com/ranjib))
|
||||
- \(feat\)Show addon cli [\#3](https://github.com/PagerDuty/go-pagerduty/pull/3) ([ranjib](https://github.com/ranjib))
|
||||
- \(feat\) addon list api. create cli [\#2](https://github.com/PagerDuty/go-pagerduty/pull/2) ([ranjib](https://github.com/ranjib))
|
||||
- \(chore\) list addon [\#1](https://github.com/PagerDuty/go-pagerduty/pull/1) ([ranjib](https://github.com/ranjib))
|
||||
|
||||
|
||||
|
||||
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
|
4
vendor/github.com/PagerDuty/go-pagerduty/Dockerfile
generated
vendored
4
vendor/github.com/PagerDuty/go-pagerduty/Dockerfile
generated
vendored
@ -1,4 +0,0 @@
|
||||
FROM golang
|
||||
ADD . /go/src/github.com/PagerDuty/go-pagerduty
|
||||
WORKDIR /go/src/github.com/PagerDuty/go-pagerduty
|
||||
RUN go get ./... && go test -v -race -cover ./...
|
201
vendor/github.com/PagerDuty/go-pagerduty/LICENSE.txt
generated
vendored
201
vendor/github.com/PagerDuty/go-pagerduty/LICENSE.txt
generated
vendored
@ -1,201 +0,0 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://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
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2017 PagerDuty, Inc.
|
||||
|
||||
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
|
||||
|
||||
http://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.
|
23
vendor/github.com/PagerDuty/go-pagerduty/Makefile
generated
vendored
23
vendor/github.com/PagerDuty/go-pagerduty/Makefile
generated
vendored
@ -1,23 +0,0 @@
|
||||
# SOURCEDIR=.
|
||||
# SOURCES = $(shell find $(SOURCEDIR) -name '*.go')
|
||||
# VERSION=$(git describe --always --tags)
|
||||
# BINARY=bin/pd
|
||||
|
||||
# bin: $(BINARY)
|
||||
|
||||
# $(BINARY): $(SOURCES)
|
||||
# go build -o $(BINARY) command/*
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
go get ./...
|
||||
# go test -v -race -cover ./...
|
||||
# go tool vet $(SOURCES)
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
go test ./...
|
||||
|
||||
deploy:
|
||||
- curl -sL https://git.io/goreleaser | bash
|
||||
|
92
vendor/github.com/PagerDuty/go-pagerduty/README.md
generated
vendored
92
vendor/github.com/PagerDuty/go-pagerduty/README.md
generated
vendored
@ -1,92 +0,0 @@
|
||||
[](http://godoc.org/github.com/PagerDuty/go-pagerduty) [](https://goreportcard.com/report/github.com/PagerDuty/go-pagerduty) [](https://github.com/gojp/goreportcard/blob/master/LICENSE)
|
||||
# go-pagerduty
|
||||
|
||||
go-pagerduty is a CLI and [go](https://golang.org/) client library for the [PagerDuty v2 API](https://v2.developer.pagerduty.com/v2/page/api-reference).
|
||||
|
||||
## Installation
|
||||
|
||||
First, download the source code
|
||||
```cli
|
||||
go get github.com/PagerDuty/go-pagerduty
|
||||
```
|
||||
|
||||
Next build the application.
|
||||
```cli
|
||||
cd $GOPATH/src/github.com/PagerDuty/go-pagerduty
|
||||
go build -o $GOPATH/bin/pd command/*
|
||||
```
|
||||
If you do not have the dependencies necessary to build the project, run this in the project root and try again
|
||||
|
||||
```cli
|
||||
go get ./...
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### CLI
|
||||
|
||||
The CLI requires an [authentication token](https://v2.developer.pagerduty.com/docs/authentication), which can be specified in `.pd.yml`
|
||||
file in the home directory of the user, or passed as a command-line argument.
|
||||
Example of config file:
|
||||
|
||||
```yaml
|
||||
---
|
||||
authtoken: fooBar
|
||||
```
|
||||
|
||||
#### Commands
|
||||
`pd` command provides a single entrypoint for all the API endpoints, with individual
|
||||
API represented by their own sub commands. For an exhaustive list of sub-commands, try:
|
||||
```
|
||||
pd --help
|
||||
```
|
||||
|
||||
An example of the `service` sub-command
|
||||
|
||||
```
|
||||
pd service list
|
||||
```
|
||||
|
||||
|
||||
### Client Library
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/PagerDuty/go-pagerduty"
|
||||
)
|
||||
|
||||
var authtoken = "" // Set your auth token here
|
||||
|
||||
func main() {
|
||||
var opts pagerduty.ListEscalationPoliciesOptions
|
||||
client := pagerduty.NewClient(authtoken)
|
||||
eps, err := client.ListEscalationPolicies(opts)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, p := range eps.EscalationPolicies {
|
||||
fmt.Println(p.Name)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The PagerDuty API client also exposes its HTTP client as the `HTTPClient` field.
|
||||
If you need to use your own HTTP client, for doing things like defining your own
|
||||
transport settings, you can replace the default HTTP client with your own by
|
||||
simply by setting a new value in the `HTTPClient` field.
|
||||
## License
|
||||
[Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
||||
## Contributing
|
||||
|
||||
1. Fork it ( https://github.com/PagerDuty/go-pagerduty/fork )
|
||||
2. Create your feature branch (`git checkout -b my-new-feature`)
|
||||
3. Commit your changes (`git commit -am 'Add some feature'`)
|
||||
4. Push to the branch (`git push origin my-new-feature`)
|
||||
5. Create a new Pull Request
|
||||
|
||||
## License
|
||||
[Apache 2](http://www.apache.org/licenses/LICENSE-2.0)
|
22
vendor/github.com/PagerDuty/go-pagerduty/ability.go
generated
vendored
22
vendor/github.com/PagerDuty/go-pagerduty/ability.go
generated
vendored
@ -1,22 +0,0 @@
|
||||
package pagerduty
|
||||
|
||||
// ListAbilityResponse is the response when calling the ListAbility API endpoint.
|
||||
type ListAbilityResponse struct {
|
||||
Abilities []string `json:"abilities"`
|
||||
}
|
||||
|
||||
// ListAbilities lists all abilities on your account.
|
||||
func (c *Client) ListAbilities() (*ListAbilityResponse, error) {
|
||||
resp, err := c.get("/abilities")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result ListAbilityResponse
|
||||
return &result, c.decodeJSON(resp, &result)
|
||||
}
|
||||
|
||||
// TestAbility Check if your account has the given ability.
|
||||
func (c *Client) TestAbility(ability string) error {
|
||||
_, err := c.get("/abilities/" + ability)
|
||||
return err
|
||||
}
|
97
vendor/github.com/PagerDuty/go-pagerduty/addon.go
generated
vendored
97
vendor/github.com/PagerDuty/go-pagerduty/addon.go
generated
vendored
@ -1,97 +0,0 @@
|
||||
package pagerduty
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/google/go-querystring/query"
|
||||
)
|
||||
|
||||
// Addon is a third-party add-on to PagerDuty's UI.
|
||||
type Addon struct {
|
||||
APIObject
|
||||
Name string `json:"name,omitempty"`
|
||||
Src string `json:"src,omitempty"`
|
||||
Services []APIObject `json:"services,omitempty"`
|
||||
}
|
||||
|
||||
// ListAddonOptions are the options available when calling the ListAddons API endpoint.
|
||||
type ListAddonOptions struct {
|
||||
APIListObject
|
||||
Includes []string `url:"include,omitempty,brackets"`
|
||||
ServiceIDs []string `url:"service_ids,omitempty,brackets"`
|
||||
Filter string `url:"filter,omitempty"`
|
||||
}
|
||||
|
||||
// ListAddonResponse is the response when calling the ListAddons API endpoint.
|
||||
type ListAddonResponse struct {
|
||||
APIListObject
|
||||
Addons []Addon `json:"addons"`
|
||||
}
|
||||
|
||||
// ListAddons lists all of the add-ons installed on your account.
|
||||
func (c *Client) ListAddons(o ListAddonOptions) (*ListAddonResponse, error) {
|
||||
v, err := query.Values(o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := c.get("/addons?" + v.Encode())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result ListAddonResponse
|
||||
return &result, c.decodeJSON(resp, &result)
|
||||
}
|
||||
|
||||
// InstallAddon installs an add-on for your account.
|
||||
func (c *Client) InstallAddon(a Addon) (*Addon, error) {
|
||||
data := make(map[string]Addon)
|
||||
data["addon"] = a
|
||||
resp, err := c.post("/addons", data, nil)
|
||||
defer resp.Body.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.StatusCode != http.StatusCreated {
|
||||
return nil, fmt.Errorf("Failed to create. HTTP Status code: %d", resp.StatusCode)
|
||||
}
|
||||
return getAddonFromResponse(c, resp)
|
||||
}
|
||||
|
||||
// DeleteAddon deletes an add-on from your account.
|
||||
func (c *Client) DeleteAddon(id string) error {
|
||||
_, err := c.delete("/addons/" + id)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetAddon gets details about an existing add-on.
|
||||
func (c *Client) GetAddon(id string) (*Addon, error) {
|
||||
resp, err := c.get("/addons/" + id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return getAddonFromResponse(c, resp)
|
||||
}
|
||||
|
||||
// UpdateAddon updates an existing add-on.
|
||||
func (c *Client) UpdateAddon(id string, a Addon) (*Addon, error) {
|
||||
v := make(map[string]Addon)
|
||||
v["addon"] = a
|
||||
resp, err := c.put("/addons/"+id, v, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return getAddonFromResponse(c, resp)
|
||||
}
|
||||
|
||||
func getAddonFromResponse(c *Client, resp *http.Response) (*Addon, error) {
|
||||
var result map[string]Addon
|
||||
if err := c.decodeJSON(resp, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
a, ok := result["addon"]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("JSON response does not have 'addon' field")
|
||||
}
|
||||
return &a, nil
|
||||
}
|
181
vendor/github.com/PagerDuty/go-pagerduty/client.go
generated
vendored
181
vendor/github.com/PagerDuty/go-pagerduty/client.go
generated
vendored
@ -1,181 +0,0 @@
|
||||
package pagerduty
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"runtime"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
apiEndpoint = "https://api.pagerduty.com"
|
||||
)
|
||||
|
||||
// APIObject represents generic api json response that is shared by most
|
||||
// domain object (like escalation
|
||||
type APIObject struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Summary string `json:"summary,omitempty"`
|
||||
Self string `json:"self,omitempty"`
|
||||
HTMLURL string `json:"html_url,omitempty"`
|
||||
}
|
||||
|
||||
// APIListObject are the fields used to control pagination when listing objects.
|
||||
type APIListObject struct {
|
||||
Limit uint `url:"limit,omitempty"`
|
||||
Offset uint `url:"offset,omitempty"`
|
||||
More bool `url:"more,omitempty"`
|
||||
Total uint `url:"total,omitempty"`
|
||||
}
|
||||
|
||||
// APIReference are the fields required to reference another API object.
|
||||
type APIReference struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
type APIDetails struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
Details string `json:"details,omitempty"`
|
||||
}
|
||||
|
||||
type errorObject struct {
|
||||
Code int `json:"code,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Errors interface{} `json:"errors,omitempty"`
|
||||
}
|
||||
|
||||
func newDefaultHTTPClient() *http.Client {
|
||||
return &http.Client{
|
||||
Transport: &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
}).DialContext,
|
||||
MaxIdleConns: 10,
|
||||
IdleConnTimeout: 60 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
MaxIdleConnsPerHost: runtime.GOMAXPROCS(0) + 1,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// HTTPClient is an interface which declares the functionality we need from an
|
||||
// HTTP client. This is to allow consumers to provide their own HTTP client as
|
||||
// needed, without restricting them to only using *http.Client.
|
||||
type HTTPClient interface {
|
||||
Do(*http.Request) (*http.Response, error)
|
||||
}
|
||||
|
||||
// defaultHTTPClient is our own default HTTP client. We use this, instead of
|
||||
// http.DefaultClient, to avoid other packages tweaks to http.DefaultClient
|
||||
// causing issues with our HTTP calls. This also allows us to tweak the
|
||||
// transport values to be more resilient without making changes to the
|
||||
// http.DefaultClient.
|
||||
//
|
||||
// Keep this unexported so consumers of the package can't make changes to it.
|
||||
var defaultHTTPClient HTTPClient = newDefaultHTTPClient()
|
||||
|
||||
// Client wraps http client
|
||||
type Client struct {
|
||||
authToken string
|
||||
apiEndpoint string
|
||||
|
||||
// HTTPClient is the HTTP client used for making requests against the
|
||||
// PagerDuty API. You can use either *http.Client here, or your own
|
||||
// implementation.
|
||||
HTTPClient HTTPClient
|
||||
}
|
||||
|
||||
// NewClient creates an API client
|
||||
func NewClient(authToken string) *Client {
|
||||
return &Client{
|
||||
authToken: authToken,
|
||||
apiEndpoint: apiEndpoint,
|
||||
HTTPClient: defaultHTTPClient,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) delete(path string) (*http.Response, error) {
|
||||
return c.do("DELETE", path, nil, nil)
|
||||
}
|
||||
|
||||
func (c *Client) put(path string, payload interface{}, headers *map[string]string) (*http.Response, error) {
|
||||
|
||||
if payload != nil {
|
||||
data, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.do("PUT", path, bytes.NewBuffer(data), headers)
|
||||
}
|
||||
return c.do("PUT", path, nil, headers)
|
||||
}
|
||||
|
||||
func (c *Client) post(path string, payload interface{}, headers *map[string]string) (*http.Response, error) {
|
||||
data, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.do("POST", path, bytes.NewBuffer(data), headers)
|
||||
}
|
||||
|
||||
func (c *Client) get(path string) (*http.Response, error) {
|
||||
return c.do("GET", path, nil, nil)
|
||||
}
|
||||
|
||||
func (c *Client) do(method, path string, body io.Reader, headers *map[string]string) (*http.Response, error) {
|
||||
endpoint := c.apiEndpoint + path
|
||||
req, _ := http.NewRequest(method, endpoint, body)
|
||||
req.Header.Set("Accept", "application/vnd.pagerduty+json;version=2")
|
||||
if headers != nil {
|
||||
for k, v := range *headers {
|
||||
req.Header.Set(k, v)
|
||||
}
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Authorization", "Token token="+c.authToken)
|
||||
|
||||
resp, err := c.HTTPClient.Do(req)
|
||||
return c.checkResponse(resp, err)
|
||||
}
|
||||
|
||||
func (c *Client) decodeJSON(resp *http.Response, payload interface{}) error {
|
||||
defer resp.Body.Close()
|
||||
decoder := json.NewDecoder(resp.Body)
|
||||
return decoder.Decode(payload)
|
||||
}
|
||||
|
||||
func (c *Client) checkResponse(resp *http.Response, err error) (*http.Response, error) {
|
||||
if err != nil {
|
||||
return resp, fmt.Errorf("Error calling the API endpoint: %v", err)
|
||||
}
|
||||
if 199 >= resp.StatusCode || 300 <= resp.StatusCode {
|
||||
var eo *errorObject
|
||||
var getErr error
|
||||
if eo, getErr = c.getErrorFromResponse(resp); getErr != nil {
|
||||
return resp, fmt.Errorf("Response did not contain formatted error: %s. HTTP response code: %v. Raw response: %+v", getErr, resp.StatusCode, resp)
|
||||
}
|
||||
return resp, fmt.Errorf("Failed call API endpoint. HTTP response code: %v. Error: %v", resp.StatusCode, eo)
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (c *Client) getErrorFromResponse(resp *http.Response) (*errorObject, error) {
|
||||
var result map[string]errorObject
|
||||
if err := c.decodeJSON(resp, &result); err != nil {
|
||||
return nil, fmt.Errorf("Could not decode JSON response: %v", err)
|
||||
}
|
||||
s, ok := result["error"]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("JSON response does not have error field")
|
||||
}
|
||||
return &s, nil
|
||||
}
|
186
vendor/github.com/PagerDuty/go-pagerduty/escalation_policy.go
generated
vendored
186
vendor/github.com/PagerDuty/go-pagerduty/escalation_policy.go
generated
vendored
@ -1,186 +0,0 @@
|
||||
package pagerduty
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/google/go-querystring/query"
|
||||
)
|
||||
|
||||
const (
|
||||
escPath = "/escalation_policies"
|
||||
)
|
||||
|
||||
// EscalationRule is a rule for an escalation policy to trigger.
|
||||
type EscalationRule struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Delay uint `json:"escalation_delay_in_minutes,omitempty"`
|
||||
Targets []APIObject `json:"targets"`
|
||||
}
|
||||
|
||||
// EscalationPolicy is a collection of escalation rules.
|
||||
type EscalationPolicy struct {
|
||||
APIObject
|
||||
Name string `json:"name,omitempty"`
|
||||
EscalationRules []EscalationRule `json:"escalation_rules,omitempty"`
|
||||
Services []APIObject `json:"services,omitempty"`
|
||||
NumLoops uint `json:"num_loops,omitempty"`
|
||||
Teams []APIReference `json:"teams"`
|
||||
Description string `json:"description,omitempty"`
|
||||
RepeatEnabled bool `json:"repeat_enabled,omitempty"`
|
||||
}
|
||||
|
||||
// ListEscalationPoliciesResponse is the data structure returned from calling the ListEscalationPolicies API endpoint.
|
||||
type ListEscalationPoliciesResponse struct {
|
||||
APIListObject
|
||||
EscalationPolicies []EscalationPolicy `json:"escalation_policies"`
|
||||
}
|
||||
|
||||
type ListEscalationRulesResponse struct {
|
||||
APIListObject
|
||||
EscalationRules []EscalationRule `json:"escalation_rules"`
|
||||
}
|
||||
|
||||
// ListEscalationPoliciesOptions is the data structure used when calling the ListEscalationPolicies API endpoint.
|
||||
type ListEscalationPoliciesOptions struct {
|
||||
APIListObject
|
||||
Query string `url:"query,omitempty"`
|
||||
UserIDs []string `url:"user_ids,omitempty,brackets"`
|
||||
TeamIDs []string `url:"team_ids,omitempty,brackets"`
|
||||
Includes []string `url:"include,omitempty,brackets"`
|
||||
SortBy string `url:"sort_by,omitempty"`
|
||||
}
|
||||
|
||||
// GetEscalationRuleOptions is the data structure used when calling the GetEscalationRule API endpoint.
|
||||
type GetEscalationRuleOptions struct {
|
||||
Includes []string `url:"include,omitempty,brackets"`
|
||||
}
|
||||
|
||||
// ListEscalationPolicies lists all of the existing escalation policies.
|
||||
func (c *Client) ListEscalationPolicies(o ListEscalationPoliciesOptions) (*ListEscalationPoliciesResponse, error) {
|
||||
v, err := query.Values(o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := c.get(escPath + "?" + v.Encode())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result ListEscalationPoliciesResponse
|
||||
return &result, c.decodeJSON(resp, &result)
|
||||
}
|
||||
|
||||
// CreateEscalationPolicy creates a new escalation policy.
|
||||
func (c *Client) CreateEscalationPolicy(e EscalationPolicy) (*EscalationPolicy, error) {
|
||||
data := make(map[string]EscalationPolicy)
|
||||
data["escalation_policy"] = e
|
||||
resp, err := c.post(escPath, data, nil)
|
||||
return getEscalationPolicyFromResponse(c, resp, err)
|
||||
}
|
||||
|
||||
// DeleteEscalationPolicy deletes an existing escalation policy and rules.
|
||||
func (c *Client) DeleteEscalationPolicy(id string) error {
|
||||
_, err := c.delete(escPath + "/" + id)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetEscalationPolicyOptions is the data structure used when calling the GetEscalationPolicy API endpoint.
|
||||
type GetEscalationPolicyOptions struct {
|
||||
Includes []string `url:"include,omitempty,brackets"`
|
||||
}
|
||||
|
||||
// GetEscalationPolicy gets information about an existing escalation policy and its rules.
|
||||
func (c *Client) GetEscalationPolicy(id string, o *GetEscalationPolicyOptions) (*EscalationPolicy, error) {
|
||||
v, err := query.Values(o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := c.get(escPath + "/" + id + "?" + v.Encode())
|
||||
return getEscalationPolicyFromResponse(c, resp, err)
|
||||
}
|
||||
|
||||
// UpdateEscalationPolicy updates an existing escalation policy and its rules.
|
||||
func (c *Client) UpdateEscalationPolicy(id string, e *EscalationPolicy) (*EscalationPolicy, error) {
|
||||
data := make(map[string]EscalationPolicy)
|
||||
data["escalation_policy"] = *e
|
||||
resp, err := c.put(escPath+"/"+id, data, nil)
|
||||
return getEscalationPolicyFromResponse(c, resp, err)
|
||||
}
|
||||
|
||||
// CreateEscalationRule creates a new escalation rule for an escalation policy
|
||||
// and appends it to the end of the existing escalation rules.
|
||||
func (c *Client) CreateEscalationRule(escID string, e EscalationRule) (*EscalationRule, error) {
|
||||
data := make(map[string]EscalationRule)
|
||||
data["escalation_rule"] = e
|
||||
resp, err := c.post(escPath+"/"+escID+"/escalation_rules", data, nil)
|
||||
return getEscalationRuleFromResponse(c, resp, err)
|
||||
}
|
||||
|
||||
// GetEscalationRule gets information about an existing escalation rule.
|
||||
func (c *Client) GetEscalationRule(escID string, id string, o *GetEscalationRuleOptions) (*EscalationRule, error) {
|
||||
v, err := query.Values(o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := c.get(escPath + "/" + escID + "/escalation_rules/" + id + "?" + v.Encode())
|
||||
return getEscalationRuleFromResponse(c, resp, err)
|
||||
}
|
||||
|
||||
// DeleteEscalationRule deletes an existing escalation rule.
|
||||
func (c *Client) DeleteEscalationRule(escID string, id string) error {
|
||||
_, err := c.delete(escPath + "/" + escID + "/escalation_rules/" + id)
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateEscalationRule updates an existing escalation rule.
|
||||
func (c *Client) UpdateEscalationRule(escID string, id string, e *EscalationRule) (*EscalationRule, error) {
|
||||
data := make(map[string]EscalationRule)
|
||||
data["escalation_rule"] = *e
|
||||
resp, err := c.put(escPath+"/"+escID+"/escalation_rules/"+id, data, nil)
|
||||
return getEscalationRuleFromResponse(c, resp, err)
|
||||
}
|
||||
|
||||
// ListEscalationRules lists all of the escalation rules for an existing escalation policy.
|
||||
func (c *Client) ListEscalationRules(escID string) (*ListEscalationRulesResponse, error) {
|
||||
resp, err := c.get(escPath + "/" + escID + "/escalation_rules")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result ListEscalationRulesResponse
|
||||
return &result, c.decodeJSON(resp, &result)
|
||||
}
|
||||
|
||||
func getEscalationRuleFromResponse(c *Client, resp *http.Response, err error) (*EscalationRule, error) {
|
||||
defer resp.Body.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var target map[string]EscalationRule
|
||||
if dErr := c.decodeJSON(resp, &target); dErr != nil {
|
||||
return nil, fmt.Errorf("Could not decode JSON response: %v", dErr)
|
||||
}
|
||||
rootNode := "escalation_rule"
|
||||
t, nodeOK := target[rootNode]
|
||||
if !nodeOK {
|
||||
return nil, fmt.Errorf("JSON response does not have %s field", rootNode)
|
||||
}
|
||||
return &t, nil
|
||||
}
|
||||
|
||||
func getEscalationPolicyFromResponse(c *Client, resp *http.Response, err error) (*EscalationPolicy, error) {
|
||||
defer resp.Body.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var target map[string]EscalationPolicy
|
||||
if dErr := c.decodeJSON(resp, &target); dErr != nil {
|
||||
return nil, fmt.Errorf("Could not decode JSON response: %v", dErr)
|
||||
}
|
||||
rootNode := "escalation_policy"
|
||||
t, nodeOK := target[rootNode]
|
||||
if !nodeOK {
|
||||
return nil, fmt.Errorf("JSON response does not have %s field", rootNode)
|
||||
}
|
||||
return &t, nil
|
||||
}
|
62
vendor/github.com/PagerDuty/go-pagerduty/event.go
generated
vendored
62
vendor/github.com/PagerDuty/go-pagerduty/event.go
generated
vendored
@ -1,62 +0,0 @@
|
||||
package pagerduty
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const eventEndPoint = "https://events.pagerduty.com/generic/2010-04-15/create_event.json"
|
||||
|
||||
// Event stores data for problem reporting, acknowledgement, and resolution.
|
||||
type Event struct {
|
||||
ServiceKey string `json:"service_key"`
|
||||
Type string `json:"event_type"`
|
||||
IncidentKey string `json:"incident_key,omitempty"`
|
||||
Description string `json:"description"`
|
||||
Client string `json:"client,omitempty"`
|
||||
ClientURL string `json:"client_url,omitempty"`
|
||||
Details interface{} `json:"details,omitempty"`
|
||||
Contexts []interface{} `json:"contexts,omitempty"`
|
||||
}
|
||||
|
||||
// EventResponse is the data returned from the CreateEvent API endpoint.
|
||||
type EventResponse struct {
|
||||
Status string `json:"status"`
|
||||
Message string `json:"message"`
|
||||
IncidentKey string `json:"incident_key"`
|
||||
}
|
||||
|
||||
// CreateEvent sends PagerDuty an event to trigger, acknowledge, or resolve a
|
||||
// problem. If you need to provide a custom HTTP client, please use
|
||||
// CreateEventWithHTTPClient.
|
||||
func CreateEvent(e Event) (*EventResponse, error) {
|
||||
return CreateEventWithHTTPClient(e, defaultHTTPClient)
|
||||
}
|
||||
|
||||
// CreateEventWithHTTPClient sends PagerDuty an event to trigger, acknowledge,
|
||||
// or resolve a problem. This function accepts a custom HTTP Client, if the
|
||||
// default one used by this package doesn't fit your needs. If you don't need a
|
||||
// custom HTTP client, please use CreateEvent instead.
|
||||
func CreateEventWithHTTPClient(e Event, client HTTPClient) (*EventResponse, error) {
|
||||
data, err := json.Marshal(e)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, _ := http.NewRequest("POST", eventEndPoint, bytes.NewBuffer(data))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("HTTP Status Code: %d", resp.StatusCode)
|
||||
}
|
||||
var eventResponse EventResponse
|
||||
if err := json.NewDecoder(resp.Body).Decode(&eventResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &eventResponse, nil
|
||||
}
|
69
vendor/github.com/PagerDuty/go-pagerduty/event_v2.go
generated
vendored
69
vendor/github.com/PagerDuty/go-pagerduty/event_v2.go
generated
vendored
@ -1,69 +0,0 @@
|
||||
package pagerduty
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Event includes the incident/alert details
|
||||
type V2Event struct {
|
||||
RoutingKey string `json:"routing_key"`
|
||||
Action string `json:"event_action"`
|
||||
DedupKey string `json:"dedup_key,omitempty"`
|
||||
Images []interface{} `json:"images,omitempty"`
|
||||
Links []interface{} `json:"links,omitempty"`
|
||||
Client string `json:"client,omitempty"`
|
||||
ClientURL string `json:"client_url,omitempty"`
|
||||
Payload *V2Payload `json:"payload,omitempty"`
|
||||
}
|
||||
|
||||
// Payload represents the individual event details for an event
|
||||
type V2Payload struct {
|
||||
Summary string `json:"summary"`
|
||||
Source string `json:"source"`
|
||||
Severity string `json:"severity"`
|
||||
Timestamp string `json:"timestamp,omitempty"`
|
||||
Component string `json:"component,omitempty"`
|
||||
Group string `json:"group,omitempty"`
|
||||
Class string `json:"class,omitempty"`
|
||||
Details interface{} `json:"custom_details,omitempty"`
|
||||
}
|
||||
|
||||
// Response is the json response body for an event
|
||||
type V2EventResponse struct {
|
||||
RoutingKey string `json:"routing_key"`
|
||||
DedupKey string `json:"dedup_key"`
|
||||
EventAction string `json:"event_action"`
|
||||
}
|
||||
|
||||
const v2eventEndPoint = "https://events.pagerduty.com/v2/enqueue"
|
||||
|
||||
// ManageEvent handles the trigger, acknowledge, and resolve methods for an event
|
||||
func ManageEvent(e V2Event) (*V2EventResponse, error) {
|
||||
data, err := json.Marshal(e)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, _ := http.NewRequest("POST", v2eventEndPoint, bytes.NewBuffer(data))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusAccepted {
|
||||
bytes, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("HTTP Status Code: %d", resp.StatusCode)
|
||||
}
|
||||
return nil, fmt.Errorf("HTTP Status Code: %d, Message: %s", resp.StatusCode, string(bytes))
|
||||
}
|
||||
var eventResponse V2EventResponse
|
||||
if err := json.NewDecoder(resp.Body).Decode(&eventResponse); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &eventResponse, nil
|
||||
}
|
307
vendor/github.com/PagerDuty/go-pagerduty/incident.go
generated
vendored
307
vendor/github.com/PagerDuty/go-pagerduty/incident.go
generated
vendored
@ -1,307 +0,0 @@
|
||||
package pagerduty
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/go-querystring/query"
|
||||
)
|
||||
|
||||
// Acknowledgement is the data structure of an acknowledgement of an incident.
|
||||
type Acknowledgement struct {
|
||||
At string `json:"at,omitempty"`
|
||||
Acknowledger APIObject `json:"acknowledger,omitempty"`
|
||||
}
|
||||
|
||||
// PendingAction is the data structure for any pending actions on an incident.
|
||||
type PendingAction struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
At string `json:"at,omitempty"`
|
||||
}
|
||||
|
||||
// Assignment is the data structure for an assignment of an incident
|
||||
type Assignment struct {
|
||||
At string `json:"at,omitempty"`
|
||||
Assignee APIObject `json:"assignee,omitempty"`
|
||||
}
|
||||
|
||||
// AlertCounts is the data structure holding a summary of the number of alerts by status of an incident.
|
||||
type AlertCounts struct {
|
||||
Triggered uint `json:"triggered,omitempty"`
|
||||
Resolved uint `json:"resolved,omitempty"`
|
||||
All uint `json:"all,omitempty"`
|
||||
}
|
||||
|
||||
// Priority is the data structure describing the priority of an incident.
|
||||
type Priority struct {
|
||||
APIObject
|
||||
Name string `json:"name,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
}
|
||||
|
||||
// Resolve reason is the data structure describing the reason an incident was resolved
|
||||
type ResolveReason struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
Incident APIObject `json:"incident"`
|
||||
}
|
||||
|
||||
// IncidentBody is the datastructure containing data describing the incident.
|
||||
type IncidentBody struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
Details string `json:"details,omitempty"`
|
||||
}
|
||||
|
||||
// Incident is a normalized, de-duplicated event generated by a PagerDuty integration.
|
||||
type Incident struct {
|
||||
APIObject
|
||||
IncidentNumber uint `json:"incident_number,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
CreatedAt string `json:"created_at,omitempty"`
|
||||
PendingActions []PendingAction `json:"pending_actions,omitempty"`
|
||||
IncidentKey string `json:"incident_key,omitempty"`
|
||||
Service APIObject `json:"service,omitempty"`
|
||||
Assignments []Assignment `json:"assignments,omitempty"`
|
||||
Acknowledgements []Acknowledgement `json:"acknowledgements,omitempty"`
|
||||
LastStatusChangeAt string `json:"last_status_change_at,omitempty"`
|
||||
LastStatusChangeBy APIObject `json:"last_status_change_by,omitempty"`
|
||||
FirstTriggerLogEntry APIObject `json:"first_trigger_log_entry,omitempty"`
|
||||
EscalationPolicy APIObject `json:"escalation_policy,omitempty"`
|
||||
Teams []APIObject `json:"teams,omitempty"`
|
||||
Priority *Priority `json:"priority,omitempty"`
|
||||
Urgency string `json:"urgency,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
Id string `json:"id,omitempty"`
|
||||
ResolveReason ResolveReason `json:"resolve_reason,omitempty"`
|
||||
AlertCounts AlertCounts `json:"alert_counts,omitempty"`
|
||||
Body IncidentBody `json:"body,omitempty"`
|
||||
IsMergeable bool `json:"is_mergeable,omitempty"`
|
||||
}
|
||||
|
||||
// ListIncidentsResponse is the response structure when calling the ListIncident API endpoint.
|
||||
type ListIncidentsResponse struct {
|
||||
APIListObject
|
||||
Incidents []Incident `json:"incidents,omitempty"`
|
||||
}
|
||||
|
||||
// ListIncidentsOptions is the structure used when passing parameters to the ListIncident API endpoint.
|
||||
type ListIncidentsOptions struct {
|
||||
APIListObject
|
||||
Since string `url:"since,omitempty"`
|
||||
Until string `url:"until,omitempty"`
|
||||
DateRange string `url:"date_range,omitempty"`
|
||||
Statuses []string `url:"statuses,omitempty,brackets"`
|
||||
IncidentKey string `url:"incident_key,omitempty"`
|
||||
ServiceIDs []string `url:"service_ids,omitempty,brackets"`
|
||||
TeamIDs []string `url:"team_ids,omitempty,brackets"`
|
||||
UserIDs []string `url:"user_ids,omitempty,brackets"`
|
||||
Urgencies []string `url:"urgencies,omitempty,brackets"`
|
||||
TimeZone string `url:"time_zone,omitempty"`
|
||||
SortBy string `url:"sort_by,omitempty"`
|
||||
Includes []string `url:"include,omitempty,brackets"`
|
||||
}
|
||||
|
||||
// ListIncidents lists existing incidents.
|
||||
func (c *Client) ListIncidents(o ListIncidentsOptions) (*ListIncidentsResponse, error) {
|
||||
v, err := query.Values(o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := c.get("/incidents?" + v.Encode())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result ListIncidentsResponse
|
||||
return &result, c.decodeJSON(resp, &result)
|
||||
}
|
||||
|
||||
// createIncidentResponse is returned from the API when creating a response.
|
||||
type createIncidentResponse struct {
|
||||
Incident Incident `json:"incident"`
|
||||
}
|
||||
|
||||
// CreateIncidentOptions is the structure used when POSTing to the CreateIncident API endpoint.
|
||||
type CreateIncidentOptions struct {
|
||||
Type string `json:"type"`
|
||||
Title string `json:"title"`
|
||||
Service *APIReference `json:"service"`
|
||||
Priority *APIReference `json:"priority,omitempty"`
|
||||
IncidentKey string `json:"incident_key,omitempty"`
|
||||
Body *APIDetails `json:"body,omitempty"`
|
||||
EscalationPolicy *APIReference `json:"escalation_policy,omitempty"`
|
||||
}
|
||||
|
||||
// CreateIncident creates an incident synchronously without a corresponding event from a monitoring service.
|
||||
func (c *Client) CreateIncident(from string, o *CreateIncidentOptions) (*Incident, error) {
|
||||
headers := make(map[string]string)
|
||||
headers["From"] = from
|
||||
data := make(map[string]*CreateIncidentOptions)
|
||||
data["incident"] = o
|
||||
resp, e := c.post("/incidents", data, &headers)
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
|
||||
var ii createIncidentResponse
|
||||
e = json.NewDecoder(resp.Body).Decode(&ii)
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
|
||||
return &ii.Incident, nil
|
||||
}
|
||||
|
||||
// ManageIncidents acknowledges, resolves, escalates, or reassigns one or more incidents.
|
||||
func (c *Client) ManageIncidents(from string, incidents []Incident) error {
|
||||
r := make(map[string][]Incident)
|
||||
headers := make(map[string]string)
|
||||
headers["From"] = from
|
||||
r["incidents"] = incidents
|
||||
_, e := c.put("/incidents", r, &headers)
|
||||
return e
|
||||
}
|
||||
|
||||
// MergeIncidents a list of source incidents into a specified incident.
|
||||
func (c *Client) MergeIncidents(from string, id string, incidents []Incident) error {
|
||||
r := make(map[string][]Incident)
|
||||
r["source_incidents"] = incidents
|
||||
headers := make(map[string]string)
|
||||
headers["From"] = from
|
||||
_, e := c.put("/incidents/"+id+"/merge", r, &headers)
|
||||
return e
|
||||
}
|
||||
|
||||
// GetIncident shows detailed information about an incident.
|
||||
func (c *Client) GetIncident(id string) (*Incident, error) {
|
||||
resp, err := c.get("/incidents/" + id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result map[string]Incident
|
||||
if err := c.decodeJSON(resp, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
i, ok := result["incident"]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("JSON response does not have incident field")
|
||||
}
|
||||
return &i, nil
|
||||
}
|
||||
|
||||
// IncidentNote is a note for the specified incident.
|
||||
type IncidentNote struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
User APIObject `json:"user,omitempty"`
|
||||
Content string `json:"content,omitempty"`
|
||||
CreatedAt string `json:"created_at,omitempty"`
|
||||
}
|
||||
|
||||
// ListIncidentNotes lists existing notes for the specified incident.
|
||||
func (c *Client) ListIncidentNotes(id string) ([]IncidentNote, error) {
|
||||
resp, err := c.get("/incidents/" + id + "/notes")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result map[string][]IncidentNote
|
||||
if err := c.decodeJSON(resp, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
notes, ok := result["notes"]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("JSON response does not have notes field")
|
||||
}
|
||||
return notes, nil
|
||||
}
|
||||
|
||||
// IncidentAlert is a alert for the specified incident.
|
||||
type IncidentAlert struct {
|
||||
APIObject
|
||||
CreatedAt string `json:"created_at,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
AlertKey string `json:"alert_key,omitempty"`
|
||||
Service APIObject `json:"service,omitempty"`
|
||||
Body map[string]interface{} `json:"body,omitempty"`
|
||||
Incident APIReference `json:"incident,omitempty"`
|
||||
Suppressed bool `json:"suppressed,omitempty"`
|
||||
Severity string `json:"severity,omitempty"`
|
||||
Integration APIObject `json:"integration,omitempty"`
|
||||
}
|
||||
|
||||
// ListAlertsResponse is the response structure when calling the ListAlert API endpoint.
|
||||
type ListAlertsResponse struct {
|
||||
APIListObject
|
||||
Alerts []IncidentAlert `json:"alerts,omitempty"`
|
||||
}
|
||||
|
||||
// ListIncidentAlerts lists existing alerts for the specified incident.
|
||||
func (c *Client) ListIncidentAlerts(id string) (*ListAlertsResponse, error) {
|
||||
resp, err := c.get("/incidents/" + id + "/alerts")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result ListAlertsResponse
|
||||
return &result, c.decodeJSON(resp, &result)
|
||||
}
|
||||
|
||||
// CreateIncidentNote creates a new note for the specified incident.
|
||||
func (c *Client) CreateIncidentNote(id string, note IncidentNote) error {
|
||||
data := make(map[string]IncidentNote)
|
||||
headers := make(map[string]string)
|
||||
headers["From"] = note.User.Summary
|
||||
|
||||
data["note"] = note
|
||||
_, err := c.post("/incidents/"+id+"/notes", data, &headers)
|
||||
return err
|
||||
}
|
||||
|
||||
// SnoozeIncident sets an incident to not alert for a specified period of time.
|
||||
func (c *Client) SnoozeIncident(id string, duration uint) error {
|
||||
data := make(map[string]uint)
|
||||
data["duration"] = duration
|
||||
_, err := c.post("/incidents/"+id+"/snooze", data, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
// ListIncidentLogEntriesResponse is the response structure when calling the ListIncidentLogEntries API endpoint.
|
||||
type ListIncidentLogEntriesResponse struct {
|
||||
APIListObject
|
||||
LogEntries []LogEntry `json:"log_entries,omitempty"`
|
||||
}
|
||||
|
||||
// ListIncidentLogEntriesOptions is the structure used when passing parameters to the ListIncidentLogEntries API endpoint.
|
||||
type ListIncidentLogEntriesOptions struct {
|
||||
APIListObject
|
||||
Includes []string `url:"include,omitempty,brackets"`
|
||||
IsOverview bool `url:"is_overview,omitempty"`
|
||||
TimeZone string `url:"time_zone,omitempty"`
|
||||
}
|
||||
|
||||
// ListIncidentLogEntries lists existing log entries for the specified incident.
|
||||
func (c *Client) ListIncidentLogEntries(id string, o ListIncidentLogEntriesOptions) (*ListIncidentLogEntriesResponse, error) {
|
||||
v, err := query.Values(o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := c.get("/incidents/" + id + "/log_entries?" + v.Encode())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result ListIncidentLogEntriesResponse
|
||||
return &result, c.decodeJSON(resp, &result)
|
||||
}
|
||||
|
||||
// Alert is a list of all of the alerts that happened to an incident.
|
||||
type Alert struct {
|
||||
APIObject
|
||||
Service APIObject `json:"service,omitempty"`
|
||||
CreatedAt string `json:"created_at,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
AlertKey string `json:"alert_key,omitempty"`
|
||||
Incident APIObject `json:"incident,omitempty"`
|
||||
}
|
||||
|
||||
type ListAlertResponse struct {
|
||||
APIListObject
|
||||
Alerts []Alert `json:"alerts,omitempty"`
|
||||
}
|
94
vendor/github.com/PagerDuty/go-pagerduty/log_entry.go
generated
vendored
94
vendor/github.com/PagerDuty/go-pagerduty/log_entry.go
generated
vendored
@ -1,94 +0,0 @@
|
||||
package pagerduty
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/google/go-querystring/query"
|
||||
)
|
||||
|
||||
// Agent is the actor who carried out the action.
|
||||
type Agent APIObject
|
||||
|
||||
// Channel is the means by which the action was carried out.
|
||||
type Channel struct {
|
||||
Type string
|
||||
}
|
||||
|
||||
// Context are to be included with the trigger such as links to graphs or images.
|
||||
type Context struct {
|
||||
Alt string
|
||||
Href string
|
||||
Src string
|
||||
Text string
|
||||
Type string
|
||||
}
|
||||
|
||||
// LogEntry is a list of all of the events that happened to an incident.
|
||||
type LogEntry struct {
|
||||
APIObject
|
||||
CreatedAt string `json:"created_at"`
|
||||
Agent Agent
|
||||
Channel Channel
|
||||
Incident Incident
|
||||
Teams []Team
|
||||
Contexts []Context
|
||||
AcknowledgementTimeout int `json:"acknowledgement_timeout"`
|
||||
EventDetails map[string]string
|
||||
}
|
||||
|
||||
// ListLogEntryResponse is the response data when calling the ListLogEntry API endpoint.
|
||||
type ListLogEntryResponse struct {
|
||||
APIListObject
|
||||
LogEntries []LogEntry `json:"log_entries"`
|
||||
}
|
||||
|
||||
// ListLogEntriesOptions is the data structure used when calling the ListLogEntry API endpoint.
|
||||
type ListLogEntriesOptions struct {
|
||||
APIListObject
|
||||
TimeZone string `url:"time_zone"`
|
||||
Since string `url:"since,omitempty"`
|
||||
Until string `url:"until,omitempty"`
|
||||
IsOverview bool `url:"is_overview,omitempty"`
|
||||
Includes []string `url:"include,omitempty,brackets"`
|
||||
}
|
||||
|
||||
// ListLogEntries lists all of the incident log entries across the entire account.
|
||||
func (c *Client) ListLogEntries(o ListLogEntriesOptions) (*ListLogEntryResponse, error) {
|
||||
v, err := query.Values(o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := c.get("/log_entries?" + v.Encode())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result ListLogEntryResponse
|
||||
return &result, c.decodeJSON(resp, &result)
|
||||
}
|
||||
|
||||
// GetLogEntryOptions is the data structure used when calling the GetLogEntry API endpoint.
|
||||
type GetLogEntryOptions struct {
|
||||
TimeZone string `url:"time_zone,omitempty"`
|
||||
Includes []string `url:"include,omitempty,brackets"`
|
||||
}
|
||||
|
||||
// GetLogEntry list log entries for the specified incident.
|
||||
func (c *Client) GetLogEntry(id string, o GetLogEntryOptions) (*LogEntry, error) {
|
||||
v, err := query.Values(o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := c.get("/log_entries/" + id + "?" + v.Encode())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result map[string]LogEntry
|
||||
if err := c.decodeJSON(resp, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
le, ok := result["log_entry"]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("JSON response does not have log_entry field")
|
||||
}
|
||||
return &le, nil
|
||||
}
|
112
vendor/github.com/PagerDuty/go-pagerduty/maintenance_window.go
generated
vendored
112
vendor/github.com/PagerDuty/go-pagerduty/maintenance_window.go
generated
vendored
@ -1,112 +0,0 @@
|
||||
package pagerduty
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/google/go-querystring/query"
|
||||
)
|
||||
|
||||
// MaintenanceWindow is used to temporarily disable one or more services for a set period of time.
|
||||
type MaintenanceWindow struct {
|
||||
APIObject
|
||||
SequenceNumber uint `json:"sequence_number,omitempty"`
|
||||
StartTime string `json:"start_time"`
|
||||
EndTime string `json:"end_time"`
|
||||
Description string `json:"description"`
|
||||
Services []APIObject `json:"services"`
|
||||
Teams []APIListObject `json:"teams"`
|
||||
CreatedBy APIListObject `json:"created_by"`
|
||||
}
|
||||
|
||||
// ListMaintenanceWindowsResponse is the data structur returned from calling the ListMaintenanceWindows API endpoint.
|
||||
type ListMaintenanceWindowsResponse struct {
|
||||
APIListObject
|
||||
MaintenanceWindows []MaintenanceWindow `json:"maintenance_windows"`
|
||||
}
|
||||
|
||||
// ListMaintenanceWindowsOptions is the data structure used when calling the ListMaintenanceWindows API endpoint.
|
||||
type ListMaintenanceWindowsOptions struct {
|
||||
APIListObject
|
||||
Query string `url:"query,omitempty"`
|
||||
Includes []string `url:"include,omitempty,brackets"`
|
||||
TeamIDs []string `url:"team_ids,omitempty,brackets"`
|
||||
ServiceIDs []string `url:"service_ids,omitempty,brackets"`
|
||||
Filter string `url:"filter,omitempty,brackets"`
|
||||
}
|
||||
|
||||
// ListMaintenanceWindows lists existing maintenance windows, optionally filtered by service and/or team, or whether they are from the past, present or future.
|
||||
func (c *Client) ListMaintenanceWindows(o ListMaintenanceWindowsOptions) (*ListMaintenanceWindowsResponse, error) {
|
||||
v, err := query.Values(o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := c.get("/maintenance_windows?" + v.Encode())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result ListMaintenanceWindowsResponse
|
||||
return &result, c.decodeJSON(resp, &result)
|
||||
}
|
||||
|
||||
// CreateMaintenanceWindow creates a new maintenance window for the specified services.
|
||||
func (c *Client) CreateMaintenanceWindow(from string, o MaintenanceWindow) (*MaintenanceWindow, error) {
|
||||
data := make(map[string]MaintenanceWindow)
|
||||
o.Type = "maintenance_window"
|
||||
data["maintenance_window"] = o
|
||||
headers := make(map[string]string)
|
||||
if from != "" {
|
||||
headers["From"] = from
|
||||
}
|
||||
resp, err := c.post("/maintenance_windows", data, &headers)
|
||||
return getMaintenanceWindowFromResponse(c, resp, err)
|
||||
}
|
||||
|
||||
// CreateMaintenanceWindows creates a new maintenance window for the specified services.
|
||||
// Deprecated: Use `CreateMaintenanceWindow` instead.
|
||||
func (c *Client) CreateMaintenanceWindows(o MaintenanceWindow) (*MaintenanceWindow, error) {
|
||||
return c.CreateMaintenanceWindow("", o)
|
||||
}
|
||||
|
||||
// DeleteMaintenanceWindow deletes an existing maintenance window if it's in the future, or ends it if it's currently on-going.
|
||||
func (c *Client) DeleteMaintenanceWindow(id string) error {
|
||||
_, err := c.delete("/maintenance_windows/" + id)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetMaintenanceWindowOptions is the data structure used when calling the GetMaintenanceWindow API endpoint.
|
||||
type GetMaintenanceWindowOptions struct {
|
||||
Includes []string `url:"include,omitempty,brackets"`
|
||||
}
|
||||
|
||||
// GetMaintenanceWindow gets an existing maintenance window.
|
||||
func (c *Client) GetMaintenanceWindow(id string, o GetMaintenanceWindowOptions) (*MaintenanceWindow, error) {
|
||||
v, err := query.Values(o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := c.get("/maintenance_windows/" + id + "?" + v.Encode())
|
||||
return getMaintenanceWindowFromResponse(c, resp, err)
|
||||
}
|
||||
|
||||
// UpdateMaintenanceWindow updates an existing maintenance window.
|
||||
func (c *Client) UpdateMaintenanceWindow(m MaintenanceWindow) (*MaintenanceWindow, error) {
|
||||
resp, err := c.put("/maintenance_windows/"+m.ID, m, nil)
|
||||
return getMaintenanceWindowFromResponse(c, resp, err)
|
||||
}
|
||||
|
||||
func getMaintenanceWindowFromResponse(c *Client, resp *http.Response, err error) (*MaintenanceWindow, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var target map[string]MaintenanceWindow
|
||||
if dErr := c.decodeJSON(resp, &target); dErr != nil {
|
||||
return nil, fmt.Errorf("Could not decode JSON response: %v", dErr)
|
||||
}
|
||||
rootNode := "maintenance_window"
|
||||
t, nodeOK := target[rootNode]
|
||||
if !nodeOK {
|
||||
return nil, fmt.Errorf("JSON response does not have %s field", rootNode)
|
||||
}
|
||||
return &t, nil
|
||||
}
|
44
vendor/github.com/PagerDuty/go-pagerduty/notification.go
generated
vendored
44
vendor/github.com/PagerDuty/go-pagerduty/notification.go
generated
vendored
@ -1,44 +0,0 @@
|
||||
package pagerduty
|
||||
|
||||
import (
|
||||
"github.com/google/go-querystring/query"
|
||||
)
|
||||
|
||||
// Notification is a message containing the details of the incident.
|
||||
type Notification struct {
|
||||
ID string `json:"id"`
|
||||
Type string
|
||||
StartedAt string `json:"started_at"`
|
||||
Address string
|
||||
User APIObject
|
||||
}
|
||||
|
||||
// ListNotificationOptions is the data structure used when calling the ListNotifications API endpoint.
|
||||
type ListNotificationOptions struct {
|
||||
APIListObject
|
||||
TimeZone string `url:"time_zone,omitempty"`
|
||||
Since string `url:"since,omitempty"`
|
||||
Until string `url:"until,omitempty"`
|
||||
Filter string `url:"filter,omitempty"`
|
||||
Includes []string `url:"include,omitempty"`
|
||||
}
|
||||
|
||||
// ListNotificationsResponse is the data structure returned from the ListNotifications API endpoint.
|
||||
type ListNotificationsResponse struct {
|
||||
APIListObject
|
||||
Notifications []Notification
|
||||
}
|
||||
|
||||
// ListNotifications lists notifications for a given time range, optionally filtered by type (sms_notification, email_notification, phone_notification, or push_notification).
|
||||
func (c *Client) ListNotifications(o ListNotificationOptions) (*ListNotificationsResponse, error) {
|
||||
v, err := query.Values(o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := c.get("/notifications?" + v.Encode())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result ListNotificationsResponse
|
||||
return &result, c.decodeJSON(resp, &result)
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user