Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 24 additions & 8 deletions sdk/armcore/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,21 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
)

const scope = "https://management.azure.com//.default"
const defaultScope = "/.default"

const (
// AzureChina is the Azure Resourece Manager China cloud endpoint.
AzureChina = "https://management.chinacloudapi.cn/"
// AzureGermany is the Azure Resourece Manager Germany cloud endpoint.
AzureGermany = "https://management.microsoftazure.de/"
// AzureGovernment is the Azure Resourece Manager US government cloud endpoint.
AzureGovernment = "https://management.usgovcloudapi.net/"
// AzurePublicCloud is the Azure Resourece Manager public cloud endpoint.
AzurePublicCloud = "https://management.azure.com/"
)

// ConnectionOptions contains configuration settings for the connection's pipeline.
// Call DefaultConnectionOptions() to create an instance populated with default values.
type ConnectionOptions struct {
// HTTPClient sets the transport for making HTTP requests.
HTTPClient azcore.Transport
Expand Down Expand Up @@ -39,12 +51,9 @@ type Connection struct {
p azcore.Pipeline
}

// DefaultEndpoint is the Azure Resourece Manager public cloud endpoint.
const DefaultEndpoint = "https://management.azure.com"

// NewDefaultConnection creates an instance of the Connection type using the DefaultEndpoint.
// NewDefaultConnection creates an instance of the Connection type using the AzurePublicCloud.
func NewDefaultConnection(cred azcore.TokenCredential, options *ConnectionOptions) *Connection {
return NewConnection(DefaultEndpoint, cred, options)
return NewConnection(AzurePublicCloud, cred, options)
}

// NewConnection creates an instance of the Connection type with the specified endpoint.
Expand All @@ -56,9 +65,9 @@ func NewConnection(endpoint string, cred azcore.TokenCredential, options *Connec
}
p := azcore.NewPipeline(options.HTTPClient,
azcore.NewTelemetryPolicy(&options.Telemetry),
NewRPRegistrationPolicy(cred, &options.RegisterRPOptions),
NewRPRegistrationPolicy(endpoint, cred, &options.RegisterRPOptions),
azcore.NewRetryPolicy(&options.Retry),
cred.AuthenticationPolicy(azcore.AuthenticationPolicyOptions{Options: azcore.TokenRequestOptions{Scopes: []string{scope}}}),
cred.AuthenticationPolicy(azcore.AuthenticationPolicyOptions{Options: azcore.TokenRequestOptions{Scopes: []string{endpointToScope(endpoint)}}}),
azcore.NewLogPolicy(nil))
return NewConnectionWithPipeline(endpoint, p)
}
Expand All @@ -78,3 +87,10 @@ func (c *Connection) Endpoint() string {
func (c *Connection) Pipeline() azcore.Pipeline {
return c.p
}

func endpointToScope(endpoint string) string {
if endpoint[len(endpoint)-1] != '/' {
endpoint += "/"
}
return endpoint + defaultScope
}
11 changes: 10 additions & 1 deletion sdk/armcore/connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func (mockTokenCred) GetToken(context.Context, azcore.TokenRequestOptions) (*azc
func TestNewDefaultConnection(t *testing.T) {
opt := DefaultConnectionOptions()
con := NewDefaultConnection(mockTokenCred{}, &opt)
if ep := con.Endpoint(); ep != DefaultEndpoint {
if ep := con.Endpoint(); ep != AzurePublicCloud {
t.Fatalf("unexpected endpoint %s", ep)
}
}
Expand Down Expand Up @@ -64,3 +64,12 @@ func TestNewConnectionWithPipeline(t *testing.T) {
t.Fatalf("unexpected status code: %d", resp.StatusCode)
}
}

func TestScope(t *testing.T) {
if s := endpointToScope(AzureGermany); s != "https://management.microsoftazure.de//.default" {
t.Fatalf("unexpected scope %s", s)
}
if s := endpointToScope("https://management.usgovcloudapi.net"); s != "https://management.usgovcloudapi.net//.default" {
t.Fatalf("unexpected scope %s", s)
}
}
16 changes: 9 additions & 7 deletions sdk/armcore/policy_register_rp.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const (
)

// RegistrationOptions configures the registration policy's behavior.
// Call DefaultRegistrationOptions() to create an instance populated with default values.
type RegistrationOptions struct {
// MaxAttempts is the total number of times to attempt automatic registration
// in the event that an attempt fails.
Expand Down Expand Up @@ -60,24 +61,25 @@ func DefaultRegistrationOptions() RegistrationOptions {
}
}

// NewRPRegistrationPolicy creates a policy object configured using the specified pipeline
// and options. The policy controls if an unregistered resource provider should automatically
// be registered. See https://aka.ms/rps-not-found for more information.
// NewRPRegistrationPolicy creates a policy object configured using the specified endpoint,
// credentials and options. The policy controls if an unregistered resource provider should
// automatically be registered. See https://aka.ms/rps-not-found for more information.
// Pass nil to accept the default options; this is the same as passing the result
// from a call to DefaultRegistrationOptions().
func NewRPRegistrationPolicy(cred azcore.Credential, o *RegistrationOptions) azcore.Policy {
func NewRPRegistrationPolicy(endpoint string, cred azcore.Credential, o *RegistrationOptions) azcore.Policy {
if o == nil {
def := DefaultRegistrationOptions()
o = &def
}
p := azcore.NewPipeline(o.HTTPClient,
azcore.NewRetryPolicy(&o.Retry),
cred.AuthenticationPolicy(azcore.AuthenticationPolicyOptions{Options: azcore.TokenRequestOptions{Scopes: []string{scope}}}),
cred.AuthenticationPolicy(azcore.AuthenticationPolicyOptions{Options: azcore.TokenRequestOptions{Scopes: []string{endpointToScope(endpoint)}}}),
azcore.NewLogPolicy(nil))
return &rpRegistrationPolicy{pipeline: p, options: *o}
return &rpRegistrationPolicy{endpoint: endpoint, pipeline: p, options: *o}
}

type rpRegistrationPolicy struct {
endpoint string
pipeline azcore.Pipeline
options RegistrationOptions
}
Expand Down Expand Up @@ -128,7 +130,7 @@ func (r *rpRegistrationPolicy) Do(req *azcore.Request) (*azcore.Response, error)
// we use the scheme and host from the original request
rpOps := &providersOperations{
p: r.pipeline,
u: fmt.Sprintf("%s://%s", req.URL.Scheme, req.URL.Host),
u: r.endpoint,
subID: subID,
}
if _, err = rpOps.Register(req.Context(), rp); err != nil {
Expand Down
14 changes: 7 additions & 7 deletions sdk/armcore/policy_register_rp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func TestRPRegistrationPolicySuccess(t *testing.T) {
srv.AppendResponse(mock.WithStatusCode(http.StatusOK), mock.WithBody([]byte(rpRegisteredResp)))
// response for original request (different status code than any of the other responses)
srv.AppendResponse(mock.WithStatusCode(http.StatusAccepted))
pl := azcore.NewPipeline(srv, NewRPRegistrationPolicy(azcore.AnonymousCredential(), testRPRegistrationOptions(srv)))
pl := azcore.NewPipeline(srv, NewRPRegistrationPolicy(srv.URL(), azcore.AnonymousCredential(), testRPRegistrationOptions(srv)))
req, err := azcore.NewRequest(context.Background(), http.MethodGet, azcore.JoinPaths(srv.URL(), requestEndpoint))
if err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -108,7 +108,7 @@ func TestRPRegistrationPolicyNA(t *testing.T) {
defer close()
// response indicates no RP registration is required, policy does nothing
srv.AppendResponse(mock.WithStatusCode(http.StatusOK))
pl := azcore.NewPipeline(srv, NewRPRegistrationPolicy(azcore.AnonymousCredential(), testRPRegistrationOptions(srv)))
pl := azcore.NewPipeline(srv, NewRPRegistrationPolicy(srv.URL(), azcore.AnonymousCredential(), testRPRegistrationOptions(srv)))
req, err := azcore.NewRequest(context.Background(), http.MethodGet, srv.URL())
if err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -147,7 +147,7 @@ func TestRPRegistrationPolicy409Other(t *testing.T) {
defer close()
// test getting a 409 but not due to registration required
srv.AppendResponse(mock.WithStatusCode(http.StatusConflict), mock.WithBody([]byte(failedResp)))
pl := azcore.NewPipeline(srv, NewRPRegistrationPolicy(azcore.AnonymousCredential(), testRPRegistrationOptions(srv)))
pl := azcore.NewPipeline(srv, NewRPRegistrationPolicy(srv.URL(), azcore.AnonymousCredential(), testRPRegistrationOptions(srv)))
req, err := azcore.NewRequest(context.Background(), http.MethodGet, srv.URL())
if err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -178,7 +178,7 @@ func TestRPRegistrationPolicyTimesOut(t *testing.T) {
// polling responses to Register() and Get(), in progress but slow
// tests registration takes too long, times out
srv.RepeatResponse(10, mock.WithStatusCode(http.StatusOK), mock.WithBody([]byte(rpRegisteringResp)), mock.WithSlowResponse(400*time.Millisecond))
pl := azcore.NewPipeline(srv, NewRPRegistrationPolicy(azcore.AnonymousCredential(), testRPRegistrationOptions(srv)))
pl := azcore.NewPipeline(srv, NewRPRegistrationPolicy(srv.URL(), azcore.AnonymousCredential(), testRPRegistrationOptions(srv)))
req, err := azcore.NewRequest(context.Background(), http.MethodGet, azcore.JoinPaths(srv.URL(), requestEndpoint))
if err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -222,7 +222,7 @@ func TestRPRegistrationPolicyExceedsAttempts(t *testing.T) {
// polling response, successful registration
srv.AppendResponse(mock.WithStatusCode(http.StatusOK), mock.WithBody([]byte(rpRegisteredResp)))
}
pl := azcore.NewPipeline(srv, NewRPRegistrationPolicy(azcore.AnonymousCredential(), testRPRegistrationOptions(srv)))
pl := azcore.NewPipeline(srv, NewRPRegistrationPolicy(srv.URL(), azcore.AnonymousCredential(), testRPRegistrationOptions(srv)))
req, err := azcore.NewRequest(context.Background(), http.MethodGet, azcore.JoinPaths(srv.URL(), requestEndpoint))
if err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -270,7 +270,7 @@ func TestRPRegistrationPolicyCanCancel(t *testing.T) {
srv.RepeatResponse(10, mock.WithStatusCode(http.StatusOK), mock.WithBody([]byte(rpRegisteringResp)), mock.WithSlowResponse(300*time.Millisecond))
opts := DefaultRegistrationOptions()
opts.HTTPClient = srv
pl := azcore.NewPipeline(srv, NewRPRegistrationPolicy(azcore.AnonymousCredential(), &opts))
pl := azcore.NewPipeline(srv, NewRPRegistrationPolicy(srv.URL(), azcore.AnonymousCredential(), &opts))
// log only RP registration
azcore.Log().SetClassifications(LogRPRegistration)
defer func() {
Expand Down Expand Up @@ -323,7 +323,7 @@ func TestRPRegistrationPolicyDisabled(t *testing.T) {
srv.AppendResponse(mock.WithStatusCode(http.StatusConflict), mock.WithBody([]byte(rpUnregisteredResp)))
ops := testRPRegistrationOptions(srv)
ops.MaxAttempts = 0
pl := azcore.NewPipeline(srv, NewRPRegistrationPolicy(azcore.AnonymousCredential(), ops))
pl := azcore.NewPipeline(srv, NewRPRegistrationPolicy(srv.URL(), azcore.AnonymousCredential(), ops))
req, err := azcore.NewRequest(context.Background(), http.MethodGet, azcore.JoinPaths(srv.URL(), requestEndpoint))
if err != nil {
t.Fatal(err)
Expand Down