Skip to content

Commit

Permalink
feat(capture): add managed storage account support (#575)
Browse files Browse the repository at this point in the history
# Description

This PR introduces a managed storage account solution to Retina Capture,
which managed the storage account resources on behalf the user under the
azure resource group specified in the azure credential config file.

After this, the user does not need to create even the secret and the
captured network artificats will be uploaded to the storage account.

## Related Issue

If this pull request is related to any issue, please mention it here.
Additionally, make sure that the issue is assigned to you before
submitting this pull request.

## Checklist

- [x] I have read the [contributing
documentation](https://retina.sh/docs/contributing).
- [x] I signed and signed-off the commits (`git commit -S -s ...`). See
[this
documentation](https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification)
on signing commits.
- [x] I have correctly attributed the author(s) of the code.
- [x] I have tested the changes locally.
- [x] I have followed the project's style guidelines.
- [x] I have updated the documentation, if necessary.
- [ ] I have added tests, if applicable.

## Screenshots (if applicable) or Testing Completed

- After updating the helm charts
- a storage account and a management policy rule to auto-delete blob
after 7 days are created

![image](https://github.com/user-attachments/assets/fd93d954-8008-4b04-9afa-626463691405)
- After applying a Capture
  - a blob container with retention policy is created

![image](https://github.com/user-attachments/assets/702dab18-b0a3-4468-830e-56a7449df889)
  -  a k8s secret is created 

![image](https://github.com/user-attachments/assets/834f8977-09e2-4cb6-a99a-578fec33cdb0)
  - network artifacts are uploaded the container after Capture duration

![image](https://github.com/user-attachments/assets/fa147554-8c93-48fe-99f4-65277391ea5b)
- After deleting the capture
  - the secret is deleted

![image](https://github.com/user-attachments/assets/62c0fba4-7845-4792-8572-db412c704075)


## Additional Notes

Add any additional notes or context about the pull request here.

---

Please refer to the [CONTRIBUTING.md](../CONTRIBUTING.md) file for more
information on how to contribute to this project.

---------

Signed-off-by: Qingchuan Hao <[email protected]>
  • Loading branch information
mainred authored Aug 23, 2024
1 parent 1a02887 commit c79d94b
Show file tree
Hide file tree
Showing 17 changed files with 816 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ spec:
volumeMounts:
- name: retina-operator-config
mountPath: /retina/
{{- if .Values.capture.enableManagedStorageAccount }}
- name: cloud-config
mountPath: /etc/cloud-config
readOnly: true
{{- end }}
securityContext:
allowPrivilegeEscalation: false
capabilities:
Expand All @@ -92,7 +97,11 @@ spec:
- name: retina-operator-config
configMap:
name: retina-operator-config

{{- if .Values.capture.enableManagedStorageAccount }}
- name: cloud-config
secret:
secretName: azure-cloud-config
{{- end }}
---
apiVersion: v1
kind: ServiceAccount
Expand Down Expand Up @@ -195,10 +204,21 @@ rules:
- namespaces
- pods
- nodes
verbs:
- get
- list
- apiGroups:
- ""
resources:
- secrets
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- batch
resources:
Expand Down Expand Up @@ -276,6 +296,40 @@ data:
installCRDs: {{ .Values.operator.installCRDs }}
enableTelemetry: {{ .Values.enableTelemetry }}
remoteContext: {{ .Values.remoteContext }}
captureDebug: {{ .Values.operator.capture.debug }}
captureJobNumLimit: {{ .Values.operator.capture.jobNumLimit }}
captureDebug: {{ .Values.capture.debug }}
captureJobNumLimit: {{ .Values.capture.jobNumLimit }}
enableManagedStorageAccount: {{ .Values.capture.enableManagedStorageAccount }}
{{- if .Values.capture.enableManagedStorageAccount }}
azureCredentialConfig: /etc/cloud-config/azure.json
{{- end }}
---
{{- if .Values.capture.enableManagedStorageAccount }}
apiVersion: v1
kind: Secret
metadata:
name: azure-cloud-config
namespace: kube-system
type: Opaque
stringData:
azure.json: |-
{
{{- if .Values.capture.managedIdentityClientId }}
"useManagedIdentityExtension": true,
"aadClientId": "msi",
"aadClientSecret": "msi",
"userAssignedIdentityID": "{{ .Values.capture.managedIdentityClientId }}",
{{- else }}
"useManagedIdentityExtension": false,
"aadClientId": "{{ .Values.capture.aadClientId }}",
"aadClientSecret": "{{ .Values.capture.aadClientSecret }}",
"userAssignedIdentityID": "",
{{- end }}
"useInstanceMetadata": true,
"cloud": "AzurePublicCloud",
"tenantId": "{{ .Values.capture.tenantId }}",
"subscriptionId": "{{ .Values.capture.subscriptionId }}",
"resourceGroup": "{{ .Values.capture.resourceGroup }}",
"location": "{{ .Values.capture.location }}"
}
{{- end }}
{{- end }}
21 changes: 18 additions & 3 deletions deploy/legacy/manifests/controller/helm/retina/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ operator:
tag: "v0.0.2"
installCRDs: true
enableRetinaEndpoint: false
capture:
debug: "true"
jobNumLimit: 0
resources:
limits:
cpu: 500m
Expand Down Expand Up @@ -131,6 +128,24 @@ resources:
memory: "300Mi"
cpu: "500m"

# Retina Capture Configuration
capture:
# debug toggles the debug mode for the Capture. Must be true in production.
debug: true
# jobNumLimit indicates the maximum number of jobs that can be created for each Capture.
jobNumLimit: 0
# enableManagedStorageAccount toggles the use of managed storage account for storing artifacts.
# If set to true, the following fields related to Azure credentials must be set.
# Ref: docs/captures/managed-storage-account.md
enableManagedStorageAccount: false
tenantId: ""
subscriptionId: ""
aadClientId: ""
aadClientSecret: ""
resourceGroup: ""
location: ""
managedIdentityClientId: ""

## @param nodeSelector [object] Node labels for pod assignment
## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/
##
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
116 changes: 116 additions & 0 deletions docs/captures/managed-storage-account.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Managed Storage Account

## Motivation

Retina Capture helps customers capture network packets on Kuberentes cluster to debug network issues. Before Retina Capture can debug the packets, Retina Capture can store the network packets and the customers need to download the packets from Retina Capture supported locations with tools like Wireshark.

To simplify customers' work to decide where to store the packets and then download the packets to local environment, we propose a managed account solution for customer to help customer manage the lifecycle, security when to the storage account and garbage collection of the storage account. Customers can use managed storage account by default, or specify their own storage account ID and Storage Blob Data Owner or higher privilege should be granted to [AKS managed identity or service principal](https://learn.microsoft.com/en-us/azure/aks/use-managed-identity).

## Detailed Design

### Workflow

![Workflow of Retina Capture without managed storage account](img/capture-managed-storage-account.png "Workflow of Retina Capture without managed storage account")

## Setup

To enable the managed storage account, you need to specify the following configuration in the helm command,

```bash
--set operator.enabled=true \
--set operator.capture.enableManagedStorageAccount=true
```

Internally, `enableManagedStorageAccount` will change the following retina-operator configuration and azure credential config as explained in the following two sections.

### Retina-Operator Configuration

#### enableManagedStorageAccount Configuration

`enableManagedStorageAccount` configuration controls whether to use managed storage account or not.

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: retina-operator-config
namespace: kube-system
data:
... ...
enableManagedStorageAccount: true/false
azureCredentialConfig: /etc/kubernetes/cloud-config/azure.json
```
#### Azure credential configuration
The configuration `azureCredentialConfig` in retina-operator-config indicates the Azure credential file path to talk to azure for the managed resources.

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: retina-operator-config
namespace: kube-system
data:
.. ...
enableManagedStorageAccount: true/false
azureCredentialConfig: /etc/kubernetes/cloud-config/azure.json
```

In the above configuration, when `enableManagedStorageAccount` is true, retina-operator will pick azure credential configuration from `/etc/kubernetes/cloud-config/azure.json`. [retina-operator helm template](https://github.com/microsoft/retina/blob/main/deploy/legacy/manifests/controller/helm/retina/templates/operator.yaml) mounts the secret containing azure credentials to `/etc/kubernetes/cloud-config/azure.json`.

When default storage account is enabled, a managed storage account will be created under the resource group of the sub both specified in the credential file.
In the case of AKS, the resource group will be MC, or node, resource group, and subscription will be the overlay subscription.

#### Azure credential configuration content

Detailed explanation of the auth configuration can be found [here](https://github.com/kubernetes-sigs/cloud-provider-azure/blob/0556803/pkg/azclient/auth_conf.go).

Under the resource group, the service principal or managed identity should have `Storage Blob Data Contributor` role to create user delegation SAS, AND at least `Storage Account Contributor` role to manage storage account, container and polices in Azure.

- Managed Identity

```json
{
"cloud": "AzurePublicCloud",
"tenantId": "<tenant-id>",
"subscriptionId": "<subscription-id>",
"aadClientId": "msi",
"aadClientSecret": "msi",
"resourceGroup": "<resource-group-name>", // the resource group where the cluster is deployed in
"location": "<location>", // the location where the cluster is deployed in
"useManagedIdentityExtension": true,
"userAssignedIdentityID": "<managed-identity-client-id>",
"useInstanceMetadata": true
}
```

- Service Principal

```json
{
"cloud": "AzurePublicCloud",
"tenantId": "<tenant-id>",
"subscriptionId": "<subscription-id>",
"aadClientId": "<client-id>",
"aadClientSecret": "<client-secret>",
"resourceGroup": "<resource-group-name>", // the resource group where the cluster is deployed in
"location": "<location>", // the location where the cluster is deployed in
"useManagedIdentityExtension": false,
"userAssignedIdentityID": "",
"useInstanceMetadata": true
}
```

### Storage Account

The storage account, `retina-uuid`, is created under MC resource group and lifecycle management with 7 expiration days is created by Retina Operator if Capture is enabled. AKS customers can enable Retina Capture by upgrading their clusters after this feature is released.

### Container

A container, `capture`, will be created to store the network artifacts after the storage account is ready. And to protect the packets from being deleted or modified, a [retention policy](https://learn.microsoft.com/en-us/azure/storage/blobs/immutable-storage-overview) with 7 days retention period will be applied on this container.

## Create a Retina Capture

Retina-operator will create a container blob SAS URL with expiry time determined from Capture Duration to make sure blob SAS URL is invalid soon after the Capture is completed.
And Retina-operator will update Capture CR with the blob SAL URL to allow the customer read the URL.
4 changes: 4 additions & 0 deletions docs/captures/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ Available after after [installing Retina](../installation/setup.md) with capture

See [Capture CRD](../CRDs/Capture.md) for more details.

#### Managed Storage Account

To simply the user experience, a managed storage account is configurable when setting up Retina, which can manage the storage account, container and Kubernetes secreting container the blob SAS on behalf the user. Check [managed-storage-account.md] for more details.

#### Example

This example creates a Capture and stores the Capture artifacts into a storage account specified by Blob SAS URL.
Expand Down
12 changes: 11 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ require (
github.com/spf13/cobra v1.8.1
go.uber.org/zap v1.27.0
k8s.io/client-go v0.30.3
sigs.k8s.io/cloud-provider-azure/pkg/azclient v0.0.38
sigs.k8s.io/cloud-provider-azure/pkg/azclient/configloader v0.0.20
)

require (
Expand All @@ -17,6 +19,13 @@ require (
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerregistry/armcontainerregistry v1.2.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.4.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.2.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.1.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest v0.11.29 // indirect
Expand Down Expand Up @@ -215,7 +224,7 @@ require (
golang.org/x/crypto v0.26.0 // indirect
golang.org/x/mod v0.20.0 // indirect
golang.org/x/text v0.17.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/time v0.6.0 // indirect
golang.org/x/tools v0.24.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect
Expand Down Expand Up @@ -273,6 +282,7 @@ require (
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/monitor/armmonitor v0.11.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v5 v5.2.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.6.0
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.4.0
github.com/Microsoft/hcsshim v0.12.0-rc.3
github.com/Sytten/logrus-zap-hook v0.1.0
Expand Down
24 changes: 22 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 h1:tfLQ34V6F7tVSwoTf/4lH
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0 h1:LkHbJbgF3YyvC53aqYGR+wWQDn2Rdp9AQdGndf9QvY4=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0/go.mod h1:QyiQdW4f4/BIfB8ZutZ2s+28RAgfa/pT+zS++ZHyM1I=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerregistry/armcontainerregistry v1.2.0 h1:DWlwvVV5r/Wy1561nZ3wrpI1/vDIBRY/Wd1HWaRBZWA=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerregistry/armcontainerregistry v1.2.0/go.mod h1:E7ltexgRDmeJ0fJWv0D/HLwY2xbDdN+uv+X2uZtOx3w=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v4 v4.8.0 h1:0nGmzwBv5ougvzfGPCO2ljFRHvun57KpNrVCMrlk0ns=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v4 v4.8.0/go.mod h1:gYq8wyDgv6JLhGbAU6gg8amCPgQWRE+aCvrV2gyzdfs=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dashboard/armdashboard v1.2.0 h1:MRPU8Bge2f9tkfG3PCr4vEnqXl8XOSjlhuK3l+8Hvkc=
Expand All @@ -27,16 +31,26 @@ github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0 h1:PTFG
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0/go.mod h1:LRr2FzBTQlONPPa5HREE5+RjSCTXl7BwOvYOaWTqCaI=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v3 v3.0.0 h1:Kb8eVvjdP6kZqYnER5w/PiGCFp91yVgaxve3d7kCEpY=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v3 v3.0.0/go.mod h1:lYq15QkJyEsNegz5EhI/0SXQ6spvGfgwBH/Qyzkoc/s=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.4.0 h1:HlZMUZW8S4P9oob1nCHxCCKrytxyLc+24nUJGssoEto=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.4.0/go.mod h1:StGsLbuJh06Bd8IBfnAlIFV3fLb+gkczONWf15hpX2E=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/managementgroups/armmanagementgroups v1.0.0 h1:pPvTJ1dY0sA35JOeFq6TsY2xj6Z85Yo23Pj4wCCvu4o=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/managementgroups/armmanagementgroups v1.0.0/go.mod h1:mLfWfj8v3jfWKsL9G4eoBoXVcsqcIUTapmdKy7uGOp0=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/monitor/armmonitor v0.11.0 h1:Ds0KRF8ggpEGg4Vo42oX1cIt/IfOhHWJBikksZbVxeg=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/monitor/armmonitor v0.11.0/go.mod h1:jj6P8ybImR+5topJ+eH6fgcemSFBmU6/6bFF8KkwuDI=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0 h1:bXwSugBiSbgtz7rOtbfGf+woewp4f06orW9OP5BjHLA=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0/go.mod h1:Y/HgrePTmGy9HjdSGTqZNa+apUpTVIEVKXJyARP2lrk=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v5 v5.2.0 h1:qBlqTo40ARdI7Pmq+enBiTnejZk2BF+PHgktgG8k3r8=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v5 v5.2.0/go.mod h1:UmyOatRyQodVpp55Jr5WJmnkmVW4wKfo85uHFmMEjfM=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.2.0 h1:9Eih8XcEeQnFD0ntMlUDleKMzfeCeUfa+VbnDCI4AZs=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.2.0/go.mod h1:wGPyTi+aURdqPAGMZDQqnNs9IrShADF8w2WZb6bKeq0=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 h1:Dd+RhdJn0OTtVGaeDLZpcumkIVCtA/3/Fo42+eoYvVM=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0/go.mod h1:5kakwfW5CjC9KK+Q4wjXAg+ShuIm2mBMua0ZFj2C8PE=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.6.0 h1:PiSrjRPpkQNjrM8H0WwKMnZUdu1RGMtd/LdGKUrOo+c=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.6.0/go.mod h1:oDrbWx4ewMylP7xHivfgixbfGBT6APAwsSoHRKotnIc=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.1.0 h1:h4Zxgmi9oyZL2l8jeg1iRTqPloHktywWcu0nlJmo1tA=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.1.0/go.mod h1:LgLGXawqSreJz135Elog0ywTJDsm0Hz2k+N+6ZK35u8=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0 h1:D3occbWoio4EBLkbkevetNMAVX197GkzbUMtqjGWn80=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0/go.mod h1:bTSOgj05NGRuHHhQwAdPnYr9TOdNmKlZTgGLL6nyAdI=
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.4.0 h1:Be6KInmFEKV81c0pOAEbRYehLMwmmGI1exuFj248AMk=
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.4.0/go.mod h1:WCPBHsOXfBVnivScjs2ypRfimjEW0qPVLGgJkZlrIOA=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
Expand Down Expand Up @@ -1054,8 +1068,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/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=
Expand Down Expand Up @@ -1120,6 +1134,8 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/dnaeon/go-vcr.v3 v3.2.0 h1:Rltp0Vf+Aq0u4rQXgmXgtgoRDStTnFN83cWgSGSoRzM=
gopkg.in/dnaeon/go-vcr.v3 v3.2.0/go.mod h1:2IMOnnlx9I6u9x+YBsM3tAMx6AlOxnJ0pWxQAzZ79Ag=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
Expand Down Expand Up @@ -1175,6 +1191,10 @@ k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCf
k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
oras.land/oras-go v1.2.5 h1:XpYuAwAb0DfQsunIyMfeET92emK8km3W4yEzZvUbsTo=
oras.land/oras-go v1.2.5/go.mod h1:PuAwRShRZCsZb7g8Ar3jKKQR/2A/qN+pkYxIOd/FAoo=
sigs.k8s.io/cloud-provider-azure/pkg/azclient v0.0.38 h1:+IhYNiGym7/DoggnX19G5Xsljcyrpf9/iDZPxVlq6/c=
sigs.k8s.io/cloud-provider-azure/pkg/azclient v0.0.38/go.mod h1:xtx2LSrndKG6zbmE165Wwr6of/8g0wlPqra8/gf6XN4=
sigs.k8s.io/cloud-provider-azure/pkg/azclient/configloader v0.0.20 h1:jeEFfNxq9uJqkkxhd6WaWNsKNjKhJBcVuWTSgJoXXHM=
sigs.k8s.io/cloud-provider-azure/pkg/azclient/configloader v0.0.20/go.mod h1:5evhIg+6KdZLaezvJPN1rMcn/EY+GypQh/7gNZHD97Y=
sigs.k8s.io/controller-runtime v0.18.5 h1:nTHio/W+Q4aBlQMgbnC5hZb4IjIidyrizMai9P6n4Rk=
sigs.k8s.io/controller-runtime v0.18.5/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
Expand Down
Loading

0 comments on commit c79d94b

Please sign in to comment.