github.com/opentofu/opentofu@v1.7.1/internal/backend/remote-state/azure/client_test.go (about) 1 // Copyright (c) The OpenTofu Authors 2 // SPDX-License-Identifier: MPL-2.0 3 // Copyright (c) 2023 HashiCorp, Inc. 4 // SPDX-License-Identifier: MPL-2.0 5 6 package azure 7 8 import ( 9 "context" 10 "os" 11 "testing" 12 13 "github.com/opentofu/opentofu/internal/backend" 14 "github.com/opentofu/opentofu/internal/encryption" 15 "github.com/opentofu/opentofu/internal/legacy/helper/acctest" 16 "github.com/opentofu/opentofu/internal/states/remote" 17 "github.com/tombuildsstuff/giovanni/storage/2018-11-09/blob/blobs" 18 ) 19 20 func TestRemoteClient_impl(t *testing.T) { 21 var _ remote.Client = new(RemoteClient) 22 var _ remote.ClientLocker = new(RemoteClient) 23 } 24 25 func TestRemoteClientAccessKeyBasic(t *testing.T) { 26 testAccAzureBackend(t) 27 rs := acctest.RandString(4) 28 res := testResourceNames(rs, "testState") 29 armClient := buildTestClient(t, res) 30 31 ctx := context.TODO() 32 err := armClient.buildTestResources(ctx, &res) 33 defer armClient.destroyTestResources(ctx, res) 34 if err != nil { 35 t.Fatalf("Error creating Test Resources: %q", err) 36 } 37 38 b := backend.TestBackendConfig(t, New(encryption.StateEncryptionDisabled()), backend.TestWrapConfig(map[string]interface{}{ 39 "storage_account_name": res.storageAccountName, 40 "container_name": res.storageContainerName, 41 "key": res.storageKeyName, 42 "access_key": res.storageAccountAccessKey, 43 "environment": os.Getenv("ARM_ENVIRONMENT"), 44 "endpoint": os.Getenv("ARM_ENDPOINT"), 45 })).(*Backend) 46 47 state, err := b.StateMgr(backend.DefaultStateName) 48 if err != nil { 49 t.Fatal(err) 50 } 51 52 remote.TestClient(t, state.(*remote.State).Client) 53 } 54 55 func TestRemoteClientManagedServiceIdentityBasic(t *testing.T) { 56 testAccAzureBackendRunningInAzure(t) 57 rs := acctest.RandString(4) 58 res := testResourceNames(rs, "testState") 59 armClient := buildTestClient(t, res) 60 61 ctx := context.TODO() 62 err := armClient.buildTestResources(ctx, &res) 63 defer armClient.destroyTestResources(ctx, res) 64 if err != nil { 65 t.Fatalf("Error creating Test Resources: %q", err) 66 } 67 68 b := backend.TestBackendConfig(t, New(encryption.StateEncryptionDisabled()), backend.TestWrapConfig(map[string]interface{}{ 69 "storage_account_name": res.storageAccountName, 70 "container_name": res.storageContainerName, 71 "key": res.storageKeyName, 72 "resource_group_name": res.resourceGroup, 73 "use_msi": true, 74 "subscription_id": os.Getenv("ARM_SUBSCRIPTION_ID"), 75 "tenant_id": os.Getenv("ARM_TENANT_ID"), 76 "environment": os.Getenv("ARM_ENVIRONMENT"), 77 "endpoint": os.Getenv("ARM_ENDPOINT"), 78 })).(*Backend) 79 80 state, err := b.StateMgr(backend.DefaultStateName) 81 if err != nil { 82 t.Fatal(err) 83 } 84 85 remote.TestClient(t, state.(*remote.State).Client) 86 } 87 88 func TestRemoteClientSasTokenBasic(t *testing.T) { 89 testAccAzureBackend(t) 90 rs := acctest.RandString(4) 91 res := testResourceNames(rs, "testState") 92 armClient := buildTestClient(t, res) 93 94 ctx := context.TODO() 95 err := armClient.buildTestResources(ctx, &res) 96 defer armClient.destroyTestResources(ctx, res) 97 if err != nil { 98 t.Fatalf("Error creating Test Resources: %q", err) 99 } 100 101 sasToken, err := buildSasToken(res.storageAccountName, res.storageAccountAccessKey) 102 if err != nil { 103 t.Fatalf("Error building SAS Token: %+v", err) 104 } 105 106 b := backend.TestBackendConfig(t, New(encryption.StateEncryptionDisabled()), backend.TestWrapConfig(map[string]interface{}{ 107 "storage_account_name": res.storageAccountName, 108 "container_name": res.storageContainerName, 109 "key": res.storageKeyName, 110 "sas_token": *sasToken, 111 "environment": os.Getenv("ARM_ENVIRONMENT"), 112 "endpoint": os.Getenv("ARM_ENDPOINT"), 113 })).(*Backend) 114 115 state, err := b.StateMgr(backend.DefaultStateName) 116 if err != nil { 117 t.Fatal(err) 118 } 119 120 remote.TestClient(t, state.(*remote.State).Client) 121 } 122 123 func TestRemoteClientServicePrincipalBasic(t *testing.T) { 124 testAccAzureBackend(t) 125 rs := acctest.RandString(4) 126 res := testResourceNames(rs, "testState") 127 armClient := buildTestClient(t, res) 128 129 ctx := context.TODO() 130 err := armClient.buildTestResources(ctx, &res) 131 defer armClient.destroyTestResources(ctx, res) 132 if err != nil { 133 t.Fatalf("Error creating Test Resources: %q", err) 134 } 135 136 b := backend.TestBackendConfig(t, New(encryption.StateEncryptionDisabled()), backend.TestWrapConfig(map[string]interface{}{ 137 "storage_account_name": res.storageAccountName, 138 "container_name": res.storageContainerName, 139 "key": res.storageKeyName, 140 "resource_group_name": res.resourceGroup, 141 "subscription_id": os.Getenv("ARM_SUBSCRIPTION_ID"), 142 "tenant_id": os.Getenv("ARM_TENANT_ID"), 143 "client_id": os.Getenv("ARM_CLIENT_ID"), 144 "client_secret": os.Getenv("ARM_CLIENT_SECRET"), 145 "environment": os.Getenv("ARM_ENVIRONMENT"), 146 "endpoint": os.Getenv("ARM_ENDPOINT"), 147 })).(*Backend) 148 149 state, err := b.StateMgr(backend.DefaultStateName) 150 if err != nil { 151 t.Fatal(err) 152 } 153 154 remote.TestClient(t, state.(*remote.State).Client) 155 } 156 157 func TestRemoteClientAccessKeyLocks(t *testing.T) { 158 testAccAzureBackend(t) 159 rs := acctest.RandString(4) 160 res := testResourceNames(rs, "testState") 161 armClient := buildTestClient(t, res) 162 163 ctx := context.TODO() 164 err := armClient.buildTestResources(ctx, &res) 165 defer armClient.destroyTestResources(ctx, res) 166 if err != nil { 167 t.Fatalf("Error creating Test Resources: %q", err) 168 } 169 170 b1 := backend.TestBackendConfig(t, New(encryption.StateEncryptionDisabled()), backend.TestWrapConfig(map[string]interface{}{ 171 "storage_account_name": res.storageAccountName, 172 "container_name": res.storageContainerName, 173 "key": res.storageKeyName, 174 "access_key": res.storageAccountAccessKey, 175 "environment": os.Getenv("ARM_ENVIRONMENT"), 176 "endpoint": os.Getenv("ARM_ENDPOINT"), 177 })).(*Backend) 178 179 b2 := backend.TestBackendConfig(t, New(encryption.StateEncryptionDisabled()), backend.TestWrapConfig(map[string]interface{}{ 180 "storage_account_name": res.storageAccountName, 181 "container_name": res.storageContainerName, 182 "key": res.storageKeyName, 183 "access_key": res.storageAccountAccessKey, 184 "environment": os.Getenv("ARM_ENVIRONMENT"), 185 "endpoint": os.Getenv("ARM_ENDPOINT"), 186 })).(*Backend) 187 188 s1, err := b1.StateMgr(backend.DefaultStateName) 189 if err != nil { 190 t.Fatal(err) 191 } 192 193 s2, err := b2.StateMgr(backend.DefaultStateName) 194 if err != nil { 195 t.Fatal(err) 196 } 197 198 remote.TestRemoteLocks(t, s1.(*remote.State).Client, s2.(*remote.State).Client) 199 } 200 201 func TestRemoteClientServicePrincipalLocks(t *testing.T) { 202 testAccAzureBackend(t) 203 rs := acctest.RandString(4) 204 res := testResourceNames(rs, "testState") 205 armClient := buildTestClient(t, res) 206 207 ctx := context.TODO() 208 err := armClient.buildTestResources(ctx, &res) 209 defer armClient.destroyTestResources(ctx, res) 210 if err != nil { 211 t.Fatalf("Error creating Test Resources: %q", err) 212 } 213 214 b1 := backend.TestBackendConfig(t, New(encryption.StateEncryptionDisabled()), backend.TestWrapConfig(map[string]interface{}{ 215 "storage_account_name": res.storageAccountName, 216 "container_name": res.storageContainerName, 217 "key": res.storageKeyName, 218 "resource_group_name": res.resourceGroup, 219 "subscription_id": os.Getenv("ARM_SUBSCRIPTION_ID"), 220 "tenant_id": os.Getenv("ARM_TENANT_ID"), 221 "client_id": os.Getenv("ARM_CLIENT_ID"), 222 "client_secret": os.Getenv("ARM_CLIENT_SECRET"), 223 "environment": os.Getenv("ARM_ENVIRONMENT"), 224 "endpoint": os.Getenv("ARM_ENDPOINT"), 225 })).(*Backend) 226 227 b2 := backend.TestBackendConfig(t, New(encryption.StateEncryptionDisabled()), backend.TestWrapConfig(map[string]interface{}{ 228 "storage_account_name": res.storageAccountName, 229 "container_name": res.storageContainerName, 230 "key": res.storageKeyName, 231 "resource_group_name": res.resourceGroup, 232 "subscription_id": os.Getenv("ARM_SUBSCRIPTION_ID"), 233 "tenant_id": os.Getenv("ARM_TENANT_ID"), 234 "client_id": os.Getenv("ARM_CLIENT_ID"), 235 "client_secret": os.Getenv("ARM_CLIENT_SECRET"), 236 "environment": os.Getenv("ARM_ENVIRONMENT"), 237 "endpoint": os.Getenv("ARM_ENDPOINT"), 238 })).(*Backend) 239 240 s1, err := b1.StateMgr(backend.DefaultStateName) 241 if err != nil { 242 t.Fatal(err) 243 } 244 245 s2, err := b2.StateMgr(backend.DefaultStateName) 246 if err != nil { 247 t.Fatal(err) 248 } 249 250 remote.TestRemoteLocks(t, s1.(*remote.State).Client, s2.(*remote.State).Client) 251 } 252 253 func TestPutMaintainsMetaData(t *testing.T) { 254 testAccAzureBackend(t) 255 rs := acctest.RandString(4) 256 res := testResourceNames(rs, "testState") 257 armClient := buildTestClient(t, res) 258 259 ctx := context.TODO() 260 err := armClient.buildTestResources(ctx, &res) 261 defer armClient.destroyTestResources(ctx, res) 262 if err != nil { 263 t.Fatalf("Error creating Test Resources: %q", err) 264 } 265 266 headerName := "acceptancetest" 267 expectedValue := "f3b56bad-33ad-4b93-a600-7a66e9cbd1eb" 268 269 client, err := armClient.getBlobClient(ctx) 270 if err != nil { 271 t.Fatalf("Error building Blob Client: %+v", err) 272 } 273 274 _, err = client.PutBlockBlob(ctx, res.storageAccountName, res.storageContainerName, res.storageKeyName, blobs.PutBlockBlobInput{}) 275 if err != nil { 276 t.Fatalf("Error Creating Block Blob: %+v", err) 277 } 278 279 blobReference, err := client.GetProperties(ctx, res.storageAccountName, res.storageContainerName, res.storageKeyName, blobs.GetPropertiesInput{}) 280 if err != nil { 281 t.Fatalf("Error loading MetaData: %+v", err) 282 } 283 284 blobReference.MetaData[headerName] = expectedValue 285 opts := blobs.SetMetaDataInput{ 286 MetaData: blobReference.MetaData, 287 } 288 _, err = client.SetMetaData(ctx, res.storageAccountName, res.storageContainerName, res.storageKeyName, opts) 289 if err != nil { 290 t.Fatalf("Error setting MetaData: %+v", err) 291 } 292 293 // update the metadata using the Backend 294 remoteClient := RemoteClient{ 295 keyName: res.storageKeyName, 296 containerName: res.storageContainerName, 297 accountName: res.storageAccountName, 298 299 giovanniBlobClient: *client, 300 } 301 302 bytes := []byte(acctest.RandString(20)) 303 err = remoteClient.Put(bytes) 304 if err != nil { 305 t.Fatalf("Error putting data: %+v", err) 306 } 307 308 // Verify it still exists 309 blobReference, err = client.GetProperties(ctx, res.storageAccountName, res.storageContainerName, res.storageKeyName, blobs.GetPropertiesInput{}) 310 if err != nil { 311 t.Fatalf("Error loading MetaData: %+v", err) 312 } 313 314 if blobReference.MetaData[headerName] != expectedValue { 315 t.Fatalf("%q was not set to %q in the MetaData: %+v", headerName, expectedValue, blobReference.MetaData) 316 } 317 }