Skip to content
Closed
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
13 changes: 6 additions & 7 deletions azure/services/async/async.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,20 +63,19 @@ func (s *Service[C, D]) CreateOrUpdateResource(ctx context.Context, spec azure.R
futureType := infrav1.PutFuture

// Check if there is an ongoing long-running operation.
resumeToken := ""
createOrUpdateOpts := azure.CreateOrUpdateAsyncOpts{}
if future := s.Scope.GetLongRunningOperationState(resourceName, serviceName, futureType); future != nil {
t, err := converters.FutureToResumeToken(*future)
if err != nil {
s.Scope.DeleteLongRunningOperationState(resourceName, serviceName, futureType)
return "", errors.Wrap(err, "could not decode future data, resetting long-running operation state")
}
resumeToken = t
createOrUpdateOpts.ResumeToken = t
}

// Only when no long running operation is currently in progress do we need to get the parameters.
// The polling implemented by the SDK does not use parameters when a resume token exists.
var parameters interface{}
if resumeToken == "" {
if createOrUpdateOpts.ResumeToken == "" {
// Get the resource if it already exists, and use it to construct the desired resource parameters.
var existingResource interface{}
if existing, err := s.Creator.Get(ctx, spec); err != nil && !azure.ResourceNotFound(err) {
Expand All @@ -88,10 +87,10 @@ func (s *Service[C, D]) CreateOrUpdateResource(ctx context.Context, spec azure.R
}

// Construct parameters using the resource spec and information from the existing resource, if there is one.
parameters, err = spec.Parameters(ctx, existingResource)
createOrUpdateOpts.Parameters, err = spec.Parameters(ctx, existingResource)
if err != nil {
return nil, errors.Wrapf(err, "failed to get desired parameters for resource %s/%s (service: %s)", rgName, resourceName, serviceName)
} else if parameters == nil {
} else if createOrUpdateOpts.Parameters == nil {
// Nothing to do, don't create or update the resource and return the existing resource.
log.V(2).Info("resource up to date", "service", serviceName, "resource", resourceName, "resourceGroup", rgName)
return existingResource, nil
Expand All @@ -105,7 +104,7 @@ func (s *Service[C, D]) CreateOrUpdateResource(ctx context.Context, spec azure.R
}
}

result, poller, err := s.Creator.CreateOrUpdateAsync(ctx, spec, resumeToken, parameters)
result, poller, err := s.Creator.CreateOrUpdateAsync(ctx, spec, createOrUpdateOpts)
errWrapped := errors.Wrapf(err, "failed to create or update resource %s/%s (service: %s)", rgName, resourceName, serviceName)
if poller != nil && azure.IsContextDeadlineExceededOrCanceledError(err) {
future, err := converters.PollerToFuture(poller, infrav1.PutFuture, serviceName, resourceName, rgName)
Expand Down
16 changes: 9 additions & 7 deletions azure/services/async/async_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func TestServiceCreateOrUpdateResource(t *testing.T) {
r.ResourceName().Return(resourceName),
r.ResourceGroupName().Return(resourceGroupName),
s.GetLongRunningOperationState(resourceName, serviceName, infrav1.PutFuture).Return(validPutFuture),
c.CreateOrUpdateAsync(gomockinternal.AContext(), gomock.AssignableToTypeOf(azureResourceGetterType), resumeToken, gomock.Any()).Return(fakeResource, nil, nil),
c.CreateOrUpdateAsync(gomockinternal.AContext(), gomock.AssignableToTypeOf(azureResourceGetterType), createOrUpdateAsyncOpts).Return(fakeResource, nil, nil),
s.DeleteLongRunningOperationState(resourceName, serviceName, infrav1.PutFuture),
)
},
Expand All @@ -86,7 +86,7 @@ func TestServiceCreateOrUpdateResource(t *testing.T) {
r.ResourceName().Return(resourceName),
r.ResourceGroupName().Return(resourceGroupName),
s.GetLongRunningOperationState(resourceName, serviceName, infrav1.PutFuture).Return(validPutFuture),
c.CreateOrUpdateAsync(gomockinternal.AContext(), gomock.AssignableToTypeOf(azureResourceGetterType), resumeToken, gomock.Any()).Return(nil, fakePoller[MockCreator](g, http.StatusAccepted), context.DeadlineExceeded),
c.CreateOrUpdateAsync(gomockinternal.AContext(), gomock.AssignableToTypeOf(azureResourceGetterType), createOrUpdateAsyncOpts).Return(nil, fakePoller[MockCreator](g, http.StatusAccepted), context.DeadlineExceeded),
s.SetLongRunningOperationState(gomock.AssignableToTypeOf(&infrav1.Future{})),
s.DefaultedReconcilerRequeue().Return(reconciler.DefaultReconcilerRequeue),
)
Expand All @@ -101,7 +101,7 @@ func TestServiceCreateOrUpdateResource(t *testing.T) {
r.ResourceName().Return(resourceName),
r.ResourceGroupName().Return(resourceGroupName),
s.GetLongRunningOperationState(resourceName, serviceName, infrav1.PutFuture).Return(validPutFuture),
c.CreateOrUpdateAsync(gomockinternal.AContext(), gomock.AssignableToTypeOf(azureResourceGetterType), resumeToken, gomock.Any()).Return(nil, fakePoller[MockCreator](g, http.StatusAccepted), errors.New("foo")),
c.CreateOrUpdateAsync(gomockinternal.AContext(), gomock.AssignableToTypeOf(azureResourceGetterType), createOrUpdateAsyncOpts).Return(nil, fakePoller[MockCreator](g, http.StatusAccepted), errors.New("foo")),
s.DeleteLongRunningOperationState(resourceName, serviceName, infrav1.PutFuture),
)
},
Expand All @@ -117,7 +117,7 @@ func TestServiceCreateOrUpdateResource(t *testing.T) {
s.GetLongRunningOperationState(resourceName, serviceName, infrav1.PutFuture).Return(nil),
c.Get(gomockinternal.AContext(), gomock.AssignableToTypeOf(azureResourceGetterType)).Return(nil, &azcore.ResponseError{StatusCode: http.StatusNotFound}),
r.Parameters(gomockinternal.AContext(), nil).Return(fakeParameters, nil),
c.CreateOrUpdateAsync(gomockinternal.AContext(), gomock.AssignableToTypeOf(azureResourceGetterType), "", gomock.Any()).Return(nil, fakePoller[MockCreator](g, http.StatusAccepted), context.DeadlineExceeded),
c.CreateOrUpdateAsync(gomockinternal.AContext(), gomock.AssignableToTypeOf(azureResourceGetterType), gomock.Any()).Return(nil, fakePoller[MockCreator](g, http.StatusAccepted), context.DeadlineExceeded),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nojnhuh this is the only way I could get this test to pass, I tried using:

azure.CreateOrUpdateAsyncOpts{ResumeToken: "", Parameters: gomock.Any()}

as the 3rd argument to c.CreateOrUpdateAsync and it was complaining:

            Got: { {<nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> map[] <nil> <nil> <nil>}} (azure.CreateOrUpdateAsyncOpts)
            Want: is equal to { is anything} (azure.CreateOrUpdateAsyncOpts)

Using gomock.Any() to represent the now-current azure.CreateOrUpdateAsyncOpts type seems like cheating...

s.SetLongRunningOperationState(gomock.AssignableToTypeOf(&infrav1.Future{})),
s.DefaultedReconcilerRequeue().Return(reconciler.DefaultReconcilerRequeue),
)
Expand Down Expand Up @@ -293,17 +293,19 @@ const (
resourceGroupName = "mock-resourcegroup"
resourceName = "mock-resource"
serviceName = "mock-service"
resumeToken = "mock-resume-token"
invalidResumeToken = "!invalid-resume-token"
)

var (
createOrUpdateAsyncOpts = azure.CreateOrUpdateAsyncOpts{
ResumeToken: "mock-resume-token",
}
validPutFuture = &infrav1.Future{
Type: infrav1.PutFuture,
ServiceName: serviceName,
Name: resourceName,
ResourceGroup: resourceGroupName,
Data: base64.URLEncoding.EncodeToString([]byte(resumeToken)),
Data: base64.URLEncoding.EncodeToString([]byte(createOrUpdateAsyncOpts.ResumeToken)),
}
invalidPutFuture = &infrav1.Future{
Type: infrav1.PutFuture,
Expand All @@ -317,7 +319,7 @@ var (
ServiceName: serviceName,
Name: resourceName,
ResourceGroup: resourceGroupName,
Data: base64.URLEncoding.EncodeToString([]byte(resumeToken)),
Data: base64.URLEncoding.EncodeToString([]byte(createOrUpdateAsyncOpts.ResumeToken)),
}
invalidDeleteFuture = &infrav1.Future{
Type: infrav1.DeleteFuture,
Expand Down
2 changes: 1 addition & 1 deletion azure/services/async/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ type TagsGetter interface {
// Creator creates or updates a resource asynchronously.
type Creator[T any] interface {
Getter
CreateOrUpdateAsync(ctx context.Context, spec azure.ResourceSpecGetter, resumeToken string, parameters interface{}) (result interface{}, poller *runtime.Poller[T], err error)
CreateOrUpdateAsync(ctx context.Context, spec azure.ResourceSpecGetter, opts azure.CreateOrUpdateAsyncOpts) (result interface{}, poller *runtime.Poller[T], err error)
}

// Deleter deletes a resource asynchronously.
Expand Down
8 changes: 4 additions & 4 deletions azure/services/async/mock_async/async_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions azure/services/availabilitysets/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@
// CreateOrUpdateAsync creates or updates an availability set asynchronously.
// It sends a PUT request to Azure and if accepted without error, the func will return a Poller which can be used to track the ongoing
// progress of the operation.
func (ac *AzureClient) CreateOrUpdateAsync(ctx context.Context, spec azure.ResourceSpecGetter, _resumeToken string, parameters interface{}) (result interface{}, poller *runtime.Poller[armcompute.AvailabilitySetsClientCreateOrUpdateResponse], err error) { //nolint:revive // keeping _resumeToken for understanding purposes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That this is called CreateOrUpdateAsync but isn't actually async at all is the bigger smell to me than an unused parameter. Passing both parameters in a single struct and then only using one field of the struct is just sweeping the problem under the rug IMO.

I get that the SDK simply doesn't give async variants for some types so this is the lowest common denominator, but a more "proper" fix to me would be to have some way to classify services as either "async" or "not async" so the "not async" services like this one are never even passed a resume token at all, not even an empty placeholder. Or do a wholesale rewrite of all the service clients to be pure generic ARM like ASO where everything really is handled the same way.

This may be one reason to prefer ASO long-term. K8s resources defined by ASO are overall way more homogenous than SDK objects.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverting this probably wouldn't be that much work:

Or we could wrap the clients that don't have native asynchronous SDK interfaces in our own async business logic.

In any event these are all good considerations for how to proceed going forward. Calculated using a conventional effort * return formula.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I can convince myself that the "Async" part of "CreateOrUpdateAsync" describes CAPZ's higher-level behavior rather than reflecting exactly what's being done here, so I'm not too hung up on the name.

Overall I think if we do anything here for now we change the parameters to _ and remove the //nolints. Anything more I think isn't worth sacrificing how all the SDK services are currently set up more or less the same way.

func (ac *AzureClient) CreateOrUpdateAsync(ctx context.Context, spec azure.ResourceSpecGetter, opts azure.CreateOrUpdateAsyncOpts) (result interface{}, poller *runtime.Poller[armcompute.AvailabilitySetsClientCreateOrUpdateResponse], err error) {

Check warning on line 63 in azure/services/availabilitysets/client.go

View check run for this annotation

Codecov / codecov/patch

azure/services/availabilitysets/client.go#L63

Added line #L63 was not covered by tests
ctx, _, done := tele.StartSpanWithLogger(ctx, "availabilitySets.AzureClient.CreateOrUpdateAsync")
defer done()

availabilitySet, ok := parameters.(armcompute.AvailabilitySet)
if !ok && parameters != nil {
return nil, nil, errors.Errorf("%T is not an armcompute.AvailabilitySet", parameters)
availabilitySet, ok := opts.Parameters.(armcompute.AvailabilitySet)
if !ok && opts.Parameters != nil {
return nil, nil, errors.Errorf("%T is not an armcompute.AvailabilitySet", opts.Parameters)

Check warning on line 69 in azure/services/availabilitysets/client.go

View check run for this annotation

Codecov / codecov/patch

azure/services/availabilitysets/client.go#L67-L69

Added lines #L67 - L69 were not covered by tests
}

// Note: there is no async `BeginCreateOrUpdate` implementation for availability sets, so this func will never return a poller.
Expand All @@ -82,7 +82,7 @@
// DeleteAsync deletes a availability set asynchronously. DeleteAsync sends a DELETE
// request to Azure and if accepted without error, the func will return a Poller which can be used to track the ongoing
// progress of the operation.
func (ac *AzureClient) DeleteAsync(ctx context.Context, spec azure.ResourceSpecGetter, _resumeToken string) (poller *runtime.Poller[armcompute.AvailabilitySetsClientDeleteResponse], err error) { //nolint:revive // keeping _resumeToken for understanding purposes
func (ac *AzureClient) DeleteAsync(ctx context.Context, spec azure.ResourceSpecGetter, _ string) (poller *runtime.Poller[armcompute.AvailabilitySetsClientDeleteResponse], err error) {

Check warning on line 85 in azure/services/availabilitysets/client.go

View check run for this annotation

Codecov / codecov/patch

azure/services/availabilitysets/client.go#L85

Added line #L85 was not covered by tests
ctx, _, done := tele.StartSpanWithLogger(ctx, "availabilitysets.AzureClient.DeleteAsync")
defer done()

Expand Down
14 changes: 7 additions & 7 deletions azure/services/inboundnatrules/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,18 +90,18 @@
// CreateOrUpdateAsync creates or updates an inbound NAT rule asynchronously.
// It sends a PUT request to Azure and if accepted without error, the func will return a Poller which can be used to track the ongoing
// progress of the operation.
func (ac *azureClient) CreateOrUpdateAsync(ctx context.Context, spec azure.ResourceSpecGetter, resumeToken string, parameters interface{}) (result interface{}, poller *runtime.Poller[armnetwork.InboundNatRulesClientCreateOrUpdateResponse], err error) {
func (ac *azureClient) CreateOrUpdateAsync(ctx context.Context, spec azure.ResourceSpecGetter, opts azure.CreateOrUpdateAsyncOpts) (result interface{}, poller *runtime.Poller[armnetwork.InboundNatRulesClientCreateOrUpdateResponse], err error) {

Check warning on line 93 in azure/services/inboundnatrules/client.go

View check run for this annotation

Codecov / codecov/patch

azure/services/inboundnatrules/client.go#L93

Added line #L93 was not covered by tests
ctx, log, done := tele.StartSpanWithLogger(ctx, "inboundnatrules.azureClient.CreateOrUpdateAsync")
defer done()

natRule, ok := parameters.(armnetwork.InboundNatRule)
if !ok && parameters != nil {
return nil, nil, errors.Errorf("%T is not an armnetwork.InboundNatRule", parameters)
natRule, ok := opts.Parameters.(armnetwork.InboundNatRule)
if !ok && opts.Parameters != nil {
return nil, nil, errors.Errorf("%T is not an armnetwork.InboundNatRule", opts.Parameters)

Check warning on line 99 in azure/services/inboundnatrules/client.go

View check run for this annotation

Codecov / codecov/patch

azure/services/inboundnatrules/client.go#L97-L99

Added lines #L97 - L99 were not covered by tests
}

opts := &armnetwork.InboundNatRulesClientBeginCreateOrUpdateOptions{ResumeToken: resumeToken}
log.V(4).Info("sending request", "resumeToken", resumeToken)
poller, err = ac.inboundnatrules.BeginCreateOrUpdate(ctx, spec.ResourceGroupName(), spec.OwnerResourceName(), spec.ResourceName(), natRule, opts)
beginOpts := &armnetwork.InboundNatRulesClientBeginCreateOrUpdateOptions{ResumeToken: opts.ResumeToken}
log.V(4).Info("sending request", "resumeToken", opts.ResumeToken)
poller, err = ac.inboundnatrules.BeginCreateOrUpdate(ctx, spec.ResourceGroupName(), spec.OwnerResourceName(), spec.ResourceName(), natRule, beginOpts)

Check warning on line 104 in azure/services/inboundnatrules/client.go

View check run for this annotation

Codecov / codecov/patch

azure/services/inboundnatrules/client.go#L102-L104

Added lines #L102 - L104 were not covered by tests
if err != nil {
return nil, nil, err
}
Expand Down
12 changes: 6 additions & 6 deletions azure/services/loadbalancers/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,13 @@
// CreateOrUpdateAsync creates or updates a load balancer asynchronously.
// It sends a PUT request to Azure and if accepted without error, the func will return a Poller which can be used to track the ongoing
// progress of the operation.
func (ac *azureClient) CreateOrUpdateAsync(ctx context.Context, spec azure.ResourceSpecGetter, resumeToken string, parameters interface{}) (result interface{}, poller *runtime.Poller[armnetwork.LoadBalancersClientCreateOrUpdateResponse], err error) {
func (ac *azureClient) CreateOrUpdateAsync(ctx context.Context, spec azure.ResourceSpecGetter, opts azure.CreateOrUpdateAsyncOpts) (result interface{}, poller *runtime.Poller[armnetwork.LoadBalancersClientCreateOrUpdateResponse], err error) {

Check warning on line 70 in azure/services/loadbalancers/client.go

View check run for this annotation

Codecov / codecov/patch

azure/services/loadbalancers/client.go#L70

Added line #L70 was not covered by tests
ctx, _, done := tele.StartSpanWithLogger(ctx, "loadbalancers.azureClient.CreateOrUpdate")
defer done()

loadBalancer, ok := parameters.(armnetwork.LoadBalancer)
if !ok && parameters != nil {
return nil, nil, errors.Errorf("%T is not an armnetwork.LoadBalancer", parameters)
loadBalancer, ok := opts.Parameters.(armnetwork.LoadBalancer)
if !ok && opts.Parameters != nil {
return nil, nil, errors.Errorf("%T is not an armnetwork.LoadBalancer", opts.Parameters)

Check warning on line 76 in azure/services/loadbalancers/client.go

View check run for this annotation

Codecov / codecov/patch

azure/services/loadbalancers/client.go#L74-L76

Added lines #L74 - L76 were not covered by tests
}

var extraPolicies []policy.Policy
Expand All @@ -97,8 +97,8 @@
}

client := factory.NewLoadBalancersClient()
opts := &armnetwork.LoadBalancersClientBeginCreateOrUpdateOptions{ResumeToken: resumeToken}
poller, err = client.BeginCreateOrUpdate(ctx, spec.ResourceGroupName(), spec.ResourceName(), loadBalancer, opts)
beginOpts := &armnetwork.LoadBalancersClientBeginCreateOrUpdateOptions{ResumeToken: opts.ResumeToken}
poller, err = client.BeginCreateOrUpdate(ctx, spec.ResourceGroupName(), spec.ResourceName(), loadBalancer, beginOpts)

Check warning on line 101 in azure/services/loadbalancers/client.go

View check run for this annotation

Codecov / codecov/patch

azure/services/loadbalancers/client.go#L100-L101

Added lines #L100 - L101 were not covered by tests
if err != nil {
return nil, nil, err
}
Expand Down
24 changes: 12 additions & 12 deletions azure/services/networkinterfaces/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@
"sigs.k8s.io/cluster-api-provider-azure/util/tele"
)

// azureClient contains the Azure go-sdk Client.
type azureClient struct {
// AzureClient contains the Azure go-sdk Client.
type AzureClient struct {
interfaces *armnetwork.InterfacesClient
apiCallTimeout time.Duration
}

// NewClient creates a new network interfaces client from an authorizer.
func NewClient(auth azure.Authorizer, apiCallTimeout time.Duration) (*azureClient, error) { //nolint:revive // leave it as is
func NewClient(auth azure.Authorizer, apiCallTimeout time.Duration) (*AzureClient, error) {

Check warning on line 39 in azure/services/networkinterfaces/client.go

View check run for this annotation

Codecov / codecov/patch

azure/services/networkinterfaces/client.go#L39

Added line #L39 was not covered by tests
opts, err := azure.ARMClientOptions(auth.CloudEnvironment())
if err != nil {
return nil, errors.Wrap(err, "failed to create networkinterfaces client options")
Expand All @@ -45,11 +45,11 @@
if err != nil {
return nil, errors.Wrap(err, "failed to create armnetwork client factory")
}
return &azureClient{factory.NewInterfacesClient(), apiCallTimeout}, nil
return &AzureClient{factory.NewInterfacesClient(), apiCallTimeout}, nil

Check warning on line 48 in azure/services/networkinterfaces/client.go

View check run for this annotation

Codecov / codecov/patch

azure/services/networkinterfaces/client.go#L48

Added line #L48 was not covered by tests
}

// Get gets the specified network interface.
func (ac *azureClient) Get(ctx context.Context, spec azure.ResourceSpecGetter) (result interface{}, err error) {
func (ac *AzureClient) Get(ctx context.Context, spec azure.ResourceSpecGetter) (result interface{}, err error) {

Check warning on line 52 in azure/services/networkinterfaces/client.go

View check run for this annotation

Codecov / codecov/patch

azure/services/networkinterfaces/client.go#L52

Added line #L52 was not covered by tests
ctx, _, done := tele.StartSpanWithLogger(ctx, "networkinterfaces.AzureClient.Get")
defer done()

Expand All @@ -63,17 +63,17 @@
// CreateOrUpdateAsync creates or updates a network interface asynchronously.
// It sends a PUT request to Azure and if accepted without error, the func will return a poller which can be used to track the ongoing
// progress of the operation.
func (ac *azureClient) CreateOrUpdateAsync(ctx context.Context, spec azure.ResourceSpecGetter, resumeToken string, parameters interface{}) (result interface{}, poller *runtime.Poller[armnetwork.InterfacesClientCreateOrUpdateResponse], err error) {
func (ac *AzureClient) CreateOrUpdateAsync(ctx context.Context, spec azure.ResourceSpecGetter, opts azure.CreateOrUpdateAsyncOpts) (result interface{}, poller *runtime.Poller[armnetwork.InterfacesClientCreateOrUpdateResponse], err error) {

Check warning on line 66 in azure/services/networkinterfaces/client.go

View check run for this annotation

Codecov / codecov/patch

azure/services/networkinterfaces/client.go#L66

Added line #L66 was not covered by tests
ctx, _, done := tele.StartSpanWithLogger(ctx, "networkinterfaces.AzureClient.CreateOrUpdateAsync")
defer done()

networkInterface, ok := parameters.(armnetwork.Interface)
if !ok && parameters != nil {
return nil, nil, errors.Errorf("%T is not an armnetwork.Interface", parameters)
networkInterface, ok := opts.Parameters.(armnetwork.Interface)
if !ok && opts.Parameters != nil {
return nil, nil, errors.Errorf("%T is not an armnetwork.Interface", opts.Parameters)

Check warning on line 72 in azure/services/networkinterfaces/client.go

View check run for this annotation

Codecov / codecov/patch

azure/services/networkinterfaces/client.go#L70-L72

Added lines #L70 - L72 were not covered by tests
}

opts := &armnetwork.InterfacesClientBeginCreateOrUpdateOptions{ResumeToken: resumeToken}
poller, err = ac.interfaces.BeginCreateOrUpdate(ctx, spec.ResourceGroupName(), spec.ResourceName(), networkInterface, opts)
beginOpts := &armnetwork.InterfacesClientBeginCreateOrUpdateOptions{ResumeToken: opts.ResumeToken}
poller, err = ac.interfaces.BeginCreateOrUpdate(ctx, spec.ResourceGroupName(), spec.ResourceName(), networkInterface, beginOpts)

Check warning on line 76 in azure/services/networkinterfaces/client.go

View check run for this annotation

Codecov / codecov/patch

azure/services/networkinterfaces/client.go#L75-L76

Added lines #L75 - L76 were not covered by tests
if err != nil {
return nil, nil, err
}
Expand All @@ -96,7 +96,7 @@
// DeleteAsync deletes a network interface asynchronously. DeleteAsync sends a DELETE
// request to Azure and if accepted without error, the func will return a poller which can be used to track the ongoing
// progress of the operation.
func (ac *azureClient) DeleteAsync(ctx context.Context, spec azure.ResourceSpecGetter, resumeToken string) (poller *runtime.Poller[armnetwork.InterfacesClientDeleteResponse], err error) {
func (ac *AzureClient) DeleteAsync(ctx context.Context, spec azure.ResourceSpecGetter, resumeToken string) (poller *runtime.Poller[armnetwork.InterfacesClientDeleteResponse], err error) {

Check warning on line 99 in azure/services/networkinterfaces/client.go

View check run for this annotation

Codecov / codecov/patch

azure/services/networkinterfaces/client.go#L99

Added line #L99 was not covered by tests
ctx, _, done := tele.StartSpanWithLogger(ctx, "networkinterfaces.AzureClient.DeleteAsync")
defer done()

Expand Down
Loading