Update Azure SDK for Go to v30.0.0
This commit is contained in:
parent
078622a40d
commit
700c95c613
|
@ -22,14 +22,14 @@ func TestNewSecretOAuthTokenProvider(t *testing.T) {
|
|||
if spn.Token().RefreshToken != "" {
|
||||
t.Errorf("spn.Token().RefreshToken: expected=\"\", actual=%s", spn.Token().RefreshToken)
|
||||
}
|
||||
if spn.Token().ExpiresIn != "" {
|
||||
t.Errorf("spn.Token().ExpiresIn: expected=\"\", actual=%s", spn.Token().ExpiresIn)
|
||||
if spn.Token().ExpiresIn != "0" {
|
||||
t.Errorf("spn.Token().ExpiresIn: expected=\"0\", actual=%s", spn.Token().ExpiresIn)
|
||||
}
|
||||
if spn.Token().ExpiresOn != "" {
|
||||
t.Errorf("spn.Token().ExpiresOn: expected=\"\", actual=%s", spn.Token().ExpiresOn)
|
||||
if spn.Token().ExpiresOn != "0" {
|
||||
t.Errorf("spn.Token().ExpiresOn: expected=\"0\", actual=%s", spn.Token().ExpiresOn)
|
||||
}
|
||||
if spn.Token().NotBefore != "" {
|
||||
t.Errorf("spn.Token().NotBefore: expected=\"\", actual=%s", spn.Token().NotBefore)
|
||||
if spn.Token().NotBefore != "0" {
|
||||
t.Errorf("spn.Token().NotBefore: expected=\"0\", actual=%s", spn.Token().NotBefore)
|
||||
}
|
||||
if spn.Token().Resource != "" {
|
||||
t.Errorf("spn.Token().Resource: expected=\"\", actual=%s", spn.Token().Resource)
|
||||
|
|
|
@ -126,7 +126,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
|||
ui.Say(fmt.Sprintf("the managed image named %s already exists, but deleting it due to -force flag", b.config.ManagedImageName))
|
||||
f, err := azureClient.ImagesClient.Delete(ctx, b.config.ManagedImageResourceGroupName, b.config.ManagedImageName)
|
||||
if err == nil {
|
||||
err = f.WaitForCompletion(ctx, azureClient.ImagesClient.Client)
|
||||
err = f.WaitForCompletionRef(ctx, azureClient.ImagesClient.Client)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to delete the managed image named %s : %s", b.config.ManagedImageName, azureClient.LastError.Error())
|
||||
|
|
|
@ -54,7 +54,7 @@ func (s *StepCaptureImage) captureImageFromVM(ctx context.Context, resourceGroup
|
|||
if err != nil {
|
||||
s.say(s.client.LastError.Error())
|
||||
}
|
||||
return f.WaitForCompletion(ctx, s.client.ImagesClient.Client)
|
||||
return f.WaitForCompletionRef(ctx, s.client.ImagesClient.Client)
|
||||
}
|
||||
|
||||
func (s *StepCaptureImage) captureImage(ctx context.Context, resourceGroupName string, computeName string, parameters *compute.VirtualMachineCaptureParameters) error {
|
||||
|
@ -62,7 +62,7 @@ func (s *StepCaptureImage) captureImage(ctx context.Context, resourceGroupName s
|
|||
if err != nil {
|
||||
s.say(s.client.LastError.Error())
|
||||
}
|
||||
return f.WaitForCompletion(ctx, s.client.VirtualMachinesClient.Client)
|
||||
return f.WaitForCompletionRef(ctx, s.client.VirtualMachinesClient.Client)
|
||||
}
|
||||
|
||||
func (s *StepCaptureImage) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
|
|
|
@ -121,7 +121,7 @@ func (s *StepCreateResourceGroup) Cleanup(state multistep.StateBag) {
|
|||
if state.Get(constants.ArmAsyncResourceGroupDelete).(bool) {
|
||||
s.say(fmt.Sprintf("\n Not waiting for Resource Group delete as requested by user. Resource Group Name is %s", resourceGroupName))
|
||||
} else {
|
||||
err = f.WaitForCompletion(ctx, s.client.GroupsClient.Client)
|
||||
err = f.WaitForCompletionRef(ctx, s.client.GroupsClient.Client)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
|
|
|
@ -48,7 +48,7 @@ func (s *StepDeleteAdditionalDisk) deleteManagedDisk(ctx context.Context, resour
|
|||
diskName = xs[len(xs)-1]
|
||||
f, err := s.client.DisksClient.Delete(ctx, resourceGroupName, diskName)
|
||||
if err == nil {
|
||||
err = f.WaitForCompletion(ctx, s.client.DisksClient.Client)
|
||||
err = f.WaitForCompletionRef(ctx, s.client.DisksClient.Client)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ func (s *StepDeleteOSDisk) deleteManagedDisk(ctx context.Context, resourceGroupN
|
|||
diskName := xs[len(xs)-1]
|
||||
f, err := s.client.DisksClient.Delete(ctx, resourceGroupName, diskName)
|
||||
if err == nil {
|
||||
err = f.WaitForCompletion(ctx, s.client.DisksClient.Client)
|
||||
err = f.WaitForCompletionRef(ctx, s.client.DisksClient.Client)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ func (s *StepDeleteResourceGroup) deleteResourceGroup(ctx context.Context, state
|
|||
// No need to wait for the complition for delete if request is Accepted
|
||||
s.say(fmt.Sprintf("\nResource Group is being deleted, not waiting for deletion due to config. Resource Group Name '%s'", resourceGroupName))
|
||||
} else {
|
||||
f.WaitForCompletion(ctx, s.client.GroupsClient.Client)
|
||||
f.WaitForCompletionRef(ctx, s.client.GroupsClient.Client)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ func (s *StepDeployTemplate) deployTemplate(ctx context.Context, resourceGroupNa
|
|||
|
||||
f, err := s.client.DeploymentsClient.CreateOrUpdate(ctx, resourceGroupName, deploymentName, *deployment)
|
||||
if err == nil {
|
||||
err = f.WaitForCompletion(ctx, s.client.DeploymentsClient.Client)
|
||||
err = f.WaitForCompletionRef(ctx, s.client.DeploymentsClient.Client)
|
||||
}
|
||||
if err != nil {
|
||||
s.say(s.client.LastError.Error())
|
||||
|
@ -96,7 +96,7 @@ func deleteResource(ctx context.Context, client *AzureClient, resourceType strin
|
|||
case "Microsoft.Compute/virtualMachines":
|
||||
f, err := client.VirtualMachinesClient.Delete(ctx, resourceGroupName, resourceName)
|
||||
if err == nil {
|
||||
err = f.WaitForCompletion(ctx, client.VirtualMachinesClient.Client)
|
||||
err = f.WaitForCompletionRef(ctx, client.VirtualMachinesClient.Client)
|
||||
}
|
||||
return err
|
||||
case "Microsoft.KeyVault/vaults":
|
||||
|
@ -106,19 +106,19 @@ func deleteResource(ctx context.Context, client *AzureClient, resourceType strin
|
|||
case "Microsoft.Network/networkInterfaces":
|
||||
f, err := client.InterfacesClient.Delete(ctx, resourceGroupName, resourceName)
|
||||
if err == nil {
|
||||
err = f.WaitForCompletion(ctx, client.InterfacesClient.Client)
|
||||
err = f.WaitForCompletionRef(ctx, client.InterfacesClient.Client)
|
||||
}
|
||||
return err
|
||||
case "Microsoft.Network/virtualNetworks":
|
||||
f, err := client.VirtualNetworksClient.Delete(ctx, resourceGroupName, resourceName)
|
||||
if err == nil {
|
||||
err = f.WaitForCompletion(ctx, client.VirtualNetworksClient.Client)
|
||||
err = f.WaitForCompletionRef(ctx, client.VirtualNetworksClient.Client)
|
||||
}
|
||||
return err
|
||||
case "Microsoft.Network/publicIPAddresses":
|
||||
f, err := client.PublicIPAddressesClient.Delete(ctx, resourceGroupName, resourceName)
|
||||
if err == nil {
|
||||
err = f.WaitForCompletion(ctx, client.PublicIPAddressesClient.Client)
|
||||
err = f.WaitForCompletionRef(ctx, client.PublicIPAddressesClient.Client)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ func (s *StepDeployTemplate) deleteImage(ctx context.Context, imageType string,
|
|||
diskName := xs[len(xs)-1]
|
||||
f, err := s.client.DisksClient.Delete(ctx, resourceGroupName, diskName)
|
||||
if err == nil {
|
||||
err = f.WaitForCompletion(ctx, s.client.DisksClient.Client)
|
||||
err = f.WaitForCompletionRef(ctx, s.client.DisksClient.Client)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ func NewStepPowerOffCompute(client *AzureClient, ui packer.Ui) *StepPowerOffComp
|
|||
func (s *StepPowerOffCompute) powerOffCompute(ctx context.Context, resourceGroupName string, computeName string) error {
|
||||
f, err := s.client.VirtualMachinesClient.Deallocate(ctx, resourceGroupName, computeName)
|
||||
if err == nil {
|
||||
err = f.WaitForCompletion(ctx, s.client.VirtualMachinesClient.Client)
|
||||
err = f.WaitForCompletionRef(ctx, s.client.VirtualMachinesClient.Client)
|
||||
}
|
||||
if err != nil {
|
||||
s.say(s.client.LastError.Error())
|
||||
|
|
|
@ -52,7 +52,7 @@ func (s *StepSnapshotDataDisks) createDataDiskSnapshot(ctx context.Context, reso
|
|||
return err
|
||||
}
|
||||
|
||||
err = f.WaitForCompletion(ctx, s.client.SnapshotsClient.Client)
|
||||
err = f.WaitForCompletionRef(ctx, s.client.SnapshotsClient.Client)
|
||||
|
||||
if err != nil {
|
||||
s.say(s.client.LastError.Error())
|
||||
|
|
|
@ -51,7 +51,7 @@ func (s *StepSnapshotOSDisk) createSnapshot(ctx context.Context, resourceGroupNa
|
|||
return err
|
||||
}
|
||||
|
||||
err = f.WaitForCompletion(ctx, s.client.SnapshotsClient.Client)
|
||||
err = f.WaitForCompletionRef(ctx, s.client.SnapshotsClient.Client)
|
||||
|
||||
if err != nil {
|
||||
s.say(s.client.LastError.Error())
|
||||
|
|
|
@ -137,7 +137,7 @@ func (client *VaultClient) DeletePreparer(resourceGroupName string, vaultName st
|
|||
func (client *VaultClient) DeleteSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client,
|
||||
req,
|
||||
azure.DoPollForAsynchronous(client.PollingDelay))
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// DeleteResponder handles the response to the Delete request. The method always
|
||||
|
|
15
go.mod
15
go.mod
|
@ -1,10 +1,10 @@
|
|||
module github.com/hashicorp/packer
|
||||
|
||||
require (
|
||||
contrib.go.opencensus.io/exporter/ocagent v0.5.0 // indirect
|
||||
github.com/1and1/oneandone-cloudserver-sdk-go v1.0.1
|
||||
github.com/Azure/azure-sdk-for-go v27.3.0+incompatible
|
||||
github.com/Azure/go-autorest v10.12.0+incompatible
|
||||
github.com/Azure/go-autorest/tracing v0.1.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go v30.0.0+incompatible
|
||||
github.com/Azure/go-autorest v12.0.0+incompatible
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20180810175552-4a21cbd618b4 // indirect
|
||||
github.com/ChrisTrenkamp/goxpath v0.0.0-20170625215350-4fe035839290
|
||||
github.com/NaverCloudPlatform/ncloud-sdk-go v0.0.0-20180110055012-c2e73f942591
|
||||
|
@ -15,6 +15,7 @@ require (
|
|||
github.com/antchfx/xpath v0.0.0-20170728053731-b5c552e1acbd // indirect
|
||||
github.com/antchfx/xquery v0.0.0-20170730121040-eb8c3c172607 // indirect
|
||||
github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6 // indirect
|
||||
github.com/apache/thrift v0.12.0 // indirect
|
||||
github.com/approvals/go-approval-tests v0.0.0-20160714161514-ad96e53bea43
|
||||
github.com/armon/go-radix v1.0.0 // indirect
|
||||
github.com/aws/aws-sdk-go v1.16.24
|
||||
|
@ -80,6 +81,7 @@ require (
|
|||
github.com/mitchellh/panicwrap v0.0.0-20170106182340-fce601fe5557
|
||||
github.com/mitchellh/prefixedio v0.0.0-20151214002211-6e6954073784
|
||||
github.com/mitchellh/reflectwalk v1.0.0
|
||||
github.com/mna/pigeon v1.0.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||
github.com/moul/anonuuid v0.0.0-20160222162117-609b752a95ef // indirect
|
||||
|
@ -87,6 +89,7 @@ require (
|
|||
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 // indirect
|
||||
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.0-20180105111133-96aac992fc8b
|
||||
github.com/openzipkin/zipkin-go v0.1.6 // indirect
|
||||
github.com/oracle/oci-go-sdk v1.8.0
|
||||
github.com/packer-community/winrmcp v0.0.0-20180921204643-0fd363d6159a
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible
|
||||
|
@ -94,6 +97,7 @@ require (
|
|||
github.com/pkg/sftp v0.0.0-20160118190721-e84cc8c755ca
|
||||
github.com/posener/complete v1.1.1
|
||||
github.com/profitbricks/profitbricks-sdk-go v4.0.2+incompatible
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829 // indirect
|
||||
github.com/renstrom/fuzzysearch v0.0.0-20160331204855-2d205ac6ec17 // indirect
|
||||
github.com/rwtodd/Go.Sed v0.0.0-20170507045331-d6d5d585814e
|
||||
github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735 // indirect
|
||||
|
@ -115,8 +119,9 @@ require (
|
|||
golang.org/x/sync v0.0.0-20190423024810-112230192c58
|
||||
golang.org/x/sys v0.0.0-20190425145619-16072639606e
|
||||
golang.org/x/text v0.3.1 // indirect
|
||||
google.golang.org/api v0.3.1
|
||||
google.golang.org/grpc v1.19.1
|
||||
golang.org/x/tools v0.0.0-20190530184349-ce1a3806b557 // indirect
|
||||
google.golang.org/api v0.4.0
|
||||
google.golang.org/grpc v1.20.1
|
||||
gopkg.in/h2non/gock.v1 v1.0.12 // indirect
|
||||
gopkg.in/ini.v1 v1.42.0 // indirect
|
||||
gopkg.in/jarcoal/httpmock.v1 v1.0.0-20181117152235-275e9df93516 // indirect
|
||||
|
|
19
go.sum
19
go.sum
|
@ -5,6 +5,8 @@ cloud.google.com/go v0.36.0 h1:+aCSj7tOo2LODWVEuZDZeGCckdt6MlSF+X/rB3wUiS8=
|
|||
cloud.google.com/go v0.36.0/go.mod h1:RUoy9p/M4ge0HzT8L+SDZ8jg+Q6fth0CiBuhFJpSV40=
|
||||
contrib.go.opencensus.io/exporter/ocagent v0.4.12 h1:jGFvw3l57ViIVEPKKEUXPcLYIXJmQxLUh6ey1eJhwyc=
|
||||
contrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA=
|
||||
contrib.go.opencensus.io/exporter/ocagent v0.5.0 h1:TKXjQSRS0/cCDrP7KvkgU6SmILtF/yV2TOs/02K/WZQ=
|
||||
contrib.go.opencensus.io/exporter/ocagent v0.5.0/go.mod h1:ImxhfLRpxoYiSq891pBrLVhN+qmP8BTVvdH2YLs7Gl0=
|
||||
dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=
|
||||
dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=
|
||||
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
|
||||
|
@ -14,8 +16,12 @@ github.com/1and1/oneandone-cloudserver-sdk-go v1.0.1 h1:RMTyvS5bjvSWiUcfqfr/E2px
|
|||
github.com/1and1/oneandone-cloudserver-sdk-go v1.0.1/go.mod h1:61apmbkVJH4kg+38ftT+/l0XxdUCVnHggqcOTqZRSEE=
|
||||
github.com/Azure/azure-sdk-for-go v27.3.0+incompatible h1:i+ROfG3CsZUPoVAnhK06T3R6PmBzKB9ds+lHBpN7Mzo=
|
||||
github.com/Azure/azure-sdk-for-go v27.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v30.0.0+incompatible h1:6o1Yzl7wTBYg+xw0pY4qnalaPmEQolubEEdepo1/kmI=
|
||||
github.com/Azure/azure-sdk-for-go v30.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/go-autorest v10.12.0+incompatible h1:6YphwUK+oXbzvCc1fd5VrnxCekwzDkpA7gUEbci2MvI=
|
||||
github.com/Azure/go-autorest v10.12.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest v12.0.0+incompatible h1:N+VqClcomLGD/sHb3smbSYYtNMgKpVV3Cd5r5i8z6bQ=
|
||||
github.com/Azure/go-autorest v12.0.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/tracing v0.1.0 h1:TRBxC5Pj/fIuh4Qob0ZpkggbfT8RC0SubHbpV3p4/Vc=
|
||||
github.com/Azure/go-autorest/tracing v0.1.0/go.mod h1:ROEEAFwXycQw7Sn3DXNtEedEvdeRAgDr0izn4z5Ij88=
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20180810175552-4a21cbd618b4 h1:pSm8mp0T2OH2CPmPDPtwHPr3VAQaOwVF/JbllOPP4xA=
|
||||
|
@ -291,6 +297,8 @@ github.com/mitchellh/prefixedio v0.0.0-20151214002211-6e6954073784 h1:+DAetXqxv/
|
|||
github.com/mitchellh/prefixedio v0.0.0-20151214002211-6e6954073784/go.mod h1:kB1naBgV9ORnkiTVeyJOI1DavaJkG4oNIq0Af6ZVKUo=
|
||||
github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
|
||||
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/mna/pigeon v1.0.0 h1:n46IoStjdzjaXuyBH53j9HZ8CVqGWpC7P5/v8dP4qEY=
|
||||
github.com/mna/pigeon v1.0.0/go.mod h1:Iym28+kJVnC1hfQvv5MUtI6AiFFzvQjHcvI4RFTG/04=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
|
@ -414,9 +422,12 @@ github.com/yandex-cloud/go-sdk v0.0.0-20190402114215-3fc1d6947035 h1:2ZLZeg6xp+k
|
|||
github.com/yandex-cloud/go-sdk v0.0.0-20190402114215-3fc1d6947035/go.mod h1:Eml0jFLU4VVHgIN8zPHMuNwZXVzUMILyO6lQZSfz854=
|
||||
go.opencensus.io v0.18.0 h1:Mk5rgZcggtbvtAun5aJzAtjKKN/t0R3jJPlWILlv938=
|
||||
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
|
||||
go.opencensus.io v0.20.1 h1:pMEjRZ1M4ebWGikflH7nQpV6+Zr88KBMA2XJD3sbijw=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.20.2 h1:NAfh7zF0/3/HqtMvJNZ/RFrSlCE6ZTlHmKfhL/Dm1Jk=
|
||||
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.21.0 h1:mU6zScU4U1YAFPHEHYk+3JC4SY7JxgkqS10ZOSyksNg=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
|
||||
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
|
@ -432,6 +443,7 @@ golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTk
|
|||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
@ -498,13 +510,18 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
|
|||
golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190530184349-ce1a3806b557 h1:WFdP1eIY3AwGUPgVua5UIX4C7BzCIK8TOwm6RA+0vAQ=
|
||||
golang.org/x/tools v0.0.0-20190530184349-ce1a3806b557/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.1.0 h1:K6z2u68e86TPdSdefXdzvXgR1zEMa+459vBSfWYAZkI=
|
||||
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
|
||||
google.golang.org/api v0.3.1 h1:oJra/lMfmtm13/rgY/8i3MzjFWYXvQIAKjQ3HqofMk8=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/api v0.4.0 h1:KKgc1aqhV8wDPbDzlDtpvyjZFY3vjz85FP7p4wcQUyI=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
|
@ -525,6 +542,8 @@ google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3
|
|||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.19.1 h1:TrBcJ1yqAl1G++wO39nD/qtgpsW9/1+QGrluyMGEYgM=
|
||||
google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
|
|
@ -18,15 +18,27 @@ import (
|
|||
"math/rand"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
sDisconnected int32 = 5 + iota
|
||||
sConnected
|
||||
)
|
||||
func (ae *Exporter) lastConnectError() error {
|
||||
errPtr := (*error)(atomic.LoadPointer(&ae.lastConnectErrPtr))
|
||||
if errPtr == nil {
|
||||
return nil
|
||||
}
|
||||
return *errPtr
|
||||
}
|
||||
|
||||
func (ae *Exporter) setStateDisconnected() {
|
||||
atomic.StoreInt32(&ae.connectionState, sDisconnected)
|
||||
func (ae *Exporter) saveLastConnectError(err error) {
|
||||
var errPtr *error
|
||||
if err != nil {
|
||||
errPtr = &err
|
||||
}
|
||||
atomic.StorePointer(&ae.lastConnectErrPtr, unsafe.Pointer(errPtr))
|
||||
}
|
||||
|
||||
func (ae *Exporter) setStateDisconnected(err error) {
|
||||
ae.saveLastConnectError(err)
|
||||
select {
|
||||
case ae.disconnectedCh <- true:
|
||||
default:
|
||||
|
@ -34,11 +46,11 @@ func (ae *Exporter) setStateDisconnected() {
|
|||
}
|
||||
|
||||
func (ae *Exporter) setStateConnected() {
|
||||
atomic.StoreInt32(&ae.connectionState, sConnected)
|
||||
ae.saveLastConnectError(nil)
|
||||
}
|
||||
|
||||
func (ae *Exporter) connected() bool {
|
||||
return atomic.LoadInt32(&ae.connectionState) == sConnected
|
||||
return ae.lastConnectError() == nil
|
||||
}
|
||||
|
||||
const defaultConnReattemptPeriod = 10 * time.Second
|
||||
|
@ -77,14 +89,18 @@ func (ae *Exporter) indefiniteBackgroundConnection() error {
|
|||
if err := ae.connect(); err == nil {
|
||||
ae.setStateConnected()
|
||||
} else {
|
||||
ae.setStateDisconnected()
|
||||
ae.setStateDisconnected(err)
|
||||
}
|
||||
|
||||
// Apply some jitter to avoid lockstep retrials of other
|
||||
// agent-exporters. Lockstep retrials could result in an
|
||||
// innocent DDOS, by clogging the machine's resources and network.
|
||||
jitter := time.Duration(rng.Int63n(maxJitter))
|
||||
<-time.After(connReattemptPeriod + jitter)
|
||||
select {
|
||||
case <-ae.stopCh:
|
||||
return errStopped
|
||||
case <-time.After(connReattemptPeriod + jitter):
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ require (
|
|||
github.com/census-instrumentation/opencensus-proto v0.2.0 // this is to match the version used in census-instrumentation/opencensus-service
|
||||
github.com/golang/protobuf v1.3.1
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.8.5 // indirect
|
||||
go.opencensus.io v0.20.2
|
||||
google.golang.org/api v0.3.1
|
||||
google.golang.org/grpc v1.19.1
|
||||
go.opencensus.io v0.21.0
|
||||
google.golang.org/api v0.4.0
|
||||
google.golang.org/grpc v1.20.1
|
||||
)
|
||||
|
|
|
@ -1,26 +1,10 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.0 h1:LzQXZOgg4CQfE6bFvXGM30YZL1WW/M337pXml+GrcZ4=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
|
@ -28,60 +12,28 @@ github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM
|
|||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.8.5 h1:2+KSC78XiO6Qy0hIjfc1OD9H+hsaJdJlb8Kqsd41CTE=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.20.2 h1:NAfh7zF0/3/HqtMvJNZ/RFrSlCE6ZTlHmKfhL/Dm1Jk=
|
||||
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
go.opencensus.io v0.21.0 h1:mU6zScU4U1YAFPHEHYk+3JC4SY7JxgkqS10ZOSyksNg=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
|
@ -94,37 +46,26 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ
|
|||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
google.golang.org/api v0.3.1 h1:oJra/lMfmtm13/rgY/8i3MzjFWYXvQIAKjQ3HqofMk8=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/api v0.4.0 h1:KKgc1aqhV8wDPbDzlDtpvyjZFY3vjz85FP7p4wcQUyI=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19 h1:Lj2SnHtxkRGJDqnGaSjo+CCdIieEnwVazbOXILwQemk=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.19.1 h1:TrBcJ1yqAl1G++wO39nD/qtgpsW9/1+QGrluyMGEYgM=
|
||||
google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
|
|
@ -18,8 +18,10 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"google.golang.org/api/support/bundler"
|
||||
"google.golang.org/grpc"
|
||||
|
@ -52,12 +54,12 @@ var _ trace.Exporter = (*Exporter)(nil)
|
|||
var _ view.Exporter = (*Exporter)(nil)
|
||||
|
||||
type Exporter struct {
|
||||
connectionState int32
|
||||
|
||||
// mu protects the non-atomic and non-channel variables
|
||||
mu sync.RWMutex
|
||||
// senderMu protects the concurrent unsafe traceExporter client
|
||||
senderMu sync.RWMutex
|
||||
// senderMu protects the concurrent unsafe send on traceExporter client
|
||||
senderMu sync.Mutex
|
||||
// recvMu protects the concurrent unsafe recv on traceExporter client
|
||||
recvMu sync.Mutex
|
||||
started bool
|
||||
stopped bool
|
||||
agentAddress string
|
||||
|
@ -71,6 +73,7 @@ type Exporter struct {
|
|||
resource *resourcepb.Resource
|
||||
compressor string
|
||||
headers map[string]string
|
||||
lastConnectErrPtr unsafe.Pointer
|
||||
|
||||
startOnce sync.Once
|
||||
stopCh chan bool
|
||||
|
@ -86,6 +89,8 @@ type Exporter struct {
|
|||
viewDataBundler *bundler.Bundler
|
||||
|
||||
clientTransportCredentials credentials.TransportCredentials
|
||||
|
||||
grpcDialOptions []grpc.DialOption
|
||||
}
|
||||
|
||||
func NewExporter(opts ...ExporterOption) (*Exporter, error) {
|
||||
|
@ -134,7 +139,6 @@ var (
|
|||
errAlreadyStarted = errors.New("already started")
|
||||
errNotStarted = errors.New("not started")
|
||||
errStopped = errors.New("stopped")
|
||||
errNoConnection = errors.New("no active connection")
|
||||
)
|
||||
|
||||
// Start dials to the agent, establishing a connection to it. It also
|
||||
|
@ -146,14 +150,20 @@ func (ae *Exporter) Start() error {
|
|||
var err = errAlreadyStarted
|
||||
ae.startOnce.Do(func() {
|
||||
ae.mu.Lock()
|
||||
defer ae.mu.Unlock()
|
||||
|
||||
ae.started = true
|
||||
ae.disconnectedCh = make(chan bool, 1)
|
||||
ae.stopCh = make(chan bool)
|
||||
ae.backgroundConnectionDoneCh = make(chan bool)
|
||||
ae.mu.Unlock()
|
||||
|
||||
ae.setStateDisconnected()
|
||||
// An optimistic first connection attempt to ensure that
|
||||
// applications under heavy load can immediately process
|
||||
// data. See https://github.com/census-ecosystem/opencensus-go-exporter-ocagent/pull/63
|
||||
if err := ae.connect(); err == nil {
|
||||
ae.setStateConnected()
|
||||
} else {
|
||||
ae.setStateDisconnected(err)
|
||||
}
|
||||
go ae.indefiniteBackgroundConnection()
|
||||
|
||||
err = nil
|
||||
|
@ -270,6 +280,9 @@ func (ae *Exporter) dialToAgent() (*grpc.ClientConn, error) {
|
|||
dialOpts = append(dialOpts, grpc.WithDefaultCallOptions(grpc.UseCompressor(ae.compressor)))
|
||||
}
|
||||
dialOpts = append(dialOpts, grpc.WithStatsHandler(&ocgrpc.ClientHandler{}))
|
||||
if len(ae.grpcDialOptions) != 0 {
|
||||
dialOpts = append(dialOpts, ae.grpcDialOptions...)
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
if len(ae.headers) > 0 {
|
||||
|
@ -368,16 +381,33 @@ func (ae *Exporter) ExportTraceServiceRequest(batch *agenttracepb.ExportTraceSer
|
|||
return errStopped
|
||||
|
||||
default:
|
||||
if !ae.connected() {
|
||||
return errNoConnection
|
||||
if lastConnectErr := ae.lastConnectError(); lastConnectErr != nil {
|
||||
return fmt.Errorf("ExportTraceServiceRequest: no active connection, last connection error: %v", lastConnectErr)
|
||||
}
|
||||
|
||||
ae.senderMu.Lock()
|
||||
err := ae.traceExporter.Send(batch)
|
||||
ae.senderMu.Unlock()
|
||||
if err != nil {
|
||||
ae.setStateDisconnected()
|
||||
return err
|
||||
if err == io.EOF {
|
||||
ae.recvMu.Lock()
|
||||
// Perform a .Recv to try to find out why the RPC actually ended.
|
||||
// See:
|
||||
// * https://github.com/grpc/grpc-go/blob/d389f9fac68eea0dcc49957d0b4cca5b3a0a7171/stream.go#L98-L100
|
||||
// * https://groups.google.com/forum/#!msg/grpc-io/XcN4hA9HonI/F_UDiejTAwAJ
|
||||
for {
|
||||
_, err = ae.traceExporter.Recv()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
ae.recvMu.Unlock()
|
||||
}
|
||||
|
||||
ae.setStateDisconnected(err)
|
||||
if err != io.EOF {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -423,7 +453,7 @@ func (ae *Exporter) uploadTraces(sdl []*trace.SpanData) {
|
|||
})
|
||||
ae.senderMu.Unlock()
|
||||
if err != nil {
|
||||
ae.setStateDisconnected()
|
||||
ae.setStateDisconnected(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -467,7 +497,7 @@ func (ae *Exporter) uploadViewData(vdl []*view.Data) {
|
|||
// or better letting users of the exporter configure it.
|
||||
})
|
||||
if err != nil {
|
||||
ae.setStateDisconnected()
|
||||
ae.setStateDisconnected(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ package ocagent
|
|||
import (
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
)
|
||||
|
||||
|
@ -126,3 +127,18 @@ func WithTLSCredentials(creds credentials.TransportCredentials) ExporterOption {
|
|||
func (cc *clientCredentials) withExporter(e *Exporter) {
|
||||
e.clientTransportCredentials = cc.TransportCredentials
|
||||
}
|
||||
|
||||
type grpcDialOptions []grpc.DialOption
|
||||
|
||||
var _ ExporterOption = (*grpcDialOptions)(nil)
|
||||
|
||||
// WithGRPCDialOption opens support to any grpc.DialOption to be used. If it conflicts
|
||||
// with some other configuration the GRPC specified via the agent the ones here will
|
||||
// take preference since they are set last.
|
||||
func WithGRPCDialOption(opts ...grpc.DialOption) ExporterOption {
|
||||
return grpcDialOptions(opts)
|
||||
}
|
||||
|
||||
func (opts grpcDialOptions) withExporter(e *Exporter) {
|
||||
e.grpcDialOptions = opts
|
||||
}
|
||||
|
|
|
@ -108,6 +108,7 @@ func (client DisksClient) CreateOrUpdatePreparer(ctx context.Context, resourceGr
|
|||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
disk.ManagedBy = nil
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPut(),
|
||||
|
|
518
vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/models.go
generated
vendored
518
vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-04-01/compute/models.go
generated
vendored
File diff suppressed because it is too large
Load Diff
|
@ -107,6 +107,7 @@ func (client SnapshotsClient) CreateOrUpdatePreparer(ctx context.Context, resour
|
|||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
snapshot.ManagedBy = nil
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPut(),
|
||||
|
|
|
@ -272,6 +272,7 @@ func (client VirtualMachinesClient) CreateOrUpdatePreparer(ctx context.Context,
|
|||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
parameters.Resources = nil
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPut(),
|
||||
|
|
|
@ -1187,6 +1187,10 @@ func (client VirtualMachineScaleSetVMsClient) UpdatePreparer(ctx context.Context
|
|||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
parameters.InstanceID = nil
|
||||
parameters.Sku = nil
|
||||
parameters.Resources = nil
|
||||
parameters.Zones = nil
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPut(),
|
||||
|
|
|
@ -84,6 +84,7 @@ func (client ApplicationSecurityGroupsClient) CreateOrUpdatePreparer(ctx context
|
|||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
parameters.Etag = nil
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPut(),
|
||||
|
|
|
@ -89,6 +89,7 @@ func (client ExpressRouteCircuitAuthorizationsClient) CreateOrUpdatePreparer(ctx
|
|||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
authorizationParameters.Etag = nil
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPut(),
|
||||
|
|
|
@ -98,6 +98,7 @@ func (client ExpressRouteCircuitPeeringsClient) CreateOrUpdatePreparer(ctx conte
|
|||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
peeringParameters.Etag = nil
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPut(),
|
||||
|
|
|
@ -84,6 +84,7 @@ func (client ExpressRouteCircuitsClient) CreateOrUpdatePreparer(ctx context.Cont
|
|||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
parameters.Etag = nil
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPut(),
|
||||
|
|
728
vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/models.go
generated
vendored
728
vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network/models.go
generated
vendored
File diff suppressed because it is too large
Load Diff
|
@ -96,6 +96,9 @@ func (client PacketCapturesClient) CreatePreparer(ctx context.Context, resourceG
|
|||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
parameters.Name = nil
|
||||
parameters.ID = nil
|
||||
parameters.Type = nil
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPut(),
|
||||
|
|
|
@ -96,6 +96,7 @@ func (client RouteFilterRulesClient) CreateOrUpdatePreparer(ctx context.Context,
|
|||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
routeFilterRuleParameters.Etag = nil
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPut(),
|
||||
|
@ -450,6 +451,8 @@ func (client RouteFilterRulesClient) UpdatePreparer(ctx context.Context, resourc
|
|||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
routeFilterRuleParameters.Name = nil
|
||||
routeFilterRuleParameters.Etag = nil
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPatch(),
|
||||
|
|
|
@ -84,6 +84,7 @@ func (client RouteFiltersClient) CreateOrUpdatePreparer(ctx context.Context, res
|
|||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
routeFilterParameters.Etag = nil
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPut(),
|
||||
|
@ -544,6 +545,9 @@ func (client RouteFiltersClient) UpdatePreparer(ctx context.Context, resourceGro
|
|||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
routeFilterParameters.Name = nil
|
||||
routeFilterParameters.Etag = nil
|
||||
routeFilterParameters.Type = nil
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPatch(),
|
||||
|
|
|
@ -277,7 +277,7 @@ func (client VirtualNetworkGatewaysClient) GeneratevpnclientpackageResponder(res
|
|||
err = autorest.Respond(
|
||||
resp,
|
||||
client.ByInspecting(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
|
@ -290,13 +290,13 @@ func (client VirtualNetworkGatewaysClient) GeneratevpnclientpackageResponder(res
|
|||
// resourceGroupName - the name of the resource group.
|
||||
// virtualNetworkGatewayName - the name of the virtual network gateway.
|
||||
// parameters - parameters supplied to the generate virtual network gateway VPN client package operation.
|
||||
func (client VirtualNetworkGatewaysClient) GenerateVpnProfile(ctx context.Context, resourceGroupName string, virtualNetworkGatewayName string, parameters VpnClientParameters) (result VirtualNetworkGatewaysGenerateVpnProfileFuture, err error) {
|
||||
func (client VirtualNetworkGatewaysClient) GenerateVpnProfile(ctx context.Context, resourceGroupName string, virtualNetworkGatewayName string, parameters VpnClientParameters) (result String, err error) {
|
||||
if tracing.IsEnabled() {
|
||||
ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkGatewaysClient.GenerateVpnProfile")
|
||||
defer func() {
|
||||
sc := -1
|
||||
if result.Response() != nil {
|
||||
sc = result.Response().StatusCode
|
||||
if result.Response.Response != nil {
|
||||
sc = result.Response.Response.StatusCode
|
||||
}
|
||||
tracing.EndSpan(ctx, sc, err)
|
||||
}()
|
||||
|
@ -307,12 +307,18 @@ func (client VirtualNetworkGatewaysClient) GenerateVpnProfile(ctx context.Contex
|
|||
return
|
||||
}
|
||||
|
||||
result, err = client.GenerateVpnProfileSender(req)
|
||||
resp, err := client.GenerateVpnProfileSender(req)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysClient", "GenerateVpnProfile", result.Response(), "Failure sending request")
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysClient", "GenerateVpnProfile", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.GenerateVpnProfileResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysClient", "GenerateVpnProfile", resp, "Failure responding to request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -341,15 +347,9 @@ func (client VirtualNetworkGatewaysClient) GenerateVpnProfilePreparer(ctx contex
|
|||
|
||||
// GenerateVpnProfileSender sends the GenerateVpnProfile request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client VirtualNetworkGatewaysClient) GenerateVpnProfileSender(req *http.Request) (future VirtualNetworkGatewaysGenerateVpnProfileFuture, err error) {
|
||||
var resp *http.Response
|
||||
resp, err = autorest.SendWithSender(client, req,
|
||||
func (client VirtualNetworkGatewaysClient) GenerateVpnProfileSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
future.Future, err = azure.NewFutureFromResponse(resp)
|
||||
return
|
||||
}
|
||||
|
||||
// GenerateVpnProfileResponder handles the response to the GenerateVpnProfile request. The method always
|
||||
|
@ -359,7 +359,7 @@ func (client VirtualNetworkGatewaysClient) GenerateVpnProfileResponder(resp *htt
|
|||
resp,
|
||||
client.ByInspecting(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByUnmarshallingJSON(&result.Value),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
|
|
|
@ -214,17 +214,17 @@ func NewListResultPage(getNextPage func(context.Context, ListResult) (ListResult
|
|||
|
||||
// Location location information.
|
||||
type Location struct {
|
||||
// ID - The fully qualified ID of the location. For example, /subscriptions/00000000-0000-0000-0000-000000000000/locations/westus.
|
||||
// ID - READ-ONLY; The fully qualified ID of the location. For example, /subscriptions/00000000-0000-0000-0000-000000000000/locations/westus.
|
||||
ID *string `json:"id,omitempty"`
|
||||
// SubscriptionID - The subscription ID.
|
||||
// SubscriptionID - READ-ONLY; The subscription ID.
|
||||
SubscriptionID *string `json:"subscriptionId,omitempty"`
|
||||
// Name - The location name.
|
||||
// Name - READ-ONLY; The location name.
|
||||
Name *string `json:"name,omitempty"`
|
||||
// DisplayName - The display name of the location.
|
||||
// DisplayName - READ-ONLY; The display name of the location.
|
||||
DisplayName *string `json:"displayName,omitempty"`
|
||||
// Latitude - The latitude of the location.
|
||||
// Latitude - READ-ONLY; The latitude of the location.
|
||||
Latitude *string `json:"latitude,omitempty"`
|
||||
// Longitude - The longitude of the location.
|
||||
// Longitude - READ-ONLY; The longitude of the location.
|
||||
Longitude *string `json:"longitude,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -404,24 +404,24 @@ func NewOperationListResultPage(getNextPage func(context.Context, OperationListR
|
|||
|
||||
// Policies subscription policies.
|
||||
type Policies struct {
|
||||
// LocationPlacementID - The subscription location placement ID. The ID indicates which regions are visible for a subscription. For example, a subscription with a location placement Id of Public_2014-09-01 has access to Azure public regions.
|
||||
// LocationPlacementID - READ-ONLY; The subscription location placement ID. The ID indicates which regions are visible for a subscription. For example, a subscription with a location placement Id of Public_2014-09-01 has access to Azure public regions.
|
||||
LocationPlacementID *string `json:"locationPlacementId,omitempty"`
|
||||
// QuotaID - The subscription quota ID.
|
||||
// QuotaID - READ-ONLY; The subscription quota ID.
|
||||
QuotaID *string `json:"quotaId,omitempty"`
|
||||
// SpendingLimit - The subscription spending limit. Possible values include: 'On', 'Off', 'CurrentPeriodOff'
|
||||
// SpendingLimit - READ-ONLY; The subscription spending limit. Possible values include: 'On', 'Off', 'CurrentPeriodOff'
|
||||
SpendingLimit SpendingLimit `json:"spendingLimit,omitempty"`
|
||||
}
|
||||
|
||||
// Subscription subscription information.
|
||||
type Subscription struct {
|
||||
autorest.Response `json:"-"`
|
||||
// ID - The fully qualified ID for the subscription. For example, /subscriptions/00000000-0000-0000-0000-000000000000.
|
||||
// ID - READ-ONLY; The fully qualified ID for the subscription. For example, /subscriptions/00000000-0000-0000-0000-000000000000.
|
||||
ID *string `json:"id,omitempty"`
|
||||
// SubscriptionID - The subscription ID.
|
||||
// SubscriptionID - READ-ONLY; The subscription ID.
|
||||
SubscriptionID *string `json:"subscriptionId,omitempty"`
|
||||
// DisplayName - The subscription display name.
|
||||
// DisplayName - READ-ONLY; The subscription display name.
|
||||
DisplayName *string `json:"displayName,omitempty"`
|
||||
// State - The subscription state. Possible values are Enabled, Warned, PastDue, Disabled, and Deleted. Possible values include: 'Enabled', 'Warned', 'PastDue', 'Disabled', 'Deleted'
|
||||
// State - READ-ONLY; The subscription state. Possible values are Enabled, Warned, PastDue, Disabled, and Deleted. Possible values include: 'Enabled', 'Warned', 'PastDue', 'Disabled', 'Deleted'
|
||||
State State `json:"state,omitempty"`
|
||||
// SubscriptionPolicies - The subscription policies.
|
||||
SubscriptionPolicies *Policies `json:"subscriptionPolicies,omitempty"`
|
||||
|
@ -431,9 +431,9 @@ type Subscription struct {
|
|||
|
||||
// TenantIDDescription tenant Id information.
|
||||
type TenantIDDescription struct {
|
||||
// ID - The fully qualified ID of the tenant. For example, /tenants/00000000-0000-0000-0000-000000000000.
|
||||
// ID - READ-ONLY; The fully qualified ID of the tenant. For example, /tenants/00000000-0000-0000-0000-000000000000.
|
||||
ID *string `json:"id,omitempty"`
|
||||
// TenantID - The tenant ID. For example, 00000000-0000-0000-0000-000000000000.
|
||||
// TenantID - READ-ONLY; The tenant ID. For example, 00000000-0000-0000-0000-000000000000.
|
||||
TenantID *string `json:"tenantId,omitempty"`
|
||||
}
|
||||
|
||||
|
|
|
@ -181,6 +181,7 @@ func (client GroupsClient) CreateOrUpdatePreparer(ctx context.Context, resourceG
|
|||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
parameters.ID = nil
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPut(),
|
||||
|
|
|
@ -116,7 +116,7 @@ type CreateOrUpdateByIDFuture struct {
|
|||
// If the operation has not completed it will return an error.
|
||||
func (future *CreateOrUpdateByIDFuture) Result(client Client) (gr GenericResource, err error) {
|
||||
var done bool
|
||||
done, err = future.Done(client)
|
||||
done, err = future.DoneWithContext(context.Background(), client)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.CreateOrUpdateByIDFuture", "Result", future.Response(), "Polling failure")
|
||||
return
|
||||
|
@ -145,7 +145,7 @@ type CreateOrUpdateFuture struct {
|
|||
// If the operation has not completed it will return an error.
|
||||
func (future *CreateOrUpdateFuture) Result(client Client) (gr GenericResource, err error) {
|
||||
var done bool
|
||||
done, err = future.Done(client)
|
||||
done, err = future.DoneWithContext(context.Background(), client)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.CreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
|
||||
return
|
||||
|
@ -179,7 +179,7 @@ type DeleteByIDFuture struct {
|
|||
// If the operation has not completed it will return an error.
|
||||
func (future *DeleteByIDFuture) Result(client Client) (ar autorest.Response, err error) {
|
||||
var done bool
|
||||
done, err = future.Done(client)
|
||||
done, err = future.DoneWithContext(context.Background(), client)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.DeleteByIDFuture", "Result", future.Response(), "Polling failure")
|
||||
return
|
||||
|
@ -201,7 +201,7 @@ type DeleteFuture struct {
|
|||
// If the operation has not completed it will return an error.
|
||||
func (future *DeleteFuture) Result(client Client) (ar autorest.Response, err error) {
|
||||
var done bool
|
||||
done, err = future.Done(client)
|
||||
done, err = future.DoneWithContext(context.Background(), client)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.DeleteFuture", "Result", future.Response(), "Polling failure")
|
||||
return
|
||||
|
@ -242,7 +242,7 @@ type DeploymentExportResult struct {
|
|||
// DeploymentExtended deployment information.
|
||||
type DeploymentExtended struct {
|
||||
autorest.Response `json:"-"`
|
||||
// ID - The ID of the deployment.
|
||||
// ID - READ-ONLY; The ID of the deployment.
|
||||
ID *string `json:"id,omitempty"`
|
||||
// Name - The name of the deployment.
|
||||
Name *string `json:"name,omitempty"`
|
||||
|
@ -261,7 +261,7 @@ type DeploymentListResult struct {
|
|||
autorest.Response `json:"-"`
|
||||
// Value - An array of deployments.
|
||||
Value *[]DeploymentExtended `json:"value,omitempty"`
|
||||
// NextLink - The URL to use for getting the next set of results.
|
||||
// NextLink - READ-ONLY; The URL to use for getting the next set of results.
|
||||
NextLink *string `json:"nextLink,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -405,9 +405,9 @@ func NewDeploymentListResultPage(getNextPage func(context.Context, DeploymentLis
|
|||
// DeploymentOperation deployment operation information.
|
||||
type DeploymentOperation struct {
|
||||
autorest.Response `json:"-"`
|
||||
// ID - Full deployment operation ID.
|
||||
// ID - READ-ONLY; Full deployment operation ID.
|
||||
ID *string `json:"id,omitempty"`
|
||||
// OperationID - Deployment operation ID.
|
||||
// OperationID - READ-ONLY; Deployment operation ID.
|
||||
OperationID *string `json:"operationId,omitempty"`
|
||||
// Properties - Deployment properties.
|
||||
Properties *DeploymentOperationProperties `json:"properties,omitempty"`
|
||||
|
@ -415,21 +415,21 @@ type DeploymentOperation struct {
|
|||
|
||||
// DeploymentOperationProperties deployment operation properties.
|
||||
type DeploymentOperationProperties struct {
|
||||
// ProvisioningState - The state of the provisioning.
|
||||
// ProvisioningState - READ-ONLY; The state of the provisioning.
|
||||
ProvisioningState *string `json:"provisioningState,omitempty"`
|
||||
// Timestamp - The date and time of the operation.
|
||||
// Timestamp - READ-ONLY; The date and time of the operation.
|
||||
Timestamp *date.Time `json:"timestamp,omitempty"`
|
||||
// ServiceRequestID - Deployment operation service request id.
|
||||
// ServiceRequestID - READ-ONLY; Deployment operation service request id.
|
||||
ServiceRequestID *string `json:"serviceRequestId,omitempty"`
|
||||
// StatusCode - Operation status code.
|
||||
// StatusCode - READ-ONLY; Operation status code.
|
||||
StatusCode *string `json:"statusCode,omitempty"`
|
||||
// StatusMessage - Operation status message.
|
||||
// StatusMessage - READ-ONLY; Operation status message.
|
||||
StatusMessage interface{} `json:"statusMessage,omitempty"`
|
||||
// TargetResource - The target resource.
|
||||
// TargetResource - READ-ONLY; The target resource.
|
||||
TargetResource *TargetResource `json:"targetResource,omitempty"`
|
||||
// Request - The HTTP request message.
|
||||
// Request - READ-ONLY; The HTTP request message.
|
||||
Request *HTTPMessage `json:"request,omitempty"`
|
||||
// Response - The HTTP response message.
|
||||
// Response - READ-ONLY; The HTTP response message.
|
||||
Response *HTTPMessage `json:"response,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -438,7 +438,7 @@ type DeploymentOperationsListResult struct {
|
|||
autorest.Response `json:"-"`
|
||||
// Value - An array of deployment operations.
|
||||
Value *[]DeploymentOperation `json:"value,omitempty"`
|
||||
// NextLink - The URL to use for getting the next set of results.
|
||||
// NextLink - READ-ONLY; The URL to use for getting the next set of results.
|
||||
NextLink *string `json:"nextLink,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -600,11 +600,11 @@ type DeploymentProperties struct {
|
|||
|
||||
// DeploymentPropertiesExtended deployment properties with additional details.
|
||||
type DeploymentPropertiesExtended struct {
|
||||
// ProvisioningState - The state of the provisioning.
|
||||
// ProvisioningState - READ-ONLY; The state of the provisioning.
|
||||
ProvisioningState *string `json:"provisioningState,omitempty"`
|
||||
// CorrelationID - The correlation ID of the deployment.
|
||||
// CorrelationID - READ-ONLY; The correlation ID of the deployment.
|
||||
CorrelationID *string `json:"correlationId,omitempty"`
|
||||
// Timestamp - The timestamp of the template deployment.
|
||||
// Timestamp - READ-ONLY; The timestamp of the template deployment.
|
||||
Timestamp *date.Time `json:"timestamp,omitempty"`
|
||||
// Outputs - Key/value pairs that represent deployment output.
|
||||
Outputs interface{} `json:"outputs,omitempty"`
|
||||
|
@ -638,7 +638,7 @@ type DeploymentsCreateOrUpdateFuture struct {
|
|||
// If the operation has not completed it will return an error.
|
||||
func (future *DeploymentsCreateOrUpdateFuture) Result(client DeploymentsClient) (de DeploymentExtended, err error) {
|
||||
var done bool
|
||||
done, err = future.Done(client)
|
||||
done, err = future.DoneWithContext(context.Background(), client)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentsCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
|
||||
return
|
||||
|
@ -667,7 +667,7 @@ type DeploymentsDeleteFuture struct {
|
|||
// If the operation has not completed it will return an error.
|
||||
func (future *DeploymentsDeleteFuture) Result(client DeploymentsClient) (ar autorest.Response, err error) {
|
||||
var done bool
|
||||
done, err = future.Done(client)
|
||||
done, err = future.DoneWithContext(context.Background(), client)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentsDeleteFuture", "Result", future.Response(), "Polling failure")
|
||||
return
|
||||
|
@ -712,11 +712,11 @@ type GenericResource struct {
|
|||
Sku *Sku `json:"sku,omitempty"`
|
||||
// Identity - The identity of the resource.
|
||||
Identity *Identity `json:"identity,omitempty"`
|
||||
// ID - Resource ID
|
||||
// ID - READ-ONLY; Resource ID
|
||||
ID *string `json:"id,omitempty"`
|
||||
// Name - Resource name
|
||||
// Name - READ-ONLY; Resource name
|
||||
Name *string `json:"name,omitempty"`
|
||||
// Type - Resource type
|
||||
// Type - READ-ONLY; Resource type
|
||||
Type *string `json:"type,omitempty"`
|
||||
// Location - Resource location
|
||||
Location *string `json:"location,omitempty"`
|
||||
|
@ -745,15 +745,6 @@ func (gr GenericResource) MarshalJSON() ([]byte, error) {
|
|||
if gr.Identity != nil {
|
||||
objectMap["identity"] = gr.Identity
|
||||
}
|
||||
if gr.ID != nil {
|
||||
objectMap["id"] = gr.ID
|
||||
}
|
||||
if gr.Name != nil {
|
||||
objectMap["name"] = gr.Name
|
||||
}
|
||||
if gr.Type != nil {
|
||||
objectMap["type"] = gr.Type
|
||||
}
|
||||
if gr.Location != nil {
|
||||
objectMap["location"] = gr.Location
|
||||
}
|
||||
|
@ -776,7 +767,7 @@ type GenericResourceFilter struct {
|
|||
// Group resource group information.
|
||||
type Group struct {
|
||||
autorest.Response `json:"-"`
|
||||
// ID - The ID of the resource group.
|
||||
// ID - READ-ONLY; The ID of the resource group.
|
||||
ID *string `json:"id,omitempty"`
|
||||
// Name - The name of the resource group.
|
||||
Name *string `json:"name,omitempty"`
|
||||
|
@ -792,9 +783,6 @@ type Group struct {
|
|||
// MarshalJSON is the custom marshaler for Group.
|
||||
func (g Group) MarshalJSON() ([]byte, error) {
|
||||
objectMap := make(map[string]interface{})
|
||||
if g.ID != nil {
|
||||
objectMap["id"] = g.ID
|
||||
}
|
||||
if g.Name != nil {
|
||||
objectMap["name"] = g.Name
|
||||
}
|
||||
|
@ -835,7 +823,7 @@ type GroupListResult struct {
|
|||
autorest.Response `json:"-"`
|
||||
// Value - An array of resource groups.
|
||||
Value *[]Group `json:"value,omitempty"`
|
||||
// NextLink - The URL to use for getting the next set of results.
|
||||
// NextLink - READ-ONLY; The URL to use for getting the next set of results.
|
||||
NextLink *string `json:"nextLink,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -1007,7 +995,7 @@ func (gp GroupPatchable) MarshalJSON() ([]byte, error) {
|
|||
|
||||
// GroupProperties the resource group properties.
|
||||
type GroupProperties struct {
|
||||
// ProvisioningState - The provisioning state.
|
||||
// ProvisioningState - READ-ONLY; The provisioning state.
|
||||
ProvisioningState *string `json:"provisioningState,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -1020,7 +1008,7 @@ type GroupsDeleteFuture struct {
|
|||
// If the operation has not completed it will return an error.
|
||||
func (future *GroupsDeleteFuture) Result(client GroupsClient) (ar autorest.Response, err error) {
|
||||
var done bool
|
||||
done, err = future.Done(client)
|
||||
done, err = future.DoneWithContext(context.Background(), client)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupsDeleteFuture", "Result", future.Response(), "Polling failure")
|
||||
return
|
||||
|
@ -1041,9 +1029,9 @@ type HTTPMessage struct {
|
|||
|
||||
// Identity identity for the resource.
|
||||
type Identity struct {
|
||||
// PrincipalID - The principal ID of resource identity.
|
||||
// PrincipalID - READ-ONLY; The principal ID of resource identity.
|
||||
PrincipalID *string `json:"principalId,omitempty"`
|
||||
// TenantID - The tenant ID of resource.
|
||||
// TenantID - READ-ONLY; The tenant ID of resource.
|
||||
TenantID *string `json:"tenantId,omitempty"`
|
||||
// Type - The identity type. Possible values include: 'SystemAssigned', 'UserAssigned', 'SystemAssignedUserAssigned', 'None'
|
||||
Type ResourceIdentityType `json:"type,omitempty"`
|
||||
|
@ -1054,7 +1042,7 @@ type ListResult struct {
|
|||
autorest.Response `json:"-"`
|
||||
// Value - An array of resources.
|
||||
Value *[]GenericResource `json:"value,omitempty"`
|
||||
// NextLink - The URL to use for getting the next set of results.
|
||||
// NextLink - READ-ONLY; The URL to use for getting the next set of results.
|
||||
NextLink *string `json:"nextLink,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -1197,13 +1185,13 @@ func NewListResultPage(getNextPage func(context.Context, ListResult) (ListResult
|
|||
|
||||
// ManagementErrorWithDetails the detailed error message of resource management.
|
||||
type ManagementErrorWithDetails struct {
|
||||
// Code - The error code returned when exporting the template.
|
||||
// Code - READ-ONLY; The error code returned when exporting the template.
|
||||
Code *string `json:"code,omitempty"`
|
||||
// Message - The error message describing the export error.
|
||||
// Message - READ-ONLY; The error message describing the export error.
|
||||
Message *string `json:"message,omitempty"`
|
||||
// Target - The target of the error.
|
||||
// Target - READ-ONLY; The target of the error.
|
||||
Target *string `json:"target,omitempty"`
|
||||
// Details - Validation error.
|
||||
// Details - READ-ONLY; Validation error.
|
||||
Details *[]ManagementErrorWithDetails `json:"details,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -1225,7 +1213,7 @@ type MoveResourcesFuture struct {
|
|||
// If the operation has not completed it will return an error.
|
||||
func (future *MoveResourcesFuture) Result(client Client) (ar autorest.Response, err error) {
|
||||
var done bool
|
||||
done, err = future.Done(client)
|
||||
done, err = future.DoneWithContext(context.Background(), client)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.MoveResourcesFuture", "Result", future.Response(), "Polling failure")
|
||||
return
|
||||
|
@ -1248,7 +1236,7 @@ type OnErrorDeployment struct {
|
|||
|
||||
// OnErrorDeploymentExtended deployment on error behavior with additional details.
|
||||
type OnErrorDeploymentExtended struct {
|
||||
// ProvisioningState - The state of the provisioning for the on error deployment.
|
||||
// ProvisioningState - READ-ONLY; The state of the provisioning for the on error deployment.
|
||||
ProvisioningState *string `json:"provisioningState,omitempty"`
|
||||
// Type - The deployment on error behavior type. Possible values are LastSuccessful and SpecificDeployment. Possible values include: 'LastSuccessful', 'SpecificDeployment'
|
||||
Type OnErrorDeploymentType `json:"type,omitempty"`
|
||||
|
@ -1281,13 +1269,13 @@ type Plan struct {
|
|||
// Provider resource provider information.
|
||||
type Provider struct {
|
||||
autorest.Response `json:"-"`
|
||||
// ID - The provider ID.
|
||||
// ID - READ-ONLY; The provider ID.
|
||||
ID *string `json:"id,omitempty"`
|
||||
// Namespace - The namespace of the resource provider.
|
||||
Namespace *string `json:"namespace,omitempty"`
|
||||
// RegistrationState - The registration state of the provider.
|
||||
// RegistrationState - READ-ONLY; The registration state of the provider.
|
||||
RegistrationState *string `json:"registrationState,omitempty"`
|
||||
// ResourceTypes - The collection of provider resource types.
|
||||
// ResourceTypes - READ-ONLY; The collection of provider resource types.
|
||||
ResourceTypes *[]ProviderResourceType `json:"resourceTypes,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -1296,7 +1284,7 @@ type ProviderListResult struct {
|
|||
autorest.Response `json:"-"`
|
||||
// Value - An array of resource providers.
|
||||
Value *[]Provider `json:"value,omitempty"`
|
||||
// NextLink - The URL to use for getting the next set of results.
|
||||
// NextLink - READ-ONLY; The URL to use for getting the next set of results.
|
||||
NextLink *string `json:"nextLink,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -1488,11 +1476,11 @@ func (prt ProviderResourceType) MarshalJSON() ([]byte, error) {
|
|||
|
||||
// Resource resource.
|
||||
type Resource struct {
|
||||
// ID - Resource ID
|
||||
// ID - READ-ONLY; Resource ID
|
||||
ID *string `json:"id,omitempty"`
|
||||
// Name - Resource name
|
||||
// Name - READ-ONLY; Resource name
|
||||
Name *string `json:"name,omitempty"`
|
||||
// Type - Resource type
|
||||
// Type - READ-ONLY; Resource type
|
||||
Type *string `json:"type,omitempty"`
|
||||
// Location - Resource location
|
||||
Location *string `json:"location,omitempty"`
|
||||
|
@ -1503,15 +1491,6 @@ type Resource struct {
|
|||
// MarshalJSON is the custom marshaler for Resource.
|
||||
func (r Resource) MarshalJSON() ([]byte, error) {
|
||||
objectMap := make(map[string]interface{})
|
||||
if r.ID != nil {
|
||||
objectMap["id"] = r.ID
|
||||
}
|
||||
if r.Name != nil {
|
||||
objectMap["name"] = r.Name
|
||||
}
|
||||
if r.Type != nil {
|
||||
objectMap["type"] = r.Type
|
||||
}
|
||||
if r.Location != nil {
|
||||
objectMap["location"] = r.Location
|
||||
}
|
||||
|
@ -1554,7 +1533,7 @@ type TagCount struct {
|
|||
// TagDetails tag details.
|
||||
type TagDetails struct {
|
||||
autorest.Response `json:"-"`
|
||||
// ID - The tag ID.
|
||||
// ID - READ-ONLY; The tag ID.
|
||||
ID *string `json:"id,omitempty"`
|
||||
// TagName - The tag name.
|
||||
TagName *string `json:"tagName,omitempty"`
|
||||
|
@ -1569,7 +1548,7 @@ type TagsListResult struct {
|
|||
autorest.Response `json:"-"`
|
||||
// Value - An array of tags.
|
||||
Value *[]TagDetails `json:"value,omitempty"`
|
||||
// NextLink - The URL to use for getting the next set of results.
|
||||
// NextLink - READ-ONLY; The URL to use for getting the next set of results.
|
||||
NextLink *string `json:"nextLink,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -1713,7 +1692,7 @@ func NewTagsListResultPage(getNextPage func(context.Context, TagsListResult) (Ta
|
|||
// TagValue tag information.
|
||||
type TagValue struct {
|
||||
autorest.Response `json:"-"`
|
||||
// ID - The tag ID.
|
||||
// ID - READ-ONLY; The tag ID.
|
||||
ID *string `json:"id,omitempty"`
|
||||
// TagValue - The tag value.
|
||||
TagValue *string `json:"tagValue,omitempty"`
|
||||
|
@ -1748,7 +1727,7 @@ type UpdateByIDFuture struct {
|
|||
// If the operation has not completed it will return an error.
|
||||
func (future *UpdateByIDFuture) Result(client Client) (gr GenericResource, err error) {
|
||||
var done bool
|
||||
done, err = future.Done(client)
|
||||
done, err = future.DoneWithContext(context.Background(), client)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.UpdateByIDFuture", "Result", future.Response(), "Polling failure")
|
||||
return
|
||||
|
@ -1776,7 +1755,7 @@ type UpdateFuture struct {
|
|||
// If the operation has not completed it will return an error.
|
||||
func (future *UpdateFuture) Result(client Client) (gr GenericResource, err error) {
|
||||
var done bool
|
||||
done, err = future.Done(client)
|
||||
done, err = future.DoneWithContext(context.Background(), client)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.UpdateFuture", "Result", future.Response(), "Polling failure")
|
||||
return
|
||||
|
@ -1805,7 +1784,7 @@ type ValidateMoveResourcesFuture struct {
|
|||
// If the operation has not completed it will return an error.
|
||||
func (future *ValidateMoveResourcesFuture) Result(client Client) (ar autorest.Response, err error) {
|
||||
var done bool
|
||||
done, err = future.Done(client)
|
||||
done, err = future.DoneWithContext(context.Background(), client)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.ValidateMoveResourcesFuture", "Result", future.Response(), "Polling failure")
|
||||
return
|
||||
|
|
139
vendor/github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2017-10-01/storage/models.go
generated
vendored
139
vendor/github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2017-10-01/storage/models.go
generated
vendored
|
@ -18,6 +18,7 @@ package storage
|
|||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
|
@ -379,19 +380,19 @@ func PossibleUsageUnitValues() []UsageUnit {
|
|||
// Account the storage account.
|
||||
type Account struct {
|
||||
autorest.Response `json:"-"`
|
||||
// Sku - Gets the SKU.
|
||||
// Sku - READ-ONLY; Gets the SKU.
|
||||
Sku *Sku `json:"sku,omitempty"`
|
||||
// Kind - Gets the Kind. Possible values include: 'Storage', 'StorageV2', 'BlobStorage'
|
||||
// Kind - READ-ONLY; Gets the Kind. Possible values include: 'Storage', 'StorageV2', 'BlobStorage'
|
||||
Kind Kind `json:"kind,omitempty"`
|
||||
// Identity - The identity of the resource.
|
||||
Identity *Identity `json:"identity,omitempty"`
|
||||
// AccountProperties - Properties of the storage account.
|
||||
*AccountProperties `json:"properties,omitempty"`
|
||||
// ID - Resource Id
|
||||
// ID - READ-ONLY; Resource Id
|
||||
ID *string `json:"id,omitempty"`
|
||||
// Name - Resource name
|
||||
// Name - READ-ONLY; Resource name
|
||||
Name *string `json:"name,omitempty"`
|
||||
// Type - Resource type
|
||||
// Type - READ-ONLY; Resource type
|
||||
Type *string `json:"type,omitempty"`
|
||||
// Location - Resource location
|
||||
Location *string `json:"location,omitempty"`
|
||||
|
@ -402,27 +403,12 @@ type Account struct {
|
|||
// MarshalJSON is the custom marshaler for Account.
|
||||
func (a Account) MarshalJSON() ([]byte, error) {
|
||||
objectMap := make(map[string]interface{})
|
||||
if a.Sku != nil {
|
||||
objectMap["sku"] = a.Sku
|
||||
}
|
||||
if a.Kind != "" {
|
||||
objectMap["kind"] = a.Kind
|
||||
}
|
||||
if a.Identity != nil {
|
||||
objectMap["identity"] = a.Identity
|
||||
}
|
||||
if a.AccountProperties != nil {
|
||||
objectMap["properties"] = a.AccountProperties
|
||||
}
|
||||
if a.ID != nil {
|
||||
objectMap["id"] = a.ID
|
||||
}
|
||||
if a.Name != nil {
|
||||
objectMap["name"] = a.Name
|
||||
}
|
||||
if a.Type != nil {
|
||||
objectMap["type"] = a.Type
|
||||
}
|
||||
if a.Location != nil {
|
||||
objectMap["location"] = a.Location
|
||||
}
|
||||
|
@ -648,57 +634,57 @@ func (acp *AccountCreateParameters) UnmarshalJSON(body []byte) error {
|
|||
|
||||
// AccountKey an access key for the storage account.
|
||||
type AccountKey struct {
|
||||
// KeyName - Name of the key.
|
||||
// KeyName - READ-ONLY; Name of the key.
|
||||
KeyName *string `json:"keyName,omitempty"`
|
||||
// Value - Base 64-encoded value of the key.
|
||||
// Value - READ-ONLY; Base 64-encoded value of the key.
|
||||
Value *string `json:"value,omitempty"`
|
||||
// Permissions - Permissions for the key -- read-only or full permissions. Possible values include: 'Read', 'Full'
|
||||
// Permissions - READ-ONLY; Permissions for the key -- read-only or full permissions. Possible values include: 'Read', 'Full'
|
||||
Permissions KeyPermission `json:"permissions,omitempty"`
|
||||
}
|
||||
|
||||
// AccountListKeysResult the response from the ListKeys operation.
|
||||
type AccountListKeysResult struct {
|
||||
autorest.Response `json:"-"`
|
||||
// Keys - Gets the list of storage account keys and their properties for the specified storage account.
|
||||
// Keys - READ-ONLY; Gets the list of storage account keys and their properties for the specified storage account.
|
||||
Keys *[]AccountKey `json:"keys,omitempty"`
|
||||
}
|
||||
|
||||
// AccountListResult the response from the List Storage Accounts operation.
|
||||
type AccountListResult struct {
|
||||
autorest.Response `json:"-"`
|
||||
// Value - Gets the list of storage accounts and their properties.
|
||||
// Value - READ-ONLY; Gets the list of storage accounts and their properties.
|
||||
Value *[]Account `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
// AccountProperties properties of the storage account.
|
||||
type AccountProperties struct {
|
||||
// ProvisioningState - Gets the status of the storage account at the time the operation was called. Possible values include: 'Creating', 'ResolvingDNS', 'Succeeded'
|
||||
// ProvisioningState - READ-ONLY; Gets the status of the storage account at the time the operation was called. Possible values include: 'Creating', 'ResolvingDNS', 'Succeeded'
|
||||
ProvisioningState ProvisioningState `json:"provisioningState,omitempty"`
|
||||
// PrimaryEndpoints - Gets the URLs that are used to perform a retrieval of a public blob, queue, or table object. Note that Standard_ZRS and Premium_LRS accounts only return the blob endpoint.
|
||||
// PrimaryEndpoints - READ-ONLY; Gets the URLs that are used to perform a retrieval of a public blob, queue, or table object. Note that Standard_ZRS and Premium_LRS accounts only return the blob endpoint.
|
||||
PrimaryEndpoints *Endpoints `json:"primaryEndpoints,omitempty"`
|
||||
// PrimaryLocation - Gets the location of the primary data center for the storage account.
|
||||
// PrimaryLocation - READ-ONLY; Gets the location of the primary data center for the storage account.
|
||||
PrimaryLocation *string `json:"primaryLocation,omitempty"`
|
||||
// StatusOfPrimary - Gets the status indicating whether the primary location of the storage account is available or unavailable. Possible values include: 'Available', 'Unavailable'
|
||||
// StatusOfPrimary - READ-ONLY; Gets the status indicating whether the primary location of the storage account is available or unavailable. Possible values include: 'Available', 'Unavailable'
|
||||
StatusOfPrimary AccountStatus `json:"statusOfPrimary,omitempty"`
|
||||
// LastGeoFailoverTime - Gets the timestamp of the most recent instance of a failover to the secondary location. Only the most recent timestamp is retained. This element is not returned if there has never been a failover instance. Only available if the accountType is Standard_GRS or Standard_RAGRS.
|
||||
// LastGeoFailoverTime - READ-ONLY; Gets the timestamp of the most recent instance of a failover to the secondary location. Only the most recent timestamp is retained. This element is not returned if there has never been a failover instance. Only available if the accountType is Standard_GRS or Standard_RAGRS.
|
||||
LastGeoFailoverTime *date.Time `json:"lastGeoFailoverTime,omitempty"`
|
||||
// SecondaryLocation - Gets the location of the geo-replicated secondary for the storage account. Only available if the accountType is Standard_GRS or Standard_RAGRS.
|
||||
// SecondaryLocation - READ-ONLY; Gets the location of the geo-replicated secondary for the storage account. Only available if the accountType is Standard_GRS or Standard_RAGRS.
|
||||
SecondaryLocation *string `json:"secondaryLocation,omitempty"`
|
||||
// StatusOfSecondary - Gets the status indicating whether the secondary location of the storage account is available or unavailable. Only available if the SKU name is Standard_GRS or Standard_RAGRS. Possible values include: 'Available', 'Unavailable'
|
||||
// StatusOfSecondary - READ-ONLY; Gets the status indicating whether the secondary location of the storage account is available or unavailable. Only available if the SKU name is Standard_GRS or Standard_RAGRS. Possible values include: 'Available', 'Unavailable'
|
||||
StatusOfSecondary AccountStatus `json:"statusOfSecondary,omitempty"`
|
||||
// CreationTime - Gets the creation date and time of the storage account in UTC.
|
||||
// CreationTime - READ-ONLY; Gets the creation date and time of the storage account in UTC.
|
||||
CreationTime *date.Time `json:"creationTime,omitempty"`
|
||||
// CustomDomain - Gets the custom domain the user assigned to this storage account.
|
||||
// CustomDomain - READ-ONLY; Gets the custom domain the user assigned to this storage account.
|
||||
CustomDomain *CustomDomain `json:"customDomain,omitempty"`
|
||||
// SecondaryEndpoints - Gets the URLs that are used to perform a retrieval of a public blob, queue, or table object from the secondary location of the storage account. Only available if the SKU name is Standard_RAGRS.
|
||||
// SecondaryEndpoints - READ-ONLY; Gets the URLs that are used to perform a retrieval of a public blob, queue, or table object from the secondary location of the storage account. Only available if the SKU name is Standard_RAGRS.
|
||||
SecondaryEndpoints *Endpoints `json:"secondaryEndpoints,omitempty"`
|
||||
// Encryption - Gets the encryption settings on the account. If unspecified, the account is unencrypted.
|
||||
// Encryption - READ-ONLY; Gets the encryption settings on the account. If unspecified, the account is unencrypted.
|
||||
Encryption *Encryption `json:"encryption,omitempty"`
|
||||
// AccessTier - Required for storage accounts where kind = BlobStorage. The access tier used for billing. Possible values include: 'Hot', 'Cool'
|
||||
// AccessTier - READ-ONLY; Required for storage accounts where kind = BlobStorage. The access tier used for billing. Possible values include: 'Hot', 'Cool'
|
||||
AccessTier AccessTier `json:"accessTier,omitempty"`
|
||||
// EnableHTTPSTrafficOnly - Allows https traffic only to storage service if sets to true.
|
||||
EnableHTTPSTrafficOnly *bool `json:"supportsHttpsTrafficOnly,omitempty"`
|
||||
// NetworkRuleSet - Network rule set
|
||||
// NetworkRuleSet - READ-ONLY; Network rule set
|
||||
NetworkRuleSet *NetworkRuleSet `json:"networkAcls,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -766,7 +752,7 @@ type AccountsCreateFuture struct {
|
|||
// If the operation has not completed it will return an error.
|
||||
func (future *AccountsCreateFuture) Result(client AccountsClient) (a Account, err error) {
|
||||
var done bool
|
||||
done, err = future.Done(client)
|
||||
done, err = future.DoneWithContext(context.Background(), client)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "storage.AccountsCreateFuture", "Result", future.Response(), "Polling failure")
|
||||
return
|
||||
|
@ -884,11 +870,11 @@ func (aup *AccountUpdateParameters) UnmarshalJSON(body []byte) error {
|
|||
// CheckNameAvailabilityResult the CheckNameAvailability operation response.
|
||||
type CheckNameAvailabilityResult struct {
|
||||
autorest.Response `json:"-"`
|
||||
// NameAvailable - Gets a boolean value that indicates whether the name is available for you to use. If true, the name is available. If false, the name has already been taken or is invalid and cannot be used.
|
||||
// NameAvailable - READ-ONLY; Gets a boolean value that indicates whether the name is available for you to use. If true, the name is available. If false, the name has already been taken or is invalid and cannot be used.
|
||||
NameAvailable *bool `json:"nameAvailable,omitempty"`
|
||||
// Reason - Gets the reason that a storage account name could not be used. The Reason element is only returned if NameAvailable is false. Possible values include: 'AccountNameInvalid', 'AlreadyExists'
|
||||
// Reason - READ-ONLY; Gets the reason that a storage account name could not be used. The Reason element is only returned if NameAvailable is false. Possible values include: 'AccountNameInvalid', 'AlreadyExists'
|
||||
Reason Reason `json:"reason,omitempty"`
|
||||
// Message - Gets an error message explaining the Reason value in more detail.
|
||||
// Message - READ-ONLY; Gets an error message explaining the Reason value in more detail.
|
||||
Message *string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -922,7 +908,7 @@ type Encryption struct {
|
|||
type EncryptionService struct {
|
||||
// Enabled - A boolean indicating whether or not the service encrypts the data as it is stored.
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
// LastEnabledTime - Gets a rough estimate of the date/time when the encryption was last enabled by the user. Only returned when encryption is enabled. There might be some unencrypted blobs which were written after this time, as it is just a rough estimate.
|
||||
// LastEnabledTime - READ-ONLY; Gets a rough estimate of the date/time when the encryption was last enabled by the user. Only returned when encryption is enabled. There might be some unencrypted blobs which were written after this time, as it is just a rough estimate.
|
||||
LastEnabledTime *date.Time `json:"lastEnabledTime,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -932,29 +918,29 @@ type EncryptionServices struct {
|
|||
Blob *EncryptionService `json:"blob,omitempty"`
|
||||
// File - The encryption function of the file storage service.
|
||||
File *EncryptionService `json:"file,omitempty"`
|
||||
// Table - The encryption function of the table storage service.
|
||||
// Table - READ-ONLY; The encryption function of the table storage service.
|
||||
Table *EncryptionService `json:"table,omitempty"`
|
||||
// Queue - The encryption function of the queue storage service.
|
||||
// Queue - READ-ONLY; The encryption function of the queue storage service.
|
||||
Queue *EncryptionService `json:"queue,omitempty"`
|
||||
}
|
||||
|
||||
// Endpoints the URIs that are used to perform a retrieval of a public blob, queue, or table object.
|
||||
type Endpoints struct {
|
||||
// Blob - Gets the blob endpoint.
|
||||
// Blob - READ-ONLY; Gets the blob endpoint.
|
||||
Blob *string `json:"blob,omitempty"`
|
||||
// Queue - Gets the queue endpoint.
|
||||
// Queue - READ-ONLY; Gets the queue endpoint.
|
||||
Queue *string `json:"queue,omitempty"`
|
||||
// Table - Gets the table endpoint.
|
||||
// Table - READ-ONLY; Gets the table endpoint.
|
||||
Table *string `json:"table,omitempty"`
|
||||
// File - Gets the file endpoint.
|
||||
// File - READ-ONLY; Gets the file endpoint.
|
||||
File *string `json:"file,omitempty"`
|
||||
}
|
||||
|
||||
// Identity identity for the resource.
|
||||
type Identity struct {
|
||||
// PrincipalID - The principal ID of resource identity.
|
||||
// PrincipalID - READ-ONLY; The principal ID of resource identity.
|
||||
PrincipalID *string `json:"principalId,omitempty"`
|
||||
// TenantID - The tenant ID of resource.
|
||||
// TenantID - READ-ONLY; The tenant ID of resource.
|
||||
TenantID *string `json:"tenantId,omitempty"`
|
||||
// Type - The identity type.
|
||||
Type *string `json:"type,omitempty"`
|
||||
|
@ -981,14 +967,14 @@ type KeyVaultProperties struct {
|
|||
// ListAccountSasResponse the List SAS credentials operation response.
|
||||
type ListAccountSasResponse struct {
|
||||
autorest.Response `json:"-"`
|
||||
// AccountSasToken - List SAS credentials of storage account.
|
||||
// AccountSasToken - READ-ONLY; List SAS credentials of storage account.
|
||||
AccountSasToken *string `json:"accountSasToken,omitempty"`
|
||||
}
|
||||
|
||||
// ListServiceSasResponse the List service SAS credentials operation response.
|
||||
type ListServiceSasResponse struct {
|
||||
autorest.Response `json:"-"`
|
||||
// ServiceSasToken - List service SAS credentials of specific resource.
|
||||
// ServiceSasToken - READ-ONLY; List service SAS credentials of specific resource.
|
||||
ServiceSasToken *string `json:"serviceSasToken,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -1133,11 +1119,11 @@ type OperationProperties struct {
|
|||
|
||||
// Resource describes a storage resource.
|
||||
type Resource struct {
|
||||
// ID - Resource Id
|
||||
// ID - READ-ONLY; Resource Id
|
||||
ID *string `json:"id,omitempty"`
|
||||
// Name - Resource name
|
||||
// Name - READ-ONLY; Resource name
|
||||
Name *string `json:"name,omitempty"`
|
||||
// Type - Resource type
|
||||
// Type - READ-ONLY; Resource type
|
||||
Type *string `json:"type,omitempty"`
|
||||
// Location - Resource location
|
||||
Location *string `json:"location,omitempty"`
|
||||
|
@ -1148,15 +1134,6 @@ type Resource struct {
|
|||
// MarshalJSON is the custom marshaler for Resource.
|
||||
func (r Resource) MarshalJSON() ([]byte, error) {
|
||||
objectMap := make(map[string]interface{})
|
||||
if r.ID != nil {
|
||||
objectMap["id"] = r.ID
|
||||
}
|
||||
if r.Name != nil {
|
||||
objectMap["name"] = r.Name
|
||||
}
|
||||
if r.Type != nil {
|
||||
objectMap["type"] = r.Type
|
||||
}
|
||||
if r.Location != nil {
|
||||
objectMap["location"] = r.Location
|
||||
}
|
||||
|
@ -1168,9 +1145,9 @@ func (r Resource) MarshalJSON() ([]byte, error) {
|
|||
|
||||
// Restriction the restriction because of which SKU cannot be used.
|
||||
type Restriction struct {
|
||||
// Type - The type of restrictions. As of now only possible value for this is location.
|
||||
// Type - READ-ONLY; The type of restrictions. As of now only possible value for this is location.
|
||||
Type *string `json:"type,omitempty"`
|
||||
// Values - The value of restrictions. If the restriction type is set to location. This would be different locations where the SKU is restricted.
|
||||
// Values - READ-ONLY; The value of restrictions. If the restriction type is set to location. This would be different locations where the SKU is restricted.
|
||||
Values *[]string `json:"values,omitempty"`
|
||||
// ReasonCode - The reason for the restriction. As of now this can be "QuotaId" or "NotAvailableForSubscription". Quota Id is set when the SKU has requiredQuotas parameter as the subscription does not belong to that quota. The "NotAvailableForSubscription" is related to capacity at DC. Possible values include: 'QuotaID', 'NotAvailableForSubscription'
|
||||
ReasonCode ReasonCode `json:"reasonCode,omitempty"`
|
||||
|
@ -1226,15 +1203,15 @@ type ServiceSpecification struct {
|
|||
type Sku struct {
|
||||
// Name - Gets or sets the sku name. Required for account creation; optional for update. Note that in older versions, sku name was called accountType. Possible values include: 'StandardLRS', 'StandardGRS', 'StandardRAGRS', 'StandardZRS', 'PremiumLRS'
|
||||
Name SkuName `json:"name,omitempty"`
|
||||
// Tier - Gets the sku tier. This is based on the SKU name. Possible values include: 'Standard', 'Premium'
|
||||
// Tier - READ-ONLY; Gets the sku tier. This is based on the SKU name. Possible values include: 'Standard', 'Premium'
|
||||
Tier SkuTier `json:"tier,omitempty"`
|
||||
// ResourceType - The type of the resource, usually it is 'storageAccounts'.
|
||||
// ResourceType - READ-ONLY; The type of the resource, usually it is 'storageAccounts'.
|
||||
ResourceType *string `json:"resourceType,omitempty"`
|
||||
// Kind - Indicates the type of storage account. Possible values include: 'Storage', 'StorageV2', 'BlobStorage'
|
||||
// Kind - READ-ONLY; Indicates the type of storage account. Possible values include: 'Storage', 'StorageV2', 'BlobStorage'
|
||||
Kind Kind `json:"kind,omitempty"`
|
||||
// Locations - The set of locations that the SKU is available. This will be supported and registered Azure Geo Regions (e.g. West US, East US, Southeast Asia, etc.).
|
||||
// Locations - READ-ONLY; The set of locations that the SKU is available. This will be supported and registered Azure Geo Regions (e.g. West US, East US, Southeast Asia, etc.).
|
||||
Locations *[]string `json:"locations,omitempty"`
|
||||
// Capabilities - The capability information in the specified sku, including file encryption, network acls, change notification, etc.
|
||||
// Capabilities - READ-ONLY; The capability information in the specified sku, including file encryption, network acls, change notification, etc.
|
||||
Capabilities *[]SKUCapability `json:"capabilities,omitempty"`
|
||||
// Restrictions - The restrictions because of which SKU cannot be used. This is empty if there are no restrictions.
|
||||
Restrictions *[]Restriction `json:"restrictions,omitempty"`
|
||||
|
@ -1243,28 +1220,28 @@ type Sku struct {
|
|||
// SKUCapability the capability information in the specified sku, including file encryption, network acls,
|
||||
// change notification, etc.
|
||||
type SKUCapability struct {
|
||||
// Name - The name of capability, The capability information in the specified sku, including file encryption, network acls, change notification, etc.
|
||||
// Name - READ-ONLY; The name of capability, The capability information in the specified sku, including file encryption, network acls, change notification, etc.
|
||||
Name *string `json:"name,omitempty"`
|
||||
// Value - A string value to indicate states of given capability. Possibly 'true' or 'false'.
|
||||
// Value - READ-ONLY; A string value to indicate states of given capability. Possibly 'true' or 'false'.
|
||||
Value *string `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
// SkuListResult the response from the List Storage SKUs operation.
|
||||
type SkuListResult struct {
|
||||
autorest.Response `json:"-"`
|
||||
// Value - Get the list result of storage SKUs and their properties.
|
||||
// Value - READ-ONLY; Get the list result of storage SKUs and their properties.
|
||||
Value *[]Sku `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
// Usage describes Storage Resource Usage.
|
||||
type Usage struct {
|
||||
// Unit - Gets the unit of measurement. Possible values include: 'Count', 'Bytes', 'Seconds', 'Percent', 'CountsPerSecond', 'BytesPerSecond'
|
||||
// Unit - READ-ONLY; Gets the unit of measurement. Possible values include: 'Count', 'Bytes', 'Seconds', 'Percent', 'CountsPerSecond', 'BytesPerSecond'
|
||||
Unit UsageUnit `json:"unit,omitempty"`
|
||||
// CurrentValue - Gets the current count of the allocated resources in the subscription.
|
||||
// CurrentValue - READ-ONLY; Gets the current count of the allocated resources in the subscription.
|
||||
CurrentValue *int32 `json:"currentValue,omitempty"`
|
||||
// Limit - Gets the maximum count of the resources that can be allocated in the subscription.
|
||||
// Limit - READ-ONLY; Gets the maximum count of the resources that can be allocated in the subscription.
|
||||
Limit *int32 `json:"limit,omitempty"`
|
||||
// Name - Gets the name of the type of usage.
|
||||
// Name - READ-ONLY; Gets the name of the type of usage.
|
||||
Name *UsageName `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -1277,9 +1254,9 @@ type UsageListResult struct {
|
|||
|
||||
// UsageName the usage names that can be used; currently limited to StorageAccount.
|
||||
type UsageName struct {
|
||||
// Value - Gets a string describing the resource name.
|
||||
// Value - READ-ONLY; Gets a string describing the resource name.
|
||||
Value *string `json:"value,omitempty"`
|
||||
// LocalizedValue - Gets a localized string describing the resource name.
|
||||
// LocalizedValue - READ-ONLY; Gets a localized string describing the resource name.
|
||||
LocalizedValue *string `json:"localizedValue,omitempty"`
|
||||
}
|
||||
|
||||
|
|
|
@ -367,11 +367,14 @@ func newSASClient(accountName, baseURL string, sasToken url.Values) Client {
|
|||
accountName: accountName,
|
||||
baseURL: baseURL,
|
||||
accountSASToken: sasToken,
|
||||
useHTTPS: defaultUseHTTPS,
|
||||
}
|
||||
c.userAgent = c.getDefaultUserAgent()
|
||||
// Get API version and protocol from token
|
||||
c.apiVersion = sasToken.Get("sv")
|
||||
c.useHTTPS = sasToken.Get("spr") == "https"
|
||||
if spr := sasToken.Get("spr"); spr != "" {
|
||||
c.useHTTPS = spr == "https"
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/satori/go.uuid"
|
||||
uuid "github.com/satori/go.uuid"
|
||||
)
|
||||
|
||||
// Annotating as secure for gas scanning
|
||||
|
@ -257,6 +257,9 @@ func (e *Entity) MarshalJSON() ([]byte, error) {
|
|||
case int64:
|
||||
completeMap[typeKey] = OdataInt64
|
||||
completeMap[k] = fmt.Sprintf("%v", v)
|
||||
case float32, float64:
|
||||
completeMap[typeKey] = OdataDouble
|
||||
completeMap[k] = fmt.Sprintf("%v", v)
|
||||
default:
|
||||
completeMap[k] = v
|
||||
}
|
||||
|
@ -264,7 +267,8 @@ func (e *Entity) MarshalJSON() ([]byte, error) {
|
|||
if !(completeMap[k] == OdataBinary ||
|
||||
completeMap[k] == OdataDateTime ||
|
||||
completeMap[k] == OdataGUID ||
|
||||
completeMap[k] == OdataInt64) {
|
||||
completeMap[k] == OdataInt64 ||
|
||||
completeMap[k] == OdataDouble) {
|
||||
return nil, fmt.Errorf("Odata.type annotation %v value is not valid", k)
|
||||
}
|
||||
valueKey := strings.TrimSuffix(k, OdataTypeSuffix)
|
||||
|
@ -339,6 +343,12 @@ func (e *Entity) UnmarshalJSON(data []byte) error {
|
|||
return fmt.Errorf(errorTemplate, err)
|
||||
}
|
||||
props[valueKey] = i
|
||||
case OdataDouble:
|
||||
f, err := strconv.ParseFloat(str, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf(errorTemplate, err)
|
||||
}
|
||||
props[valueKey] = f
|
||||
default:
|
||||
return fmt.Errorf(errorTemplate, fmt.Sprintf("%v is not supported", v))
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ const (
|
|||
|
||||
OdataBinary = "Edm.Binary"
|
||||
OdataDateTime = "Edm.DateTime"
|
||||
OdataDouble = "Edm.Double"
|
||||
OdataGUID = "Edm.Guid"
|
||||
OdataInt64 = "Edm.Int64"
|
||||
|
||||
|
|
|
@ -25,8 +25,6 @@ import (
|
|||
"net/textproto"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/marstr/guid"
|
||||
)
|
||||
|
||||
// Operation type. Insert, Delete, Replace etc.
|
||||
|
@ -132,8 +130,7 @@ func (t *TableBatch) MergeEntity(entity *Entity) {
|
|||
// As per document https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/performing-entity-group-transactions
|
||||
func (t *TableBatch) ExecuteBatch() error {
|
||||
|
||||
// Using `github.com/marstr/guid` is in response to issue #947 (https://github.com/Azure/azure-sdk-for-go/issues/947).
|
||||
id, err := guid.NewGUIDs(guid.CreationStrategyVersion1)
|
||||
id, err := newUUID()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -145,7 +142,7 @@ func (t *TableBatch) ExecuteBatch() error {
|
|||
return err
|
||||
}
|
||||
|
||||
id, err = guid.NewGUIDs(guid.CreationStrategyVersion1)
|
||||
id, err = newUUID()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ package storage
|
|||
import (
|
||||
"bytes"
|
||||
"crypto/hmac"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/xml"
|
||||
|
@ -29,6 +30,8 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
uuid "github.com/satori/go.uuid"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -242,3 +245,16 @@ func getMetadataFromHeaders(header http.Header) map[string]string {
|
|||
|
||||
return metadata
|
||||
}
|
||||
|
||||
// newUUID returns a new uuid using RFC 4122 algorithm.
|
||||
func newUUID() (uuid.UUID, error) {
|
||||
u := [16]byte{}
|
||||
// Set all bits to randomly (or pseudo-randomly) chosen values.
|
||||
_, err := rand.Read(u[:])
|
||||
if err != nil {
|
||||
return uuid.UUID{}, err
|
||||
}
|
||||
u[8] = (u[8]&(0xff>>2) | (0x02 << 6)) // u.setVariant(ReservedRFC4122)
|
||||
u[6] = (u[6] & 0xF) | (uuid.V4 << 4) // u.setVersion(V4)
|
||||
return uuid.FromBytes(u[:])
|
||||
}
|
||||
|
|
|
@ -18,4 +18,4 @@ package version
|
|||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
// Number contains the semantic version of this SDK.
|
||||
const Number = "v27.3.0"
|
||||
const Number = "v30.0.0"
|
||||
|
|
|
@ -19,10 +19,6 @@ import (
|
|||
"net/url"
|
||||
)
|
||||
|
||||
const (
|
||||
activeDirectoryAPIVersion = "1.0"
|
||||
)
|
||||
|
||||
// OAuthConfig represents the endpoints needed
|
||||
// in OAuth operations
|
||||
type OAuthConfig struct {
|
||||
|
@ -46,11 +42,25 @@ func validateStringParam(param, name string) error {
|
|||
|
||||
// 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
|
||||
const activeDirectoryEndpointTemplate = "%s/oauth2/%s?api-version=%s"
|
||||
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
|
||||
|
@ -59,15 +69,15 @@ func NewOAuthConfig(activeDirectoryEndpoint, tenantID string) (*OAuthConfig, err
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
authorizeURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "authorize", activeDirectoryAPIVersion))
|
||||
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", activeDirectoryAPIVersion))
|
||||
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", activeDirectoryAPIVersion))
|
||||
deviceCodeURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "devicecode", api))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ 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
|
||||
// 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
|
||||
|
|
|
@ -29,12 +29,12 @@ import (
|
|||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest/date"
|
||||
"github.com/Azure/go-autorest/tracing"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
||||
|
@ -96,18 +96,27 @@ type RefresherWithContext interface {
|
|||
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 string `json:"expires_in"`
|
||||
ExpiresOn string `json:"expires_on"`
|
||||
NotBefore string `json:"not_before"`
|
||||
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{}
|
||||
|
@ -115,12 +124,12 @@ func (t Token) IsZero() bool {
|
|||
|
||||
// Expires returns the time.Time when the Token expires.
|
||||
func (t Token) Expires() time.Time {
|
||||
s, err := strconv.Atoi(t.ExpiresOn)
|
||||
s, err := t.ExpiresOn.Float64()
|
||||
if err != nil {
|
||||
s = -3600
|
||||
}
|
||||
|
||||
expiration := date.NewUnixTimeFromSeconds(float64(s))
|
||||
expiration := date.NewUnixTimeFromSeconds(s)
|
||||
|
||||
return time.Time(expiration).UTC()
|
||||
}
|
||||
|
@ -217,6 +226,8 @@ func (secret *ServicePrincipalCertificateSecret) SignJwt(spt *ServicePrincipalTo
|
|||
|
||||
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,
|
||||
|
@ -374,8 +385,13 @@ func (spt *ServicePrincipalToken) UnmarshalJSON(data []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
spt.refreshLock = &sync.RWMutex{}
|
||||
spt.sender = &http.Client{}
|
||||
// Don't override the refreshLock or the sender if those have been already set.
|
||||
if spt.refreshLock == nil {
|
||||
spt.refreshLock = &sync.RWMutex{}
|
||||
}
|
||||
if spt.sender == nil {
|
||||
spt.sender = &http.Client{Transport: tracing.Transport}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -413,6 +429,7 @@ func NewServicePrincipalTokenWithSecret(oauthConfig OAuthConfig, id string, reso
|
|||
}
|
||||
spt := &ServicePrincipalToken{
|
||||
inner: servicePrincipalToken{
|
||||
Token: newToken(),
|
||||
OauthConfig: oauthConfig,
|
||||
Secret: secret,
|
||||
ClientID: id,
|
||||
|
@ -421,7 +438,7 @@ func NewServicePrincipalTokenWithSecret(oauthConfig OAuthConfig, id string, reso
|
|||
RefreshWithin: defaultRefresh,
|
||||
},
|
||||
refreshLock: &sync.RWMutex{},
|
||||
sender: &http.Client{},
|
||||
sender: &http.Client{Transport: tracing.Transport},
|
||||
refreshCallbacks: callbacks,
|
||||
}
|
||||
return spt, nil
|
||||
|
@ -652,6 +669,7 @@ func newServicePrincipalTokenFromMSI(msiEndpoint, resource string, userAssignedI
|
|||
|
||||
spt := &ServicePrincipalToken{
|
||||
inner: servicePrincipalToken{
|
||||
Token: newToken(),
|
||||
OauthConfig: OAuthConfig{
|
||||
TokenEndpoint: *msiEndpointURL,
|
||||
},
|
||||
|
@ -661,7 +679,7 @@ func newServicePrincipalTokenFromMSI(msiEndpoint, resource string, userAssignedI
|
|||
RefreshWithin: defaultRefresh,
|
||||
},
|
||||
refreshLock: &sync.RWMutex{},
|
||||
sender: &http.Client{},
|
||||
sender: &http.Client{Transport: tracing.Transport},
|
||||
refreshCallbacks: callbacks,
|
||||
MaxMSIRefreshAttempts: defaultMaxMSIRefreshAttempts,
|
||||
}
|
||||
|
@ -778,6 +796,7 @@ func (spt *ServicePrincipalToken) refreshInternal(ctx context.Context, resource
|
|||
if err != nil {
|
||||
return fmt.Errorf("adal: Failed to build the refresh request. Error = '%v'", err)
|
||||
}
|
||||
req.Header.Add("User-Agent", UserAgent())
|
||||
req = req.WithContext(ctx)
|
||||
if !isIMDS(spt.inner.OauthConfig.TokenEndpoint) {
|
||||
v := url.Values{}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
package adal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// 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.
|
||||
|
||||
const number = "v1.0.0"
|
||||
|
||||
var (
|
||||
ua = fmt.Sprintf("Go/%s (%s-%s) go-autorest/adal/%s",
|
||||
runtime.Version(),
|
||||
runtime.GOARCH,
|
||||
runtime.GOOS,
|
||||
number,
|
||||
)
|
||||
)
|
||||
|
||||
// UserAgent returns a string containing the Go version, system architecture and OS, and the adal version.
|
||||
func UserAgent() string {
|
||||
return ua
|
||||
}
|
||||
|
||||
// AddToUserAgent adds an extension to the current user agent
|
||||
func AddToUserAgent(extension string) error {
|
||||
if extension != "" {
|
||||
ua = fmt.Sprintf("%s %s", ua, extension)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("Extension was empty, User Agent remained as '%s'", ua)
|
||||
}
|
|
@ -15,12 +15,14 @@ package autorest
|
|||
// limitations under the License.
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest/adal"
|
||||
"github.com/Azure/go-autorest/tracing"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -30,6 +32,8 @@ const (
|
|||
apiKeyAuthorizerHeader = "Ocp-Apim-Subscription-Key"
|
||||
bingAPISdkHeader = "X-BingApis-SDK-Client"
|
||||
golangBingAPISdkHeaderValue = "Go-SDK"
|
||||
authorization = "Authorization"
|
||||
basic = "Basic"
|
||||
)
|
||||
|
||||
// Authorizer is the interface that provides a PrepareDecorator used to supply request
|
||||
|
@ -68,7 +72,7 @@ func NewAPIKeyAuthorizer(headers map[string]interface{}, queryParameters map[str
|
|||
return &APIKeyAuthorizer{headers: headers, queryParameters: queryParameters}
|
||||
}
|
||||
|
||||
// WithAuthorization returns a PrepareDecorator that adds an HTTP headers and Query Paramaters
|
||||
// WithAuthorization returns a PrepareDecorator that adds an HTTP headers and Query Parameters.
|
||||
func (aka *APIKeyAuthorizer) WithAuthorization() PrepareDecorator {
|
||||
return func(p Preparer) Preparer {
|
||||
return DecoratePreparer(p, WithHeaders(aka.headers), WithQueryParameters(aka.queryParameters))
|
||||
|
@ -147,7 +151,7 @@ type BearerAuthorizerCallback struct {
|
|||
// is invoked when the HTTP request is submitted.
|
||||
func NewBearerAuthorizerCallback(sender Sender, callback BearerAuthorizerCallbackFunc) *BearerAuthorizerCallback {
|
||||
if sender == nil {
|
||||
sender = &http.Client{}
|
||||
sender = &http.Client{Transport: tracing.Transport}
|
||||
}
|
||||
return &BearerAuthorizerCallback{sender: sender, callback: callback}
|
||||
}
|
||||
|
@ -257,3 +261,27 @@ func (egta EventGridKeyAuthorizer) WithAuthorization() PrepareDecorator {
|
|||
}
|
||||
return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization()
|
||||
}
|
||||
|
||||
// BasicAuthorizer implements basic HTTP authorization by adding the Authorization HTTP header
|
||||
// with the value "Basic <TOKEN>" where <TOKEN> is a base64-encoded username:password tuple.
|
||||
type BasicAuthorizer struct {
|
||||
userName string
|
||||
password string
|
||||
}
|
||||
|
||||
// NewBasicAuthorizer creates a new BasicAuthorizer with the specified username and password.
|
||||
func NewBasicAuthorizer(userName, password string) *BasicAuthorizer {
|
||||
return &BasicAuthorizer{
|
||||
userName: userName,
|
||||
password: password,
|
||||
}
|
||||
}
|
||||
|
||||
// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose
|
||||
// value is "Basic " followed by the base64-encoded username:password tuple.
|
||||
func (ba *BasicAuthorizer) WithAuthorization() PrepareDecorator {
|
||||
headers := make(map[string]interface{})
|
||||
headers[authorization] = basic + " " + base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", ba.userName, ba.password)))
|
||||
|
||||
return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization()
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/tracing"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -44,24 +45,14 @@ var pollingCodes = [...]int{http.StatusNoContent, http.StatusAccepted, http.Stat
|
|||
// 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}
|
||||
pt pollingTracker
|
||||
}
|
||||
|
||||
// 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)
|
||||
if err != nil {
|
||||
return Future{}, err
|
||||
}
|
||||
return Future{pt: pt}, nil
|
||||
return Future{pt: pt}, err
|
||||
}
|
||||
|
||||
// Response returns the last HTTP response.
|
||||
|
@ -88,29 +79,25 @@ func (f Future) PollingMethod() PollingMethodType {
|
|||
return f.pt.pollingMethod()
|
||||
}
|
||||
|
||||
// Done queries the service to see if the operation has completed.
|
||||
func (f *Future) Done(sender autorest.Sender) (bool, error) {
|
||||
// support for legacy Future implementation
|
||||
if f.req != nil {
|
||||
resp, err := sender.Do(f.req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
// 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) {
|
||||
ctx = tracing.StartSpan(ctx, "github.com/Azure/go-autorest/autorest/azure/async.DoneWithContext")
|
||||
defer func() {
|
||||
sc := -1
|
||||
resp := f.Response()
|
||||
if resp != nil {
|
||||
sc = resp.StatusCode
|
||||
}
|
||||
pt, err := createPollingTracker(resp)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
f.pt = pt
|
||||
f.req = nil
|
||||
}
|
||||
// end legacy
|
||||
tracing.EndSpan(ctx, sc, err)
|
||||
}()
|
||||
|
||||
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(sender); err != nil {
|
||||
if err := f.pt.pollForStatus(ctx, sender); err != nil {
|
||||
return false, err
|
||||
}
|
||||
if err := f.pt.checkForErrors(); err != nil {
|
||||
|
@ -119,7 +106,10 @@ func (f *Future) Done(sender autorest.Sender) (bool, error) {
|
|||
if err := f.pt.updatePollingState(f.pt.provisioningStateApplicable()); err != nil {
|
||||
return false, err
|
||||
}
|
||||
if err := f.pt.updateHeaders(); err != nil {
|
||||
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()
|
||||
|
@ -151,24 +141,35 @@ func (f Future) GetPollingDelay() (time.Duration, bool) {
|
|||
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.
|
||||
func (f *Future) WaitForCompletionRef(ctx context.Context, client autorest.Client) error {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.PollingDuration)
|
||||
defer cancel()
|
||||
done, err := f.Done(client)
|
||||
for attempts := 0; !done; done, err = f.Done(client) {
|
||||
// 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) {
|
||||
ctx = tracing.StartSpan(ctx, "github.com/Azure/go-autorest/autorest/azure/async.WaitForCompletionRef")
|
||||
defer func() {
|
||||
sc := -1
|
||||
resp := f.Response()
|
||||
if resp != nil {
|
||||
sc = resp.StatusCode
|
||||
}
|
||||
tracing.EndSpan(ctx, sc, err)
|
||||
}()
|
||||
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")
|
||||
}
|
||||
|
@ -192,12 +193,12 @@ func (f *Future) WaitForCompletionRef(ctx context.Context, client autorest.Clien
|
|||
attempts++
|
||||
}
|
||||
// wait until the delay elapses or the context is cancelled
|
||||
delayElapsed := autorest.DelayForBackoff(delay, delayAttempt, ctx.Done())
|
||||
delayElapsed := autorest.DelayForBackoff(delay, delayAttempt, cancelCtx.Done())
|
||||
if !delayElapsed {
|
||||
return autorest.NewErrorWithError(ctx.Err(), "Future", "WaitForCompletion", f.pt.latestResponse(), "context has been cancelled")
|
||||
return autorest.NewErrorWithError(cancelCtx.Err(), "Future", "WaitForCompletion", f.pt.latestResponse(), "context has been cancelled")
|
||||
}
|
||||
}
|
||||
return err
|
||||
return
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
|
@ -264,7 +265,7 @@ type pollingTracker interface {
|
|||
// these methods can differ per tracker
|
||||
|
||||
// checks the response headers and status code to determine the polling mechanism
|
||||
updateHeaders() error
|
||||
updatePollingMethod() error
|
||||
|
||||
// checks the response for tracker-specific error conditions
|
||||
checkForErrors() error
|
||||
|
@ -274,11 +275,15 @@ type pollingTracker interface {
|
|||
|
||||
// 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(sender autorest.Sender) error
|
||||
pollForStatus(ctx context.Context, sender autorest.Sender) error
|
||||
|
||||
// updates internal tracker state, call this after each call to pollForStatus
|
||||
updatePollingState(provStateApl bool) error
|
||||
|
@ -348,6 +353,10 @@ func (pt *pollingTrackerBase) initializeState() error {
|
|||
case http.StatusOK:
|
||||
if ps := pt.getProvisioningState(); ps != nil {
|
||||
pt.State = *ps
|
||||
if pt.hasFailed() {
|
||||
pt.updateErrorFromResponse()
|
||||
return pt.pollingError()
|
||||
}
|
||||
} else {
|
||||
pt.State = operationSucceeded
|
||||
}
|
||||
|
@ -364,8 +373,9 @@ func (pt *pollingTrackerBase) initializeState() error {
|
|||
default:
|
||||
pt.State = operationFailed
|
||||
pt.updateErrorFromResponse()
|
||||
return pt.pollingError()
|
||||
}
|
||||
return nil
|
||||
return pt.initPollingMethod()
|
||||
}
|
||||
|
||||
func (pt pollingTrackerBase) getProvisioningState() *string {
|
||||
|
@ -387,6 +397,10 @@ func (pt *pollingTrackerBase) updateRawBody() error {
|
|||
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 {
|
||||
|
@ -396,15 +410,13 @@ func (pt *pollingTrackerBase) updateRawBody() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (pt *pollingTrackerBase) pollForStatus(sender autorest.Sender) error {
|
||||
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")
|
||||
}
|
||||
// attach the context from the original request if available (it will be absent for deserialized futures)
|
||||
if pt.resp != nil {
|
||||
req = req.WithContext(pt.resp.Request.Context())
|
||||
}
|
||||
|
||||
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")
|
||||
|
@ -416,12 +428,14 @@ func (pt *pollingTrackerBase) pollForStatus(sender autorest.Sender) error {
|
|||
} 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 {
|
||||
|
@ -431,8 +445,7 @@ func (pt *pollingTrackerBase) updateErrorFromResponse() {
|
|||
re := respErr{}
|
||||
defer pt.resp.Body.Close()
|
||||
var b []byte
|
||||
b, err = ioutil.ReadAll(pt.resp.Body)
|
||||
if err != nil {
|
||||
if b, err = ioutil.ReadAll(pt.resp.Body); err != nil || len(b) == 0 {
|
||||
goto Default
|
||||
}
|
||||
if err = json.Unmarshal(b, &re); err != nil {
|
||||
|
@ -445,20 +458,29 @@ func (pt *pollingTrackerBase) updateErrorFromResponse() {
|
|||
goto Default
|
||||
}
|
||||
}
|
||||
if re.ServiceError != nil {
|
||||
// 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: fmt.Sprintf("HTTP status code %v", pt.resp.StatusCode),
|
||||
Message: pt.resp.Status,
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -538,13 +560,33 @@ func (pt pollingTrackerBase) baseCheckForErrors() error {
|
|||
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) updateHeaders() error {
|
||||
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 {
|
||||
|
@ -600,7 +642,7 @@ type pollingTrackerPatch struct {
|
|||
pollingTrackerBase
|
||||
}
|
||||
|
||||
func (pt *pollingTrackerPatch) updateHeaders() error {
|
||||
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()
|
||||
|
@ -621,7 +663,7 @@ func (pt *pollingTrackerPatch) updateHeaders() error {
|
|||
}
|
||||
}
|
||||
// for 202 prefer the Azure-AsyncOperation header but fall back to Location if necessary
|
||||
// note the absense of the "final GET" mechanism for PATCH
|
||||
// note the absence of the "final GET" mechanism for PATCH
|
||||
if pt.resp.StatusCode == http.StatusAccepted {
|
||||
ao, err := getURLFromAsyncOpHeader(pt.resp)
|
||||
if err != nil {
|
||||
|
@ -658,7 +700,7 @@ type pollingTrackerPost struct {
|
|||
pollingTrackerBase
|
||||
}
|
||||
|
||||
func (pt *pollingTrackerPost) updateHeaders() error {
|
||||
func (pt *pollingTrackerPost) updatePollingMethod() error {
|
||||
// 201 requires Location header
|
||||
if pt.resp.StatusCode == http.StatusCreated {
|
||||
if lh, err := getURLFromLocationHeader(pt.resp); err != nil {
|
||||
|
@ -714,7 +756,7 @@ type pollingTrackerPut struct {
|
|||
pollingTrackerBase
|
||||
}
|
||||
|
||||
func (pt *pollingTrackerPut) updateHeaders() error {
|
||||
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()
|
||||
|
@ -752,8 +794,6 @@ func (pt *pollingTrackerPut) updateHeaders() error {
|
|||
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 == "" {
|
||||
|
@ -808,7 +848,7 @@ func createPollingTracker(resp *http.Response) (pollingTracker, error) {
|
|||
// 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.updateHeaders()
|
||||
return pt, pt.updatePollingMethod()
|
||||
}
|
||||
|
||||
// gets the polling URL from the Azure-AsyncOperation header.
|
||||
|
@ -843,43 +883,6 @@ func isValidURL(s string) bool {
|
|||
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
|
||||
|
||||
|
|
|
@ -44,11 +44,12 @@ const (
|
|||
// 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"`
|
||||
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 {
|
||||
|
@ -74,6 +75,14 @@ func (se ServiceError) Error() string {
|
|||
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
|
||||
}
|
||||
|
||||
|
@ -86,44 +95,47 @@ func (se *ServiceError) UnmarshalJSON(b []byte) error {
|
|||
// 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"`
|
||||
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"`
|
||||
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)
|
||||
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)
|
||||
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{}) {
|
||||
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.
|
||||
|
|
|
@ -22,9 +22,14 @@ import (
|
|||
"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"
|
||||
const (
|
||||
// EnvironmentFilepathName captures the name of the environment variable containing the path to the file
|
||||
// to be used while populating the Azure Environment.
|
||||
EnvironmentFilepathName = "AZURE_ENVIRONMENT_FILEPATH"
|
||||
|
||||
// NotAvailable is used for endpoints and resource IDs that are not available for a given cloud.
|
||||
NotAvailable = "N/A"
|
||||
)
|
||||
|
||||
var environments = map[string]Environment{
|
||||
"AZURECHINACLOUD": ChinaCloud,
|
||||
|
@ -33,28 +38,39 @@ var environments = map[string]Environment{
|
|||
"AZUREUSGOVERNMENTCLOUD": USGovernmentCloud,
|
||||
}
|
||||
|
||||
// ResourceIdentifier contains a set of Azure resource IDs.
|
||||
type ResourceIdentifier struct {
|
||||
Graph string `json:"graph"`
|
||||
KeyVault string `json:"keyVault"`
|
||||
Datalake string `json:"datalake"`
|
||||
Batch string `json:"batch"`
|
||||
OperationalInsights string `json:"operationalInsights"`
|
||||
}
|
||||
|
||||
// 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"`
|
||||
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"`
|
||||
CosmosDBDNSSuffix string `json:"cosmosDBDNSSuffix"`
|
||||
TokenAudience string `json:"tokenAudience"`
|
||||
ResourceIdentifiers ResourceIdentifier `json:"resourceIdentifiers"`
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -79,7 +95,15 @@ var (
|
|||
ServiceManagementVMDNSSuffix: "cloudapp.net",
|
||||
ResourceManagerVMDNSSuffix: "cloudapp.azure.com",
|
||||
ContainerRegistryDNSSuffix: "azurecr.io",
|
||||
CosmosDBDNSSuffix: "documents.azure.com",
|
||||
TokenAudience: "https://management.azure.com/",
|
||||
ResourceIdentifiers: ResourceIdentifier{
|
||||
Graph: "https://graph.windows.net/",
|
||||
KeyVault: "https://vault.azure.net",
|
||||
Datalake: "https://datalake.azure.net/",
|
||||
Batch: "https://batch.core.windows.net/",
|
||||
OperationalInsights: "https://api.loganalytics.io",
|
||||
},
|
||||
}
|
||||
|
||||
// USGovernmentCloud is the cloud environment for the US Government
|
||||
|
@ -102,8 +126,16 @@ var (
|
|||
ServiceBusEndpointSuffix: "servicebus.usgovcloudapi.net",
|
||||
ServiceManagementVMDNSSuffix: "usgovcloudapp.net",
|
||||
ResourceManagerVMDNSSuffix: "cloudapp.windowsazure.us",
|
||||
ContainerRegistryDNSSuffix: "azurecr.io",
|
||||
ContainerRegistryDNSSuffix: "azurecr.us",
|
||||
CosmosDBDNSSuffix: "documents.azure.us",
|
||||
TokenAudience: "https://management.usgovcloudapi.net/",
|
||||
ResourceIdentifiers: ResourceIdentifier{
|
||||
Graph: "https://graph.windows.net/",
|
||||
KeyVault: "https://vault.usgovcloudapi.net",
|
||||
Datalake: NotAvailable,
|
||||
Batch: "https://batch.core.usgovcloudapi.net/",
|
||||
OperationalInsights: "https://api.loganalytics.us",
|
||||
},
|
||||
}
|
||||
|
||||
// ChinaCloud is the cloud environment operated in China
|
||||
|
@ -126,8 +158,16 @@ var (
|
|||
ServiceBusEndpointSuffix: "servicebus.chinacloudapi.cn",
|
||||
ServiceManagementVMDNSSuffix: "chinacloudapp.cn",
|
||||
ResourceManagerVMDNSSuffix: "cloudapp.azure.cn",
|
||||
ContainerRegistryDNSSuffix: "azurecr.io",
|
||||
ContainerRegistryDNSSuffix: "azurecr.cn",
|
||||
CosmosDBDNSSuffix: "documents.azure.cn",
|
||||
TokenAudience: "https://management.chinacloudapi.cn/",
|
||||
ResourceIdentifiers: ResourceIdentifier{
|
||||
Graph: "https://graph.chinacloudapi.cn/",
|
||||
KeyVault: "https://vault.azure.cn",
|
||||
Datalake: NotAvailable,
|
||||
Batch: "https://batch.chinacloudapi.cn/",
|
||||
OperationalInsights: NotAvailable,
|
||||
},
|
||||
}
|
||||
|
||||
// GermanCloud is the cloud environment operated in Germany
|
||||
|
@ -150,8 +190,16 @@ var (
|
|||
ServiceBusEndpointSuffix: "servicebus.cloudapi.de",
|
||||
ServiceManagementVMDNSSuffix: "azurecloudapp.de",
|
||||
ResourceManagerVMDNSSuffix: "cloudapp.microsoftazure.de",
|
||||
ContainerRegistryDNSSuffix: "azurecr.io",
|
||||
ContainerRegistryDNSSuffix: NotAvailable,
|
||||
CosmosDBDNSSuffix: "documents.microsoftazure.de",
|
||||
TokenAudience: "https://management.microsoftazure.de/",
|
||||
ResourceIdentifiers: ResourceIdentifier{
|
||||
Graph: "https://graph.cloudapi.de/",
|
||||
KeyVault: "https://vault.microsoftazure.de",
|
||||
Datalake: NotAvailable,
|
||||
Batch: "https://batch.cloudapi.de/",
|
||||
OperationalInsights: NotAvailable,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
@ -140,8 +140,8 @@ func register(client autorest.Client, originalReq *http.Request, re RequestError
|
|||
}
|
||||
|
||||
// poll for registered provisioning state
|
||||
now := time.Now()
|
||||
for err == nil && time.Since(now) < client.PollingDuration {
|
||||
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(
|
||||
|
@ -183,7 +183,7 @@ func register(client autorest.Client, originalReq *http.Request, re RequestError
|
|||
return originalReq.Context().Err()
|
||||
}
|
||||
}
|
||||
if !(time.Since(now) < client.PollingDuration) {
|
||||
if client.PollingDuration != 0 && !(time.Since(registrationStartTime) < client.PollingDuration) {
|
||||
return errors.New("polling for resource provider registration has exceeded the polling duration")
|
||||
}
|
||||
return err
|
||||
|
|
|
@ -16,14 +16,18 @@ package autorest
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/go-autorest/logger"
|
||||
"github.com/Azure/go-autorest/tracing"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -41,15 +45,6 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
// defaultUserAgent builds a string containing the Go version, system archityecture and OS,
|
||||
// and the go-autorest version.
|
||||
defaultUserAgent = fmt.Sprintf("Go/%s (%s-%s) go-autorest/%s",
|
||||
runtime.Version(),
|
||||
runtime.GOARCH,
|
||||
runtime.GOOS,
|
||||
Version(),
|
||||
)
|
||||
|
||||
// StatusCodesForRetry are a defined group of status code for which the client will retry
|
||||
StatusCodesForRetry = []int{
|
||||
http.StatusRequestTimeout, // 408
|
||||
|
@ -153,6 +148,7 @@ type Client struct {
|
|||
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.
|
||||
|
@ -174,14 +170,32 @@ type Client struct {
|
|||
// NewClientWithUserAgent returns an instance of a Client with the UserAgent set to the passed
|
||||
// string.
|
||||
func NewClientWithUserAgent(ua string) Client {
|
||||
return newClient(ua, tls.RenegotiateNever)
|
||||
}
|
||||
|
||||
// ClientOptions contains various Client configuration options.
|
||||
type ClientOptions struct {
|
||||
// UserAgent is an optional user-agent string to append to the default user agent.
|
||||
UserAgent string
|
||||
|
||||
// Renegotiation is an optional setting to control client-side TLS renegotiation.
|
||||
Renegotiation tls.RenegotiationSupport
|
||||
}
|
||||
|
||||
// NewClientWithOptions returns an instance of a Client with the specified values.
|
||||
func NewClientWithOptions(options ClientOptions) Client {
|
||||
return newClient(options.UserAgent, options.Renegotiation)
|
||||
}
|
||||
|
||||
func newClient(ua string, renegotiation tls.RenegotiationSupport) Client {
|
||||
c := Client{
|
||||
PollingDelay: DefaultPollingDelay,
|
||||
PollingDuration: DefaultPollingDuration,
|
||||
RetryAttempts: DefaultRetryAttempts,
|
||||
RetryDuration: DefaultRetryDuration,
|
||||
UserAgent: defaultUserAgent,
|
||||
UserAgent: UserAgent(),
|
||||
}
|
||||
c.Sender = c.sender()
|
||||
c.Sender = c.sender(renegotiation)
|
||||
c.AddToUserAgent(ua)
|
||||
return c
|
||||
}
|
||||
|
@ -216,18 +230,48 @@ func (c Client) Do(r *http.Request) (*http.Response, error) {
|
|||
}
|
||||
return resp, NewErrorWithError(err, "autorest/Client", "Do", nil, "Preparing request failed")
|
||||
}
|
||||
|
||||
resp, err := SendWithSender(c.sender(), r)
|
||||
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(tls.RenegotiateNever), 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 {
|
||||
func (c Client) sender(renengotiation tls.RenegotiationSupport) Sender {
|
||||
if c.Sender == nil {
|
||||
// Use behaviour compatible with DefaultTransport, but require TLS minimum version.
|
||||
var defaultTransport = http.DefaultTransport.(*http.Transport)
|
||||
transport := tracing.Transport
|
||||
// for non-default values of TLS renegotiation create a new tracing transport.
|
||||
// updating tracing.Transport affects all clients which is not what we want.
|
||||
if renengotiation != tls.RenegotiateNever {
|
||||
transport = tracing.NewTransport()
|
||||
}
|
||||
transport.Base = &http.Transport{
|
||||
Proxy: defaultTransport.Proxy,
|
||||
DialContext: defaultTransport.DialContext,
|
||||
MaxIdleConns: defaultTransport.MaxIdleConns,
|
||||
IdleConnTimeout: defaultTransport.IdleConnTimeout,
|
||||
TLSHandshakeTimeout: defaultTransport.TLSHandshakeTimeout,
|
||||
ExpectContinueTimeout: defaultTransport.ExpectContinueTimeout,
|
||||
TLSClientConfig: &tls.Config{
|
||||
MinVersion: tls.VersionTLS12,
|
||||
Renegotiation: renengotiation,
|
||||
},
|
||||
}
|
||||
j, _ := cookiejar.New(nil)
|
||||
return &http.Client{Jar: j}
|
||||
return &http.Client{Jar: j, Transport: transport}
|
||||
}
|
||||
|
||||
return c.Sender
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@ import (
|
|||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/go-autorest/tracing"
|
||||
)
|
||||
|
||||
// Sender is the interface that wraps the Do method to send HTTP requests.
|
||||
|
@ -38,7 +40,7 @@ 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
|
||||
// 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
|
||||
|
@ -68,7 +70,7 @@ func DecorateSender(s Sender, decorators ...SendDecorator) Sender {
|
|||
//
|
||||
// Send will not poll or retry requests.
|
||||
func Send(r *http.Request, decorators ...SendDecorator) (*http.Response, error) {
|
||||
return SendWithSender(&http.Client{}, r, decorators...)
|
||||
return SendWithSender(&http.Client{Transport: tracing.Transport}, r, decorators...)
|
||||
}
|
||||
|
||||
// SendWithSender sends the passed http.Request, through the provided Sender, returning the
|
||||
|
@ -216,8 +218,7 @@ func DoRetryForStatusCodes(attempts int, backoff time.Duration, codes ...int) Se
|
|||
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; {
|
||||
for attempt := 0; attempt < attempts+1; {
|
||||
err = rr.Prepare()
|
||||
if err != nil {
|
||||
return resp, err
|
||||
|
@ -234,7 +235,7 @@ func DoRetryForStatusCodes(attempts int, backoff time.Duration, codes ...int) Se
|
|||
}
|
||||
delayed := DelayWithRetryAfter(resp, r.Context().Done())
|
||||
if !delayed && !DelayForBackoff(backoff, attempt, r.Context().Done()) {
|
||||
return nil, r.Context().Err()
|
||||
return resp, r.Context().Err()
|
||||
}
|
||||
// don't count a 429 against the number of attempts
|
||||
// so that we continue to retry until it succeeds
|
||||
|
|
|
@ -157,7 +157,7 @@ func AsStringSlice(s interface{}) ([]string, error) {
|
|||
}
|
||||
|
||||
// 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
|
||||
// joins list elements using the separator. 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 {
|
||||
|
|
|
@ -398,11 +398,3 @@ func toInt64(v interface{}) (int64, bool) {
|
|||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// NewErrorWithValidationError appends package type and method name in
|
||||
// validation error.
|
||||
//
|
||||
// Deprecated: Please use validation.NewError() instead.
|
||||
func NewErrorWithValidationError(err error, packageType, method string) error {
|
||||
return NewError(packageType, method, err.Error())
|
||||
}
|
||||
|
|
|
@ -14,7 +14,28 @@ package autorest
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
const number = "v12.0.0"
|
||||
|
||||
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 architecture and OS, and the go-autorest version.
|
||||
func UserAgent() string {
|
||||
return userAgent
|
||||
}
|
||||
|
||||
// Version returns the semantic version (see http://semver.org).
|
||||
func Version() string {
|
||||
return "v10.12.0"
|
||||
return number
|
||||
}
|
||||
|
|
|
@ -0,0 +1,328 @@
|
|||
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 response 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.Contains(ct, "application/octet-stream")
|
||||
}
|
||||
|
||||
// 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())
|
||||
}
|
|
@ -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.
|
|
@ -1,8 +0,0 @@
|
|||
module github.com/Azure/go-autorest/tracing
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
contrib.go.opencensus.io/exporter/ocagent v0.4.12
|
||||
go.opencensus.io v0.20.2
|
||||
)
|
|
@ -1,130 +0,0 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
contrib.go.opencensus.io/exporter/ocagent v0.4.12 h1:jGFvw3l57ViIVEPKKEUXPcLYIXJmQxLUh6ey1eJhwyc=
|
||||
contrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.0 h1:LzQXZOgg4CQfE6bFvXGM30YZL1WW/M337pXml+GrcZ4=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.8.5 h1:2+KSC78XiO6Qy0hIjfc1OD9H+hsaJdJlb8Kqsd41CTE=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.20.2 h1:NAfh7zF0/3/HqtMvJNZ/RFrSlCE6ZTlHmKfhL/Dm1Jk=
|
||||
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
google.golang.org/api v0.3.1 h1:oJra/lMfmtm13/rgY/8i3MzjFWYXvQIAKjQ3HqofMk8=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19 h1:Lj2SnHtxkRGJDqnGaSjo+CCdIieEnwVazbOXILwQemk=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.19.1 h1:TrBcJ1yqAl1G++wO39nD/qtgpsW9/1+QGrluyMGEYgM=
|
||||
google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
@ -1,18 +0,0 @@
|
|||
sudo: false
|
||||
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.7
|
||||
- 1.8
|
||||
|
||||
install:
|
||||
- go get -u github.com/golang/lint/golint
|
||||
- go get -u github.com/HewlettPackard/gas
|
||||
|
||||
script:
|
||||
- golint --set_exit_status
|
||||
- go vet
|
||||
- go test -v -cover -race
|
||||
- go test -bench .
|
||||
- gas ./...
|
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2016 Martin Strobel
|
||||
|
||||
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.
|
|
@ -1,27 +0,0 @@
|
|||
[![Build Status](https://travis-ci.org/marstr/guid.svg?branch=master)](https://travis-ci.org/marstr/guid)
|
||||
[![GoDoc](https://godoc.org/github.com/marstr/guid?status.svg)](https://godoc.org/github.com/marstr/guid)
|
||||
[![Go Report Card](https://goreportcard.com/badge/github.com/marstr/guid)](https://goreportcard.com/report/github.com/marstr/guid)
|
||||
|
||||
# Guid
|
||||
Globally unique identifiers offer a quick means of generating non-colliding values across a distributed system. For this implemenation, [RFC 4122](http://ietf.org/rfc/rfc4122.txt) governs the desired behavior.
|
||||
|
||||
## What's in a name?
|
||||
You have likely already noticed that RFC and some implementations refer to these structures as UUIDs (Universally Unique Identifiers), where as this project is annotated as GUIDs (Globally Unique Identifiers). The name Guid was selected to make clear this project's ties to the [.NET struct Guid.](https://msdn.microsoft.com/en-us/library/system.guid(v=vs.110).aspx) The most obvious relationship is the desire to have the same format specifiers available in this library's Format and Parse methods as .NET would have in its ToString and Parse methods.
|
||||
|
||||
# Installation
|
||||
- Ensure you have the [Go Programming Language](https://golang.org/) installed on your system.
|
||||
- Run the command: `go get -u github.com/marstr/guid`
|
||||
|
||||
# Contribution
|
||||
Contributions are welcome! Feel free to send Pull Requests. Continuous Integration will ensure that you have conformed to Go conventions. Please remember to add tests for your changes.
|
||||
|
||||
# Versioning
|
||||
This library will adhere to the
|
||||
[Semantic Versioning 2.0.0](http://semver.org/spec/v2.0.0.html) specification. It may be worth noting this should allow for tools like [glide](https://glide.readthedocs.io/en/latest/) to pull in this library with ease.
|
||||
|
||||
The Release Notes portion of this file will be updated to reflect the most recent major/minor updates, with the option to tag particular bug-fixes as well. Updates to the Release Notes for patches should be addative, where as major/minor updates should replace the previous version. If one desires to see the release notes for an older version, checkout that version of code and open this file.
|
||||
|
||||
# Release Notes 1.1.*
|
||||
|
||||
## v1.1.0
|
||||
Adding support for JSON marshaling and unmarshaling.
|
|
@ -1,301 +0,0 @@
|
|||
package guid
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// GUID is a unique identifier designed to virtually guarantee non-conflict between values generated
|
||||
// across a distributed system.
|
||||
type GUID struct {
|
||||
timeHighAndVersion uint16
|
||||
timeMid uint16
|
||||
timeLow uint32
|
||||
clockSeqHighAndReserved uint8
|
||||
clockSeqLow uint8
|
||||
node [6]byte
|
||||
}
|
||||
|
||||
// Format enumerates the values that are supported by Parse and Format
|
||||
type Format string
|
||||
|
||||
// These constants define the possible string formats available via this implementation of Guid.
|
||||
const (
|
||||
FormatB Format = "B" // {00000000-0000-0000-0000-000000000000}
|
||||
FormatD Format = "D" // 00000000-0000-0000-0000-000000000000
|
||||
FormatN Format = "N" // 00000000000000000000000000000000
|
||||
FormatP Format = "P" // (00000000-0000-0000-0000-000000000000)
|
||||
FormatX Format = "X" // {0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
|
||||
FormatDefault Format = FormatD
|
||||
)
|
||||
|
||||
// CreationStrategy enumerates the values that are supported for populating the bits of a new Guid.
|
||||
type CreationStrategy string
|
||||
|
||||
// These constants define the possible creation strategies available via this implementation of Guid.
|
||||
const (
|
||||
CreationStrategyVersion1 CreationStrategy = "version1"
|
||||
CreationStrategyVersion2 CreationStrategy = "version2"
|
||||
CreationStrategyVersion3 CreationStrategy = "version3"
|
||||
CreationStrategyVersion4 CreationStrategy = "version4"
|
||||
CreationStrategyVersion5 CreationStrategy = "version5"
|
||||
)
|
||||
|
||||
var emptyGUID GUID
|
||||
|
||||
// NewGUID generates and returns a new globally unique identifier
|
||||
func NewGUID() GUID {
|
||||
result, err := version4()
|
||||
if err != nil {
|
||||
panic(err) //Version 4 (pseudo-random GUID) doesn't use anything that could fail.
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
var knownStrategies = map[CreationStrategy]func() (GUID, error){
|
||||
CreationStrategyVersion1: version1,
|
||||
CreationStrategyVersion4: version4,
|
||||
}
|
||||
|
||||
// NewGUIDs generates and returns a new globally unique identifier that conforms to the given strategy.
|
||||
func NewGUIDs(strategy CreationStrategy) (GUID, error) {
|
||||
if creator, present := knownStrategies[strategy]; present {
|
||||
result, err := creator()
|
||||
return result, err
|
||||
}
|
||||
return emptyGUID, errors.New("Unsupported CreationStrategy")
|
||||
}
|
||||
|
||||
// Empty returns a copy of the default and empty GUID.
|
||||
func Empty() GUID {
|
||||
return emptyGUID
|
||||
}
|
||||
|
||||
var knownFormats = map[Format]string{
|
||||
FormatN: "%08x%04x%04x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||
FormatD: "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
FormatB: "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
|
||||
FormatP: "(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
|
||||
FormatX: "{0x%08x,0x%04x,0x%04x,{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x}}",
|
||||
}
|
||||
|
||||
// MarshalJSON writes a GUID as a JSON string.
|
||||
func (guid GUID) MarshalJSON() (marshaled []byte, err error) {
|
||||
buf := bytes.Buffer{}
|
||||
|
||||
_, err = buf.WriteRune('"')
|
||||
buf.WriteString(guid.String())
|
||||
buf.WriteRune('"')
|
||||
|
||||
marshaled = buf.Bytes()
|
||||
return
|
||||
}
|
||||
|
||||
// Parse instantiates a GUID from a text representation of the same GUID.
|
||||
// This is the inverse of function family String()
|
||||
func Parse(value string) (GUID, error) {
|
||||
var guid GUID
|
||||
for _, fullFormat := range knownFormats {
|
||||
parity, err := fmt.Sscanf(
|
||||
value,
|
||||
fullFormat,
|
||||
&guid.timeLow,
|
||||
&guid.timeMid,
|
||||
&guid.timeHighAndVersion,
|
||||
&guid.clockSeqHighAndReserved,
|
||||
&guid.clockSeqLow,
|
||||
&guid.node[0],
|
||||
&guid.node[1],
|
||||
&guid.node[2],
|
||||
&guid.node[3],
|
||||
&guid.node[4],
|
||||
&guid.node[5])
|
||||
if parity == 11 && err == nil {
|
||||
return guid, err
|
||||
}
|
||||
}
|
||||
return emptyGUID, fmt.Errorf("\"%s\" is not in a recognized format", value)
|
||||
}
|
||||
|
||||
// String returns a text representation of a GUID in the default format.
|
||||
func (guid GUID) String() string {
|
||||
return guid.Stringf(FormatDefault)
|
||||
}
|
||||
|
||||
// Stringf returns a text representation of a GUID that conforms to the specified format.
|
||||
// If an unrecognized format is provided, the empty string is returned.
|
||||
func (guid GUID) Stringf(format Format) string {
|
||||
if format == "" {
|
||||
format = FormatDefault
|
||||
}
|
||||
fullFormat, present := knownFormats[format]
|
||||
if !present {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf(
|
||||
fullFormat,
|
||||
guid.timeLow,
|
||||
guid.timeMid,
|
||||
guid.timeHighAndVersion,
|
||||
guid.clockSeqHighAndReserved,
|
||||
guid.clockSeqLow,
|
||||
guid.node[0],
|
||||
guid.node[1],
|
||||
guid.node[2],
|
||||
guid.node[3],
|
||||
guid.node[4],
|
||||
guid.node[5])
|
||||
}
|
||||
|
||||
// UnmarshalJSON parses a GUID from a JSON string token.
|
||||
func (guid *GUID) UnmarshalJSON(marshaled []byte) (err error) {
|
||||
if len(marshaled) < 2 {
|
||||
err = errors.New("JSON GUID must be surrounded by quotes")
|
||||
return
|
||||
}
|
||||
stripped := marshaled[1 : len(marshaled)-1]
|
||||
*guid, err = Parse(string(stripped))
|
||||
return
|
||||
}
|
||||
|
||||
// Version reads a GUID to parse which mechanism of generating GUIDS was employed.
|
||||
// Values returned here are documented in rfc4122.txt.
|
||||
func (guid GUID) Version() uint {
|
||||
return uint(guid.timeHighAndVersion >> 12)
|
||||
}
|
||||
|
||||
var unixToGregorianOffset = time.Date(1970, 01, 01, 0, 0, 00, 0, time.UTC).Sub(time.Date(1582, 10, 15, 0, 0, 0, 0, time.UTC))
|
||||
|
||||
// getRFC4122Time returns a 60-bit count of 100-nanosecond intervals since 00:00:00.00 October 15th, 1582
|
||||
func getRFC4122Time() int64 {
|
||||
currentTime := time.Now().UTC().Add(unixToGregorianOffset).UnixNano()
|
||||
currentTime /= 100
|
||||
return currentTime & 0x0FFFFFFFFFFFFFFF
|
||||
}
|
||||
|
||||
var clockSeqVal uint16
|
||||
var clockSeqKey sync.Mutex
|
||||
|
||||
func getClockSequence() (uint16, error) {
|
||||
clockSeqKey.Lock()
|
||||
defer clockSeqKey.Unlock()
|
||||
|
||||
if 0 == clockSeqVal {
|
||||
var temp [2]byte
|
||||
if parity, err := rand.Read(temp[:]); !(2 == parity && nil == err) {
|
||||
return 0, err
|
||||
}
|
||||
clockSeqVal = uint16(temp[0])<<8 | uint16(temp[1])
|
||||
}
|
||||
clockSeqVal++
|
||||
return clockSeqVal, nil
|
||||
}
|
||||
|
||||
func getMACAddress() (mac [6]byte, err error) {
|
||||
var hostNICs []net.Interface
|
||||
|
||||
hostNICs, err = net.Interfaces()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, nic := range hostNICs {
|
||||
var parity int
|
||||
|
||||
parity, err = fmt.Sscanf(
|
||||
strings.ToLower(nic.HardwareAddr.String()),
|
||||
"%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
&mac[0],
|
||||
&mac[1],
|
||||
&mac[2],
|
||||
&mac[3],
|
||||
&mac[4],
|
||||
&mac[5])
|
||||
|
||||
if parity == len(mac) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
err = fmt.Errorf("No suitable address found")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func version1() (result GUID, err error) {
|
||||
var localMAC [6]byte
|
||||
var clockSeq uint16
|
||||
|
||||
currentTime := getRFC4122Time()
|
||||
|
||||
result.timeLow = uint32(currentTime)
|
||||
result.timeMid = uint16(currentTime >> 32)
|
||||
result.timeHighAndVersion = uint16(currentTime >> 48)
|
||||
if err = result.setVersion(1); err != nil {
|
||||
return emptyGUID, err
|
||||
}
|
||||
|
||||
if localMAC, err = getMACAddress(); nil != err {
|
||||
if parity, err := rand.Read(localMAC[:]); !(len(localMAC) != parity && err == nil) {
|
||||
return emptyGUID, err
|
||||
}
|
||||
localMAC[0] |= 0x1
|
||||
}
|
||||
copy(result.node[:], localMAC[:])
|
||||
|
||||
if clockSeq, err = getClockSequence(); nil != err {
|
||||
return emptyGUID, err
|
||||
}
|
||||
|
||||
result.clockSeqLow = uint8(clockSeq)
|
||||
result.clockSeqHighAndReserved = uint8(clockSeq >> 8)
|
||||
|
||||
result.setReservedBits()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func version4() (GUID, error) {
|
||||
var retval GUID
|
||||
var bits [10]byte
|
||||
|
||||
if parity, err := rand.Read(bits[:]); !(len(bits) == parity && err == nil) {
|
||||
return emptyGUID, err
|
||||
}
|
||||
retval.timeHighAndVersion |= uint16(bits[0]) | uint16(bits[1])<<8
|
||||
retval.timeMid |= uint16(bits[2]) | uint16(bits[3])<<8
|
||||
retval.timeLow |= uint32(bits[4]) | uint32(bits[5])<<8 | uint32(bits[6])<<16 | uint32(bits[7])<<24
|
||||
retval.clockSeqHighAndReserved = uint8(bits[8])
|
||||
retval.clockSeqLow = uint8(bits[9])
|
||||
|
||||
//Randomly set clock-sequence, reserved, and node
|
||||
if written, err := rand.Read(retval.node[:]); !(nil == err && written == len(retval.node)) {
|
||||
retval = emptyGUID
|
||||
return retval, err
|
||||
}
|
||||
|
||||
if err := retval.setVersion(4); nil != err {
|
||||
return emptyGUID, err
|
||||
}
|
||||
retval.setReservedBits()
|
||||
|
||||
return retval, nil
|
||||
}
|
||||
|
||||
func (guid *GUID) setVersion(version uint16) error {
|
||||
if version > 5 || version == 0 {
|
||||
return fmt.Errorf("While setting GUID version, unsupported version: %d", version)
|
||||
}
|
||||
guid.timeHighAndVersion = (guid.timeHighAndVersion & 0x0fff) | version<<12
|
||||
return nil
|
||||
}
|
||||
|
||||
func (guid *GUID) setReservedBits() {
|
||||
guid.clockSeqHighAndReserved = (guid.clockSeqHighAndReserved & 0x3f) | 0x80
|
||||
}
|
|
@ -15,6 +15,7 @@ EMBEDMD=embedmd
|
|||
# TODO decide if we need to change these names.
|
||||
TRACE_ID_LINT_EXCEPTION="type name will be used as trace.TraceID by other packages"
|
||||
TRACE_OPTION_LINT_EXCEPTION="type name will be used as trace.TraceOptions by other packages"
|
||||
README_FILES := $(shell find . -name '*README.md' | sort | tr '\n' ' ')
|
||||
|
||||
.DEFAULT_GOAL := fmt-lint-vet-embedmd-test
|
||||
|
||||
|
@ -79,7 +80,7 @@ vet:
|
|||
|
||||
.PHONY: embedmd
|
||||
embedmd:
|
||||
@EMBEDMDOUT=`$(EMBEDMD) -d README.md 2>&1`; \
|
||||
@EMBEDMDOUT=`$(EMBEDMD) -d $(README_FILES) 2>&1`; \
|
||||
if [ "$$EMBEDMDOUT" ]; then \
|
||||
echo "$(EMBEDMD) FAILED => embedmd the following files:\n"; \
|
||||
echo "$$EMBEDMDOUT\n"; \
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
module go.opencensus.io
|
||||
|
||||
require (
|
||||
github.com/apache/thrift v0.12.0
|
||||
github.com/golang/protobuf v1.2.0
|
||||
github.com/google/go-cmp v0.2.0
|
||||
github.com/hashicorp/golang-lru v0.5.0
|
||||
github.com/openzipkin/zipkin-go v0.1.6
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a
|
||||
google.golang.org/api v0.3.1
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19 // indirect
|
||||
google.golang.org/grpc v1.19.0
|
||||
)
|
||||
|
|
|
@ -1,127 +1,50 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/apache/thrift v0.12.0 h1:pODnxUFNcjP9UTLZGTdeh+j16A8lJbRvD3rOtrk/7bs=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
|
||||
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/openzipkin/zipkin-go v0.1.6 h1:yXiysv1CSK7Q5yjGy1710zZGnsbMUIjluWBxtLXHPBo=
|
||||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829 h1:D+CiwcpGTW6pL6bv6KI3KbyEyCKyS+1JWS2h8PNDnGA=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f h1:BVwpUVJDADN2ufcGik7W992pyps0wZ888b/y9GXcLTU=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/common v0.2.0 h1:kUZDBDTdBVBYBj5Tmh2NZLlF60mfjA27rM34b+cVwNU=
|
||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1 h1:/K3IL0Z1quvmJ7X0A1AwNEK7CRkVK3YwfOU/QAL4WGg=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3 h1:ulvT7fqt0yHWzpJwI57MezWnYDVpCAYBVuYst/L+fAY=
|
||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
google.golang.org/api v0.3.1 h1:oJra/lMfmtm13/rgY/8i3MzjFWYXvQIAKjQ3HqofMk8=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19 h1:Lj2SnHtxkRGJDqnGaSjo+CCdIieEnwVazbOXILwQemk=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8=
|
||||
google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
|
|
@ -18,6 +18,11 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// Exemplars keys.
|
||||
const (
|
||||
AttachmentKeySpanContext = "SpanContext"
|
||||
)
|
||||
|
||||
// Exemplar is an example data point associated with each bucket of a
|
||||
// distribution type aggregation.
|
||||
//
|
||||
|
|
|
@ -14,6 +14,13 @@
|
|||
|
||||
package metricdata
|
||||
|
||||
// LabelKey represents key of a label. It has optional
|
||||
// description attribute.
|
||||
type LabelKey struct {
|
||||
Key string
|
||||
Description string
|
||||
}
|
||||
|
||||
// LabelValue represents the value of a label.
|
||||
// The zero value represents a missing label value, which may be treated
|
||||
// differently to an empty string value by some back ends.
|
||||
|
|
|
@ -22,11 +22,11 @@ import (
|
|||
|
||||
// Descriptor holds metadata about a metric.
|
||||
type Descriptor struct {
|
||||
Name string // full name of the metric
|
||||
Description string // human-readable description
|
||||
Unit Unit // units for the measure
|
||||
Type Type // type of measure
|
||||
LabelKeys []string // label keys
|
||||
Name string // full name of the metric
|
||||
Description string // human-readable description
|
||||
Unit Unit // units for the measure
|
||||
Type Type // type of measure
|
||||
LabelKeys []LabelKey // label keys
|
||||
}
|
||||
|
||||
// Metric represents a quantity measured against a resource with different
|
||||
|
|
|
@ -22,9 +22,11 @@ import (
|
|||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"go.opencensus.io/metric/metricdata"
|
||||
ocstats "go.opencensus.io/stats"
|
||||
"go.opencensus.io/stats/view"
|
||||
"go.opencensus.io/tag"
|
||||
"go.opencensus.io/trace"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
"google.golang.org/grpc/stats"
|
||||
|
@ -141,27 +143,31 @@ func handleRPCEnd(ctx context.Context, s *stats.End) {
|
|||
}
|
||||
|
||||
latencyMillis := float64(elapsedTime) / float64(time.Millisecond)
|
||||
attachments := getSpanCtxAttachment(ctx)
|
||||
if s.Client {
|
||||
ocstats.RecordWithTags(ctx,
|
||||
[]tag.Mutator{
|
||||
ocstats.RecordWithOptions(ctx,
|
||||
ocstats.WithTags(
|
||||
tag.Upsert(KeyClientMethod, methodName(d.method)),
|
||||
tag.Upsert(KeyClientStatus, st),
|
||||
},
|
||||
ClientSentBytesPerRPC.M(atomic.LoadInt64(&d.sentBytes)),
|
||||
ClientSentMessagesPerRPC.M(atomic.LoadInt64(&d.sentCount)),
|
||||
ClientReceivedMessagesPerRPC.M(atomic.LoadInt64(&d.recvCount)),
|
||||
ClientReceivedBytesPerRPC.M(atomic.LoadInt64(&d.recvBytes)),
|
||||
ClientRoundtripLatency.M(latencyMillis))
|
||||
tag.Upsert(KeyClientStatus, st)),
|
||||
ocstats.WithAttachments(attachments),
|
||||
ocstats.WithMeasurements(
|
||||
ClientSentBytesPerRPC.M(atomic.LoadInt64(&d.sentBytes)),
|
||||
ClientSentMessagesPerRPC.M(atomic.LoadInt64(&d.sentCount)),
|
||||
ClientReceivedMessagesPerRPC.M(atomic.LoadInt64(&d.recvCount)),
|
||||
ClientReceivedBytesPerRPC.M(atomic.LoadInt64(&d.recvBytes)),
|
||||
ClientRoundtripLatency.M(latencyMillis)))
|
||||
} else {
|
||||
ocstats.RecordWithTags(ctx,
|
||||
[]tag.Mutator{
|
||||
ocstats.RecordWithOptions(ctx,
|
||||
ocstats.WithTags(
|
||||
tag.Upsert(KeyServerStatus, st),
|
||||
},
|
||||
ServerSentBytesPerRPC.M(atomic.LoadInt64(&d.sentBytes)),
|
||||
ServerSentMessagesPerRPC.M(atomic.LoadInt64(&d.sentCount)),
|
||||
ServerReceivedMessagesPerRPC.M(atomic.LoadInt64(&d.recvCount)),
|
||||
ServerReceivedBytesPerRPC.M(atomic.LoadInt64(&d.recvBytes)),
|
||||
ServerLatency.M(latencyMillis))
|
||||
),
|
||||
ocstats.WithAttachments(attachments),
|
||||
ocstats.WithMeasurements(
|
||||
ServerSentBytesPerRPC.M(atomic.LoadInt64(&d.sentBytes)),
|
||||
ServerSentMessagesPerRPC.M(atomic.LoadInt64(&d.sentCount)),
|
||||
ServerReceivedMessagesPerRPC.M(atomic.LoadInt64(&d.recvCount)),
|
||||
ServerReceivedBytesPerRPC.M(atomic.LoadInt64(&d.recvBytes)),
|
||||
ServerLatency.M(latencyMillis)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -206,3 +212,16 @@ func statusCodeToString(s *status.Status) string {
|
|||
return "CODE_" + strconv.FormatInt(int64(c), 10)
|
||||
}
|
||||
}
|
||||
|
||||
func getSpanCtxAttachment(ctx context.Context) metricdata.Attachments {
|
||||
attachments := map[string]interface{}{}
|
||||
span := trace.FromContext(ctx)
|
||||
if span == nil {
|
||||
return attachments
|
||||
}
|
||||
spanCtx := span.SpanContext()
|
||||
if spanCtx.IsSampled() {
|
||||
attachments[metricdata.AttachmentKeySpanContext] = spanCtx
|
||||
}
|
||||
return attachments
|
||||
}
|
||||
|
|
|
@ -124,6 +124,12 @@ func (h *Handler) startTrace(w http.ResponseWriter, r *http.Request) (*http.Requ
|
|||
}
|
||||
}
|
||||
span.AddAttributes(requestAttrs(r)...)
|
||||
if r.Body == nil {
|
||||
// TODO: Handle cases where ContentLength is not set.
|
||||
} else if r.ContentLength > 0 {
|
||||
span.AddMessageReceiveEvent(0, /* TODO: messageID */
|
||||
int64(r.ContentLength), -1)
|
||||
}
|
||||
return r.WithContext(ctx), span.End
|
||||
}
|
||||
|
||||
|
@ -201,6 +207,9 @@ func (t *trackingResponseWriter) Header() http.Header {
|
|||
func (t *trackingResponseWriter) Write(data []byte) (int, error) {
|
||||
n, err := t.writer.Write(data)
|
||||
t.respSize += int64(n)
|
||||
// Add message event for request bytes sent.
|
||||
span := trace.FromContext(t.ctx)
|
||||
span.AddMessageSendEvent(0 /* TODO: messageID */, int64(n), -1)
|
||||
return n, err
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ package stats
|
|||
import (
|
||||
"context"
|
||||
|
||||
"go.opencensus.io/metric/metricdata"
|
||||
"go.opencensus.io/stats/internal"
|
||||
"go.opencensus.io/tag"
|
||||
)
|
||||
|
@ -30,28 +31,48 @@ func init() {
|
|||
}
|
||||
}
|
||||
|
||||
type recordOptions struct {
|
||||
attachments metricdata.Attachments
|
||||
mutators []tag.Mutator
|
||||
measurements []Measurement
|
||||
}
|
||||
|
||||
// WithAttachments applies provided exemplar attachments.
|
||||
func WithAttachments(attachments metricdata.Attachments) Options {
|
||||
return func(ro *recordOptions) {
|
||||
ro.attachments = attachments
|
||||
}
|
||||
}
|
||||
|
||||
// WithTags applies provided tag mutators.
|
||||
func WithTags(mutators ...tag.Mutator) Options {
|
||||
return func(ro *recordOptions) {
|
||||
ro.mutators = mutators
|
||||
}
|
||||
}
|
||||
|
||||
// WithMeasurements applies provided measurements.
|
||||
func WithMeasurements(measurements ...Measurement) Options {
|
||||
return func(ro *recordOptions) {
|
||||
ro.measurements = measurements
|
||||
}
|
||||
}
|
||||
|
||||
// Options apply changes to recordOptions.
|
||||
type Options func(*recordOptions)
|
||||
|
||||
func createRecordOption(ros ...Options) *recordOptions {
|
||||
o := &recordOptions{}
|
||||
for _, ro := range ros {
|
||||
ro(o)
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// Record records one or multiple measurements with the same context at once.
|
||||
// If there are any tags in the context, measurements will be tagged with them.
|
||||
func Record(ctx context.Context, ms ...Measurement) {
|
||||
recorder := internal.DefaultRecorder
|
||||
if recorder == nil {
|
||||
return
|
||||
}
|
||||
if len(ms) == 0 {
|
||||
return
|
||||
}
|
||||
record := false
|
||||
for _, m := range ms {
|
||||
if m.desc.subscribed() {
|
||||
record = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !record {
|
||||
return
|
||||
}
|
||||
// TODO(songy23): fix attachments.
|
||||
recorder(tag.FromContext(ctx), ms, map[string]interface{}{})
|
||||
RecordWithOptions(ctx, WithMeasurements(ms...))
|
||||
}
|
||||
|
||||
// RecordWithTags records one or multiple measurements at once.
|
||||
|
@ -60,10 +81,37 @@ func Record(ctx context.Context, ms ...Measurement) {
|
|||
// RecordWithTags is useful if you want to record with tag mutations but don't want
|
||||
// to propagate the mutations in the context.
|
||||
func RecordWithTags(ctx context.Context, mutators []tag.Mutator, ms ...Measurement) error {
|
||||
ctx, err := tag.New(ctx, mutators...)
|
||||
if err != nil {
|
||||
return err
|
||||
return RecordWithOptions(ctx, WithTags(mutators...), WithMeasurements(ms...))
|
||||
}
|
||||
|
||||
// RecordWithOptions records measurements from the given options (if any) against context
|
||||
// and tags and attachments in the options (if any).
|
||||
// If there are any tags in the context, measurements will be tagged with them.
|
||||
func RecordWithOptions(ctx context.Context, ros ...Options) error {
|
||||
o := createRecordOption(ros...)
|
||||
if len(o.measurements) == 0 {
|
||||
return nil
|
||||
}
|
||||
Record(ctx, ms...)
|
||||
recorder := internal.DefaultRecorder
|
||||
if recorder == nil {
|
||||
return nil
|
||||
}
|
||||
record := false
|
||||
for _, m := range o.measurements {
|
||||
if m.desc.subscribed() {
|
||||
record = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !record {
|
||||
return nil
|
||||
}
|
||||
if len(o.mutators) > 0 {
|
||||
var err error
|
||||
if ctx, err = tag.New(ctx, o.mutators...); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
recorder(tag.FromContext(ctx), o.measurements, o.attachments)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -73,10 +73,10 @@ func getType(v *View) metricdata.Type {
|
|||
}
|
||||
}
|
||||
|
||||
func getLableKeys(v *View) []string {
|
||||
labelKeys := []string{}
|
||||
func getLableKeys(v *View) []metricdata.LabelKey {
|
||||
labelKeys := []metricdata.LabelKey{}
|
||||
for _, k := range v.TagKeys {
|
||||
labelKeys = append(labelKeys, k.Name())
|
||||
labelKeys = append(labelKeys, metricdata.LabelKey{Key: k.Name()})
|
||||
}
|
||||
return labelKeys
|
||||
}
|
||||
|
@ -91,10 +91,19 @@ func viewToMetricDescriptor(v *View) *metricdata.Descriptor {
|
|||
}
|
||||
}
|
||||
|
||||
func toLabelValues(row *Row) []metricdata.LabelValue {
|
||||
func toLabelValues(row *Row, expectedKeys []metricdata.LabelKey) []metricdata.LabelValue {
|
||||
labelValues := []metricdata.LabelValue{}
|
||||
tagMap := make(map[string]string)
|
||||
for _, tag := range row.Tags {
|
||||
labelValues = append(labelValues, metricdata.NewLabelValue(tag.Value))
|
||||
tagMap[tag.Key.Name()] = tag.Value
|
||||
}
|
||||
|
||||
for _, key := range expectedKeys {
|
||||
if val, ok := tagMap[key.Key]; ok {
|
||||
labelValues = append(labelValues, metricdata.NewLabelValue(val))
|
||||
} else {
|
||||
labelValues = append(labelValues, metricdata.LabelValue{})
|
||||
}
|
||||
}
|
||||
return labelValues
|
||||
}
|
||||
|
@ -102,7 +111,7 @@ func toLabelValues(row *Row) []metricdata.LabelValue {
|
|||
func rowToTimeseries(v *viewInternal, row *Row, now time.Time, startTime time.Time) *metricdata.TimeSeries {
|
||||
return &metricdata.TimeSeries{
|
||||
Points: []metricdata.Point{row.Data.toPoint(v.metricDescriptor.Type, now)},
|
||||
LabelValues: toLabelValues(row),
|
||||
LabelValues: toLabelValues(row, v.metricDescriptor.LabelKeys),
|
||||
StartTime: startTime,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -236,6 +236,8 @@ func (w *worker) reportView(v *viewInternal, now time.Time) {
|
|||
}
|
||||
|
||||
func (w *worker) reportUsage(now time.Time) {
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
for _, v := range w.views {
|
||||
w.reportView(v, now)
|
||||
}
|
||||
|
|
|
@ -121,6 +121,8 @@ type retrieveDataResp struct {
|
|||
}
|
||||
|
||||
func (cmd *retrieveDataReq) handleCommand(w *worker) {
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
vi, ok := w.views[cmd.v]
|
||||
if !ok {
|
||||
cmd.c <- &retrieveDataResp{
|
||||
|
@ -153,6 +155,8 @@ type recordReq struct {
|
|||
}
|
||||
|
||||
func (cmd *recordReq) handleCommand(w *worker) {
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
for _, m := range cmd.ms {
|
||||
if (m == stats.Measurement{}) { // not registered
|
||||
continue
|
||||
|
|
|
@ -28,10 +28,15 @@ type Tag struct {
|
|||
Value string
|
||||
}
|
||||
|
||||
type tagContent struct {
|
||||
value string
|
||||
m metadatas
|
||||
}
|
||||
|
||||
// Map is a map of tags. Use New to create a context containing
|
||||
// a new Map.
|
||||
type Map struct {
|
||||
m map[Key]string
|
||||
m map[Key]tagContent
|
||||
}
|
||||
|
||||
// Value returns the value for the key if a value for the key exists.
|
||||
|
@ -40,7 +45,7 @@ func (m *Map) Value(k Key) (string, bool) {
|
|||
return "", false
|
||||
}
|
||||
v, ok := m.m[k]
|
||||
return v, ok
|
||||
return v.value, ok
|
||||
}
|
||||
|
||||
func (m *Map) String() string {
|
||||
|
@ -62,21 +67,21 @@ func (m *Map) String() string {
|
|||
return buffer.String()
|
||||
}
|
||||
|
||||
func (m *Map) insert(k Key, v string) {
|
||||
func (m *Map) insert(k Key, v string, md metadatas) {
|
||||
if _, ok := m.m[k]; ok {
|
||||
return
|
||||
}
|
||||
m.m[k] = v
|
||||
m.m[k] = tagContent{value: v, m: md}
|
||||
}
|
||||
|
||||
func (m *Map) update(k Key, v string) {
|
||||
func (m *Map) update(k Key, v string, md metadatas) {
|
||||
if _, ok := m.m[k]; ok {
|
||||
m.m[k] = v
|
||||
m.m[k] = tagContent{value: v, m: md}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Map) upsert(k Key, v string) {
|
||||
m.m[k] = v
|
||||
func (m *Map) upsert(k Key, v string, md metadatas) {
|
||||
m.m[k] = tagContent{value: v, m: md}
|
||||
}
|
||||
|
||||
func (m *Map) delete(k Key) {
|
||||
|
@ -84,7 +89,7 @@ func (m *Map) delete(k Key) {
|
|||
}
|
||||
|
||||
func newMap() *Map {
|
||||
return &Map{m: make(map[Key]string)}
|
||||
return &Map{m: make(map[Key]tagContent)}
|
||||
}
|
||||
|
||||
// Mutator modifies a tag map.
|
||||
|
@ -95,13 +100,17 @@ type Mutator interface {
|
|||
// Insert returns a mutator that inserts a
|
||||
// value associated with k. If k already exists in the tag map,
|
||||
// mutator doesn't update the value.
|
||||
func Insert(k Key, v string) Mutator {
|
||||
// Metadata applies metadata to the tag. It is optional.
|
||||
// Metadatas are applied in the order in which it is provided.
|
||||
// If more than one metadata updates the same attribute then
|
||||
// the update from the last metadata prevails.
|
||||
func Insert(k Key, v string, mds ...Metadata) Mutator {
|
||||
return &mutator{
|
||||
fn: func(m *Map) (*Map, error) {
|
||||
if !checkValue(v) {
|
||||
return nil, errInvalidValue
|
||||
}
|
||||
m.insert(k, v)
|
||||
m.insert(k, v, createMetadatas(mds...))
|
||||
return m, nil
|
||||
},
|
||||
}
|
||||
|
@ -110,13 +119,17 @@ func Insert(k Key, v string) Mutator {
|
|||
// Update returns a mutator that updates the
|
||||
// value of the tag associated with k with v. If k doesn't
|
||||
// exists in the tag map, the mutator doesn't insert the value.
|
||||
func Update(k Key, v string) Mutator {
|
||||
// Metadata applies metadata to the tag. It is optional.
|
||||
// Metadatas are applied in the order in which it is provided.
|
||||
// If more than one metadata updates the same attribute then
|
||||
// the update from the last metadata prevails.
|
||||
func Update(k Key, v string, mds ...Metadata) Mutator {
|
||||
return &mutator{
|
||||
fn: func(m *Map) (*Map, error) {
|
||||
if !checkValue(v) {
|
||||
return nil, errInvalidValue
|
||||
}
|
||||
m.update(k, v)
|
||||
m.update(k, v, createMetadatas(mds...))
|
||||
return m, nil
|
||||
},
|
||||
}
|
||||
|
@ -126,18 +139,37 @@ func Update(k Key, v string) Mutator {
|
|||
// value of the tag associated with k with v. It inserts the
|
||||
// value if k doesn't exist already. It mutates the value
|
||||
// if k already exists.
|
||||
func Upsert(k Key, v string) Mutator {
|
||||
// Metadata applies metadata to the tag. It is optional.
|
||||
// Metadatas are applied in the order in which it is provided.
|
||||
// If more than one metadata updates the same attribute then
|
||||
// the update from the last metadata prevails.
|
||||
func Upsert(k Key, v string, mds ...Metadata) Mutator {
|
||||
return &mutator{
|
||||
fn: func(m *Map) (*Map, error) {
|
||||
if !checkValue(v) {
|
||||
return nil, errInvalidValue
|
||||
}
|
||||
m.upsert(k, v)
|
||||
m.upsert(k, v, createMetadatas(mds...))
|
||||
return m, nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func createMetadatas(mds ...Metadata) metadatas {
|
||||
var metas metadatas
|
||||
if len(mds) > 0 {
|
||||
for _, md := range mds {
|
||||
if md != nil {
|
||||
md(&metas)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
WithTTL(TTLUnlimitedPropagation)(&metas)
|
||||
}
|
||||
return metas
|
||||
|
||||
}
|
||||
|
||||
// Delete returns a mutator that deletes
|
||||
// the value associated with k.
|
||||
func Delete(k Key) Mutator {
|
||||
|
@ -160,10 +192,10 @@ func New(ctx context.Context, mutator ...Mutator) (context.Context, error) {
|
|||
if !checkKeyName(k.Name()) {
|
||||
return ctx, fmt.Errorf("key:%q: %v", k, errInvalidKeyName)
|
||||
}
|
||||
if !checkValue(v) {
|
||||
if !checkValue(v.value) {
|
||||
return ctx, fmt.Errorf("key:%q value:%q: %v", k.Name(), v, errInvalidValue)
|
||||
}
|
||||
m.insert(k, v)
|
||||
m.insert(k, v.value, v.m)
|
||||
}
|
||||
}
|
||||
var err error
|
||||
|
|
|
@ -170,9 +170,11 @@ func Encode(m *Map) []byte {
|
|||
}
|
||||
eg.writeByte(byte(tagsVersionID))
|
||||
for k, v := range m.m {
|
||||
eg.writeByte(byte(keyTypeString))
|
||||
eg.writeStringWithVarintLen(k.name)
|
||||
eg.writeBytesWithVarintLen([]byte(v))
|
||||
if v.m.ttl.ttl == valueTTLUnlimitedPropagation {
|
||||
eg.writeByte(byte(keyTypeString))
|
||||
eg.writeStringWithVarintLen(k.name)
|
||||
eg.writeBytesWithVarintLen([]byte(v.value))
|
||||
}
|
||||
}
|
||||
return eg.bytes()
|
||||
}
|
||||
|
@ -190,7 +192,7 @@ func Decode(bytes []byte) (*Map, error) {
|
|||
|
||||
// DecodeEach decodes the given serialized tag map, calling handler for each
|
||||
// tag key and value decoded.
|
||||
func DecodeEach(bytes []byte, fn func(key Key, val string)) error {
|
||||
func DecodeEach(bytes []byte, fn func(key Key, val string, md metadatas)) error {
|
||||
eg := &encoderGRPC{
|
||||
buf: bytes,
|
||||
}
|
||||
|
@ -228,7 +230,7 @@ func DecodeEach(bytes []byte, fn func(key Key, val string)) error {
|
|||
if !checkValue(val) {
|
||||
return errInvalidValue
|
||||
}
|
||||
fn(key, val)
|
||||
fn(key, val, createMetadatas(WithTTL(TTLUnlimitedPropagation)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
// Copyright 2019, OpenCensus Authors
|
||||
//
|
||||
// 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 tag
|
||||
|
||||
const (
|
||||
// valueTTLNoPropagation prevents tag from propagating.
|
||||
valueTTLNoPropagation = 0
|
||||
|
||||
// valueTTLUnlimitedPropagation allows tag to propagate without any limits on number of hops.
|
||||
valueTTLUnlimitedPropagation = -1
|
||||
)
|
||||
|
||||
// TTL is metadata that specifies number of hops a tag can propagate.
|
||||
// Details about TTL metadata is specified at https://github.com/census-instrumentation/opencensus-specs/blob/master/tags/TagMap.md#tagmetadata
|
||||
type TTL struct {
|
||||
ttl int
|
||||
}
|
||||
|
||||
var (
|
||||
// TTLUnlimitedPropagation is TTL metadata that allows tag to propagate without any limits on number of hops.
|
||||
TTLUnlimitedPropagation = TTL{ttl: valueTTLUnlimitedPropagation}
|
||||
|
||||
// TTLNoPropagation is TTL metadata that prevents tag from propagating.
|
||||
TTLNoPropagation = TTL{ttl: valueTTLNoPropagation}
|
||||
)
|
||||
|
||||
type metadatas struct {
|
||||
ttl TTL
|
||||
}
|
||||
|
||||
// Metadata applies metadatas specified by the function.
|
||||
type Metadata func(*metadatas)
|
||||
|
||||
// WithTTL applies metadata with provided ttl.
|
||||
func WithTTL(ttl TTL) Metadata {
|
||||
return func(m *metadatas) {
|
||||
m.ttl = ttl
|
||||
}
|
||||
}
|
|
@ -25,7 +25,7 @@ func do(ctx context.Context, f func(ctx context.Context)) {
|
|||
m := FromContext(ctx)
|
||||
keyvals := make([]string, 0, 2*len(m.m))
|
||||
for k, v := range m.m {
|
||||
keyvals = append(keyvals, k.Name(), v)
|
||||
keyvals = append(keyvals, k.Name(), v.value)
|
||||
}
|
||||
pprof.Do(ctx, pprof.Labels(keyvals...), f)
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
"description": "Creates and runs virtual machines on Google Cloud Platform.",
|
||||
"discoveryVersion": "v1",
|
||||
"documentationLink": "https://developers.google.com/compute/docs/reference/latest/",
|
||||
"etag": "\"VPK3KBfpaEgZ16pozGOoMYfKc0U/tWhhqPM3LuAtFmJlbBMA8m8TfaA\"",
|
||||
"etag": "\"VPK3KBfpaEgZ16pozGOoMYfKc0U/L7OHwc6Gh2BR8n3__eQkZu5iQsE\"",
|
||||
"icons": {
|
||||
"x16": "https://www.google.com/images/icons/product/compute_engine-16.png",
|
||||
"x32": "https://www.google.com/images/icons/product/compute_engine-32.png"
|
||||
|
@ -18314,7 +18314,7 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"revision": "20190320",
|
||||
"revision": "20190403",
|
||||
"rootUrl": "https://www.googleapis.com/",
|
||||
"schemas": {
|
||||
"AcceleratorConfig": {
|
||||
|
@ -20758,7 +20758,7 @@
|
|||
"properties": {
|
||||
"condition": {
|
||||
"$ref": "Expr",
|
||||
"description": "The condition that is associated with this binding. NOTE: an unsatisfied condition will not allow user access via current binding. Different bindings, including their conditions, are examined independently."
|
||||
"description": "The condition that is associated with this binding. NOTE: An unsatisfied condition will not allow user access via current binding. Different bindings, including their conditions, are examined independently."
|
||||
},
|
||||
"members": {
|
||||
"description": "Specifies the identities requesting access for a Cloud Platform resource. `members` can have the following values:\n\n* `allUsers`: A special identifier that represents anyone who is on the internet; with or without a Google account.\n\n* `allAuthenticatedUsers`: A special identifier that represents anyone who is authenticated with a Google account or a service account.\n\n* `user:{emailid}`: An email address that represents a specific Google account. For example, `alice@gmail.com` .\n\n\n\n* `serviceAccount:{emailid}`: An email address that represents a service account. For example, `my-other-app@appspot.gserviceaccount.com`.\n\n* `group:{emailid}`: An email address that represents a Google group. For example, `admins@example.com`.\n\n\n\n* `domain:{domain}`: The G Suite domain (primary) that represents all the users of that domain. For example, `google.com` or `example.com`.",
|
||||
|
@ -22641,7 +22641,7 @@
|
|||
"id": "FixedOrPercent",
|
||||
"properties": {
|
||||
"calculated": {
|
||||
"description": "[Output Only] Absolute value of VM instances calculated based on the specific mode.\n\n \n- If the value is fixed, then the caculated value is equal to the fixed value. \n- If the value is a percent, then the calculated value is percent/100 * targetSize. For example, the calculated value of a 80% of a managed instance group with 150 instances would be (80/100 * 150) = 120 VM instances. If there is a remainder, the number is rounded up.",
|
||||
"description": "[Output Only] Absolute value of VM instances calculated based on the specific mode.\n\n \n- If the value is fixed, then the calculated value is equal to the fixed value. \n- If the value is a percent, then the calculated value is percent/100 * targetSize. For example, the calculated value of a 80% of a managed instance group with 150 instances would be (80/100 * 150) = 120 VM instances. If there is a remainder, the number is rounded up.",
|
||||
"format": "int32",
|
||||
"type": "integer"
|
||||
},
|
||||
|
@ -23415,7 +23415,7 @@
|
|||
"type": "integer"
|
||||
},
|
||||
"type": {
|
||||
"description": "Specifies the type of the healthCheck, either TCP, SSL, HTTP or HTTPS. If not specified, the default is TCP. Exactly one of the protocol-specific health check field must be specified, which must match type field.",
|
||||
"description": "Specifies the type of the healthCheck, either TCP, SSL, HTTP, HTTPS or HTTP2. If not specified, the default is TCP. Exactly one of the protocol-specific health check field must be specified, which must match type field.",
|
||||
"enum": [
|
||||
"HTTP",
|
||||
"HTTP2",
|
||||
|
@ -24993,7 +24993,7 @@
|
|||
"description": "The update policy for this managed instance group."
|
||||
},
|
||||
"versions": {
|
||||
"description": "Specifies the instance templates used by this managed instance group to create instances.\n\nEach version is defined by an instanceTemplate. Every template can appear at most once per instance group. This field overrides the top-level instanceTemplate field. Read more about the relationships between these fields. Exactly one version must leave the targetSize field unset. That version will be applied to all remaining instances. For more information, read about canary updates.",
|
||||
"description": "Specifies the instance templates used by this managed instance group to create instances.\n\nEach version is defined by an instanceTemplate and a name. Every version can appear at most once per instance group. This field overrides the top-level instanceTemplate field. Read more about the relationships between these fields. Exactly one version must leave the targetSize field unset. That version will be applied to all remaining instances. For more information, read about canary updates.",
|
||||
"items": {
|
||||
"$ref": "InstanceGroupManagerVersion"
|
||||
},
|
||||
|
@ -25348,6 +25348,7 @@
|
|||
"id": "InstanceGroupManagerVersion",
|
||||
"properties": {
|
||||
"instanceTemplate": {
|
||||
"description": "The URL of the instance template that is specified for this managed instance group. The group uses this template to create new instances in the managed instance group until the `targetSize` for this version is reached.",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
|
@ -29595,7 +29596,7 @@
|
|||
"type": "object"
|
||||
},
|
||||
"NodeGroup": {
|
||||
"description": "A NodeGroup resource. (== resource_for beta.nodeGroups ==) (== resource_for v1.nodeGroups ==)",
|
||||
"description": "A NodeGroup resource. To create a node group, you must first create a node templates. To learn more about node groups and sole-tenant nodes, read the Sole-tenant nodes documentation. (== resource_for beta.nodeGroups ==) (== resource_for v1.nodeGroups ==)",
|
||||
"id": "NodeGroup",
|
||||
"properties": {
|
||||
"creationTimestamp": {
|
||||
|
@ -30156,7 +30157,7 @@
|
|||
"type": "object"
|
||||
},
|
||||
"NodeTemplate": {
|
||||
"description": "A Node Template resource.",
|
||||
"description": "A Node Template resource. To learn more about node templates and sole-tenant nodes, read the Sole-tenant nodes documentation. (== resource_for beta.nodeTemplates ==) (== resource_for v1.nodeTemplates ==)",
|
||||
"id": "NodeTemplate",
|
||||
"properties": {
|
||||
"creationTimestamp": {
|
||||
|
@ -38914,7 +38915,7 @@
|
|||
"type": "object"
|
||||
},
|
||||
"Zone": {
|
||||
"description": "A Zone resource. (== resource_for beta.zones ==) (== resource_for v1.zones ==)",
|
||||
"description": "A Zone resource. (== resource_for beta.zones ==) (== resource_for v1.zones ==) Next ID: 17",
|
||||
"id": "Zone",
|
||||
"properties": {
|
||||
"availableCpuPlatforms": {
|
||||
|
|
|
@ -4518,7 +4518,7 @@ func (s *BackendServicesScopedListWarningData) MarshalJSON() ([]byte, error) {
|
|||
// Binding: Associates `members` with a `role`.
|
||||
type Binding struct {
|
||||
// Condition: The condition that is associated with this binding. NOTE:
|
||||
// an unsatisfied condition will not allow user access via current
|
||||
// An unsatisfied condition will not allow user access via current
|
||||
// binding. Different bindings, including their conditions, are examined
|
||||
// independently.
|
||||
Condition *Expr `json:"condition,omitempty"`
|
||||
|
@ -7316,7 +7316,7 @@ type FixedOrPercent struct {
|
|||
// based on the specific mode.
|
||||
//
|
||||
//
|
||||
// - If the value is fixed, then the caculated value is equal to the
|
||||
// - If the value is fixed, then the calculated value is equal to the
|
||||
// fixed value.
|
||||
// - If the value is a percent, then the calculated value is percent/100
|
||||
// * targetSize. For example, the calculated value of a 80% of a managed
|
||||
|
@ -8506,10 +8506,10 @@ type HealthCheck struct {
|
|||
// greater value than checkIntervalSec.
|
||||
TimeoutSec int64 `json:"timeoutSec,omitempty"`
|
||||
|
||||
// Type: Specifies the type of the healthCheck, either TCP, SSL, HTTP or
|
||||
// HTTPS. If not specified, the default is TCP. Exactly one of the
|
||||
// protocol-specific health check field must be specified, which must
|
||||
// match type field.
|
||||
// Type: Specifies the type of the healthCheck, either TCP, SSL, HTTP,
|
||||
// HTTPS or HTTP2. If not specified, the default is TCP. Exactly one of
|
||||
// the protocol-specific health check field must be specified, which
|
||||
// must match type field.
|
||||
//
|
||||
// Possible values:
|
||||
// "HTTP"
|
||||
|
@ -10597,12 +10597,12 @@ type InstanceGroupManager struct {
|
|||
// Versions: Specifies the instance templates used by this managed
|
||||
// instance group to create instances.
|
||||
//
|
||||
// Each version is defined by an instanceTemplate. Every template can
|
||||
// appear at most once per instance group. This field overrides the
|
||||
// top-level instanceTemplate field. Read more about the relationships
|
||||
// between these fields. Exactly one version must leave the targetSize
|
||||
// field unset. That version will be applied to all remaining instances.
|
||||
// For more information, read about canary updates.
|
||||
// Each version is defined by an instanceTemplate and a name. Every
|
||||
// version can appear at most once per instance group. This field
|
||||
// overrides the top-level instanceTemplate field. Read more about the
|
||||
// relationships between these fields. Exactly one version must leave
|
||||
// the targetSize field unset. That version will be applied to all
|
||||
// remaining instances. For more information, read about canary updates.
|
||||
Versions []*InstanceGroupManagerVersion `json:"versions,omitempty"`
|
||||
|
||||
// Zone: [Output Only] The URL of the zone where the managed instance
|
||||
|
@ -11172,6 +11172,10 @@ func (s *InstanceGroupManagerUpdatePolicy) MarshalJSON() ([]byte, error) {
|
|||
}
|
||||
|
||||
type InstanceGroupManagerVersion struct {
|
||||
// InstanceTemplate: The URL of the instance template that is specified
|
||||
// for this managed instance group. The group uses this template to
|
||||
// create new instances in the managed instance group until the
|
||||
// `targetSize` for this version is reached.
|
||||
InstanceTemplate string `json:"instanceTemplate,omitempty"`
|
||||
|
||||
// Name: Name of the version. Unique among all versions in the scope of
|
||||
|
@ -17500,8 +17504,10 @@ func (s *NetworksRemovePeeringRequest) MarshalJSON() ([]byte, error) {
|
|||
return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
|
||||
}
|
||||
|
||||
// NodeGroup: A NodeGroup resource. (== resource_for beta.nodeGroups ==)
|
||||
// (== resource_for v1.nodeGroups ==)
|
||||
// NodeGroup: A NodeGroup resource. To create a node group, you must
|
||||
// first create a node templates. To learn more about node groups and
|
||||
// sole-tenant nodes, read the Sole-tenant nodes documentation. (==
|
||||
// resource_for beta.nodeGroups ==) (== resource_for v1.nodeGroups ==)
|
||||
type NodeGroup struct {
|
||||
// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
|
||||
// format.
|
||||
|
@ -18302,7 +18308,10 @@ func (s *NodeGroupsSetNodeTemplateRequest) MarshalJSON() ([]byte, error) {
|
|||
return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
|
||||
}
|
||||
|
||||
// NodeTemplate: A Node Template resource.
|
||||
// NodeTemplate: A Node Template resource. To learn more about node
|
||||
// templates and sole-tenant nodes, read the Sole-tenant nodes
|
||||
// documentation. (== resource_for beta.nodeTemplates ==) (==
|
||||
// resource_for v1.nodeTemplates ==)
|
||||
type NodeTemplate struct {
|
||||
// CreationTimestamp: [Output Only] Creation timestamp in RFC3339 text
|
||||
// format.
|
||||
|
@ -31065,7 +31074,7 @@ func (s *XpnResourceId) MarshalJSON() ([]byte, error) {
|
|||
}
|
||||
|
||||
// Zone: A Zone resource. (== resource_for beta.zones ==) (==
|
||||
// resource_for v1.zones ==)
|
||||
// resource_for v1.zones ==) Next ID: 17
|
||||
type Zone struct {
|
||||
// AvailableCpuPlatforms: [Output Only] Available cpu/platform
|
||||
// selections for the zone.
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
"description": "Stores and retrieves potentially large, immutable data objects.",
|
||||
"discoveryVersion": "v1",
|
||||
"documentationLink": "https://developers.google.com/storage/docs/json_api/",
|
||||
"etag": "\"J3WqvAcMk4eQjJXvfSI4Yr8VouA/5J1bGH010PqoE1O9vmClDRlYmZI\"",
|
||||
"etag": "\"VPK3KBfpaEgZ16pozGOoMYfKc0U/0oTiRxFg5a8IRGYou40wPCps2h4\"",
|
||||
"icons": {
|
||||
"x16": "https://www.google.com/images/icons/product/cloud_storage-16.png",
|
||||
"x32": "https://www.google.com/images/icons/product/cloud_storage-32.png"
|
||||
|
@ -2727,6 +2727,185 @@
|
|||
},
|
||||
"projects": {
|
||||
"resources": {
|
||||
"hmacKeys": {
|
||||
"methods": {
|
||||
"create": {
|
||||
"description": "Creates a new HMAC key for the specified service account.",
|
||||
"httpMethod": "POST",
|
||||
"id": "storage.projects.hmacKeys.create",
|
||||
"parameterOrder": [
|
||||
"projectId",
|
||||
"serviceAccountEmail"
|
||||
],
|
||||
"parameters": {
|
||||
"projectId": {
|
||||
"description": "Project ID owning the service account.",
|
||||
"location": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"serviceAccountEmail": {
|
||||
"description": "Email address of the service account.",
|
||||
"location": "query",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"path": "projects/{projectId}/hmacKeys",
|
||||
"response": {
|
||||
"$ref": "HmacKey"
|
||||
},
|
||||
"scopes": [
|
||||
"https://www.googleapis.com/auth/cloud-platform",
|
||||
"https://www.googleapis.com/auth/devstorage.full_control"
|
||||
]
|
||||
},
|
||||
"delete": {
|
||||
"description": "Deletes an HMAC key.",
|
||||
"httpMethod": "DELETE",
|
||||
"id": "storage.projects.hmacKeys.delete",
|
||||
"parameterOrder": [
|
||||
"projectId",
|
||||
"accessId"
|
||||
],
|
||||
"parameters": {
|
||||
"accessId": {
|
||||
"description": "Name of the HMAC key to be deleted.",
|
||||
"location": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"projectId": {
|
||||
"description": "Project ID owning the requested key",
|
||||
"location": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"path": "projects/{projectId}/hmacKeys/{accessId}",
|
||||
"scopes": [
|
||||
"https://www.googleapis.com/auth/cloud-platform",
|
||||
"https://www.googleapis.com/auth/devstorage.full_control",
|
||||
"https://www.googleapis.com/auth/devstorage.read_write"
|
||||
]
|
||||
},
|
||||
"get": {
|
||||
"description": "Retrieves an HMAC key's metadata",
|
||||
"httpMethod": "GET",
|
||||
"id": "storage.projects.hmacKeys.get",
|
||||
"parameterOrder": [
|
||||
"projectId",
|
||||
"accessId"
|
||||
],
|
||||
"parameters": {
|
||||
"accessId": {
|
||||
"description": "Name of the HMAC key.",
|
||||
"location": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"projectId": {
|
||||
"description": "Project ID owning the service account of the requested key.",
|
||||
"location": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"path": "projects/{projectId}/hmacKeys/{accessId}",
|
||||
"response": {
|
||||
"$ref": "HmacKeyMetadata"
|
||||
},
|
||||
"scopes": [
|
||||
"https://www.googleapis.com/auth/cloud-platform",
|
||||
"https://www.googleapis.com/auth/cloud-platform.read-only",
|
||||
"https://www.googleapis.com/auth/devstorage.read_only"
|
||||
]
|
||||
},
|
||||
"list": {
|
||||
"description": "Retrieves a list of HMAC keys matching the criteria.",
|
||||
"httpMethod": "GET",
|
||||
"id": "storage.projects.hmacKeys.list",
|
||||
"parameterOrder": [
|
||||
"projectId"
|
||||
],
|
||||
"parameters": {
|
||||
"maxResults": {
|
||||
"default": "1000",
|
||||
"description": "Maximum number of items plus prefixes to return in a single page of responses. Because duplicate prefixes are omitted, fewer total results may be returned than requested. The service uses this parameter or 1,000 items, whichever is smaller.",
|
||||
"format": "uint32",
|
||||
"location": "query",
|
||||
"minimum": "0",
|
||||
"type": "integer"
|
||||
},
|
||||
"pageToken": {
|
||||
"description": "A previously-returned page token representing part of the larger set of results to view.",
|
||||
"location": "query",
|
||||
"type": "string"
|
||||
},
|
||||
"projectId": {
|
||||
"description": "Name of the project in which to look for HMAC keys.",
|
||||
"location": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"serviceAccountEmail": {
|
||||
"description": "If present, only keys for the given service account are returned.",
|
||||
"location": "query",
|
||||
"type": "string"
|
||||
},
|
||||
"showDeletedKeys": {
|
||||
"description": "Whether or not to show keys in the DELETED state.",
|
||||
"location": "query",
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"path": "projects/{projectId}/hmacKeys",
|
||||
"response": {
|
||||
"$ref": "HmacKeysMetadata"
|
||||
},
|
||||
"scopes": [
|
||||
"https://www.googleapis.com/auth/cloud-platform",
|
||||
"https://www.googleapis.com/auth/cloud-platform.read-only",
|
||||
"https://www.googleapis.com/auth/devstorage.full_control",
|
||||
"https://www.googleapis.com/auth/devstorage.read_only"
|
||||
]
|
||||
},
|
||||
"update": {
|
||||
"description": "Updates the state of an HMAC key. See the HMAC Key resource descriptor for valid states.",
|
||||
"httpMethod": "PUT",
|
||||
"id": "storage.projects.hmacKeys.update",
|
||||
"parameterOrder": [
|
||||
"projectId",
|
||||
"accessId"
|
||||
],
|
||||
"parameters": {
|
||||
"accessId": {
|
||||
"description": "Name of the HMAC key being updated.",
|
||||
"location": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"projectId": {
|
||||
"description": "Project ID owning the service account of the updated key.",
|
||||
"location": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"path": "projects/{projectId}/hmacKeys/{accessId}",
|
||||
"request": {
|
||||
"$ref": "HmacKeyMetadata"
|
||||
},
|
||||
"response": {
|
||||
"$ref": "HmacKeyMetadata"
|
||||
},
|
||||
"scopes": [
|
||||
"https://www.googleapis.com/auth/cloud-platform",
|
||||
"https://www.googleapis.com/auth/devstorage.full_control"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"serviceAccount": {
|
||||
"methods": {
|
||||
"get": {
|
||||
|
@ -2766,7 +2945,7 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"revision": "20190129",
|
||||
"revision": "20190326",
|
||||
"rootUrl": "https://www.googleapis.com/",
|
||||
"schemas": {
|
||||
"Bucket": {
|
||||
|
@ -3324,6 +3503,97 @@
|
|||
},
|
||||
"type": "object"
|
||||
},
|
||||
"HmacKey": {
|
||||
"description": "JSON template to produce a JSON-style HMAC Key resource for Create responses.",
|
||||
"id": "HmacKey",
|
||||
"properties": {
|
||||
"kind": {
|
||||
"default": "storage#hmacKey",
|
||||
"description": "The kind of item this is. For HMAC keys, this is always storage#hmacKey.",
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"description": "Key metadata.",
|
||||
"type": "any"
|
||||
},
|
||||
"secret": {
|
||||
"description": "HMAC secret key material.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"HmacKeyMetadata": {
|
||||
"description": "JSON template to produce a JSON-style HMAC Key metadata resource.",
|
||||
"id": "HmacKeyMetadata",
|
||||
"properties": {
|
||||
"accessId": {
|
||||
"description": "The ID of the HMAC Key.",
|
||||
"type": "string"
|
||||
},
|
||||
"etag": {
|
||||
"description": "HTTP 1.1 Entity tag for the access-control entry.",
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"description": "The ID of the HMAC key, including the Project ID and the Access ID.",
|
||||
"type": "string"
|
||||
},
|
||||
"kind": {
|
||||
"default": "storage#hmacKeyMetadata",
|
||||
"description": "The kind of item this is. For HMAC Key metadata, this is always storage#hmacKeyMetadata.",
|
||||
"type": "string"
|
||||
},
|
||||
"projectId": {
|
||||
"description": "Project ID owning the service account to which the key authenticates.",
|
||||
"type": "string"
|
||||
},
|
||||
"selfLink": {
|
||||
"description": "The link to this resource.",
|
||||
"type": "string"
|
||||
},
|
||||
"serviceAccountEmail": {
|
||||
"description": "The email address of the key's associated service account.",
|
||||
"type": "string"
|
||||
},
|
||||
"state": {
|
||||
"description": "The state of the key. Can be one of ACTIVE, INACTIVE, or DELETED.",
|
||||
"type": "string"
|
||||
},
|
||||
"timeCreated": {
|
||||
"description": "The creation time of the HMAC key in RFC 3339 format.",
|
||||
"type": "string"
|
||||
},
|
||||
"updated": {
|
||||
"description": "The last modification time of the HMAC key metadata in RFC 3339 format.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"HmacKeysMetadata": {
|
||||
"description": "A list of hmacKeys.",
|
||||
"id": "HmacKeysMetadata",
|
||||
"properties": {
|
||||
"items": {
|
||||
"description": "The list of items.",
|
||||
"items": {
|
||||
"$ref": "HmacKeyMetadata"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"kind": {
|
||||
"default": "storage#hmacKeysMetadata",
|
||||
"description": "The kind of item this is. For lists of hmacKeys, this is always storage#hmacKeysMetadata.",
|
||||
"type": "string"
|
||||
},
|
||||
"nextPageToken": {
|
||||
"description": "The continuation token, used to page through large result sets. Provide this value in a subsequent request to return the next page of results.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"Notification": {
|
||||
"description": "A subscription to receive Google PubSub notifications.",
|
||||
"id": "Notification",
|
||||
|
|
|
@ -238,6 +238,7 @@ type ObjectsService struct {
|
|||
|
||||
func NewProjectsService(s *Service) *ProjectsService {
|
||||
rs := &ProjectsService{s: s}
|
||||
rs.HmacKeys = NewProjectsHmacKeysService(s)
|
||||
rs.ServiceAccount = NewProjectsServiceAccountService(s)
|
||||
return rs
|
||||
}
|
||||
|
@ -245,9 +246,20 @@ func NewProjectsService(s *Service) *ProjectsService {
|
|||
type ProjectsService struct {
|
||||
s *Service
|
||||
|
||||
HmacKeys *ProjectsHmacKeysService
|
||||
|
||||
ServiceAccount *ProjectsServiceAccountService
|
||||
}
|
||||
|
||||
func NewProjectsHmacKeysService(s *Service) *ProjectsHmacKeysService {
|
||||
rs := &ProjectsHmacKeysService{s: s}
|
||||
return rs
|
||||
}
|
||||
|
||||
type ProjectsHmacKeysService struct {
|
||||
s *Service
|
||||
}
|
||||
|
||||
func NewProjectsServiceAccountService(s *Service) *ProjectsServiceAccountService {
|
||||
rs := &ProjectsServiceAccountService{s: s}
|
||||
return rs
|
||||
|
@ -1313,6 +1325,153 @@ func (s *Expr) MarshalJSON() ([]byte, error) {
|
|||
return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
|
||||
}
|
||||
|
||||
// HmacKey: JSON template to produce a JSON-style HMAC Key resource for
|
||||
// Create responses.
|
||||
type HmacKey struct {
|
||||
// Kind: The kind of item this is. For HMAC keys, this is always
|
||||
// storage#hmacKey.
|
||||
Kind string `json:"kind,omitempty"`
|
||||
|
||||
// Metadata: Key metadata.
|
||||
Metadata interface{} `json:"metadata,omitempty"`
|
||||
|
||||
// Secret: HMAC secret key material.
|
||||
Secret string `json:"secret,omitempty"`
|
||||
|
||||
// ServerResponse contains the HTTP response code and headers from the
|
||||
// server.
|
||||
googleapi.ServerResponse `json:"-"`
|
||||
|
||||
// ForceSendFields is a list of field names (e.g. "Kind") to
|
||||
// unconditionally include in API requests. By default, fields with
|
||||
// empty values are omitted from API requests. However, any non-pointer,
|
||||
// non-interface field appearing in ForceSendFields will be sent to the
|
||||
// server regardless of whether the field is empty or not. This may be
|
||||
// used to include empty fields in Patch requests.
|
||||
ForceSendFields []string `json:"-"`
|
||||
|
||||
// NullFields is a list of field names (e.g. "Kind") to include in API
|
||||
// requests with the JSON null value. By default, fields with empty
|
||||
// values are omitted from API requests. However, any field with an
|
||||
// empty value appearing in NullFields will be sent to the server as
|
||||
// null. It is an error if a field in this list has a non-empty value.
|
||||
// This may be used to include null fields in Patch requests.
|
||||
NullFields []string `json:"-"`
|
||||
}
|
||||
|
||||
func (s *HmacKey) MarshalJSON() ([]byte, error) {
|
||||
type NoMethod HmacKey
|
||||
raw := NoMethod(*s)
|
||||
return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
|
||||
}
|
||||
|
||||
// HmacKeyMetadata: JSON template to produce a JSON-style HMAC Key
|
||||
// metadata resource.
|
||||
type HmacKeyMetadata struct {
|
||||
// AccessId: The ID of the HMAC Key.
|
||||
AccessId string `json:"accessId,omitempty"`
|
||||
|
||||
// Etag: HTTP 1.1 Entity tag for the access-control entry.
|
||||
Etag string `json:"etag,omitempty"`
|
||||
|
||||
// Id: The ID of the HMAC key, including the Project ID and the Access
|
||||
// ID.
|
||||
Id string `json:"id,omitempty"`
|
||||
|
||||
// Kind: The kind of item this is. For HMAC Key metadata, this is always
|
||||
// storage#hmacKeyMetadata.
|
||||
Kind string `json:"kind,omitempty"`
|
||||
|
||||
// ProjectId: Project ID owning the service account to which the key
|
||||
// authenticates.
|
||||
ProjectId string `json:"projectId,omitempty"`
|
||||
|
||||
// SelfLink: The link to this resource.
|
||||
SelfLink string `json:"selfLink,omitempty"`
|
||||
|
||||
// ServiceAccountEmail: The email address of the key's associated
|
||||
// service account.
|
||||
ServiceAccountEmail string `json:"serviceAccountEmail,omitempty"`
|
||||
|
||||
// State: The state of the key. Can be one of ACTIVE, INACTIVE, or
|
||||
// DELETED.
|
||||
State string `json:"state,omitempty"`
|
||||
|
||||
// TimeCreated: The creation time of the HMAC key in RFC 3339 format.
|
||||
TimeCreated string `json:"timeCreated,omitempty"`
|
||||
|
||||
// Updated: The last modification time of the HMAC key metadata in RFC
|
||||
// 3339 format.
|
||||
Updated string `json:"updated,omitempty"`
|
||||
|
||||
// ServerResponse contains the HTTP response code and headers from the
|
||||
// server.
|
||||
googleapi.ServerResponse `json:"-"`
|
||||
|
||||
// ForceSendFields is a list of field names (e.g. "AccessId") to
|
||||
// unconditionally include in API requests. By default, fields with
|
||||
// empty values are omitted from API requests. However, any non-pointer,
|
||||
// non-interface field appearing in ForceSendFields will be sent to the
|
||||
// server regardless of whether the field is empty or not. This may be
|
||||
// used to include empty fields in Patch requests.
|
||||
ForceSendFields []string `json:"-"`
|
||||
|
||||
// NullFields is a list of field names (e.g. "AccessId") to include in
|
||||
// API requests with the JSON null value. By default, fields with empty
|
||||
// values are omitted from API requests. However, any field with an
|
||||
// empty value appearing in NullFields will be sent to the server as
|
||||
// null. It is an error if a field in this list has a non-empty value.
|
||||
// This may be used to include null fields in Patch requests.
|
||||
NullFields []string `json:"-"`
|
||||
}
|
||||
|
||||
func (s *HmacKeyMetadata) MarshalJSON() ([]byte, error) {
|
||||
type NoMethod HmacKeyMetadata
|
||||
raw := NoMethod(*s)
|
||||
return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
|
||||
}
|
||||
|
||||
// HmacKeysMetadata: A list of hmacKeys.
|
||||
type HmacKeysMetadata struct {
|
||||
// Items: The list of items.
|
||||
Items []*HmacKeyMetadata `json:"items,omitempty"`
|
||||
|
||||
// Kind: The kind of item this is. For lists of hmacKeys, this is always
|
||||
// storage#hmacKeysMetadata.
|
||||
Kind string `json:"kind,omitempty"`
|
||||
|
||||
// NextPageToken: The continuation token, used to page through large
|
||||
// result sets. Provide this value in a subsequent request to return the
|
||||
// next page of results.
|
||||
NextPageToken string `json:"nextPageToken,omitempty"`
|
||||
|
||||
// ServerResponse contains the HTTP response code and headers from the
|
||||
// server.
|
||||
googleapi.ServerResponse `json:"-"`
|
||||
|
||||
// ForceSendFields is a list of field names (e.g. "Items") to
|
||||
// unconditionally include in API requests. By default, fields with
|
||||
// empty values are omitted from API requests. However, any non-pointer,
|
||||
// non-interface field appearing in ForceSendFields will be sent to the
|
||||
// server regardless of whether the field is empty or not. This may be
|
||||
// used to include empty fields in Patch requests.
|
||||
ForceSendFields []string `json:"-"`
|
||||
|
||||
// NullFields is a list of field names (e.g. "Items") to include in API
|
||||
// requests with the JSON null value. By default, fields with empty
|
||||
// values are omitted from API requests. However, any field with an
|
||||
// empty value appearing in NullFields will be sent to the server as
|
||||
// null. It is an error if a field in this list has a non-empty value.
|
||||
// This may be used to include null fields in Patch requests.
|
||||
NullFields []string `json:"-"`
|
||||
}
|
||||
|
||||
func (s *HmacKeysMetadata) MarshalJSON() ([]byte, error) {
|
||||
type NoMethod HmacKeysMetadata
|
||||
raw := NoMethod(*s)
|
||||
return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
|
||||
}
|
||||
|
||||
// Notification: A subscription to receive Google PubSub notifications.
|
||||
type Notification struct {
|
||||
// CustomAttributes: An optional list of additional attributes to attach
|
||||
|
@ -11429,6 +11588,776 @@ func (c *ObjectsWatchAllCall) Do(opts ...googleapi.CallOption) (*Channel, error)
|
|||
|
||||
}
|
||||
|
||||
// method id "storage.projects.hmacKeys.create":
|
||||
|
||||
type ProjectsHmacKeysCreateCall struct {
|
||||
s *Service
|
||||
projectId string
|
||||
urlParams_ gensupport.URLParams
|
||||
ctx_ context.Context
|
||||
header_ http.Header
|
||||
}
|
||||
|
||||
// Create: Creates a new HMAC key for the specified service account.
|
||||
func (r *ProjectsHmacKeysService) Create(projectId string, serviceAccountEmail string) *ProjectsHmacKeysCreateCall {
|
||||
c := &ProjectsHmacKeysCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
|
||||
c.projectId = projectId
|
||||
c.urlParams_.Set("serviceAccountEmail", serviceAccountEmail)
|
||||
return c
|
||||
}
|
||||
|
||||
// Fields allows partial responses to be retrieved. See
|
||||
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
|
||||
// for more information.
|
||||
func (c *ProjectsHmacKeysCreateCall) Fields(s ...googleapi.Field) *ProjectsHmacKeysCreateCall {
|
||||
c.urlParams_.Set("fields", googleapi.CombineFields(s))
|
||||
return c
|
||||
}
|
||||
|
||||
// Context sets the context to be used in this call's Do method. Any
|
||||
// pending HTTP request will be aborted if the provided context is
|
||||
// canceled.
|
||||
func (c *ProjectsHmacKeysCreateCall) Context(ctx context.Context) *ProjectsHmacKeysCreateCall {
|
||||
c.ctx_ = ctx
|
||||
return c
|
||||
}
|
||||
|
||||
// Header returns an http.Header that can be modified by the caller to
|
||||
// add HTTP headers to the request.
|
||||
func (c *ProjectsHmacKeysCreateCall) Header() http.Header {
|
||||
if c.header_ == nil {
|
||||
c.header_ = make(http.Header)
|
||||
}
|
||||
return c.header_
|
||||
}
|
||||
|
||||
func (c *ProjectsHmacKeysCreateCall) doRequest(alt string) (*http.Response, error) {
|
||||
reqHeaders := make(http.Header)
|
||||
for k, v := range c.header_ {
|
||||
reqHeaders[k] = v
|
||||
}
|
||||
reqHeaders.Set("User-Agent", c.s.userAgent())
|
||||
var body io.Reader = nil
|
||||
c.urlParams_.Set("alt", alt)
|
||||
c.urlParams_.Set("prettyPrint", "false")
|
||||
urls := googleapi.ResolveRelative(c.s.BasePath, "projects/{projectId}/hmacKeys")
|
||||
urls += "?" + c.urlParams_.Encode()
|
||||
req, err := http.NewRequest("POST", urls, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header = reqHeaders
|
||||
googleapi.Expand(req.URL, map[string]string{
|
||||
"projectId": c.projectId,
|
||||
})
|
||||
return gensupport.SendRequest(c.ctx_, c.s.client, req)
|
||||
}
|
||||
|
||||
// Do executes the "storage.projects.hmacKeys.create" call.
|
||||
// Exactly one of *HmacKey or error will be non-nil. Any non-2xx status
|
||||
// code is an error. Response headers are in either
|
||||
// *HmacKey.ServerResponse.Header or (if a response was returned at all)
|
||||
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
|
||||
// check whether the returned error was because http.StatusNotModified
|
||||
// was returned.
|
||||
func (c *ProjectsHmacKeysCreateCall) Do(opts ...googleapi.CallOption) (*HmacKey, error) {
|
||||
gensupport.SetOptions(c.urlParams_, opts...)
|
||||
res, err := c.doRequest("json")
|
||||
if res != nil && res.StatusCode == http.StatusNotModified {
|
||||
if res.Body != nil {
|
||||
res.Body.Close()
|
||||
}
|
||||
return nil, &googleapi.Error{
|
||||
Code: res.StatusCode,
|
||||
Header: res.Header,
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer googleapi.CloseBody(res)
|
||||
if err := googleapi.CheckResponse(res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := &HmacKey{
|
||||
ServerResponse: googleapi.ServerResponse{
|
||||
Header: res.Header,
|
||||
HTTPStatusCode: res.StatusCode,
|
||||
},
|
||||
}
|
||||
target := &ret
|
||||
if err := gensupport.DecodeResponse(target, res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, nil
|
||||
// {
|
||||
// "description": "Creates a new HMAC key for the specified service account.",
|
||||
// "httpMethod": "POST",
|
||||
// "id": "storage.projects.hmacKeys.create",
|
||||
// "parameterOrder": [
|
||||
// "projectId",
|
||||
// "serviceAccountEmail"
|
||||
// ],
|
||||
// "parameters": {
|
||||
// "projectId": {
|
||||
// "description": "Project ID owning the service account.",
|
||||
// "location": "path",
|
||||
// "required": true,
|
||||
// "type": "string"
|
||||
// },
|
||||
// "serviceAccountEmail": {
|
||||
// "description": "Email address of the service account.",
|
||||
// "location": "query",
|
||||
// "required": true,
|
||||
// "type": "string"
|
||||
// }
|
||||
// },
|
||||
// "path": "projects/{projectId}/hmacKeys",
|
||||
// "response": {
|
||||
// "$ref": "HmacKey"
|
||||
// },
|
||||
// "scopes": [
|
||||
// "https://www.googleapis.com/auth/cloud-platform",
|
||||
// "https://www.googleapis.com/auth/devstorage.full_control"
|
||||
// ]
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
// method id "storage.projects.hmacKeys.delete":
|
||||
|
||||
type ProjectsHmacKeysDeleteCall struct {
|
||||
s *Service
|
||||
projectId string
|
||||
accessId string
|
||||
urlParams_ gensupport.URLParams
|
||||
ctx_ context.Context
|
||||
header_ http.Header
|
||||
}
|
||||
|
||||
// Delete: Deletes an HMAC key.
|
||||
func (r *ProjectsHmacKeysService) Delete(projectId string, accessId string) *ProjectsHmacKeysDeleteCall {
|
||||
c := &ProjectsHmacKeysDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
|
||||
c.projectId = projectId
|
||||
c.accessId = accessId
|
||||
return c
|
||||
}
|
||||
|
||||
// Fields allows partial responses to be retrieved. See
|
||||
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
|
||||
// for more information.
|
||||
func (c *ProjectsHmacKeysDeleteCall) Fields(s ...googleapi.Field) *ProjectsHmacKeysDeleteCall {
|
||||
c.urlParams_.Set("fields", googleapi.CombineFields(s))
|
||||
return c
|
||||
}
|
||||
|
||||
// Context sets the context to be used in this call's Do method. Any
|
||||
// pending HTTP request will be aborted if the provided context is
|
||||
// canceled.
|
||||
func (c *ProjectsHmacKeysDeleteCall) Context(ctx context.Context) *ProjectsHmacKeysDeleteCall {
|
||||
c.ctx_ = ctx
|
||||
return c
|
||||
}
|
||||
|
||||
// Header returns an http.Header that can be modified by the caller to
|
||||
// add HTTP headers to the request.
|
||||
func (c *ProjectsHmacKeysDeleteCall) Header() http.Header {
|
||||
if c.header_ == nil {
|
||||
c.header_ = make(http.Header)
|
||||
}
|
||||
return c.header_
|
||||
}
|
||||
|
||||
func (c *ProjectsHmacKeysDeleteCall) doRequest(alt string) (*http.Response, error) {
|
||||
reqHeaders := make(http.Header)
|
||||
for k, v := range c.header_ {
|
||||
reqHeaders[k] = v
|
||||
}
|
||||
reqHeaders.Set("User-Agent", c.s.userAgent())
|
||||
var body io.Reader = nil
|
||||
c.urlParams_.Set("alt", alt)
|
||||
c.urlParams_.Set("prettyPrint", "false")
|
||||
urls := googleapi.ResolveRelative(c.s.BasePath, "projects/{projectId}/hmacKeys/{accessId}")
|
||||
urls += "?" + c.urlParams_.Encode()
|
||||
req, err := http.NewRequest("DELETE", urls, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header = reqHeaders
|
||||
googleapi.Expand(req.URL, map[string]string{
|
||||
"projectId": c.projectId,
|
||||
"accessId": c.accessId,
|
||||
})
|
||||
return gensupport.SendRequest(c.ctx_, c.s.client, req)
|
||||
}
|
||||
|
||||
// Do executes the "storage.projects.hmacKeys.delete" call.
|
||||
func (c *ProjectsHmacKeysDeleteCall) Do(opts ...googleapi.CallOption) error {
|
||||
gensupport.SetOptions(c.urlParams_, opts...)
|
||||
res, err := c.doRequest("json")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer googleapi.CloseBody(res)
|
||||
if err := googleapi.CheckResponse(res); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
// {
|
||||
// "description": "Deletes an HMAC key.",
|
||||
// "httpMethod": "DELETE",
|
||||
// "id": "storage.projects.hmacKeys.delete",
|
||||
// "parameterOrder": [
|
||||
// "projectId",
|
||||
// "accessId"
|
||||
// ],
|
||||
// "parameters": {
|
||||
// "accessId": {
|
||||
// "description": "Name of the HMAC key to be deleted.",
|
||||
// "location": "path",
|
||||
// "required": true,
|
||||
// "type": "string"
|
||||
// },
|
||||
// "projectId": {
|
||||
// "description": "Project ID owning the requested key",
|
||||
// "location": "path",
|
||||
// "required": true,
|
||||
// "type": "string"
|
||||
// }
|
||||
// },
|
||||
// "path": "projects/{projectId}/hmacKeys/{accessId}",
|
||||
// "scopes": [
|
||||
// "https://www.googleapis.com/auth/cloud-platform",
|
||||
// "https://www.googleapis.com/auth/devstorage.full_control",
|
||||
// "https://www.googleapis.com/auth/devstorage.read_write"
|
||||
// ]
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
// method id "storage.projects.hmacKeys.get":
|
||||
|
||||
type ProjectsHmacKeysGetCall struct {
|
||||
s *Service
|
||||
projectId string
|
||||
accessId string
|
||||
urlParams_ gensupport.URLParams
|
||||
ifNoneMatch_ string
|
||||
ctx_ context.Context
|
||||
header_ http.Header
|
||||
}
|
||||
|
||||
// Get: Retrieves an HMAC key's metadata
|
||||
func (r *ProjectsHmacKeysService) Get(projectId string, accessId string) *ProjectsHmacKeysGetCall {
|
||||
c := &ProjectsHmacKeysGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
|
||||
c.projectId = projectId
|
||||
c.accessId = accessId
|
||||
return c
|
||||
}
|
||||
|
||||
// Fields allows partial responses to be retrieved. See
|
||||
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
|
||||
// for more information.
|
||||
func (c *ProjectsHmacKeysGetCall) Fields(s ...googleapi.Field) *ProjectsHmacKeysGetCall {
|
||||
c.urlParams_.Set("fields", googleapi.CombineFields(s))
|
||||
return c
|
||||
}
|
||||
|
||||
// IfNoneMatch sets the optional parameter which makes the operation
|
||||
// fail if the object's ETag matches the given value. This is useful for
|
||||
// getting updates only after the object has changed since the last
|
||||
// request. Use googleapi.IsNotModified to check whether the response
|
||||
// error from Do is the result of In-None-Match.
|
||||
func (c *ProjectsHmacKeysGetCall) IfNoneMatch(entityTag string) *ProjectsHmacKeysGetCall {
|
||||
c.ifNoneMatch_ = entityTag
|
||||
return c
|
||||
}
|
||||
|
||||
// Context sets the context to be used in this call's Do method. Any
|
||||
// pending HTTP request will be aborted if the provided context is
|
||||
// canceled.
|
||||
func (c *ProjectsHmacKeysGetCall) Context(ctx context.Context) *ProjectsHmacKeysGetCall {
|
||||
c.ctx_ = ctx
|
||||
return c
|
||||
}
|
||||
|
||||
// Header returns an http.Header that can be modified by the caller to
|
||||
// add HTTP headers to the request.
|
||||
func (c *ProjectsHmacKeysGetCall) Header() http.Header {
|
||||
if c.header_ == nil {
|
||||
c.header_ = make(http.Header)
|
||||
}
|
||||
return c.header_
|
||||
}
|
||||
|
||||
func (c *ProjectsHmacKeysGetCall) doRequest(alt string) (*http.Response, error) {
|
||||
reqHeaders := make(http.Header)
|
||||
for k, v := range c.header_ {
|
||||
reqHeaders[k] = v
|
||||
}
|
||||
reqHeaders.Set("User-Agent", c.s.userAgent())
|
||||
if c.ifNoneMatch_ != "" {
|
||||
reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
|
||||
}
|
||||
var body io.Reader = nil
|
||||
c.urlParams_.Set("alt", alt)
|
||||
c.urlParams_.Set("prettyPrint", "false")
|
||||
urls := googleapi.ResolveRelative(c.s.BasePath, "projects/{projectId}/hmacKeys/{accessId}")
|
||||
urls += "?" + c.urlParams_.Encode()
|
||||
req, err := http.NewRequest("GET", urls, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header = reqHeaders
|
||||
googleapi.Expand(req.URL, map[string]string{
|
||||
"projectId": c.projectId,
|
||||
"accessId": c.accessId,
|
||||
})
|
||||
return gensupport.SendRequest(c.ctx_, c.s.client, req)
|
||||
}
|
||||
|
||||
// Do executes the "storage.projects.hmacKeys.get" call.
|
||||
// Exactly one of *HmacKeyMetadata or error will be non-nil. Any non-2xx
|
||||
// status code is an error. Response headers are in either
|
||||
// *HmacKeyMetadata.ServerResponse.Header or (if a response was returned
|
||||
// at all) in error.(*googleapi.Error).Header. Use
|
||||
// googleapi.IsNotModified to check whether the returned error was
|
||||
// because http.StatusNotModified was returned.
|
||||
func (c *ProjectsHmacKeysGetCall) Do(opts ...googleapi.CallOption) (*HmacKeyMetadata, error) {
|
||||
gensupport.SetOptions(c.urlParams_, opts...)
|
||||
res, err := c.doRequest("json")
|
||||
if res != nil && res.StatusCode == http.StatusNotModified {
|
||||
if res.Body != nil {
|
||||
res.Body.Close()
|
||||
}
|
||||
return nil, &googleapi.Error{
|
||||
Code: res.StatusCode,
|
||||
Header: res.Header,
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer googleapi.CloseBody(res)
|
||||
if err := googleapi.CheckResponse(res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := &HmacKeyMetadata{
|
||||
ServerResponse: googleapi.ServerResponse{
|
||||
Header: res.Header,
|
||||
HTTPStatusCode: res.StatusCode,
|
||||
},
|
||||
}
|
||||
target := &ret
|
||||
if err := gensupport.DecodeResponse(target, res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, nil
|
||||
// {
|
||||
// "description": "Retrieves an HMAC key's metadata",
|
||||
// "httpMethod": "GET",
|
||||
// "id": "storage.projects.hmacKeys.get",
|
||||
// "parameterOrder": [
|
||||
// "projectId",
|
||||
// "accessId"
|
||||
// ],
|
||||
// "parameters": {
|
||||
// "accessId": {
|
||||
// "description": "Name of the HMAC key.",
|
||||
// "location": "path",
|
||||
// "required": true,
|
||||
// "type": "string"
|
||||
// },
|
||||
// "projectId": {
|
||||
// "description": "Project ID owning the service account of the requested key.",
|
||||
// "location": "path",
|
||||
// "required": true,
|
||||
// "type": "string"
|
||||
// }
|
||||
// },
|
||||
// "path": "projects/{projectId}/hmacKeys/{accessId}",
|
||||
// "response": {
|
||||
// "$ref": "HmacKeyMetadata"
|
||||
// },
|
||||
// "scopes": [
|
||||
// "https://www.googleapis.com/auth/cloud-platform",
|
||||
// "https://www.googleapis.com/auth/cloud-platform.read-only",
|
||||
// "https://www.googleapis.com/auth/devstorage.read_only"
|
||||
// ]
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
// method id "storage.projects.hmacKeys.list":
|
||||
|
||||
type ProjectsHmacKeysListCall struct {
|
||||
s *Service
|
||||
projectId string
|
||||
urlParams_ gensupport.URLParams
|
||||
ifNoneMatch_ string
|
||||
ctx_ context.Context
|
||||
header_ http.Header
|
||||
}
|
||||
|
||||
// List: Retrieves a list of HMAC keys matching the criteria.
|
||||
func (r *ProjectsHmacKeysService) List(projectId string) *ProjectsHmacKeysListCall {
|
||||
c := &ProjectsHmacKeysListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
|
||||
c.projectId = projectId
|
||||
return c
|
||||
}
|
||||
|
||||
// MaxResults sets the optional parameter "maxResults": Maximum number
|
||||
// of items plus prefixes to return in a single page of responses.
|
||||
// Because duplicate prefixes are omitted, fewer total results may be
|
||||
// returned than requested. The service uses this parameter or 1,000
|
||||
// items, whichever is smaller.
|
||||
func (c *ProjectsHmacKeysListCall) MaxResults(maxResults int64) *ProjectsHmacKeysListCall {
|
||||
c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
|
||||
return c
|
||||
}
|
||||
|
||||
// PageToken sets the optional parameter "pageToken": A
|
||||
// previously-returned page token representing part of the larger set of
|
||||
// results to view.
|
||||
func (c *ProjectsHmacKeysListCall) PageToken(pageToken string) *ProjectsHmacKeysListCall {
|
||||
c.urlParams_.Set("pageToken", pageToken)
|
||||
return c
|
||||
}
|
||||
|
||||
// ServiceAccountEmail sets the optional parameter
|
||||
// "serviceAccountEmail": If present, only keys for the given service
|
||||
// account are returned.
|
||||
func (c *ProjectsHmacKeysListCall) ServiceAccountEmail(serviceAccountEmail string) *ProjectsHmacKeysListCall {
|
||||
c.urlParams_.Set("serviceAccountEmail", serviceAccountEmail)
|
||||
return c
|
||||
}
|
||||
|
||||
// ShowDeletedKeys sets the optional parameter "showDeletedKeys":
|
||||
// Whether or not to show keys in the DELETED state.
|
||||
func (c *ProjectsHmacKeysListCall) ShowDeletedKeys(showDeletedKeys bool) *ProjectsHmacKeysListCall {
|
||||
c.urlParams_.Set("showDeletedKeys", fmt.Sprint(showDeletedKeys))
|
||||
return c
|
||||
}
|
||||
|
||||
// Fields allows partial responses to be retrieved. See
|
||||
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
|
||||
// for more information.
|
||||
func (c *ProjectsHmacKeysListCall) Fields(s ...googleapi.Field) *ProjectsHmacKeysListCall {
|
||||
c.urlParams_.Set("fields", googleapi.CombineFields(s))
|
||||
return c
|
||||
}
|
||||
|
||||
// IfNoneMatch sets the optional parameter which makes the operation
|
||||
// fail if the object's ETag matches the given value. This is useful for
|
||||
// getting updates only after the object has changed since the last
|
||||
// request. Use googleapi.IsNotModified to check whether the response
|
||||
// error from Do is the result of In-None-Match.
|
||||
func (c *ProjectsHmacKeysListCall) IfNoneMatch(entityTag string) *ProjectsHmacKeysListCall {
|
||||
c.ifNoneMatch_ = entityTag
|
||||
return c
|
||||
}
|
||||
|
||||
// Context sets the context to be used in this call's Do method. Any
|
||||
// pending HTTP request will be aborted if the provided context is
|
||||
// canceled.
|
||||
func (c *ProjectsHmacKeysListCall) Context(ctx context.Context) *ProjectsHmacKeysListCall {
|
||||
c.ctx_ = ctx
|
||||
return c
|
||||
}
|
||||
|
||||
// Header returns an http.Header that can be modified by the caller to
|
||||
// add HTTP headers to the request.
|
||||
func (c *ProjectsHmacKeysListCall) Header() http.Header {
|
||||
if c.header_ == nil {
|
||||
c.header_ = make(http.Header)
|
||||
}
|
||||
return c.header_
|
||||
}
|
||||
|
||||
func (c *ProjectsHmacKeysListCall) doRequest(alt string) (*http.Response, error) {
|
||||
reqHeaders := make(http.Header)
|
||||
for k, v := range c.header_ {
|
||||
reqHeaders[k] = v
|
||||
}
|
||||
reqHeaders.Set("User-Agent", c.s.userAgent())
|
||||
if c.ifNoneMatch_ != "" {
|
||||
reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
|
||||
}
|
||||
var body io.Reader = nil
|
||||
c.urlParams_.Set("alt", alt)
|
||||
c.urlParams_.Set("prettyPrint", "false")
|
||||
urls := googleapi.ResolveRelative(c.s.BasePath, "projects/{projectId}/hmacKeys")
|
||||
urls += "?" + c.urlParams_.Encode()
|
||||
req, err := http.NewRequest("GET", urls, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header = reqHeaders
|
||||
googleapi.Expand(req.URL, map[string]string{
|
||||
"projectId": c.projectId,
|
||||
})
|
||||
return gensupport.SendRequest(c.ctx_, c.s.client, req)
|
||||
}
|
||||
|
||||
// Do executes the "storage.projects.hmacKeys.list" call.
|
||||
// Exactly one of *HmacKeysMetadata or error will be non-nil. Any
|
||||
// non-2xx status code is an error. Response headers are in either
|
||||
// *HmacKeysMetadata.ServerResponse.Header or (if a response was
|
||||
// returned at all) in error.(*googleapi.Error).Header. Use
|
||||
// googleapi.IsNotModified to check whether the returned error was
|
||||
// because http.StatusNotModified was returned.
|
||||
func (c *ProjectsHmacKeysListCall) Do(opts ...googleapi.CallOption) (*HmacKeysMetadata, error) {
|
||||
gensupport.SetOptions(c.urlParams_, opts...)
|
||||
res, err := c.doRequest("json")
|
||||
if res != nil && res.StatusCode == http.StatusNotModified {
|
||||
if res.Body != nil {
|
||||
res.Body.Close()
|
||||
}
|
||||
return nil, &googleapi.Error{
|
||||
Code: res.StatusCode,
|
||||
Header: res.Header,
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer googleapi.CloseBody(res)
|
||||
if err := googleapi.CheckResponse(res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := &HmacKeysMetadata{
|
||||
ServerResponse: googleapi.ServerResponse{
|
||||
Header: res.Header,
|
||||
HTTPStatusCode: res.StatusCode,
|
||||
},
|
||||
}
|
||||
target := &ret
|
||||
if err := gensupport.DecodeResponse(target, res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, nil
|
||||
// {
|
||||
// "description": "Retrieves a list of HMAC keys matching the criteria.",
|
||||
// "httpMethod": "GET",
|
||||
// "id": "storage.projects.hmacKeys.list",
|
||||
// "parameterOrder": [
|
||||
// "projectId"
|
||||
// ],
|
||||
// "parameters": {
|
||||
// "maxResults": {
|
||||
// "default": "1000",
|
||||
// "description": "Maximum number of items plus prefixes to return in a single page of responses. Because duplicate prefixes are omitted, fewer total results may be returned than requested. The service uses this parameter or 1,000 items, whichever is smaller.",
|
||||
// "format": "uint32",
|
||||
// "location": "query",
|
||||
// "minimum": "0",
|
||||
// "type": "integer"
|
||||
// },
|
||||
// "pageToken": {
|
||||
// "description": "A previously-returned page token representing part of the larger set of results to view.",
|
||||
// "location": "query",
|
||||
// "type": "string"
|
||||
// },
|
||||
// "projectId": {
|
||||
// "description": "Name of the project in which to look for HMAC keys.",
|
||||
// "location": "path",
|
||||
// "required": true,
|
||||
// "type": "string"
|
||||
// },
|
||||
// "serviceAccountEmail": {
|
||||
// "description": "If present, only keys for the given service account are returned.",
|
||||
// "location": "query",
|
||||
// "type": "string"
|
||||
// },
|
||||
// "showDeletedKeys": {
|
||||
// "description": "Whether or not to show keys in the DELETED state.",
|
||||
// "location": "query",
|
||||
// "type": "boolean"
|
||||
// }
|
||||
// },
|
||||
// "path": "projects/{projectId}/hmacKeys",
|
||||
// "response": {
|
||||
// "$ref": "HmacKeysMetadata"
|
||||
// },
|
||||
// "scopes": [
|
||||
// "https://www.googleapis.com/auth/cloud-platform",
|
||||
// "https://www.googleapis.com/auth/cloud-platform.read-only",
|
||||
// "https://www.googleapis.com/auth/devstorage.full_control",
|
||||
// "https://www.googleapis.com/auth/devstorage.read_only"
|
||||
// ]
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
// Pages invokes f for each page of results.
|
||||
// A non-nil error returned from f will halt the iteration.
|
||||
// The provided context supersedes any context provided to the Context method.
|
||||
func (c *ProjectsHmacKeysListCall) Pages(ctx context.Context, f func(*HmacKeysMetadata) error) error {
|
||||
c.ctx_ = ctx
|
||||
defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
|
||||
for {
|
||||
x, err := c.Do()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := f(x); err != nil {
|
||||
return err
|
||||
}
|
||||
if x.NextPageToken == "" {
|
||||
return nil
|
||||
}
|
||||
c.PageToken(x.NextPageToken)
|
||||
}
|
||||
}
|
||||
|
||||
// method id "storage.projects.hmacKeys.update":
|
||||
|
||||
type ProjectsHmacKeysUpdateCall struct {
|
||||
s *Service
|
||||
projectId string
|
||||
accessId string
|
||||
hmackeymetadata *HmacKeyMetadata
|
||||
urlParams_ gensupport.URLParams
|
||||
ctx_ context.Context
|
||||
header_ http.Header
|
||||
}
|
||||
|
||||
// Update: Updates the state of an HMAC key. See the HMAC Key resource
|
||||
// descriptor for valid states.
|
||||
func (r *ProjectsHmacKeysService) Update(projectId string, accessId string, hmackeymetadata *HmacKeyMetadata) *ProjectsHmacKeysUpdateCall {
|
||||
c := &ProjectsHmacKeysUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
|
||||
c.projectId = projectId
|
||||
c.accessId = accessId
|
||||
c.hmackeymetadata = hmackeymetadata
|
||||
return c
|
||||
}
|
||||
|
||||
// Fields allows partial responses to be retrieved. See
|
||||
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
|
||||
// for more information.
|
||||
func (c *ProjectsHmacKeysUpdateCall) Fields(s ...googleapi.Field) *ProjectsHmacKeysUpdateCall {
|
||||
c.urlParams_.Set("fields", googleapi.CombineFields(s))
|
||||
return c
|
||||
}
|
||||
|
||||
// Context sets the context to be used in this call's Do method. Any
|
||||
// pending HTTP request will be aborted if the provided context is
|
||||
// canceled.
|
||||
func (c *ProjectsHmacKeysUpdateCall) Context(ctx context.Context) *ProjectsHmacKeysUpdateCall {
|
||||
c.ctx_ = ctx
|
||||
return c
|
||||
}
|
||||
|
||||
// Header returns an http.Header that can be modified by the caller to
|
||||
// add HTTP headers to the request.
|
||||
func (c *ProjectsHmacKeysUpdateCall) Header() http.Header {
|
||||
if c.header_ == nil {
|
||||
c.header_ = make(http.Header)
|
||||
}
|
||||
return c.header_
|
||||
}
|
||||
|
||||
func (c *ProjectsHmacKeysUpdateCall) doRequest(alt string) (*http.Response, error) {
|
||||
reqHeaders := make(http.Header)
|
||||
for k, v := range c.header_ {
|
||||
reqHeaders[k] = v
|
||||
}
|
||||
reqHeaders.Set("User-Agent", c.s.userAgent())
|
||||
var body io.Reader = nil
|
||||
body, err := googleapi.WithoutDataWrapper.JSONReader(c.hmackeymetadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reqHeaders.Set("Content-Type", "application/json")
|
||||
c.urlParams_.Set("alt", alt)
|
||||
c.urlParams_.Set("prettyPrint", "false")
|
||||
urls := googleapi.ResolveRelative(c.s.BasePath, "projects/{projectId}/hmacKeys/{accessId}")
|
||||
urls += "?" + c.urlParams_.Encode()
|
||||
req, err := http.NewRequest("PUT", urls, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header = reqHeaders
|
||||
googleapi.Expand(req.URL, map[string]string{
|
||||
"projectId": c.projectId,
|
||||
"accessId": c.accessId,
|
||||
})
|
||||
return gensupport.SendRequest(c.ctx_, c.s.client, req)
|
||||
}
|
||||
|
||||
// Do executes the "storage.projects.hmacKeys.update" call.
|
||||
// Exactly one of *HmacKeyMetadata or error will be non-nil. Any non-2xx
|
||||
// status code is an error. Response headers are in either
|
||||
// *HmacKeyMetadata.ServerResponse.Header or (if a response was returned
|
||||
// at all) in error.(*googleapi.Error).Header. Use
|
||||
// googleapi.IsNotModified to check whether the returned error was
|
||||
// because http.StatusNotModified was returned.
|
||||
func (c *ProjectsHmacKeysUpdateCall) Do(opts ...googleapi.CallOption) (*HmacKeyMetadata, error) {
|
||||
gensupport.SetOptions(c.urlParams_, opts...)
|
||||
res, err := c.doRequest("json")
|
||||
if res != nil && res.StatusCode == http.StatusNotModified {
|
||||
if res.Body != nil {
|
||||
res.Body.Close()
|
||||
}
|
||||
return nil, &googleapi.Error{
|
||||
Code: res.StatusCode,
|
||||
Header: res.Header,
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer googleapi.CloseBody(res)
|
||||
if err := googleapi.CheckResponse(res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := &HmacKeyMetadata{
|
||||
ServerResponse: googleapi.ServerResponse{
|
||||
Header: res.Header,
|
||||
HTTPStatusCode: res.StatusCode,
|
||||
},
|
||||
}
|
||||
target := &ret
|
||||
if err := gensupport.DecodeResponse(target, res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, nil
|
||||
// {
|
||||
// "description": "Updates the state of an HMAC key. See the HMAC Key resource descriptor for valid states.",
|
||||
// "httpMethod": "PUT",
|
||||
// "id": "storage.projects.hmacKeys.update",
|
||||
// "parameterOrder": [
|
||||
// "projectId",
|
||||
// "accessId"
|
||||
// ],
|
||||
// "parameters": {
|
||||
// "accessId": {
|
||||
// "description": "Name of the HMAC key being updated.",
|
||||
// "location": "path",
|
||||
// "required": true,
|
||||
// "type": "string"
|
||||
// },
|
||||
// "projectId": {
|
||||
// "description": "Project ID owning the service account of the updated key.",
|
||||
// "location": "path",
|
||||
// "required": true,
|
||||
// "type": "string"
|
||||
// }
|
||||
// },
|
||||
// "path": "projects/{projectId}/hmacKeys/{accessId}",
|
||||
// "request": {
|
||||
// "$ref": "HmacKeyMetadata"
|
||||
// },
|
||||
// "response": {
|
||||
// "$ref": "HmacKeyMetadata"
|
||||
// },
|
||||
// "scopes": [
|
||||
// "https://www.googleapis.com/auth/cloud-platform",
|
||||
// "https://www.googleapis.com/auth/devstorage.full_control"
|
||||
// ]
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
// method id "storage.projects.serviceAccount.get":
|
||||
|
||||
type ProjectsServiceAccountGetCall struct {
|
||||
|
|
|
@ -2,7 +2,7 @@ language: go
|
|||
|
||||
matrix:
|
||||
include:
|
||||
- go: 1.12beta2
|
||||
- go: 1.12.x
|
||||
env: GO111MODULE=on
|
||||
- go: 1.11.x
|
||||
env: VET=1 GO111MODULE=on
|
||||
|
|
|
@ -171,9 +171,6 @@ type PickOptions struct {
|
|||
// FullMethodName is the method name that NewClientStream() is called
|
||||
// with. The canonical format is /service/Method.
|
||||
FullMethodName string
|
||||
// Header contains the metadata from the RPC's client header. The metadata
|
||||
// should not be modified; make a copy first if needed.
|
||||
Header metadata.MD
|
||||
}
|
||||
|
||||
// DoneInfo contains additional information for done.
|
||||
|
@ -186,6 +183,11 @@ type DoneInfo struct {
|
|||
BytesSent bool
|
||||
// BytesReceived indicates if any byte has been received from the server.
|
||||
BytesReceived bool
|
||||
// ServerLoad is the load received from server. It's usually sent as part of
|
||||
// trailing metadata.
|
||||
//
|
||||
// The only supported type now is *orca_v1.LoadReport.
|
||||
ServerLoad interface{}
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -215,8 +217,10 @@ type Picker interface {
|
|||
//
|
||||
// If a SubConn is returned:
|
||||
// - If it is READY, gRPC will send the RPC on it;
|
||||
// - If it is not ready, or becomes not ready after it's returned, gRPC will block
|
||||
// until UpdateBalancerState() is called and will call pick on the new picker.
|
||||
// - If it is not ready, or becomes not ready after it's returned, gRPC will
|
||||
// block until UpdateBalancerState() is called and will call pick on the
|
||||
// new picker. The done function returned from Pick(), if not nil, will be
|
||||
// called with nil error, no bytes sent and no bytes received.
|
||||
//
|
||||
// If the returned error is not nil:
|
||||
// - If the error is ErrNoSubConnAvailable, gRPC will block until UpdateBalancerState()
|
||||
|
@ -249,18 +253,46 @@ type Balancer interface {
|
|||
// that back to gRPC.
|
||||
// Balancer should also generate and update Pickers when its internal state has
|
||||
// been changed by the new state.
|
||||
//
|
||||
// Deprecated: if V2Balancer is implemented by the Balancer,
|
||||
// UpdateSubConnState will be called instead.
|
||||
HandleSubConnStateChange(sc SubConn, state connectivity.State)
|
||||
// HandleResolvedAddrs is called by gRPC to send updated resolved addresses to
|
||||
// balancers.
|
||||
// Balancer can create new SubConn or remove SubConn with the addresses.
|
||||
// An empty address slice and a non-nil error will be passed if the resolver returns
|
||||
// non-nil error to gRPC.
|
||||
//
|
||||
// Deprecated: if V2Balancer is implemented by the Balancer,
|
||||
// UpdateResolverState will be called instead.
|
||||
HandleResolvedAddrs([]resolver.Address, error)
|
||||
// Close closes the balancer. The balancer is not required to call
|
||||
// ClientConn.RemoveSubConn for its existing SubConns.
|
||||
Close()
|
||||
}
|
||||
|
||||
// SubConnState describes the state of a SubConn.
|
||||
type SubConnState struct {
|
||||
ConnectivityState connectivity.State
|
||||
// TODO: add last connection error
|
||||
}
|
||||
|
||||
// V2Balancer is defined for documentation purposes. If a Balancer also
|
||||
// implements V2Balancer, its UpdateResolverState method will be called instead
|
||||
// of HandleResolvedAddrs and its UpdateSubConnState will be called instead of
|
||||
// HandleSubConnStateChange.
|
||||
type V2Balancer interface {
|
||||
// UpdateResolverState is called by gRPC when the state of the resolver
|
||||
// changes.
|
||||
UpdateResolverState(resolver.State)
|
||||
// UpdateSubConnState is called by gRPC when the state of a SubConn
|
||||
// changes.
|
||||
UpdateSubConnState(SubConn, SubConnState)
|
||||
// Close closes the balancer. The balancer is not required to call
|
||||
// ClientConn.RemoveSubConn for its existing SubConns.
|
||||
Close()
|
||||
}
|
||||
|
||||
// ConnectivityStateEvaluator takes the connectivity states of multiple SubConns
|
||||
// and returns one aggregated connectivity state.
|
||||
//
|
||||
|
|
|
@ -67,14 +67,16 @@ type baseBalancer struct {
|
|||
}
|
||||
|
||||
func (b *baseBalancer) HandleResolvedAddrs(addrs []resolver.Address, err error) {
|
||||
if err != nil {
|
||||
grpclog.Infof("base.baseBalancer: HandleResolvedAddrs called with error %v", err)
|
||||
return
|
||||
}
|
||||
grpclog.Infoln("base.baseBalancer: got new resolved addresses: ", addrs)
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (b *baseBalancer) UpdateResolverState(s resolver.State) {
|
||||
// TODO: handle s.Err (log if not nil) once implemented.
|
||||
// TODO: handle s.ServiceConfig?
|
||||
grpclog.Infoln("base.baseBalancer: got new resolver state: ", s)
|
||||
// addrsSet is the set converted from addrs, it's used for quick lookup of an address.
|
||||
addrsSet := make(map[resolver.Address]struct{})
|
||||
for _, a := range addrs {
|
||||
for _, a := range s.Addresses {
|
||||
addrsSet[a] = struct{}{}
|
||||
if _, ok := b.subConns[a]; !ok {
|
||||
// a is a new address (not existing in b.subConns).
|
||||
|
@ -120,6 +122,11 @@ func (b *baseBalancer) regeneratePicker() {
|
|||
}
|
||||
|
||||
func (b *baseBalancer) HandleSubConnStateChange(sc balancer.SubConn, s connectivity.State) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) {
|
||||
s := state.ConnectivityState
|
||||
grpclog.Infof("base.baseBalancer: handle SubConn state change: %p, %v", sc, s)
|
||||
oldS, ok := b.scStates[sc]
|
||||
if !ok {
|
||||
|
|
|
@ -82,20 +82,13 @@ func (b *scStateUpdateBuffer) get() <-chan *scStateUpdate {
|
|||
return b.c
|
||||
}
|
||||
|
||||
// resolverUpdate contains the new resolved addresses or error if there's
|
||||
// any.
|
||||
type resolverUpdate struct {
|
||||
addrs []resolver.Address
|
||||
err error
|
||||
}
|
||||
|
||||
// ccBalancerWrapper is a wrapper on top of cc for balancers.
|
||||
// It implements balancer.ClientConn interface.
|
||||
type ccBalancerWrapper struct {
|
||||
cc *ClientConn
|
||||
balancer balancer.Balancer
|
||||
stateChangeQueue *scStateUpdateBuffer
|
||||
resolverUpdateCh chan *resolverUpdate
|
||||
resolverUpdateCh chan *resolver.State
|
||||
done chan struct{}
|
||||
|
||||
mu sync.Mutex
|
||||
|
@ -106,7 +99,7 @@ func newCCBalancerWrapper(cc *ClientConn, b balancer.Builder, bopts balancer.Bui
|
|||
ccb := &ccBalancerWrapper{
|
||||
cc: cc,
|
||||
stateChangeQueue: newSCStateUpdateBuffer(),
|
||||
resolverUpdateCh: make(chan *resolverUpdate, 1),
|
||||
resolverUpdateCh: make(chan *resolver.State, 1),
|
||||
done: make(chan struct{}),
|
||||
subConns: make(map[*acBalancerWrapper]struct{}),
|
||||
}
|
||||
|
@ -128,15 +121,23 @@ func (ccb *ccBalancerWrapper) watcher() {
|
|||
return
|
||||
default:
|
||||
}
|
||||
ccb.balancer.HandleSubConnStateChange(t.sc, t.state)
|
||||
case t := <-ccb.resolverUpdateCh:
|
||||
if ub, ok := ccb.balancer.(balancer.V2Balancer); ok {
|
||||
ub.UpdateSubConnState(t.sc, balancer.SubConnState{ConnectivityState: t.state})
|
||||
} else {
|
||||
ccb.balancer.HandleSubConnStateChange(t.sc, t.state)
|
||||
}
|
||||
case s := <-ccb.resolverUpdateCh:
|
||||
select {
|
||||
case <-ccb.done:
|
||||
ccb.balancer.Close()
|
||||
return
|
||||
default:
|
||||
}
|
||||
ccb.balancer.HandleResolvedAddrs(t.addrs, t.err)
|
||||
if ub, ok := ccb.balancer.(balancer.V2Balancer); ok {
|
||||
ub.UpdateResolverState(*s)
|
||||
} else {
|
||||
ccb.balancer.HandleResolvedAddrs(s.Addresses, nil)
|
||||
}
|
||||
case <-ccb.done:
|
||||
}
|
||||
|
||||
|
@ -177,37 +178,23 @@ func (ccb *ccBalancerWrapper) handleSubConnStateChange(sc balancer.SubConn, s co
|
|||
})
|
||||
}
|
||||
|
||||
func (ccb *ccBalancerWrapper) handleResolvedAddrs(addrs []resolver.Address, err error) {
|
||||
func (ccb *ccBalancerWrapper) updateResolverState(s resolver.State) {
|
||||
if ccb.cc.curBalancerName != grpclbName {
|
||||
var containsGRPCLB bool
|
||||
for _, a := range addrs {
|
||||
if a.Type == resolver.GRPCLB {
|
||||
containsGRPCLB = true
|
||||
break
|
||||
// Filter any grpclb addresses since we don't have the grpclb balancer.
|
||||
for i := 0; i < len(s.Addresses); {
|
||||
if s.Addresses[i].Type == resolver.GRPCLB {
|
||||
copy(s.Addresses[i:], s.Addresses[i+1:])
|
||||
s.Addresses = s.Addresses[:len(s.Addresses)-1]
|
||||
continue
|
||||
}
|
||||
}
|
||||
if containsGRPCLB {
|
||||
// The current balancer is not grpclb, but addresses contain grpclb
|
||||
// address. This means we failed to switch to grpclb, most likely
|
||||
// because grpclb is not registered. Filter out all grpclb addresses
|
||||
// from addrs before sending to balancer.
|
||||
tempAddrs := make([]resolver.Address, 0, len(addrs))
|
||||
for _, a := range addrs {
|
||||
if a.Type != resolver.GRPCLB {
|
||||
tempAddrs = append(tempAddrs, a)
|
||||
}
|
||||
}
|
||||
addrs = tempAddrs
|
||||
i++
|
||||
}
|
||||
}
|
||||
select {
|
||||
case <-ccb.resolverUpdateCh:
|
||||
default:
|
||||
}
|
||||
ccb.resolverUpdateCh <- &resolverUpdate{
|
||||
addrs: addrs,
|
||||
err: err,
|
||||
}
|
||||
ccb.resolverUpdateCh <- &s
|
||||
}
|
||||
|
||||
func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) {
|
||||
|
|
|
@ -42,7 +42,6 @@ import (
|
|||
"google.golang.org/grpc/internal/grpcsync"
|
||||
"google.golang.org/grpc/internal/transport"
|
||||
"google.golang.org/grpc/keepalive"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/resolver"
|
||||
_ "google.golang.org/grpc/resolver/dns" // To register dns resolver.
|
||||
_ "google.golang.org/grpc/resolver/passthrough" // To register passthrough resolver.
|
||||
|
@ -69,11 +68,9 @@ var (
|
|||
errConnClosing = errors.New("grpc: the connection is closing")
|
||||
// errBalancerClosed indicates that the balancer is closed.
|
||||
errBalancerClosed = errors.New("grpc: balancer is closed")
|
||||
// We use an accessor so that minConnectTimeout can be
|
||||
// atomically read and updated while testing.
|
||||
getMinConnectTimeout = func() time.Duration {
|
||||
return minConnectTimeout
|
||||
}
|
||||
// invalidDefaultServiceConfigErrPrefix is used to prefix the json parsing error for the default
|
||||
// service config.
|
||||
invalidDefaultServiceConfigErrPrefix = "grpc: the provided default service config is invalid"
|
||||
)
|
||||
|
||||
// The following errors are returned from Dial and DialContext
|
||||
|
@ -140,6 +137,12 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
|
|||
opt.apply(&cc.dopts)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
cc.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
if channelz.IsOn() {
|
||||
if cc.dopts.channelzParentID != 0 {
|
||||
cc.channelzID = channelz.RegisterChannel(&channelzChannel{cc}, cc.dopts.channelzParentID, target)
|
||||
|
@ -179,6 +182,13 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
|
|||
}
|
||||
}
|
||||
|
||||
if cc.dopts.defaultServiceConfigRawJSON != nil {
|
||||
sc, err := parseServiceConfig(*cc.dopts.defaultServiceConfigRawJSON)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: %v", invalidDefaultServiceConfigErrPrefix, err)
|
||||
}
|
||||
cc.dopts.defaultServiceConfig = sc
|
||||
}
|
||||
cc.mkp = cc.dopts.copts.KeepaliveParams
|
||||
|
||||
if cc.dopts.copts.Dialer == nil {
|
||||
|
@ -201,17 +211,12 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
|
|||
ctx, cancel = context.WithTimeout(ctx, cc.dopts.timeout)
|
||||
defer cancel()
|
||||
}
|
||||
|
||||
defer func() {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
conn, err = nil, ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
cc.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
scSet := false
|
||||
|
@ -220,7 +225,7 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
|
|||
select {
|
||||
case sc, ok := <-cc.dopts.scChan:
|
||||
if ok {
|
||||
cc.sc = sc
|
||||
cc.sc = &sc
|
||||
scSet = true
|
||||
}
|
||||
default:
|
||||
|
@ -266,7 +271,7 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
|
|||
select {
|
||||
case sc, ok := <-cc.dopts.scChan:
|
||||
if ok {
|
||||
cc.sc = sc
|
||||
cc.sc = &sc
|
||||
}
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
|
@ -388,14 +393,11 @@ type ClientConn struct {
|
|||
|
||||
mu sync.RWMutex
|
||||
resolverWrapper *ccResolverWrapper
|
||||
sc ServiceConfig
|
||||
scRaw string
|
||||
sc *ServiceConfig
|
||||
conns map[*addrConn]struct{}
|
||||
// Keepalive parameter can be updated if a GoAway is received.
|
||||
mkp keepalive.ClientParameters
|
||||
curBalancerName string
|
||||
preBalancerName string // previous balancer name.
|
||||
curAddresses []resolver.Address
|
||||
balancerWrapper *ccBalancerWrapper
|
||||
retryThrottler atomic.Value
|
||||
|
||||
|
@ -437,8 +439,7 @@ func (cc *ClientConn) scWatcher() {
|
|||
cc.mu.Lock()
|
||||
// TODO: load balance policy runtime change is ignored.
|
||||
// We may revisit this decision in the future.
|
||||
cc.sc = sc
|
||||
cc.scRaw = ""
|
||||
cc.sc = &sc
|
||||
cc.mu.Unlock()
|
||||
case <-cc.ctx.Done():
|
||||
return
|
||||
|
@ -465,50 +466,72 @@ func (cc *ClientConn) waitForResolvedAddrs(ctx context.Context) error {
|
|||
}
|
||||
}
|
||||
|
||||
func (cc *ClientConn) handleResolvedAddrs(addrs []resolver.Address, err error) {
|
||||
// gRPC should resort to default service config when:
|
||||
// * resolver service config is disabled
|
||||
// * or, resolver does not return a service config or returns an invalid one.
|
||||
func (cc *ClientConn) fallbackToDefaultServiceConfig(sc string) bool {
|
||||
if cc.dopts.disableServiceConfig {
|
||||
return true
|
||||
}
|
||||
// The logic below is temporary, will be removed once we change the resolver.State ServiceConfig field type.
|
||||
// Right now, we assume that empty service config string means resolver does not return a config.
|
||||
if sc == "" {
|
||||
return true
|
||||
}
|
||||
// TODO: the logic below is temporary. Once we finish the logic to validate service config
|
||||
// in resolver, we will replace the logic below.
|
||||
_, err := parseServiceConfig(sc)
|
||||
return err != nil
|
||||
}
|
||||
|
||||
func (cc *ClientConn) updateResolverState(s resolver.State) error {
|
||||
cc.mu.Lock()
|
||||
defer cc.mu.Unlock()
|
||||
// Check if the ClientConn is already closed. Some fields (e.g.
|
||||
// balancerWrapper) are set to nil when closing the ClientConn, and could
|
||||
// cause nil pointer panic if we don't have this check.
|
||||
if cc.conns == nil {
|
||||
// cc was closed.
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
if reflect.DeepEqual(cc.curAddresses, addrs) {
|
||||
return
|
||||
if cc.fallbackToDefaultServiceConfig(s.ServiceConfig) {
|
||||
if cc.dopts.defaultServiceConfig != nil && cc.sc == nil {
|
||||
cc.applyServiceConfig(cc.dopts.defaultServiceConfig)
|
||||
}
|
||||
} else {
|
||||
// TODO: the parsing logic below will be moved inside resolver.
|
||||
sc, err := parseServiceConfig(s.ServiceConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if cc.sc == nil || cc.sc.rawJSONString != s.ServiceConfig {
|
||||
cc.applyServiceConfig(sc)
|
||||
}
|
||||
}
|
||||
|
||||
cc.curAddresses = addrs
|
||||
cc.firstResolveEvent.Fire()
|
||||
// update the service config that will be sent to balancer.
|
||||
if cc.sc != nil {
|
||||
s.ServiceConfig = cc.sc.rawJSONString
|
||||
}
|
||||
|
||||
if cc.dopts.balancerBuilder == nil {
|
||||
// Only look at balancer types and switch balancer if balancer dial
|
||||
// option is not set.
|
||||
var isGRPCLB bool
|
||||
for _, a := range addrs {
|
||||
for _, a := range s.Addresses {
|
||||
if a.Type == resolver.GRPCLB {
|
||||
isGRPCLB = true
|
||||
break
|
||||
}
|
||||
}
|
||||
var newBalancerName string
|
||||
// TODO: use new loadBalancerConfig field with appropriate priority.
|
||||
if isGRPCLB {
|
||||
newBalancerName = grpclbName
|
||||
} else if cc.sc != nil && cc.sc.LB != nil {
|
||||
newBalancerName = *cc.sc.LB
|
||||
} else {
|
||||
// Address list doesn't contain grpclb address. Try to pick a
|
||||
// non-grpclb balancer.
|
||||
newBalancerName = cc.curBalancerName
|
||||
// If current balancer is grpclb, switch to the previous one.
|
||||
if newBalancerName == grpclbName {
|
||||
newBalancerName = cc.preBalancerName
|
||||
}
|
||||
// The following could be true in two cases:
|
||||
// - the first time handling resolved addresses
|
||||
// (curBalancerName="")
|
||||
// - the first time handling non-grpclb addresses
|
||||
// (curBalancerName="grpclb", preBalancerName="")
|
||||
if newBalancerName == "" {
|
||||
newBalancerName = PickFirstBalancerName
|
||||
}
|
||||
newBalancerName = PickFirstBalancerName
|
||||
}
|
||||
cc.switchBalancer(newBalancerName)
|
||||
} else if cc.balancerWrapper == nil {
|
||||
|
@ -517,7 +540,9 @@ func (cc *ClientConn) handleResolvedAddrs(addrs []resolver.Address, err error) {
|
|||
cc.balancerWrapper = newCCBalancerWrapper(cc, cc.dopts.balancerBuilder, cc.balancerBuildOpts)
|
||||
}
|
||||
|
||||
cc.balancerWrapper.handleResolvedAddrs(addrs, nil)
|
||||
cc.balancerWrapper.updateResolverState(s)
|
||||
cc.firstResolveEvent.Fire()
|
||||
return nil
|
||||
}
|
||||
|
||||
// switchBalancer starts the switching from current balancer to the balancer
|
||||
|
@ -529,10 +554,6 @@ func (cc *ClientConn) handleResolvedAddrs(addrs []resolver.Address, err error) {
|
|||
//
|
||||
// Caller must hold cc.mu.
|
||||
func (cc *ClientConn) switchBalancer(name string) {
|
||||
if cc.conns == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if strings.ToLower(cc.curBalancerName) == strings.ToLower(name) {
|
||||
return
|
||||
}
|
||||
|
@ -542,15 +563,11 @@ func (cc *ClientConn) switchBalancer(name string) {
|
|||
grpclog.Infoln("ignoring balancer switching: Balancer DialOption used instead")
|
||||
return
|
||||
}
|
||||
// TODO(bar switching) change this to two steps: drain and close.
|
||||
// Keep track of sc in wrapper.
|
||||
if cc.balancerWrapper != nil {
|
||||
cc.balancerWrapper.close()
|
||||
}
|
||||
|
||||
builder := balancer.Get(name)
|
||||
// TODO(yuxuanli): If user send a service config that does not contain a valid balancer name, should
|
||||
// we reuse previous one?
|
||||
if channelz.IsOn() {
|
||||
if builder == nil {
|
||||
channelz.AddTraceEvent(cc.channelzID, &channelz.TraceEventDesc{
|
||||
|
@ -569,7 +586,6 @@ func (cc *ClientConn) switchBalancer(name string) {
|
|||
builder = newPickfirstBuilder()
|
||||
}
|
||||
|
||||
cc.preBalancerName = cc.curBalancerName
|
||||
cc.curBalancerName = builder.Name()
|
||||
cc.balancerWrapper = newCCBalancerWrapper(cc, builder, cc.balancerBuildOpts)
|
||||
}
|
||||
|
@ -732,6 +748,9 @@ func (cc *ClientConn) GetMethodConfig(method string) MethodConfig {
|
|||
// TODO: Avoid the locking here.
|
||||
cc.mu.RLock()
|
||||
defer cc.mu.RUnlock()
|
||||
if cc.sc == nil {
|
||||
return MethodConfig{}
|
||||
}
|
||||
m, ok := cc.sc.Methods[method]
|
||||
if !ok {
|
||||
i := strings.LastIndex(method, "/")
|
||||
|
@ -743,14 +762,15 @@ func (cc *ClientConn) GetMethodConfig(method string) MethodConfig {
|
|||
func (cc *ClientConn) healthCheckConfig() *healthCheckConfig {
|
||||
cc.mu.RLock()
|
||||
defer cc.mu.RUnlock()
|
||||
if cc.sc == nil {
|
||||
return nil
|
||||
}
|
||||
return cc.sc.healthCheckConfig
|
||||
}
|
||||
|
||||
func (cc *ClientConn) getTransport(ctx context.Context, failfast bool, method string) (transport.ClientTransport, func(balancer.DoneInfo), error) {
|
||||
hdr, _ := metadata.FromOutgoingContext(ctx)
|
||||
t, done, err := cc.blockingpicker.pick(ctx, failfast, balancer.PickOptions{
|
||||
FullMethodName: method,
|
||||
Header: hdr,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, toRPCErr(err)
|
||||
|
@ -758,65 +778,25 @@ func (cc *ClientConn) getTransport(ctx context.Context, failfast bool, method st
|
|||
return t, done, nil
|
||||
}
|
||||
|
||||
// handleServiceConfig parses the service config string in JSON format to Go native
|
||||
// struct ServiceConfig, and store both the struct and the JSON string in ClientConn.
|
||||
func (cc *ClientConn) handleServiceConfig(js string) error {
|
||||
if cc.dopts.disableServiceConfig {
|
||||
return nil
|
||||
func (cc *ClientConn) applyServiceConfig(sc *ServiceConfig) error {
|
||||
if sc == nil {
|
||||
// should never reach here.
|
||||
return fmt.Errorf("got nil pointer for service config")
|
||||
}
|
||||
if cc.scRaw == js {
|
||||
return nil
|
||||
}
|
||||
if channelz.IsOn() {
|
||||
channelz.AddTraceEvent(cc.channelzID, &channelz.TraceEventDesc{
|
||||
// The special formatting of \"%s\" instead of %q is to provide nice printing of service config
|
||||
// for human consumption.
|
||||
Desc: fmt.Sprintf("Channel has a new service config \"%s\"", js),
|
||||
Severity: channelz.CtINFO,
|
||||
})
|
||||
}
|
||||
sc, err := parseServiceConfig(js)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cc.mu.Lock()
|
||||
// Check if the ClientConn is already closed. Some fields (e.g.
|
||||
// balancerWrapper) are set to nil when closing the ClientConn, and could
|
||||
// cause nil pointer panic if we don't have this check.
|
||||
if cc.conns == nil {
|
||||
cc.mu.Unlock()
|
||||
return nil
|
||||
}
|
||||
cc.scRaw = js
|
||||
cc.sc = sc
|
||||
|
||||
if sc.retryThrottling != nil {
|
||||
if cc.sc.retryThrottling != nil {
|
||||
newThrottler := &retryThrottler{
|
||||
tokens: sc.retryThrottling.MaxTokens,
|
||||
max: sc.retryThrottling.MaxTokens,
|
||||
thresh: sc.retryThrottling.MaxTokens / 2,
|
||||
ratio: sc.retryThrottling.TokenRatio,
|
||||
tokens: cc.sc.retryThrottling.MaxTokens,
|
||||
max: cc.sc.retryThrottling.MaxTokens,
|
||||
thresh: cc.sc.retryThrottling.MaxTokens / 2,
|
||||
ratio: cc.sc.retryThrottling.TokenRatio,
|
||||
}
|
||||
cc.retryThrottler.Store(newThrottler)
|
||||
} else {
|
||||
cc.retryThrottler.Store((*retryThrottler)(nil))
|
||||
}
|
||||
|
||||
if sc.LB != nil && *sc.LB != grpclbName { // "grpclb" is not a valid balancer option in service config.
|
||||
if cc.curBalancerName == grpclbName {
|
||||
// If current balancer is grpclb, there's at least one grpclb
|
||||
// balancer address in the resolved list. Don't switch the balancer,
|
||||
// but change the previous balancer name, so if a new resolved
|
||||
// address list doesn't contain grpclb address, balancer will be
|
||||
// switched to *sc.LB.
|
||||
cc.preBalancerName = *sc.LB
|
||||
} else {
|
||||
cc.switchBalancer(*sc.LB)
|
||||
cc.balancerWrapper.handleResolvedAddrs(cc.curAddresses, nil)
|
||||
}
|
||||
}
|
||||
|
||||
cc.mu.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -892,7 +872,7 @@ func (cc *ClientConn) Close() error {
|
|||
}
|
||||
channelz.AddTraceEvent(cc.channelzID, ted)
|
||||
// TraceEvent needs to be called before RemoveEntry, as TraceEvent may add trace reference to
|
||||
// the entity beng deleted, and thus prevent it from being deleted right away.
|
||||
// the entity being deleted, and thus prevent it from being deleted right away.
|
||||
channelz.RemoveEntry(cc.channelzID)
|
||||
}
|
||||
return nil
|
||||
|
@ -921,8 +901,6 @@ type addrConn struct {
|
|||
// Use updateConnectivityState for updating addrConn's connectivity state.
|
||||
state connectivity.State
|
||||
|
||||
tearDownErr error // The reason this addrConn is torn down.
|
||||
|
||||
backoffIdx int // Needs to be stateful for resetConnectBackoff.
|
||||
resetBackoff chan struct{}
|
||||
|
||||
|
@ -963,191 +941,169 @@ func (ac *addrConn) adjustParams(r transport.GoAwayReason) {
|
|||
|
||||
func (ac *addrConn) resetTransport() {
|
||||
for i := 0; ; i++ {
|
||||
tryNextAddrFromStart := grpcsync.NewEvent()
|
||||
|
||||
ac.mu.Lock()
|
||||
if i > 0 {
|
||||
ac.cc.resolveNow(resolver.ResolveNowOption{})
|
||||
}
|
||||
|
||||
ac.mu.Lock()
|
||||
if ac.state == connectivity.Shutdown {
|
||||
ac.mu.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
addrs := ac.addrs
|
||||
backoffFor := ac.dopts.bs.Backoff(ac.backoffIdx)
|
||||
|
||||
// This will be the duration that dial gets to finish.
|
||||
dialDuration := getMinConnectTimeout()
|
||||
dialDuration := minConnectTimeout
|
||||
if ac.dopts.minConnectTimeout != nil {
|
||||
dialDuration = ac.dopts.minConnectTimeout()
|
||||
}
|
||||
|
||||
if dialDuration < backoffFor {
|
||||
// Give dial more time as we keep failing to connect.
|
||||
dialDuration = backoffFor
|
||||
}
|
||||
// We can potentially spend all the time trying the first address, and
|
||||
// if the server accepts the connection and then hangs, the following
|
||||
// addresses will never be tried.
|
||||
//
|
||||
// The spec doesn't mention what should be done for multiple addresses.
|
||||
// https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md#proposed-backoff-algorithm
|
||||
connectDeadline := time.Now().Add(dialDuration)
|
||||
ac.mu.Unlock()
|
||||
|
||||
addrLoop:
|
||||
for _, addr := range addrs {
|
||||
newTr, addr, reconnect, err := ac.tryAllAddrs(addrs, connectDeadline)
|
||||
if err != nil {
|
||||
// After exhausting all addresses, the addrConn enters
|
||||
// TRANSIENT_FAILURE.
|
||||
ac.mu.Lock()
|
||||
|
||||
if ac.state == connectivity.Shutdown {
|
||||
ac.mu.Unlock()
|
||||
return
|
||||
}
|
||||
ac.updateConnectivityState(connectivity.Connecting)
|
||||
ac.transport = nil
|
||||
ac.updateConnectivityState(connectivity.TransientFailure)
|
||||
|
||||
ac.cc.mu.RLock()
|
||||
ac.dopts.copts.KeepaliveParams = ac.cc.mkp
|
||||
ac.cc.mu.RUnlock()
|
||||
// Backoff.
|
||||
b := ac.resetBackoff
|
||||
ac.mu.Unlock()
|
||||
|
||||
if ac.state == connectivity.Shutdown {
|
||||
timer := time.NewTimer(backoffFor)
|
||||
select {
|
||||
case <-timer.C:
|
||||
ac.mu.Lock()
|
||||
ac.backoffIdx++
|
||||
ac.mu.Unlock()
|
||||
case <-b:
|
||||
timer.Stop()
|
||||
case <-ac.ctx.Done():
|
||||
timer.Stop()
|
||||
return
|
||||
}
|
||||
|
||||
copts := ac.dopts.copts
|
||||
if ac.scopts.CredsBundle != nil {
|
||||
copts.CredsBundle = ac.scopts.CredsBundle
|
||||
}
|
||||
hctx, hcancel := context.WithCancel(ac.ctx)
|
||||
defer hcancel()
|
||||
ac.mu.Unlock()
|
||||
|
||||
if channelz.IsOn() {
|
||||
channelz.AddTraceEvent(ac.channelzID, &channelz.TraceEventDesc{
|
||||
Desc: fmt.Sprintf("Subchannel picks a new address %q to connect", addr.Addr),
|
||||
Severity: channelz.CtINFO,
|
||||
})
|
||||
}
|
||||
|
||||
reconnect := grpcsync.NewEvent()
|
||||
prefaceReceived := make(chan struct{})
|
||||
newTr, err := ac.createTransport(addr, copts, connectDeadline, reconnect, prefaceReceived)
|
||||
if err == nil {
|
||||
ac.mu.Lock()
|
||||
ac.curAddr = addr
|
||||
ac.transport = newTr
|
||||
ac.mu.Unlock()
|
||||
|
||||
healthCheckConfig := ac.cc.healthCheckConfig()
|
||||
// LB channel health checking is only enabled when all the four requirements below are met:
|
||||
// 1. it is not disabled by the user with the WithDisableHealthCheck DialOption,
|
||||
// 2. the internal.HealthCheckFunc is set by importing the grpc/healthcheck package,
|
||||
// 3. a service config with non-empty healthCheckConfig field is provided,
|
||||
// 4. the current load balancer allows it.
|
||||
healthcheckManagingState := false
|
||||
if !ac.cc.dopts.disableHealthCheck && healthCheckConfig != nil && ac.scopts.HealthCheckEnabled {
|
||||
if ac.cc.dopts.healthCheckFunc == nil {
|
||||
// TODO: add a link to the health check doc in the error message.
|
||||
grpclog.Error("the client side LB channel health check function has not been set.")
|
||||
} else {
|
||||
// TODO(deklerk) refactor to just return transport
|
||||
go ac.startHealthCheck(hctx, newTr, addr, healthCheckConfig.ServiceName)
|
||||
healthcheckManagingState = true
|
||||
}
|
||||
}
|
||||
if !healthcheckManagingState {
|
||||
ac.mu.Lock()
|
||||
ac.updateConnectivityState(connectivity.Ready)
|
||||
ac.mu.Unlock()
|
||||
}
|
||||
} else {
|
||||
hcancel()
|
||||
if err == errConnClosing {
|
||||
return
|
||||
}
|
||||
|
||||
if tryNextAddrFromStart.HasFired() {
|
||||
break addrLoop
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
backoffFor = 0
|
||||
ac.mu.Lock()
|
||||
reqHandshake := ac.dopts.reqHandshake
|
||||
ac.mu.Unlock()
|
||||
|
||||
<-reconnect.Done()
|
||||
hcancel()
|
||||
|
||||
if reqHandshake == envconfig.RequireHandshakeHybrid {
|
||||
// In RequireHandshakeHybrid mode, we must check to see whether
|
||||
// server preface has arrived yet to decide whether to start
|
||||
// reconnecting at the top of the list (server preface received)
|
||||
// or continue with the next addr in the list as if the
|
||||
// connection were not successful (server preface not received).
|
||||
select {
|
||||
case <-prefaceReceived:
|
||||
// We received a server preface - huzzah! We consider this
|
||||
// a success and restart from the top of the addr list.
|
||||
ac.mu.Lock()
|
||||
ac.backoffIdx = 0
|
||||
ac.mu.Unlock()
|
||||
break addrLoop
|
||||
default:
|
||||
// Despite having set state to READY, in hybrid mode we
|
||||
// consider this a failure and continue connecting at the
|
||||
// next addr in the list.
|
||||
ac.mu.Lock()
|
||||
if ac.state == connectivity.Shutdown {
|
||||
ac.mu.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
ac.updateConnectivityState(connectivity.TransientFailure)
|
||||
ac.mu.Unlock()
|
||||
|
||||
if tryNextAddrFromStart.HasFired() {
|
||||
break addrLoop
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// In RequireHandshakeOn mode, we would have already waited for
|
||||
// the server preface, so we consider this a success and restart
|
||||
// from the top of the addr list. In RequireHandshakeOff mode,
|
||||
// we don't care to wait for the server preface before
|
||||
// considering this a success, so we also restart from the top
|
||||
// of the addr list.
|
||||
ac.mu.Lock()
|
||||
ac.backoffIdx = 0
|
||||
ac.mu.Unlock()
|
||||
break addrLoop
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// After exhausting all addresses, or after need to reconnect after a
|
||||
// READY, the addrConn enters TRANSIENT_FAILURE.
|
||||
ac.mu.Lock()
|
||||
if ac.state == connectivity.Shutdown {
|
||||
newTr.Close()
|
||||
ac.mu.Unlock()
|
||||
return
|
||||
}
|
||||
ac.curAddr = addr
|
||||
ac.transport = newTr
|
||||
ac.backoffIdx = 0
|
||||
|
||||
healthCheckConfig := ac.cc.healthCheckConfig()
|
||||
// LB channel health checking is only enabled when all the four requirements below are met:
|
||||
// 1. it is not disabled by the user with the WithDisableHealthCheck DialOption,
|
||||
// 2. the internal.HealthCheckFunc is set by importing the grpc/healthcheck package,
|
||||
// 3. a service config with non-empty healthCheckConfig field is provided,
|
||||
// 4. the current load balancer allows it.
|
||||
hctx, hcancel := context.WithCancel(ac.ctx)
|
||||
healthcheckManagingState := false
|
||||
if !ac.cc.dopts.disableHealthCheck && healthCheckConfig != nil && ac.scopts.HealthCheckEnabled {
|
||||
if ac.cc.dopts.healthCheckFunc == nil {
|
||||
// TODO: add a link to the health check doc in the error message.
|
||||
grpclog.Error("the client side LB channel health check function has not been set.")
|
||||
} else {
|
||||
// TODO(deklerk) refactor to just return transport
|
||||
go ac.startHealthCheck(hctx, newTr, addr, healthCheckConfig.ServiceName)
|
||||
healthcheckManagingState = true
|
||||
}
|
||||
}
|
||||
if !healthcheckManagingState {
|
||||
ac.updateConnectivityState(connectivity.Ready)
|
||||
}
|
||||
ac.mu.Unlock()
|
||||
|
||||
// Block until the created transport is down. And when this happens,
|
||||
// we restart from the top of the addr list.
|
||||
<-reconnect.Done()
|
||||
hcancel()
|
||||
|
||||
// Need to reconnect after a READY, the addrConn enters
|
||||
// TRANSIENT_FAILURE.
|
||||
//
|
||||
// This will set addrConn to TRANSIENT_FAILURE for a very short period
|
||||
// of time, and turns CONNECTING. It seems reasonable to skip this, but
|
||||
// READY-CONNECTING is not a valid transition.
|
||||
ac.mu.Lock()
|
||||
if ac.state == connectivity.Shutdown {
|
||||
ac.mu.Unlock()
|
||||
return
|
||||
}
|
||||
ac.updateConnectivityState(connectivity.TransientFailure)
|
||||
|
||||
// Backoff.
|
||||
b := ac.resetBackoff
|
||||
timer := time.NewTimer(backoffFor)
|
||||
acctx := ac.ctx
|
||||
ac.mu.Unlock()
|
||||
|
||||
select {
|
||||
case <-timer.C:
|
||||
ac.mu.Lock()
|
||||
ac.backoffIdx++
|
||||
ac.mu.Unlock()
|
||||
case <-b:
|
||||
timer.Stop()
|
||||
case <-acctx.Done():
|
||||
timer.Stop()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// createTransport creates a connection to one of the backends in addrs. It
|
||||
// sets ac.transport in the success case, or it returns an error if it was
|
||||
// unable to successfully create a transport.
|
||||
//
|
||||
// If waitForHandshake is enabled, it blocks until server preface arrives.
|
||||
func (ac *addrConn) createTransport(addr resolver.Address, copts transport.ConnectOptions, connectDeadline time.Time, reconnect *grpcsync.Event, prefaceReceived chan struct{}) (transport.ClientTransport, error) {
|
||||
// tryAllAddrs tries to creates a connection to the addresses, and stop when at the
|
||||
// first successful one. It returns the transport, the address and a Event in
|
||||
// the successful case. The Event fires when the returned transport disconnects.
|
||||
func (ac *addrConn) tryAllAddrs(addrs []resolver.Address, connectDeadline time.Time) (transport.ClientTransport, resolver.Address, *grpcsync.Event, error) {
|
||||
for _, addr := range addrs {
|
||||
ac.mu.Lock()
|
||||
if ac.state == connectivity.Shutdown {
|
||||
ac.mu.Unlock()
|
||||
return nil, resolver.Address{}, nil, errConnClosing
|
||||
}
|
||||
ac.updateConnectivityState(connectivity.Connecting)
|
||||
ac.transport = nil
|
||||
|
||||
ac.cc.mu.RLock()
|
||||
ac.dopts.copts.KeepaliveParams = ac.cc.mkp
|
||||
ac.cc.mu.RUnlock()
|
||||
|
||||
copts := ac.dopts.copts
|
||||
if ac.scopts.CredsBundle != nil {
|
||||
copts.CredsBundle = ac.scopts.CredsBundle
|
||||
}
|
||||
ac.mu.Unlock()
|
||||
|
||||
if channelz.IsOn() {
|
||||
channelz.AddTraceEvent(ac.channelzID, &channelz.TraceEventDesc{
|
||||
Desc: fmt.Sprintf("Subchannel picks a new address %q to connect", addr.Addr),
|
||||
Severity: channelz.CtINFO,
|
||||
})
|
||||
}
|
||||
|
||||
newTr, reconnect, err := ac.createTransport(addr, copts, connectDeadline)
|
||||
if err == nil {
|
||||
return newTr, addr, reconnect, nil
|
||||
}
|
||||
ac.cc.blockingpicker.updateConnectionError(err)
|
||||
}
|
||||
|
||||
// Couldn't connect to any address.
|
||||
return nil, resolver.Address{}, nil, fmt.Errorf("couldn't connect to any address")
|
||||
}
|
||||
|
||||
// createTransport creates a connection to addr. It returns the transport and a
|
||||
// Event in the successful case. The Event fires when the returned transport
|
||||
// disconnects.
|
||||
func (ac *addrConn) createTransport(addr resolver.Address, copts transport.ConnectOptions, connectDeadline time.Time) (transport.ClientTransport, *grpcsync.Event, error) {
|
||||
prefaceReceived := make(chan struct{})
|
||||
onCloseCalled := make(chan struct{})
|
||||
reconnect := grpcsync.NewEvent()
|
||||
|
||||
target := transport.TargetInfo{
|
||||
Addr: addr.Addr,
|
||||
|
@ -1155,8 +1111,6 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne
|
|||
Authority: ac.cc.authority,
|
||||
}
|
||||
|
||||
prefaceTimer := time.NewTimer(time.Until(connectDeadline))
|
||||
|
||||
onGoAway := func(r transport.GoAwayReason) {
|
||||
ac.mu.Lock()
|
||||
ac.adjustParams(r)
|
||||
|
@ -1166,13 +1120,11 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne
|
|||
|
||||
onClose := func() {
|
||||
close(onCloseCalled)
|
||||
prefaceTimer.Stop()
|
||||
reconnect.Fire()
|
||||
}
|
||||
|
||||
onPrefaceReceipt := func() {
|
||||
close(prefaceReceived)
|
||||
prefaceTimer.Stop()
|
||||
}
|
||||
|
||||
connectCtx, cancel := context.WithDeadline(ac.ctx, connectDeadline)
|
||||
|
@ -1182,69 +1134,28 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne
|
|||
}
|
||||
|
||||
newTr, err := transport.NewClientTransport(connectCtx, ac.cc.ctx, target, copts, onPrefaceReceipt, onGoAway, onClose)
|
||||
|
||||
if err == nil {
|
||||
if ac.dopts.reqHandshake == envconfig.RequireHandshakeOn {
|
||||
select {
|
||||
case <-prefaceTimer.C:
|
||||
// We didn't get the preface in time.
|
||||
newTr.Close()
|
||||
err = errors.New("timed out waiting for server handshake")
|
||||
case <-prefaceReceived:
|
||||
// We got the preface - huzzah! things are good.
|
||||
case <-onCloseCalled:
|
||||
// The transport has already closed - noop.
|
||||
return nil, errors.New("connection closed")
|
||||
}
|
||||
} else if ac.dopts.reqHandshake == envconfig.RequireHandshakeHybrid {
|
||||
go func() {
|
||||
select {
|
||||
case <-prefaceTimer.C:
|
||||
// We didn't get the preface in time.
|
||||
newTr.Close()
|
||||
case <-prefaceReceived:
|
||||
// We got the preface just in the nick of time - huzzah!
|
||||
case <-onCloseCalled:
|
||||
// The transport has already closed - noop.
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
// newTr is either nil, or closed.
|
||||
ac.cc.blockingpicker.updateConnectionError(err)
|
||||
ac.mu.Lock()
|
||||
if ac.state == connectivity.Shutdown {
|
||||
// ac.tearDown(...) has been invoked.
|
||||
ac.mu.Unlock()
|
||||
|
||||
return nil, errConnClosing
|
||||
}
|
||||
ac.mu.Unlock()
|
||||
grpclog.Warningf("grpc: addrConn.createTransport failed to connect to %v. Err :%v. Reconnecting...", addr, err)
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Now there is a viable transport to be use, so set ac.transport to reflect the new viable transport.
|
||||
ac.mu.Lock()
|
||||
if ac.state == connectivity.Shutdown {
|
||||
ac.mu.Unlock()
|
||||
newTr.Close()
|
||||
return nil, errConnClosing
|
||||
if ac.dopts.reqHandshake == envconfig.RequireHandshakeOn {
|
||||
select {
|
||||
case <-time.After(connectDeadline.Sub(time.Now())):
|
||||
// We didn't get the preface in time.
|
||||
newTr.Close()
|
||||
grpclog.Warningf("grpc: addrConn.createTransport failed to connect to %v: didn't receive server preface in time. Reconnecting...", addr)
|
||||
return nil, nil, errors.New("timed out waiting for server handshake")
|
||||
case <-prefaceReceived:
|
||||
// We got the preface - huzzah! things are good.
|
||||
case <-onCloseCalled:
|
||||
// The transport has already closed - noop.
|
||||
return nil, nil, errors.New("connection closed")
|
||||
// TODO(deklerk) this should bail on ac.ctx.Done(). Add a test and fix.
|
||||
}
|
||||
}
|
||||
ac.mu.Unlock()
|
||||
|
||||
// Now there is a viable transport to be use, so set ac.transport to reflect the new viable transport.
|
||||
ac.mu.Lock()
|
||||
if ac.state == connectivity.Shutdown {
|
||||
ac.mu.Unlock()
|
||||
newTr.Close()
|
||||
return nil, errConnClosing
|
||||
}
|
||||
ac.mu.Unlock()
|
||||
|
||||
return newTr, nil
|
||||
return newTr, reconnect, nil
|
||||
}
|
||||
|
||||
func (ac *addrConn) startHealthCheck(ctx context.Context, newTr transport.ClientTransport, addr resolver.Address, serviceName string) {
|
||||
|
@ -1332,7 +1243,6 @@ func (ac *addrConn) tearDown(err error) {
|
|||
// between setting the state and logic that waits on context cancelation / etc.
|
||||
ac.updateConnectivityState(connectivity.Shutdown)
|
||||
ac.cancel()
|
||||
ac.tearDownErr = err
|
||||
ac.curAddr = resolver.Address{}
|
||||
if err == errConnDrain && curTr != nil {
|
||||
// GracefulClose(...) may be executed multiple times when
|
||||
|
|
|
@ -36,9 +36,6 @@ import (
|
|||
"google.golang.org/grpc/credentials/internal"
|
||||
)
|
||||
|
||||
// alpnProtoStr are the specified application level protocols for gRPC.
|
||||
var alpnProtoStr = []string{"h2"}
|
||||
|
||||
// PerRPCCredentials defines the common interface for the credentials which need to
|
||||
// attach security information to every RPC (e.g., oauth2).
|
||||
type PerRPCCredentials interface {
|
||||
|
@ -208,10 +205,23 @@ func (c *tlsCreds) OverrideServerName(serverNameOverride string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
const alpnProtoStrH2 = "h2"
|
||||
|
||||
func appendH2ToNextProtos(ps []string) []string {
|
||||
for _, p := range ps {
|
||||
if p == alpnProtoStrH2 {
|
||||
return ps
|
||||
}
|
||||
}
|
||||
ret := make([]string, 0, len(ps)+1)
|
||||
ret = append(ret, ps...)
|
||||
return append(ret, alpnProtoStrH2)
|
||||
}
|
||||
|
||||
// NewTLS uses c to construct a TransportCredentials based on TLS.
|
||||
func NewTLS(c *tls.Config) TransportCredentials {
|
||||
tc := &tlsCreds{cloneTLSConfig(c)}
|
||||
tc.config.NextProtos = alpnProtoStr
|
||||
tc.config.NextProtos = appendH2ToNextProtos(tc.config.NextProtos)
|
||||
return tc
|
||||
}
|
||||
|
||||
|
|
|
@ -55,13 +55,16 @@ type dialOptions struct {
|
|||
// balancer, and also by WithBalancerName dial option.
|
||||
balancerBuilder balancer.Builder
|
||||
// This is to support grpclb.
|
||||
resolverBuilder resolver.Builder
|
||||
reqHandshake envconfig.RequireHandshakeSetting
|
||||
channelzParentID int64
|
||||
disableServiceConfig bool
|
||||
disableRetry bool
|
||||
disableHealthCheck bool
|
||||
healthCheckFunc internal.HealthChecker
|
||||
resolverBuilder resolver.Builder
|
||||
reqHandshake envconfig.RequireHandshakeSetting
|
||||
channelzParentID int64
|
||||
disableServiceConfig bool
|
||||
disableRetry bool
|
||||
disableHealthCheck bool
|
||||
healthCheckFunc internal.HealthChecker
|
||||
minConnectTimeout func() time.Duration
|
||||
defaultServiceConfig *ServiceConfig // defaultServiceConfig is parsed from defaultServiceConfigRawJSON.
|
||||
defaultServiceConfigRawJSON *string
|
||||
}
|
||||
|
||||
// DialOption configures how we set up the connection.
|
||||
|
@ -440,12 +443,27 @@ func WithChannelzParentID(id int64) DialOption {
|
|||
// WithDisableServiceConfig returns a DialOption that causes grpc to ignore any
|
||||
// service config provided by the resolver and provides a hint to the resolver
|
||||
// to not fetch service configs.
|
||||
//
|
||||
// Note that, this dial option only disables service config from resolver. If
|
||||
// default service config is provided, grpc will use the default service config.
|
||||
func WithDisableServiceConfig() DialOption {
|
||||
return newFuncDialOption(func(o *dialOptions) {
|
||||
o.disableServiceConfig = true
|
||||
})
|
||||
}
|
||||
|
||||
// WithDefaultServiceConfig returns a DialOption that configures the default
|
||||
// service config, which will be used in cases where:
|
||||
// 1. WithDisableServiceConfig is called.
|
||||
// 2. Resolver does not return service config or if the resolver gets and invalid config.
|
||||
//
|
||||
// This API is EXPERIMENTAL.
|
||||
func WithDefaultServiceConfig(s string) DialOption {
|
||||
return newFuncDialOption(func(o *dialOptions) {
|
||||
o.defaultServiceConfigRawJSON = &s
|
||||
})
|
||||
}
|
||||
|
||||
// WithDisableRetry returns a DialOption that disables retries, even if the
|
||||
// service config enables them. This does not impact transparent retries, which
|
||||
// will happen automatically if no data is written to the wire or if the RPC is
|
||||
|
@ -470,7 +488,8 @@ func WithMaxHeaderListSize(s uint32) DialOption {
|
|||
})
|
||||
}
|
||||
|
||||
// WithDisableHealthCheck disables the LB channel health checking for all SubConns of this ClientConn.
|
||||
// WithDisableHealthCheck disables the LB channel health checking for all
|
||||
// SubConns of this ClientConn.
|
||||
//
|
||||
// This API is EXPERIMENTAL.
|
||||
func WithDisableHealthCheck() DialOption {
|
||||
|
@ -479,8 +498,8 @@ func WithDisableHealthCheck() DialOption {
|
|||
})
|
||||
}
|
||||
|
||||
// withHealthCheckFunc replaces the default health check function with the provided one. It makes
|
||||
// tests easier to change the health check function.
|
||||
// withHealthCheckFunc replaces the default health check function with the
|
||||
// provided one. It makes tests easier to change the health check function.
|
||||
//
|
||||
// For testing purpose only.
|
||||
func withHealthCheckFunc(f internal.HealthChecker) DialOption {
|
||||
|
@ -500,3 +519,14 @@ func defaultDialOptions() dialOptions {
|
|||
},
|
||||
}
|
||||
}
|
||||
|
||||
// withGetMinConnectDeadline specifies the function that clientconn uses to
|
||||
// get minConnectDeadline. This can be used to make connection attempts happen
|
||||
// faster/slower.
|
||||
//
|
||||
// For testing purpose only.
|
||||
func withMinConnectDeadline(f func() time.Duration) DialOption {
|
||||
return newFuncDialOption(func(o *dialOptions) {
|
||||
o.minConnectTimeout = f
|
||||
})
|
||||
}
|
||||
|
|
|
@ -102,10 +102,10 @@ func RegisterCodec(codec Codec) {
|
|||
if codec == nil {
|
||||
panic("cannot register a nil Codec")
|
||||
}
|
||||
contentSubtype := strings.ToLower(codec.Name())
|
||||
if contentSubtype == "" {
|
||||
panic("cannot register Codec with empty string result for String()")
|
||||
if codec.Name() == "" {
|
||||
panic("cannot register Codec with empty string result for Name()")
|
||||
}
|
||||
contentSubtype := strings.ToLower(codec.Name())
|
||||
registeredCodecs[contentSubtype] = codec
|
||||
}
|
||||
|
||||
|
|
|
@ -7,13 +7,12 @@ require (
|
|||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
|
||||
github.com/golang/mock v1.1.1
|
||||
github.com/golang/protobuf v1.2.0
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f // indirect
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522
|
||||
golang.org/x/text v0.3.0 // indirect
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd
|
||||
google.golang.org/appengine v1.1.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099
|
||||
|
|
|
@ -10,20 +10,21 @@ github.com/golang/mock v1.1.1 h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8=
|
|||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3 h1:x/bBzNauLQAlE3fLku/xy92Y8QwKX5HZymrMz2IiKFc=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d h1:g9qWBGx4puODJTMVyoPrpoxPFgVGd+z1DZwjfRu4d0I=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522 h1:Ve1ORMCxvRmSXBwJK+t3Oy+V2vRW2OetUQBq4rJIkZE=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b h1:qMK98NmNCRVDIYFycQ5yVRkvgDUFfdP8Ip4KqmDEB7g=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd h1:/e+gpKk9r3dJobndpTytxS2gOy6m5uvpg+ISQoEcusQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
google.golang.org/appengine v1.1.0 h1:igQkv0AAhEIvTEpD5LIpAfav2eeVO9HBTjvKHVJPRSs=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
// Package grpclog defines logging for grpc.
|
||||
//
|
||||
// All logs in transport package only go to verbose level 2.
|
||||
// All logs in transport and grpclb packages only go to verbose level 2.
|
||||
// All logs in other packages in grpc are logged in spite of the verbosity level.
|
||||
//
|
||||
// In the default logger,
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright 2019 gRPC authors.
|
||||
*
|
||||
* 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 balancerload defines APIs to parse server loads in trailers. The
|
||||
// parsed loads are sent to balancers in DoneInfo.
|
||||
package balancerload
|
||||
|
||||
import (
|
||||
"google.golang.org/grpc/metadata"
|
||||
)
|
||||
|
||||
// Parser converts loads from metadata into a concrete type.
|
||||
type Parser interface {
|
||||
// Parse parses loads from metadata.
|
||||
Parse(md metadata.MD) interface{}
|
||||
}
|
||||
|
||||
var parser Parser
|
||||
|
||||
// SetParser sets the load parser.
|
||||
//
|
||||
// Not mutex-protected, should be called before any gRPC functions.
|
||||
func SetParser(lr Parser) {
|
||||
parser = lr
|
||||
}
|
||||
|
||||
// Parse calls parser.Read().
|
||||
func Parse(md metadata.MD) interface{} {
|
||||
if parser == nil {
|
||||
return nil
|
||||
}
|
||||
return parser.Parse(md)
|
||||
}
|
|
@ -34,13 +34,9 @@ const (
|
|||
type RequireHandshakeSetting int
|
||||
|
||||
const (
|
||||
// RequireHandshakeHybrid (default, deprecated) indicates to not wait for
|
||||
// handshake before considering a connection ready, but wait before
|
||||
// considering successful.
|
||||
RequireHandshakeHybrid RequireHandshakeSetting = iota
|
||||
// RequireHandshakeOn (default after the 1.17 release) indicates to wait
|
||||
// for handshake before considering a connection ready/successful.
|
||||
RequireHandshakeOn
|
||||
// RequireHandshakeOn indicates to wait for handshake before considering a
|
||||
// connection ready/successful.
|
||||
RequireHandshakeOn RequireHandshakeSetting = iota
|
||||
// RequireHandshakeOff indicates to not wait for handshake before
|
||||
// considering a connection ready/successful.
|
||||
RequireHandshakeOff
|
||||
|
@ -53,7 +49,7 @@ var (
|
|||
// environment variable.
|
||||
//
|
||||
// Will be removed after the 1.18 release.
|
||||
RequireHandshake RequireHandshakeSetting
|
||||
RequireHandshake = RequireHandshakeOn
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -64,8 +60,5 @@ func init() {
|
|||
RequireHandshake = RequireHandshakeOn
|
||||
case "off":
|
||||
RequireHandshake = RequireHandshakeOff
|
||||
case "hybrid":
|
||||
// Will be removed after the 1.17 release.
|
||||
RequireHandshake = RequireHandshakeHybrid
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,18 +22,24 @@ package syscall
|
|||
|
||||
import (
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc/grpclog"
|
||||
)
|
||||
|
||||
func init() {
|
||||
grpclog.Info("CPU time info is unavailable on non-linux or appengine environment.")
|
||||
var once sync.Once
|
||||
|
||||
func log() {
|
||||
once.Do(func() {
|
||||
grpclog.Info("CPU time info is unavailable on non-linux or appengine environment.")
|
||||
})
|
||||
}
|
||||
|
||||
// GetCPUTime returns the how much CPU time has passed since the start of this process.
|
||||
// It always returns 0 under non-linux or appengine environment.
|
||||
func GetCPUTime() int64 {
|
||||
log()
|
||||
return 0
|
||||
}
|
||||
|
||||
|
@ -42,22 +48,26 @@ type Rusage struct{}
|
|||
|
||||
// GetRusage is a no-op function under non-linux or appengine environment.
|
||||
func GetRusage() (rusage *Rusage) {
|
||||
log()
|
||||
return nil
|
||||
}
|
||||
|
||||
// CPUTimeDiff returns the differences of user CPU time and system CPU time used
|
||||
// between two Rusage structs. It a no-op function for non-linux or appengine environment.
|
||||
func CPUTimeDiff(first *Rusage, latest *Rusage) (float64, float64) {
|
||||
log()
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
// SetTCPUserTimeout is a no-op function under non-linux or appengine environments
|
||||
func SetTCPUserTimeout(conn net.Conn, timeout time.Duration) error {
|
||||
log()
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetTCPUserTimeout is a no-op function under non-linux or appengine environments
|
||||
// a negative return value indicates the operation is not supported
|
||||
func GetTCPUserTimeout(conn net.Conn) (int, error) {
|
||||
log()
|
||||
return -1, nil
|
||||
}
|
||||
|
|
|
@ -63,9 +63,6 @@ func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request, stats sta
|
|||
if _, ok := w.(http.Flusher); !ok {
|
||||
return nil, errors.New("gRPC requires a ResponseWriter supporting http.Flusher")
|
||||
}
|
||||
if _, ok := w.(http.CloseNotifier); !ok {
|
||||
return nil, errors.New("gRPC requires a ResponseWriter supporting http.CloseNotifier")
|
||||
}
|
||||
|
||||
st := &serverHandlerTransport{
|
||||
rw: w,
|
||||
|
@ -176,17 +173,11 @@ func (a strAddr) String() string { return string(a) }
|
|||
|
||||
// do runs fn in the ServeHTTP goroutine.
|
||||
func (ht *serverHandlerTransport) do(fn func()) error {
|
||||
// Avoid a panic writing to closed channel. Imperfect but maybe good enough.
|
||||
select {
|
||||
case <-ht.closedCh:
|
||||
return ErrConnClosing
|
||||
default:
|
||||
select {
|
||||
case ht.writes <- fn:
|
||||
return nil
|
||||
case <-ht.closedCh:
|
||||
return ErrConnClosing
|
||||
}
|
||||
case ht.writes <- fn:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -237,7 +228,6 @@ func (ht *serverHandlerTransport) WriteStatus(s *Stream, st *status.Status) erro
|
|||
if ht.stats != nil {
|
||||
ht.stats.HandleRPC(s.Context(), &stats.OutTrailer{})
|
||||
}
|
||||
close(ht.writes)
|
||||
}
|
||||
ht.Close()
|
||||
return err
|
||||
|
@ -315,19 +305,13 @@ func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream), trace
|
|||
ctx, cancel = context.WithCancel(ctx)
|
||||
}
|
||||
|
||||
// requestOver is closed when either the request's context is done
|
||||
// or the status has been written via WriteStatus.
|
||||
// requestOver is closed when the status has been written via WriteStatus.
|
||||
requestOver := make(chan struct{})
|
||||
|
||||
// clientGone receives a single value if peer is gone, either
|
||||
// because the underlying connection is dead or because the
|
||||
// peer sends an http2 RST_STREAM.
|
||||
clientGone := ht.rw.(http.CloseNotifier).CloseNotify()
|
||||
go func() {
|
||||
select {
|
||||
case <-requestOver:
|
||||
case <-ht.closedCh:
|
||||
case <-clientGone:
|
||||
case <-ht.req.Context().Done():
|
||||
}
|
||||
cancel()
|
||||
ht.Close()
|
||||
|
@ -407,10 +391,7 @@ func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream), trace
|
|||
func (ht *serverHandlerTransport) runStream() {
|
||||
for {
|
||||
select {
|
||||
case fn, ok := <-ht.writes:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
case fn := <-ht.writes:
|
||||
fn()
|
||||
case <-ht.closedCh:
|
||||
return
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue