Skip to content

Commit

Permalink
Redact the (fake) AWS access key id in an Azure example that blocks G…
Browse files Browse the repository at this point in the history
…H pushes (#3167)

The Azure spec example
[CreateUpdateAwsCredConnectorSubscription](https://github.com/Azure/azure-rest-api-specs/blob/main/specification/security/resource-manager/Microsoft.Security/preview/2020-01-01-preview/examples/Connectors/CreateUpdateAwsCredConnectorSubscription_example.json#L23)
contains a probably fake, but real looking AWS Access Key id. It hasn't
been modified in years, but it seems GitHub expanded their secrets
scanning, because now our schema.json containing this example is
refused:
```
remote: - GITHUB PUSH PROTECTION        
remote:   ——————————————————————————————————————————————————————        
remote:    Resolve the following secrets before pushing again.        
remote:           
remote:    (?) Learn how to resolve a blocked push        
remote:    https://docs.github.com/code-security/secret-scanning/pushing-a-branch-blocked-by-push-protection        
remote:           
remote:           
remote:   —— Amazon AWS Access Key ID ——————————————————————————        
remote:    locations:        
remote:      - commit: f1b05bccccfa232413de3e74d1c34c189e536117        
remote:        path: provider/cmd/pulumi-resource-azure-native/schema.json:652276        
remote:      - commit: f1b05bccccfa232413de3e74d1c34c189e536117        
remote:        path: provider/cmd/pulumi-resource-azure-native/schema.json:652276        
remote:      - commit: f1b05bccccfa232413de3e74d1c34c189e536117        
remote:        path: provider/cmd/pulumi-resource-azure-native/schema.json:652276        
remote:      - commit: f1b05bccccfa232413de3e74d1c34c189e536117        
remote:        path: provider/cmd/pulumi-resource-azure-native/schema.json:652276        
remote:      - commit: f1b05bccccfa232413de3e74d1c34c189e536117        
remote:        path: provider/cmd/pulumi-resource-azure-native/schema.json:652276 
```

This blocks both developer PRs and automated upgrades.

I first thought of excluding the offending API version, but it's the
only one containing this resource.

Instead, this PR redacts the key id from the example before we process
it further. That way, we keep both the resource and the example.

I've also filed an [upstream
issue](Azure/azure-rest-api-specs#28404).

Fixes #3164 
Fixes #3166
  • Loading branch information
thomas11 committed Mar 22, 2024
1 parent 7c53860 commit 58b1322
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 22 deletions.
9 changes: 9 additions & 0 deletions provider/pkg/gen/examples.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/pulumi/pulumi-azure-native/v2/provider/pkg/debug"
"github.com/pulumi/pulumi-azure-native/v2/provider/pkg/pcl"
"github.com/pulumi/pulumi-azure-native/v2/provider/pkg/resources"
"github.com/pulumi/pulumi-azure-native/v2/provider/pkg/util"

"github.com/pulumi/pulumi-java/pkg/codegen/java"
yaml "github.com/pulumi/pulumi-yaml/pkg/pulumiyaml/codegen"
Expand Down Expand Up @@ -108,6 +109,7 @@ func Examples(rootDir string, pkgSpec *schema.PackageSpec, metadata *resources.A
if err != nil {
return err
}

var exampleJSON map[string]interface{}
if err = json.NewDecoder(f).Decode(&exampleJSON); err != nil {
return err
Expand All @@ -131,6 +133,13 @@ func Examples(rootDir string, pkgSpec *schema.PackageSpec, metadata *resources.A
}
exampleParams := exampleJSON["parameters"].(map[string]interface{})

// Due to https://github.com/Azure/azure-rest-api-specs/issues/28404
if strings.HasSuffix(example.Location, "Microsoft.Security/preview/2020-01-01-preview/examples/Connectors/CreateUpdateAwsCredConnectorSubscription_example.json") {
if authenticationDetails, ok := util.GetInnerMap(exampleParams, "connectorSetting", "properties", "authenticationDetails"); ok {
authenticationDetails["awsAccessKeyId"] = "<awsAccessKeyId>"
}
}

// Fill in sample name and ID for the import section.
responseId, responseName := extractExampleResponseNameId(exampleJSON)
if responseName != "" {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/pkg/errors"
"github.com/pulumi/pulumi-azure-native/v2/provider/pkg/azure"
. "github.com/pulumi/pulumi-azure-native/v2/provider/pkg/resources"
"github.com/pulumi/pulumi-azure-native/v2/provider/pkg/util"
"github.com/pulumi/pulumi-azure-native/v2/provider/pkg/versionLookup"
"github.com/pulumi/pulumi/pkg/v3/codegen"
"github.com/pulumi/pulumi/pkg/v3/codegen/schema"
Expand Down Expand Up @@ -126,7 +127,7 @@ func blobContainerLegalHold(azureClient azure.AzureClient) *CustomResource {
return nil, false, err
}

legalHoldProp, ok := getInnerMap(container, "properties", "legalHold")
legalHoldProp, ok := util.GetInnerMap(container, "properties", "legalHold")
if !ok {
return nil, false, nil
}
Expand All @@ -152,7 +153,7 @@ func blobContainerLegalHold(azureClient azure.AzureClient) *CustomResource {
}
result[tagsProp] = tagsResult
}
if hist, ok := getInnerMap(legalHoldProp, "protectedAppendWritesHistory"); ok {
if hist, ok := util.GetInnerMap(legalHoldProp, "protectedAppendWritesHistory"); ok {
if allow, ok := hist["allowProtectedAppendWritesAll"]; ok {
result[allowProtectedAppendWritesAllProp] = allow.(bool)
}
Expand Down Expand Up @@ -263,23 +264,3 @@ func readTags(p map[string]any) (codegen.StringSet, error) {
}
return strTags, nil
}

func getInnerMap(m map[string]any, keys ...string) (map[string]any, bool) {
cur := m
for i, key := range keys {
val, ok := cur[key]
if !ok {
return nil, false
}
if i == len(keys)-1 {
if valMap, ok := val.(map[string]any); ok {
return valMap, true
}
}
cur, ok = val.(map[string]any)
if !ok {
return nil, false
}
}
return nil, false
}
25 changes: 25 additions & 0 deletions provider/pkg/util/data_structures.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package util

// GetInnerMap returns a map nested inside another. It traverses the list of keys, such that in
// {a: {b: {c: 1}}}, GetInnerMap(m, "a", "b") returns {c: 1}.
// Its purpose is to let callers avoid the repeated `if ..., ok` double check of does the key
// exist, and is the value a map, at each level.
func GetInnerMap(m map[string]any, keys ...string) (map[string]any, bool) {
cur := m
for i, key := range keys {
val, ok := cur[key]
if !ok {
return nil, false
}
if i == len(keys)-1 {
if valMap, ok := val.(map[string]any); ok {
return valMap, true
}
}
cur, ok = val.(map[string]any)
if !ok {
return nil, false
}
}
return nil, false
}
57 changes: 57 additions & 0 deletions provider/pkg/util/data_structures_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package util

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestGetInnerMap(t *testing.T) {
t.Run("no keys", func(t *testing.T) {
m := map[string]any{
"a": "b",
}
_, ok := GetInnerMap(m)
assert.False(t, ok)
})

t.Run("empty map", func(t *testing.T) {
m := map[string]any{}
_, ok := GetInnerMap(m, "a", "b")
assert.False(t, ok)
})

t.Run("key has no map value", func(t *testing.T) {
m := map[string]any{
"a": 1,
}
_, ok := GetInnerMap(m, "a")
assert.False(t, ok)
})

t.Run("single key", func(t *testing.T) {
m := map[string]any{
"a": map[string]any{"b": 1},
}
inner, ok := GetInnerMap(m, "a")
assert.True(t, ok)
assert.Equal(t, map[string]any{"b": 1}, inner)
})

t.Run("multiple keys", func(t *testing.T) {
m := map[string]any{
"a": map[string]any{"b": map[string]any{"c": 1}},
}
inner, ok := GetInnerMap(m, "a", "b")
assert.True(t, ok)
assert.Equal(t, map[string]any{"c": 1}, inner)
})

t.Run("multiple keys, one has no map value", func(t *testing.T) {
m := map[string]any{
"a": map[string]any{"b": 1},
}
_, ok := GetInnerMap(m, "a", "b", "c")
assert.False(t, ok)
})
}

0 comments on commit 58b1322

Please sign in to comment.