Repository: hashicorp/vault (Go)

Issue:
openapi definition for postAuthAlicloudLogin does not match api
the openapi definition for postAuthAlicloudLogin does not match the api definition (https://www.vaultproject.io/api/auth/alicloud/index.html) 

Specifically the openapi defines a header parameter for `identity_request_headers` and the api defines it as a body parameter

```
 "/auth/alicloud/login": {
            "description": "Authenticates an RAM entity with Vault.",
            "parameters": [
                {
                    "name": "identity_request_headers",
                    "description": "The request headers. This must include the headers over which AliCloud has included a signature.",
                    "in": "header",
                    "schema": { "type": "string" }
                }
            ],
            "x-vault-unauthenticated": true,
            "post": {
                "summary": "Authenticates an RAM entity with Vault.",
                "operationId": "postAuthAlicloudLogin",
                "tags": ["auth"],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "identity_request_url": {
                                        "type": "string",
                                        "description": "Base64-encoded full URL against which to make the AliCloud request."
                                    },
                                    "role": {
                                        "type": "string",
                                        "description": "Name of the role against which the login is being attempted. If 'role' is not specified, then the login endpoint looks for a role name in the ARN returned by the GetCallerIdentity request. If a matching role is not found, login fails."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": { "200": { "description": "OK" } }
            }
        },
```

![image](https://user-images.githubusercontent.com/929523/57065039-11d1e600-6cc0-11e9-8b31-1f3bdf2553e6.png)

**Expected behavior**
the openapi and api definitions should match

**Environment:**
* Vault Server Version 1.1.1
* Vault CLI Version Vault v1.1.1 ('a3dcd63451cf6da1d04928b601bbe9748d53842e')
* Server Operating System/Architecture: Ubunti 64 bit

Vault server configuration file(s):



Discussion:
Thanks for the report (and the in-depth checks of OpenAPI in general).



Patch:
diff --git a/scripts/gen_openapi.sh b/scripts/gen_openapi.sh
index de956e21bb2..0472b6df6b9 100755
--- a/scripts/gen_openapi.sh
+++ b/scripts/gen_openapi.sh
@@ -61,7 +61,11 @@ vault secrets enable ssh
 vault secrets enable totp
 vault secrets enable transit
 
-curl -H "X-Vault-Token: root" "http://127.0.0.1:8200/v1/sys/internal/specs/openapi" > openapi.json
+if [ "$1" == "-p" ]; then
+  curl -H "X-Vault-Token: root" "http://127.0.0.1:8200/v1/sys/internal/specs/openapi" | jq > openapi.json
+else
+  curl -H "X-Vault-Token: root" "http://127.0.0.1:8200/v1/sys/internal/specs/openapi" > openapi.json
+fi
 
 kill $VAULT_PID
 sleep 1
diff --git a/sdk/framework/openapi.go b/sdk/framework/openapi.go
index 9d97337f13f..37de53fdbeb 100644
--- a/sdk/framework/openapi.go
+++ b/sdk/framework/openapi.go
@@ -257,13 +257,6 @@ func documentPath(p *Path, specialPaths *logical.Paths, backendType logical.Back
 				required = false
 			}
 
-			// Header parameters are part of the Parameters group but with
-			// a dedicated "header" location, a header parameter is not required.
-			if field.Type == TypeHeader {
-				location = "header"
-				required = false
-			}
-
 			t := convertType(field.Type)
 			p := OASParameter{
 				Name:        name,
@@ -608,8 +601,7 @@ func splitFields(allFields map[string]*FieldSchema, pattern string) (pathFields,
 
 	for name, field := range allFields {
 		if _, ok := pathFields[name]; !ok {
-			// Header fields are in "parameters" with other path fields
-			if field.Type == TypeHeader || field.Query {
+			if field.Query {
 				pathFields[name] = field
 			} else {
 				bodyFields[name] = field


Test patch:
diff --git a/sdk/framework/openapi_test.go b/sdk/framework/openapi_test.go
index a9966ca312f..b9990902f6d 100644
--- a/sdk/framework/openapi_test.go
+++ b/sdk/framework/openapi_test.go
@@ -151,8 +151,8 @@ func TestOpenAPI_Regex(t *testing.T) {
 
 func TestOpenAPI_ExpandPattern(t *testing.T) {
 	tests := []struct {
-		in_pattern   string
-		out_pathlets []string
+		inPattern   string
+		outPathlets []string
 	}{
 		{"rekey/backup", []string{"rekey/backup"}},
 		{"rekey/backup$", []string{"rekey/backup"}},
@@ -203,10 +203,10 @@ func TestOpenAPI_ExpandPattern(t *testing.T) {
 	}
 
 	for i, test := range tests {
-		out := expandPattern(test.in_pattern)
+		out := expandPattern(test.inPattern)
 		sort.Strings(out)
-		if !reflect.DeepEqual(out, test.out_pathlets) {
-			t.Fatalf("Test %d: Expected %v got %v", i, test.out_pathlets, out)
+		if !reflect.DeepEqual(out, test.outPathlets) {
+			t.Fatalf("Test %d: Expected %v got %v", i, test.outPathlets, out)
 		}
 	}
 }
@@ -266,7 +266,10 @@ func TestOpenAPI_SpecialPaths(t *testing.T) {
 			Root:            test.rootPaths,
 			Unauthenticated: test.unauthPaths,
 		}
-		documentPath(&path, sp, logical.TypeLogical, doc)
+		err := documentPath(&path, sp, logical.TypeLogical, doc)
+		if err != nil {
+			t.Fatal(err)
+		}
 		result := test.root
 		if doc.Paths["/"+test.pattern].Sudo != result {
 			t.Fatalf("Test (root) %d: Expected %v got %v", i, test.root, result)
@@ -288,11 +291,11 @@ func TestOpenAPI_Paths(t *testing.T) {
 			Pattern: "lookup/" + GenericNameRegex("id"),
 
 			Fields: map[string]*FieldSchema{
-				"id": &FieldSchema{
+				"id": {
 					Type:        TypeString,
 					Description: "My id parameter",
 				},
-				"token": &FieldSchema{
+				"token": {
 					Type:        TypeString,
 					Description: "My token",
 				},
@@ -442,8 +445,14 @@ func TestOpenAPI_OperationID(t *testing.T) {
 
 	for _, context := range []string{"", "bar"} {
 		doc := NewOASDocument()
-		documentPath(path1, nil, logical.TypeLogical, doc)
-		documentPath(path2, nil, logical.TypeLogical, doc)
+		err := documentPath(path1, nil, logical.TypeLogical, doc)
+		if err != nil {
+			t.Fatal(err)
+		}
+		err = documentPath(path2, nil, logical.TypeLogical, doc)
+		if err != nil {
+			t.Fatal(err)
+		}
 		doc.CreateOperationIDs(context)
 
 		tests := []struct {
@@ -500,7 +509,10 @@ func TestOpenAPI_CustomDecoder(t *testing.T) {
 	}
 
 	docOrig := NewOASDocument()
-	documentPath(p, nil, logical.TypeLogical, docOrig)
+	err := documentPath(p, nil, logical.TypeLogical, docOrig)
+	if err != nil {
+		t.Fatal(err)
+	}
 
 	docJSON := mustJSONMarshal(t, docOrig)
 
diff --git a/sdk/framework/testdata/operations.json b/sdk/framework/testdata/operations.json
index ad36dfaa5b2..f889f118237 100644
--- a/sdk/framework/testdata/operations.json
+++ b/sdk/framework/testdata/operations.json
@@ -31,15 +31,6 @@
             "type": "string"
           },
           "required": true
-        },
-        {
-          "name": "x-abc-token",
-          "description": "a header value",
-          "in": "header",
-          "schema": {
-            "type": "string",
-            "enum": ["a", "b", "c"]
-          }
         }
       ],
       "get": {
@@ -95,6 +86,11 @@
                     "description": "the name",
                     "default": "Larry",
                     "pattern": "\\w([\\w-.]*\\w)?"
+                  },
+                  "x-abc-token": {
+                    "type": "string",
+                    "description": "a header value",
+                    "enum": ["a", "b", "c"]
                   }
                 }
               }