From ed340a484c015afad79439350af924c987b70cd2 Mon Sep 17 00:00:00 2001 From: srinandan <13950006+srinandan@users.noreply.github.com> Date: Tue, 1 Aug 2023 16:43:36 -0700 Subject: [PATCH 1/6] bug: fixes incorrect parsing of quota and rate limit #246 --- internal/bundlegen/generateapi.go | 46 +++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/internal/bundlegen/generateapi.go b/internal/bundlegen/generateapi.go index 708e1e1ff..9b4ce7d4c 100644 --- a/internal/bundlegen/generateapi.go +++ b/internal/bundlegen/generateapi.go @@ -15,12 +15,12 @@ package bundlegen import ( - "encoding/json" "fmt" "net/url" "path" "path/filepath" "regexp" + "strconv" "strings" "internal/clilog" @@ -617,10 +617,8 @@ func getQuotaDefinition(i interface{}) (quotaDef, error) { quota := quotaDef{} jsonMap := map[string]string{} str := fmt.Sprintf("%s", i) - - if err := json.Unmarshal([]byte(str), &jsonArrayMap); err != nil { - return quotaDef{}, err - } + fmt.Println(str) + jsonArrayMap = parseExtension(str) for _, m := range jsonArrayMap { for k, v := range m { @@ -693,10 +691,7 @@ func getSpikeArrestDefinition(i interface{}) (spikeArrestDef, error) { spikeArrest := spikeArrestDef{} jsonMap := map[string]string{} str := fmt.Sprintf("%s", i) - - if err := json.Unmarshal([]byte(str), &jsonArrayMap); err != nil { - return spikeArrestDef{}, err - } + jsonArrayMap = parseExtension(str) for _, m := range jsonArrayMap { for k, v := range m { @@ -790,3 +785,36 @@ func readScopes(scopes map[string]string) string { } return strings.TrimSpace(scopeString) } + +func parseExtension(extension string) []map[string]interface{} { + var result []map[string]interface{} + pattern := `map\[(.*?)\]` + re := regexp.MustCompile(pattern) + matches := re.FindAllStringSubmatch(extension, -1) + for _, match := range matches { + kvPairs := parseKeyValuePairs(match[1]) + result = append(result, kvPairs) + } + return result +} + +func parseKeyValuePairs(match string) map[string]interface{} { + //HACK: numbers in yaml are represented as %!s(float64=xx) + match = strings.ReplaceAll(match, "%!s(float64=", "") + match = strings.ReplaceAll(match, ")", "") + + keyValuePairs := make(map[string]interface{}) + keyValuePattern := `\b([A-Za-z0-9\-]+)\s*:\s*(\w+)\b` + keyValueRe := regexp.MustCompile(keyValuePattern) + kvMatches := keyValueRe.FindAllStringSubmatch(match, -1) + for _, kvMatch := range kvMatches { + key := kvMatch[1] + value := kvMatch[2] + if intValue, err := strconv.Atoi(value); err == nil { + keyValuePairs[key] = intValue + } else { + keyValuePairs[key] = value + } + } + return keyValuePairs +} From e598e89c74d66817484b7960c34cb634088090e7 Mon Sep 17 00:00:00 2001 From: srinandan <13950006+srinandan@users.noreply.github.com> Date: Wed, 2 Aug 2023 08:01:27 -0700 Subject: [PATCH 2/6] bug: policy name can have dashes #246 --- internal/bundlegen/generateapi.go | 3 +-- test/petstore-ext1.yaml | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/internal/bundlegen/generateapi.go b/internal/bundlegen/generateapi.go index 9b4ce7d4c..42fb00bb6 100644 --- a/internal/bundlegen/generateapi.go +++ b/internal/bundlegen/generateapi.go @@ -617,7 +617,6 @@ func getQuotaDefinition(i interface{}) (quotaDef, error) { quota := quotaDef{} jsonMap := map[string]string{} str := fmt.Sprintf("%s", i) - fmt.Println(str) jsonArrayMap = parseExtension(str) for _, m := range jsonArrayMap { @@ -804,7 +803,7 @@ func parseKeyValuePairs(match string) map[string]interface{} { match = strings.ReplaceAll(match, ")", "") keyValuePairs := make(map[string]interface{}) - keyValuePattern := `\b([A-Za-z0-9\-]+)\s*:\s*(\w+)\b` + keyValuePattern := `\b([A-Za-z0-9\-]+)\s*:\s*([A-Za-z0-9\-]+)\b` keyValueRe := regexp.MustCompile(keyValuePattern) kvMatches := keyValueRe.FindAllStringSubmatch(match, -1) for _, kvMatch := range kvMatches { diff --git a/test/petstore-ext1.yaml b/test/petstore-ext1.yaml index a0ede1ed3..c98b076b9 100644 --- a/test/petstore-ext1.yaml +++ b/test/petstore-ext1.yaml @@ -57,8 +57,8 @@ paths: $ref: '#/components/schemas/Pet' '405': description: Invalid input - x-google-quota: - - name: test2 + x-google-quota: + - name: post-pet interval-literal: 1 timeunit-literal: minute allow-literal: 1 From 4c699c9c97b745c9230237764a93674c1a1374bc Mon Sep 17 00:00:00 2001 From: srinandan <13950006+srinandan@users.noreply.github.com> Date: Wed, 2 Aug 2023 09:01:40 -0700 Subject: [PATCH 3/6] feat: add warning for multiple defs #246 --- internal/bundlegen/generateapi.go | 10 +++++++++- test/petstore-ext1.yaml | 7 +++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/internal/bundlegen/generateapi.go b/internal/bundlegen/generateapi.go index 42fb00bb6..dd2fff008 100644 --- a/internal/bundlegen/generateapi.go +++ b/internal/bundlegen/generateapi.go @@ -619,6 +619,10 @@ func getQuotaDefinition(i interface{}) (quotaDef, error) { str := fmt.Sprintf("%s", i) jsonArrayMap = parseExtension(str) + if len(jsonArrayMap) > 1 { + clilog.Warning.Println("multiple ratelimit definitions are not supported. selecting the last definition") + } + for _, m := range jsonArrayMap { for k, v := range m { jsonMap[k] = fmt.Sprintf("%v", v) @@ -692,6 +696,10 @@ func getSpikeArrestDefinition(i interface{}) (spikeArrestDef, error) { str := fmt.Sprintf("%s", i) jsonArrayMap = parseExtension(str) + if len(jsonArrayMap) > 1 { + clilog.Warning.Println("multiple ratelimit definitions are not supported. selecting the last definition") + } + for _, m := range jsonArrayMap { for k, v := range m { jsonMap[k] = fmt.Sprintf("%v", v) @@ -803,7 +811,7 @@ func parseKeyValuePairs(match string) map[string]interface{} { match = strings.ReplaceAll(match, ")", "") keyValuePairs := make(map[string]interface{}) - keyValuePattern := `\b([A-Za-z0-9\-]+)\s*:\s*([A-Za-z0-9\-]+)\b` + keyValuePattern := `\b([A-Za-z0-9\-_]+)\s*:\s*([A-Za-z0-9\-_]+)\b` keyValueRe := regexp.MustCompile(keyValuePattern) kvMatches := keyValueRe.FindAllStringSubmatch(match, -1) for _, kvMatch := range kvMatches { diff --git a/test/petstore-ext1.yaml b/test/petstore-ext1.yaml index c98b076b9..6c55a6287 100644 --- a/test/petstore-ext1.yaml +++ b/test/petstore-ext1.yaml @@ -32,8 +32,11 @@ tags: - name: user description: Operations about user -x-google-ratelimit: - - name: test1 +x-google-ratelimit: + - name: test1_test + rate-literal: 10ps + identifier-ref: request.header.url #optional + - name: test2_test rate-literal: 10ps identifier-ref: request.header.url #optional From af7a5f1109e84232cddb860ab4b32d4d72825b0c Mon Sep 17 00:00:00 2001 From: srinandan <13950006+srinandan@users.noreply.github.com> Date: Wed, 2 Aug 2023 09:47:09 -0700 Subject: [PATCH 4/6] feat: add support for multiple definitions #246 --- internal/bundlegen/generateapi.go | 218 ++++++++++++++--------------- internal/bundlegen/generateswag.go | 7 +- test/petstore-ext1.yaml | 8 +- 3 files changed, 117 insertions(+), 116 deletions(-) diff --git a/internal/bundlegen/generateapi.go b/internal/bundlegen/generateapi.go index dd2fff008..e4606e44b 100644 --- a/internal/bundlegen/generateapi.go +++ b/internal/bundlegen/generateapi.go @@ -42,8 +42,8 @@ type pathDetailDef struct { AssignMessage string Backend backendDef SecurityScheme securitySchemesDef - SpikeArrest spikeArrestDef - Quota quotaDef + SpikeArrest []spikeArrestDef + Quota []quotaDef } type spikeArrestDef struct { @@ -527,14 +527,18 @@ func generateFlows(paths openapi3.Paths) (err error) { return err } } - if pathDetail.SpikeArrest.SpikeArrestEnabled { - if err = proxies.AddStepToFlowRequest("Spike-Arrest-"+pathDetail.SpikeArrest.SpikeArrestName, pathDetail.OperationID); err != nil { - return err + for _, s := range pathDetail.SpikeArrest { + if s.SpikeArrestEnabled { + if err = proxies.AddStepToFlowRequest("Spike-Arrest-"+s.SpikeArrestName, pathDetail.OperationID); err != nil { + return err + } } } - if pathDetail.Quota.QuotaEnabled { - if err = proxies.AddStepToFlowRequest("Quota-"+pathDetail.Quota.QuotaName, pathDetail.OperationID); err != nil { - return err + for _, q := range pathDetail.Quota { + if q.QuotaEnabled { + if err = proxies.AddStepToFlowRequest("Quota-"+q.QuotaName, pathDetail.OperationID); err != nil { + return err + } } } } @@ -611,129 +615,119 @@ func GetSecuritySchemesList() []securitySchemesDef { return securitySchemesList.SecuritySchemes } -func getQuotaDefinition(i interface{}) (quotaDef, error) { +func getQuotaDefinition(i interface{}) ([]quotaDef, error) { var jsonArrayMap []map[string]interface{} - quota := quotaDef{} - jsonMap := map[string]string{} + quotas := []quotaDef{} str := fmt.Sprintf("%s", i) jsonArrayMap = parseExtension(str) - if len(jsonArrayMap) > 1 { - clilog.Warning.Println("multiple ratelimit definitions are not supported. selecting the last definition") - } - for _, m := range jsonArrayMap { + quota := quotaDef{} for k, v := range m { - jsonMap[k] = fmt.Sprintf("%v", v) + if k == "name" { + quota.QuotaName = fmt.Sprintf("%v", v) + quota.QuotaEnabled = true + } else if k == "useQuotaConfigInAPIProduct" { + quota.QuotaConfigStepName = fmt.Sprintf("%v", v) + } else if k == "allow-ref" { + quota.QuotaAllowRef = fmt.Sprintf("%v", v) + } else if k == "allow-literal" { + quota.QuotaAllowLiteral = fmt.Sprintf("%v", v) + } else if k == "interval-ref" { + quota.QuotaIntervalRef = fmt.Sprintf("%v", v) + } else if k == "interval-literal" { + quota.QuotaIntervalLiteral = fmt.Sprintf("%v", v) + } else if k == "timeunit-ref" { + quota.QuotaTimeUnitRef = fmt.Sprintf("%v", v) + } else if k == "timeunit-literal" { + quota.QuotaTimeUnitLiteral = fmt.Sprintf("%v", v) + } else if k == "identifier-ref" { + quota.QuotaIdentifierRef = fmt.Sprintf("%v", v) + } else if k == "identifier-literal" { + quota.QuotaIdentiferLiteral = fmt.Sprintf("%v", v) + } } + quotas = append(quotas, quota) } - if jsonMap["name"] != "" { - quota.QuotaName = jsonMap["name"] - quota.QuotaEnabled = true - } else { - return quotaDef{}, fmt.Errorf("x-google-quota extension must have a name") - } - - if jsonMap["useQuotaConfigInAPIProduct"] != "" { - quota.QuotaConfigStepName = jsonMap["useQuotaConfigInAPIProduct"] - } else { - if jsonMap["allow-ref"] == "" && jsonMap["allow-literal"] == "" { - return quotaDef{}, fmt.Errorf("x-google-quota extension must have either allow-ref or allow-literal") - } else if jsonMap["allow-literal"] != "" { - quota.QuotaAllowLiteral = jsonMap["allow-literal"] - } else if jsonMap["allow-ref"] != "" { - quota.QuotaAllowRef = jsonMap["allow-ref"] - } - - if jsonMap["interval-ref"] == "" && jsonMap["interval-literal"] == "" { - return quotaDef{}, fmt.Errorf("x-google-quota extension must have either interval-ref or interval-literal") - } else if jsonMap["interval-literal"] != "" { - quota.QuotaIntervalLiteral = jsonMap["interval-literal"] - } else if jsonMap["interval-ref"] != "" { - quota.QuotaIntervalRef = jsonMap["interval-ref"] - } - - if jsonMap["timeunit-ref"] == "" && jsonMap["timeunit-literal"] == "" { - return quotaDef{}, fmt.Errorf("x-google-quota extension must have either timeunit-ref or timeunit-literal") - } else if jsonMap["timeunit-literal"] != "" { - quota.QuotaTimeUnitLiteral = jsonMap["timeunit-literal"] - } else if jsonMap["timeunit-ref"] != "" { - quota.QuotaTimeUnitRef = jsonMap["timeunit-ref"] - } - - if jsonMap["indentifier-literal"] != "" && jsonMap["indentifier-ref"] != "" { - return quotaDef{}, fmt.Errorf("x-google-quota extension must have either identifier-ref or identifier-literal") - } else if jsonMap["indentifier-literal"] != "" { - quota.QuotaIntervalLiteral = jsonMap["identifier-literal"] - } else if jsonMap["indentifier-ref"] != "" { - quota.QuotaIntervalRef = jsonMap["identifier-ref"] - } - } - - // store policy XML contents - quotaPolicyContent[quota.QuotaName] = policies.AddQuotaPolicy( - "Quota-"+quota.QuotaName, - quota.QuotaConfigStepName, - quota.QuotaAllowRef, - quota.QuotaAllowLiteral, - quota.QuotaIntervalRef, - quota.QuotaIntervalLiteral, - quota.QuotaTimeUnitRef, - quota.QuotaTimeUnitLiteral, - quota.QuotaIdentifierRef, - quota.QuotaIdentiferLiteral) - - return quota, nil + for _, q := range quotas { + if q.QuotaName == "" { + return nil, fmt.Errorf("x-google-quota extension must have a name") + } + if q.QuotaConfigStepName == "" { + if q.QuotaAllowLiteral == "" && q.QuotaAllowRef == "" { + return nil, fmt.Errorf("x-google-quota extension must have either allow-ref or allow-literal") + } + if q.QuotaIntervalLiteral == "" && q.QuotaIntervalRef == "" { + return nil, fmt.Errorf("x-google-quota extension must have either interval-ref or interval-literal") + } + if q.QuotaTimeUnitLiteral == "" && q.QuotaTimeUnitRef == "" { + return nil, fmt.Errorf("x-google-quota extension must have either timeunit-ref or timeunit-literal") + } + if q.QuotaIdentiferLiteral == "" && q.QuotaIdentifierRef == "" { + return nil, fmt.Errorf("x-google-quota extension must have either identifier-ref or identifier-literal") + } + } + // store policy XML contents + quotaPolicyContent[q.QuotaName] = policies.AddQuotaPolicy( + "Quota-"+q.QuotaName, + q.QuotaConfigStepName, + q.QuotaAllowRef, + q.QuotaAllowLiteral, + q.QuotaIntervalRef, + q.QuotaIntervalLiteral, + q.QuotaTimeUnitRef, + q.QuotaTimeUnitLiteral, + q.QuotaIdentifierRef, + q.QuotaIdentiferLiteral) + } + + return quotas, nil } -func getSpikeArrestDefinition(i interface{}) (spikeArrestDef, error) { +func getSpikeArrestDefinition(i interface{}) ([]spikeArrestDef, error) { var jsonArrayMap []map[string]interface{} - spikeArrest := spikeArrestDef{} - jsonMap := map[string]string{} + spikeArrests := []spikeArrestDef{} str := fmt.Sprintf("%s", i) jsonArrayMap = parseExtension(str) - if len(jsonArrayMap) > 1 { - clilog.Warning.Println("multiple ratelimit definitions are not supported. selecting the last definition") - } - for _, m := range jsonArrayMap { + spikeArrest := spikeArrestDef{} for k, v := range m { - jsonMap[k] = fmt.Sprintf("%v", v) + if k == "identifier-ref" { + spikeArrest.SpikeArrestIdentifierRef = fmt.Sprintf("%v", v) + } else if k == "name" { + spikeArrest.SpikeArrestName = fmt.Sprintf("%v", v) + spikeArrest.SpikeArrestEnabled = true + } else if k == "rate-literal" { + spikeArrest.SpikeArrestRateLiteral = fmt.Sprintf("%v", v) + } else if k == "rate-ref" { + spikeArrest.SpikeArrestRateRef = fmt.Sprintf("%v", v) + } } + spikeArrests = append(spikeArrests, spikeArrest) } - if jsonMap["identifier-ref"] != "" { - spikeArrest.SpikeArrestIdentifierRef = jsonMap["identifier-ref"] - } else { - return spikeArrestDef{}, fmt.Errorf("x-google-ratelimit extension must have an identifier-ref") - } - - if jsonMap["name"] != "" { - spikeArrest.SpikeArrestName = jsonMap["name"] - spikeArrest.SpikeArrestEnabled = true - } else { - return spikeArrestDef{}, fmt.Errorf("x-google-ratelimit extension must have a name") - } - - if jsonMap["rate-ref"] == "" && jsonMap["rate-literal"] == "" { - return spikeArrestDef{}, fmt.Errorf("x-google-ratelimit extension must have either rate-ref or rate-literal") - } else if jsonMap["rate-literal"] != "" { - spikeArrest.SpikeArrestRateLiteral = jsonMap["rate-literal"] - } else if jsonMap["rate-ref"] != "" { - spikeArrest.SpikeArrestRateRef = jsonMap["rate-ref"] + for _, s := range spikeArrests { + if s.SpikeArrestName == "" { + return nil, fmt.Errorf("x-google-ratelimit extension must have a name") + } + if s.SpikeArrestIdentifierRef == "" { + return nil, fmt.Errorf("x-google-ratelimit extension must have an identifier-ref") + } + if s.SpikeArrestRateLiteral == "" && s.SpikeArrestRateRef == "" { + return nil, fmt.Errorf("x-google-ratelimit extension must have either rate-ref or rate-literal") + } + // store policy XML contents + spikeArrestPolicyContent[s.SpikeArrestName] = policies.AddSpikeArrestPolicy("Spike-Arrest-"+s.SpikeArrestName, + s.SpikeArrestIdentifierRef, + s.SpikeArrestRateRef, + s.SpikeArrestRateLiteral) } - // store policy XML contents - spikeArrestPolicyContent[spikeArrest.SpikeArrestName] = policies.AddSpikeArrestPolicy("Spike-Arrest-"+spikeArrest.SpikeArrestName, - spikeArrest.SpikeArrestIdentifierRef, - spikeArrest.SpikeArrestRateRef, - spikeArrest.SpikeArrestRateLiteral) - - return spikeArrest, nil + return spikeArrests, nil } func processPathExtensions(extensions map[string]interface{}, pathDetail pathDetailDef) (pathDetailDef, error) { @@ -759,19 +753,19 @@ func processPreFlowExtensions(extensions map[string]interface{}) ([]spikeArrestD for extensionName, extensionValue := range extensions { if extensionName == "x-google-ratelimit" { // process ratelimit - spikeArrest, err := getSpikeArrestDefinition(extensionValue) + spikeArrests, err := getSpikeArrestDefinition(extensionValue) if err != nil { return []spikeArrestDef{}, []quotaDef{}, err } - spikeArrestList = append(spikeArrestList, spikeArrest) + spikeArrestList = append(spikeArrestList, spikeArrests...) } if extensionName == "x-google-quota" { // process quota - quota, err := getQuotaDefinition(extensionValue) + quotas, err := getQuotaDefinition(extensionValue) if err != nil { return []spikeArrestDef{}, []quotaDef{}, err } - quotaList = append(quotaList, quota) + quotaList = append(quotaList, quotas...) } } return spikeArrestList, quotaList, err @@ -811,7 +805,7 @@ func parseKeyValuePairs(match string) map[string]interface{} { match = strings.ReplaceAll(match, ")", "") keyValuePairs := make(map[string]interface{}) - keyValuePattern := `\b([A-Za-z0-9\-_]+)\s*:\s*([A-Za-z0-9\-_]+)\b` + keyValuePattern := `\b([A-Za-z0-9\-_]+)\s*:\s*([A-Za-z0-9\-_\.]+)\b` keyValueRe := regexp.MustCompile(keyValuePattern) kvMatches := keyValueRe.FindAllStringSubmatch(match, -1) for _, kvMatch := range kvMatches { diff --git a/internal/bundlegen/generateswag.go b/internal/bundlegen/generateswag.go index 4e2c532d3..5912561af 100644 --- a/internal/bundlegen/generateswag.go +++ b/internal/bundlegen/generateswag.go @@ -590,8 +590,9 @@ func generateSwaggerFlows(paths map[string]*openapi2.PathItem) (err error) { return err } } - if pathDetail.Quota.QuotaEnabled { - if err = proxies.AddStepToFlowRequest("Quota-"+pathDetail.Quota.QuotaName, pathDetail.OperationID); err != nil { + //TODO: assumes only 1 quota policy + if pathDetail.Quota[0].QuotaEnabled { + if err = proxies.AddStepToFlowRequest("Quota-"+pathDetail.Quota[0].QuotaName, pathDetail.OperationID); err != nil { return err } } @@ -779,7 +780,7 @@ func processPathSwaggerExtensions(extensions map[string]interface{}, pathDetail if err != nil { return pathDetail, err } - pathDetail.Quota = quota + pathDetail.Quota = append(pathDetail.Quota, quota) } } return pathDetail, err diff --git a/test/petstore-ext1.yaml b/test/petstore-ext1.yaml index 6c55a6287..af592eb6e 100644 --- a/test/petstore-ext1.yaml +++ b/test/petstore-ext1.yaml @@ -61,10 +61,16 @@ paths: '405': description: Invalid input x-google-quota: - - name: post-pet + - name: post-pet1 interval-literal: 1 timeunit-literal: minute allow-literal: 1 + identifier-ref: request.header.url + - name: post-pet2 + interval-literal: 1 + timeunit-literal: minute + allow-literal: 1 + identifier-ref: request.header.url #interval-ref: propertyset.quota.interval #timeunit-ref: propertyset.quota.timeunit #allow-ref: propertyset.quota.allow From d0390dca6c17e110e0d713f8507ef1f258953942 Mon Sep 17 00:00:00 2001 From: srinandan <13950006+srinandan@users.noreply.github.com> Date: Wed, 2 Aug 2023 09:47:34 -0700 Subject: [PATCH 5/6] chore: lint files #246 --- internal/bundlegen/generateapi.go | 2 +- internal/bundlegen/generateswag.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/bundlegen/generateapi.go b/internal/bundlegen/generateapi.go index e4606e44b..c2e75620b 100644 --- a/internal/bundlegen/generateapi.go +++ b/internal/bundlegen/generateapi.go @@ -800,7 +800,7 @@ func parseExtension(extension string) []map[string]interface{} { } func parseKeyValuePairs(match string) map[string]interface{} { - //HACK: numbers in yaml are represented as %!s(float64=xx) + // HACK: numbers in yaml are represented as %!s(float64=xx) match = strings.ReplaceAll(match, "%!s(float64=", "") match = strings.ReplaceAll(match, ")", "") diff --git a/internal/bundlegen/generateswag.go b/internal/bundlegen/generateswag.go index 5912561af..3f474b6b2 100644 --- a/internal/bundlegen/generateswag.go +++ b/internal/bundlegen/generateswag.go @@ -590,7 +590,7 @@ func generateSwaggerFlows(paths map[string]*openapi2.PathItem) (err error) { return err } } - //TODO: assumes only 1 quota policy + // TODO: assumes only 1 quota policy if pathDetail.Quota[0].QuotaEnabled { if err = proxies.AddStepToFlowRequest("Quota-"+pathDetail.Quota[0].QuotaName, pathDetail.OperationID); err != nil { return err From 853b560e29211b5e1a0bef3498667560dc913f3d Mon Sep 17 00:00:00 2001 From: srinandan <13950006+srinandan@users.noreply.github.com> Date: Wed, 2 Aug 2023 10:40:48 -0700 Subject: [PATCH 6/6] bug: quota identifier is optional #246 --- internal/bundlegen/generateapi.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/internal/bundlegen/generateapi.go b/internal/bundlegen/generateapi.go index c2e75620b..b51c3a1e8 100644 --- a/internal/bundlegen/generateapi.go +++ b/internal/bundlegen/generateapi.go @@ -665,9 +665,6 @@ func getQuotaDefinition(i interface{}) ([]quotaDef, error) { if q.QuotaTimeUnitLiteral == "" && q.QuotaTimeUnitRef == "" { return nil, fmt.Errorf("x-google-quota extension must have either timeunit-ref or timeunit-literal") } - if q.QuotaIdentiferLiteral == "" && q.QuotaIdentifierRef == "" { - return nil, fmt.Errorf("x-google-quota extension must have either identifier-ref or identifier-literal") - } } // store policy XML contents quotaPolicyContent[q.QuotaName] = policies.AddQuotaPolicy(