From e16348eda49bb83794cefec66bfeaedf8f72e342 Mon Sep 17 00:00:00 2001 From: Sanne Raymaekers Date: Mon, 9 Sep 2024 12:31:09 +0200 Subject: [PATCH] api/compliance: add endpoints Policies to query the list of policies, and policy to get the details of a single policy. --- api/config/compliance.ts | 2 +- src/constants.ts | 1 + src/store/complianceApi.ts | 148 +++++++++++++++++++++++++++++++- src/store/emptyComplianceApi.ts | 12 +++ 4 files changed, 159 insertions(+), 4 deletions(-) create mode 100644 src/store/emptyComplianceApi.ts diff --git a/api/config/compliance.ts b/api/config/compliance.ts index a4457b2e..54c0f9df 100644 --- a/api/config/compliance.ts +++ b/api/config/compliance.ts @@ -7,7 +7,7 @@ const config: ConfigFile = { outputFile: '../../src/store/complianceApi.ts', exportName: 'complianceApi', hooks: true, - filterEndpoints: [], + filterEndpoints: ['policies', 'policy'], }; export default config; diff --git a/src/constants.ts b/src/constants.ts index 4e55684c..910c15b1 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -5,6 +5,7 @@ export const RHSM_API = '/api/rhsm/v2'; export const EDGE_API = '/api/edge/v1'; export const CONTENT_SOURCES_API = '/api/content-sources/v1'; export const PROVISIONING_API = '/api/provisioning/v1'; +export const COMPLIANCE_API = '/api/compliance/v2'; export const CREATE_BLUEPRINT = `${IMAGE_BUILDER_API}/blueprints`; export const EDIT_BLUEPRINT = `${IMAGE_BUILDER_API}/blueprints`; diff --git a/src/store/complianceApi.ts b/src/store/complianceApi.ts index 5dba7b21..f58a8e95 100644 --- a/src/store/complianceApi.ts +++ b/src/store/complianceApi.ts @@ -1,7 +1,149 @@ -import { emptyComplianceApi as api } from './emptyComplianceApi'; +import { emptyComplianceApi as api } from "./emptyComplianceApi"; const injectedRtkApi = api.injectEndpoints({ - endpoints: (build) => ({}), + endpoints: (build) => ({ + policies: build.query({ + query: (queryArg) => ({ + url: `/policies`, + headers: { "X-RH-IDENTITY": queryArg["X-RH-IDENTITY"] }, + params: { + limit: queryArg.limit, + offset: queryArg.offset, + sort_by: queryArg.sortBy, + filter: queryArg.filter, + }, + }), + }), + policy: build.query({ + query: (queryArg) => ({ + url: `/policies/${queryArg.policyId}`, + headers: { "X-RH-IDENTITY": queryArg["X-RH-IDENTITY"] }, + }), + }), + }), overrideExisting: false, }); export { injectedRtkApi as complianceApi }; -export const {} = injectedRtkApi; +export type PoliciesApiResponse = /** status 200 Lists Policies */ { + meta?: MetadataRead; + links?: LinksRead; + data?: { + schema?: PolicyRead; + }[]; +}; +export type PoliciesApiArg = { + /** For internal use only */ + "X-RH-IDENTITY"?: string; + /** Number of items to return per page */ + limit?: number; + /** Offset of first item of paginated response */ + offset?: number; + /** Attribute and direction to sort the items by. Represented by an array of fields with an optional direction (`:asc` or `:desc`).

If no direction is selected, `:asc` is used by default. */ + sortBy?: ( + | "title" + | "os_major_version" + | "total_system_count" + | "business_objective" + | "compliance_threshold" + | "title:asc" + | "title:desc" + | "os_major_version:asc" + | "os_major_version:desc" + | "total_system_count:asc" + | "total_system_count:desc" + | "business_objective:asc" + | "business_objective:desc" + | "compliance_threshold:asc" + | "compliance_threshold:desc" + )[]; + /** Query string to filter items by their attributes. Compliant with scoped_search query language. However, only `=` or `!=` (resp. `<>`) operators are supported.

Policies are searchable using attributes `title`, `os_major_version`, and `os_minor_version`

(e.g.: `(field_1=something AND field_2!="something else") OR field_3>40`) */ + filter?: string; +}; +export type PolicyApiResponse = /** status 200 Returns a Policy */ { + data?: { + schema?: PolicyRead; + }; +}; +export type PolicyApiArg = { + /** For internal use only */ + "X-RH-IDENTITY"?: string; + policyId: string; +}; +export type Metadata = { + /** Attribute and direction the items are sorted by */ + sort_by?: string; + /** Query string used to filter items by their attributes */ + filter?: string; +}; +export type MetadataRead = { + /** Total number of items */ + total?: number; + /** Number of items returned per page */ + limit?: number; + /** Offset of the first item of paginated response */ + offset?: number; + /** Attribute and direction the items are sorted by */ + sort_by?: string; + /** Query string used to filter items by their attributes */ + filter?: string; +}; +export type Links = {}; +export type LinksRead = { + /** Link to first page */ + first?: string; + /** Link to last page */ + last?: string; + /** Link to previous page */ + previous?: string; + /** Link to next page */ + next?: string; +}; +export type Id = string; +export type IdRead = string; +export type Policy = { + id?: Id; + /** Short title of the Policy */ + title?: string; + /** Longer description of the Policy */ + description?: string; + /** The Business Objective associated to the Policy */ + business_objective?: string; + /** The percentage above which the Policy meets compliance requirements */ + compliance_threshold: number; +}; +export type PolicyRead = { + id?: IdRead; + type?: "policy"; + /** Short title of the Policy */ + title?: string; + /** Longer description of the Policy */ + description?: string; + /** The Business Objective associated to the Policy */ + business_objective?: string; + /** The percentage above which the Policy meets compliance requirements */ + compliance_threshold: number; + /** Major version of the Operating System that the Policy covers */ + os_major_version?: number; + /** Identificator of the Profile */ + ref_id?: string; + /** Title of the associated Policy */ + profile_title?: string; + /** The number of Systems assigned to this Policy */ + total_system_count?: number; +}; +export type PolicyWrite = { + id?: Id; + /** Short title of the Policy */ + title?: string; + /** Longer description of the Policy */ + description?: string; + /** The Business Objective associated to the Policy */ + business_objective?: string; + /** The percentage above which the Policy meets compliance requirements */ + compliance_threshold: number; + /** Identifier of the underlying Profile */ + profile_id: string; +}; +export type Errors = { + errors: string[]; +}; +export const { usePoliciesQuery, usePolicyQuery } = injectedRtkApi; diff --git a/src/store/emptyComplianceApi.ts b/src/store/emptyComplianceApi.ts new file mode 100644 index 00000000..1fb49d99 --- /dev/null +++ b/src/store/emptyComplianceApi.ts @@ -0,0 +1,12 @@ +import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; + +import { COMPLIANCE_API } from '../constants'; + +// initialize an empty api service that we'll inject endpoints into later as needed +export const emptyComplianceApi = createApi({ + reducerPath: 'complianceApi', + baseQuery: fetchBaseQuery({ + baseUrl: window.location.origin + COMPLIANCE_API, + }), + endpoints: () => ({}), +});