Skip to content

Commit

Permalink
Add QueryParametersInCollectionGet linter rule
Browse files Browse the repository at this point in the history
  • Loading branch information
akhilailla committed Sep 12, 2024
1 parent a19b89c commit 87c755c
Show file tree
Hide file tree
Showing 6 changed files with 585 additions and 0 deletions.
78 changes: 78 additions & 0 deletions docs/query-parameters-in-collection-get.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# QueryParametersInCollectionGet

## Category

ARM Error

## Applies to

ARM OpenAPI(swagger) specs

## Related ARM Guideline Code

- RPC-Get-V1-15

## Description

Collection Get's/List operations MUST not have query parameters other than api-version & OData filter.

## How to fix the violation

Ensure that collection GET/List operations do not include any query parameters other than api-version and the OData $filter.

## Good Examples

```json
"Microsoft.Music/Songs": {
get: {
operationId: "Foo_Update",
description: "Test Description",
parameters: [
{
name: "api-version",
in: "query"
},
],
},
},
```

```json
"Microsoft.Music/Songs": {
get: {
operationId: "Foo_Update",
description: "Test Description",
parameters: [
{
name: "api-version",
in: "query"
},
{
name: "$filter",
in: "query",
required: false,
type: "string",
},
],
},
},
```

## Bad Examples

```json
"Microsoft.Music/Songs": {
get: {
operationId: "Foo_Update",
description: "Test Description",
parameters: [
{
name: "name",
in: "query",
required: false,
type: "string",
},
],
},
},
```
6 changes: 6 additions & 0 deletions docs/rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -1040,6 +1040,12 @@ Synchronous and long-running PUT operations must have responses with 200, 201 an

Please refer to [put-response-codes.md](./put-response-codes.md) for details.

### QueryParametersInCollectionGet

Collection Get's/List operations MUST not have query parameters other than api-version & OData filter.

Please refer to [query-parameters-in-collection-get.md](./query-parameters-in-collection-get.md) for details.

### RepeatedPathInfo

Information in the URI must not be repeated in the request body (i.e. subscription ID, resource group name, resource name).
Expand Down
42 changes: 42 additions & 0 deletions packages/rulesets/generated/spectral/az-arm.js
Original file line number Diff line number Diff line change
Expand Up @@ -2539,6 +2539,36 @@ const PutResponseCodes = (putOp, _opts, ctx) => {
return errors;
};

const queryParametersInCollectionGet = (pathItem, _opts, ctx) => {
if (pathItem === null || typeof pathItem !== "object") {
return [];
}
const path = ctx.path || [];
const uris = Object.keys(pathItem);
if (uris.length < 1) {
return [];
}
const GET = "get";
const errors = [];
for (const uri of uris) {
if (!pathItem[uri][GET]) {
continue;
}
const hierarchy = getResourcesPathHierarchyBasedOnResourceType(uri);
if (hierarchy.length == 0 && pathItem[uri][GET]) {
const params = pathItem[uri][GET]["parameters"];
const queryParams = params === null || params === void 0 ? void 0 : params.filter((param) => param.in === "query" && param.name !== "api-version" && param.name !== "$filter");
queryParams === null || queryParams === void 0 ? void 0 : queryParams.forEach((param) => {
errors.push({
message: `Query parameter ${param.name} should be removed. Collection Get's/List operation MUST not have query parameters other than api version & OData filter.`,
path: [path, uri, GET, "parameters"],
});
});
}
}
return errors;
};

const requestBodyMustExistForPutPatch = (putPatchOperationParameters, _opts, ctx) => {
const errors = [];
const path = ctx.path;
Expand Down Expand Up @@ -3459,6 +3489,18 @@ const ruleset = {
function: falsy,
},
},
QueryParametersInCollectionGet: {
rpcGuidelineCode: "RPC-Get-V1-15",
description: "Collection Get's/List operations MUST not have query parameters other than api-version & OData filter.",
severity: "error",
message: "{{error}}",
resolved: true,
formats: [oas2],
given: "$[paths,'x-ms-paths']",
then: {
function: queryParametersInCollectionGet,
},
},
PatchPropertiesCorrespondToPutProperties: {
rpcGuidelineCode: "RPC-Patch-V1-01",
description: "PATCH request body must only contain properties present in the corresponding PUT request body, and must contain at least one property.",
Expand Down
15 changes: 15 additions & 0 deletions packages/rulesets/src/spectral/az-arm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import { provisioningStateMustBeReadOnly } from "./functions/provisioning-state-
import putGetPatchSchema from "./functions/put-get-patch-schema"
import { putRequestResponseScheme } from "./functions/put-request-response-scheme"
import { PutResponseCodes } from "./functions/put-response-codes"
import { queryParametersInCollectionGet } from "./functions/query-parameters-in-collection-get"
import { requestBodyMustExistForPutPatch } from "./functions/request-body-must-exist-for-put-patch"
import { reservedResourceNamesModelAsEnum } from "./functions/reserved-resource-names-model-as-enum"
import resourceNameRestriction from "./functions/resource-name-restriction"
Expand Down Expand Up @@ -449,6 +450,20 @@ const ruleset: any = {
},
},

// RPC Code: RPC-Get-V1-15
QueryParametersInCollectionGet: {
rpcGuidelineCode: "RPC-Get-V1-15",
description: "Collection Get's/List operations MUST not have query parameters other than api-version & OData filter.",
severity: "error",
message: "{{error}}",
resolved: true,
formats: [oas2],
given: "$[paths,'x-ms-paths']",
then: {
function: queryParametersInCollectionGet,
},
},

///
/// ARM RPC rules for Patch patterns
///
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { getResourcesPathHierarchyBasedOnResourceType } from "./utils"

export const queryParametersInCollectionGet = (pathItem: any, _opts: any, ctx: any) => {
if (pathItem === null || typeof pathItem !== "object") {
return []
}

const path = ctx.path || []
const uris = Object.keys(pathItem)
if (uris.length < 1) {
return []
}
const GET = "get"
const errors: any[] = []

for (const uri of uris) {
// skip, if GET op isn't defined
if (!pathItem[uri][GET]) {
continue
}
// check if the GET op is a collection get/list call
const hierarchy = getResourcesPathHierarchyBasedOnResourceType(uri)
if (hierarchy.length == 0 && pathItem[uri][GET]) {
const params = pathItem[uri][GET]["parameters"]
const queryParams = params?.filter(
(param: { in: string; name: string }) => param.in === "query" && param.name !== "api-version" && param.name !== "$filter",
)
queryParams?.forEach((param: { name: any }) => {
errors.push({
message: `Query parameter ${param.name} should be removed. Collection Get's/List operation MUST not have query parameters other than api version & OData filter.`,
path: [path, uri, GET, "parameters"],
})
})
}
}

return errors
}
Loading

0 comments on commit 87c755c

Please sign in to comment.