From 98c7be88edb8c7b7539647c2a0d3782aa382985c Mon Sep 17 00:00:00 2001 From: sangkenlee Date: Sun, 10 Mar 2024 23:26:48 +0900 Subject: [PATCH 1/4] policy template admin api initial version --- api/swagger/docs.go | 1030 ++++++++++++++++- api/swagger/swagger.json | 1030 ++++++++++++++++- api/swagger/swagger.yaml | 635 ++++++++++ go.mod | 37 +- go.sum | 413 +------ internal/database/database.go | 9 + internal/delivery/api/endpoint.go | 54 + .../delivery/api/generated_endpoints.go.go | 344 ++++++ internal/delivery/http/policy-template.go | 647 +++++++++++ internal/delivery/http/utility.go | 73 ++ internal/repository/policy-template.go | 553 +++++++++ internal/repository/repository.go | 29 +- internal/route/route.go | 80 +- internal/usecase/policy-template.go | 228 ++++ internal/usecase/usecase.go | 32 +- internal/usecase/utility.go | 161 +++ pkg/domain/policy-template.go | 278 +++++ pkg/domain/rego.go | 25 + 18 files changed, 5156 insertions(+), 502 deletions(-) create mode 100644 internal/delivery/http/policy-template.go create mode 100644 internal/delivery/http/utility.go create mode 100644 internal/repository/policy-template.go create mode 100644 internal/usecase/policy-template.go create mode 100644 internal/usecase/utility.go create mode 100644 pkg/domain/policy-template.go create mode 100644 pkg/domain/rego.go diff --git a/api/swagger/docs.go b/api/swagger/docs.go index 4d0948f0..47e43b6b 100644 --- a/api/swagger/docs.go +++ b/api/swagger/docs.go @@ -482,6 +482,529 @@ const docTemplate = `{ } } }, + "/api/1.0/admin/policytemplates": { + "get": { + "security": [ + { + "JWT": [] + } + ], + "description": "정책 템플릿 목록을 조회한다. 정책 템플릿 목록 조회 결과는 최신 템플릿 버전 목록만 조회된다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[ListPolicyTemplate] 정책 템플릿 목록 조회", + "parameters": [ + { + "type": "string", + "description": "pageSize", + "name": "limit", + "in": "query" + }, + { + "type": "string", + "description": "pageNumber", + "name": "page", + "in": "query" + }, + { + "type": "string", + "description": "sortColumn", + "name": "soertColumn", + "in": "query" + }, + { + "type": "string", + "description": "sortOrder", + "name": "sortOrder", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "filters", + "name": "filters", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateResponse" + } + } + } + }, + "post": { + "security": [ + { + "JWT": [] + } + ], + "description": "정책 템플릿을 신규 생성(v1.0.0을 생성)한다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[CreatePolicyTemplate] 정책 템플릿 신규 생성", + "parameters": [ + { + "description": "create policy template request", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateReponse" + } + } + } + } + }, + "/api/1.0/admin/policytemplates/kind/{policyTemplateKind}/existence": { + "get": { + "security": [ + { + "JWT": [] + } + ], + "description": "해당 유형을 가진 정책 템플릿이 이미 존재하는지 확인한다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[ExistsPolicyTemplateKind] 정책 템플릿 유형 존재 여부 확인", + "parameters": [ + { + "type": "string", + "description": "정책 템플릿 이름", + "name": "policyTemplateKind", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ExistsPolicyTemplateKindResponse" + } + } + } + } + }, + "/api/1.0/admin/policytemplates/name/{policyTemplateName}/existence": { + "get": { + "security": [ + { + "JWT": [] + } + ], + "description": "해당 이름을 가진 정책 템플릿이 이미 존재하는지 확인한다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[ExistsPolicyTemplateName] 정책 템플릿 아름 존재 여부 확인", + "parameters": [ + { + "type": "string", + "description": "정책 템플릿 이름", + "name": "policyTemplateName", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CheckExistedResponse" + } + } + } + } + }, + "/api/1.0/admin/policytemplates/{policyTemplateId}": { + "get": { + "security": [ + { + "JWT": [] + } + ], + "description": "해당 식별자를 가진 정책 템플릿의 최신 버전을 조회한다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[GetPolicyTemplate] 정책 템플릿 조회(최신 버전)", + "parameters": [ + { + "type": "string", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateResponse" + } + } + } + }, + "delete": { + "security": [ + { + "JWT": [] + } + ], + "description": "정책 템플릿을 삭제한다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[DeletePolicyTemplate] 정책 템플릿 삭제", + "parameters": [ + { + "type": "string", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "patch": { + "security": [ + { + "JWT": [] + } + ], + "description": "정책 템플릿의 업데이트 가능한 필드들을 업데이트한다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[UpdatePolicyTemplate] 정책 템플릿 업데이트", + "parameters": [ + { + "type": "string", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true + }, + { + "description": "update policy template request", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.UpdatePolicyTemplateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/api/1.0/admin/policytemplates/{policyTemplateId}/deploy": { + "get": { + "security": [ + { + "JWT": [] + } + ], + "description": "해당 식별자를 가진 정책 템플릿의 정책 템플릿 클러스터 별 설치 버전을 조회한다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[GetPolicyTemplateDeploy] 정책 템플릿 클러스터 별 설치 버전 조회", + "parameters": [ + { + "type": "string", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateDeployResponse" + } + } + } + } + }, + "/api/1.0/admin/policytemplates/{policyTemplateId}/statistics": { + "get": { + "security": [ + { + "JWT": [] + } + ], + "description": "해당 식별자를 가진 정책 템플릿의 최신 버전을 조회한다. 전체 조직의 통계를 조회하려면 organizationId를 tks로 설정한다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[ListPolicyTemplateStatistics] 정책 템플릿 사용 카운트 조회", + "parameters": [ + { + "type": "string", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateStatisticsResponse" + } + } + } + } + }, + "/api/1.0/admin/policytemplates/{policyTemplateId}/versions": { + "get": { + "security": [ + { + "JWT": [] + } + ], + "description": "해당 식별자를 가진 정책 템플릿의 최신 버전을 조회한다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[ListPolicyTemplateVersions] 정책 템플릿 버전목록 조회", + "parameters": [ + { + "type": "string", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateVersionsResponse" + } + } + } + }, + "post": { + "security": [ + { + "JWT": [] + } + ], + "description": "해당 식별자를 가진 정책 템플릿의 특정 버전을 저장한다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[CreatePolicyTemplateVersion] 정책 템플릿 특정 버전 저장", + "parameters": [ + { + "type": "string", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true + }, + { + "description": "create policy template version request", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateVersionRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateVersionResponse" + } + } + } + } + }, + "/api/1.0/admin/policytemplates/{policyTemplateId}/versions/{version}": { + "get": { + "security": [ + { + "JWT": [] + } + ], + "description": "해당 식별자를 가진 정책 템플릿의 특정 버전을 조회한다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[GetPolicyTemplateVersion] 정책 템플릿 특정 버전 조회", + "parameters": [ + { + "type": "string", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "조회할 버전(v0.0.0 형식)", + "name": "version", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateVersionResponse" + } + } + } + }, + "delete": { + "security": [ + { + "JWT": [] + } + ], + "description": "해당 식별자를 가진 정책 템플릿의 특정 버전을 삭제한다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[DeletePolicyTemplateVersion] 정책 템플릿 특정 버전 삭제", + "parameters": [ + { + "type": "string", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "삭제할 버전(v0.0.0 형식)", + "name": "version", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/app-groups": { "get": { "security": [ @@ -6048,6 +6571,52 @@ const docTemplate = `{ } } } + }, + "/utility/rego-compile": { + "post": { + "security": [ + { + "JWT": [] + } + ], + "description": "Rego 코드 컴파일 및 파라미터 파싱을 수행한다. 파라미터 파싱을 위해서는 먼저 컴파일이 성공해야 하며, parseParameter를 false로 하면 컴파일만 수행할 수 있다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Rego" + ], + "summary": "[CompileRego] Rego 코드 컴파일 및 파라미터 파싱", + "parameters": [ + { + "type": "boolean", + "description": "파라미터 파싱 여부", + "name": "parseParameter", + "in": "query", + "required": true + }, + { + "description": "Rego 코드", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.RegoCompileRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.RegoCompileResponse" + } + } + } + } } }, "definitions": { @@ -7296,51 +7865,169 @@ const docTemplate = `{ "tksInfraNode": { "type": "integer" }, - "tksInfraNodeMax": { - "type": "integer" + "tksInfraNodeMax": { + "type": "integer" + }, + "tksInfraNodeType": { + "type": "string" + }, + "tksUserNode": { + "type": "integer" + }, + "tksUserNodeMax": { + "type": "integer" + }, + "tksUserNodeType": { + "type": "string" + } + } + }, + "github_com_openinfradev_tks-api_pkg_domain.CreateClusterResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + } + }, + "github_com_openinfradev_tks-api_pkg_domain.CreateOrganizationRequest": { + "type": "object", + "required": [ + "Email", + "name" + ], + "properties": { + "Email": { + "type": "string" + }, + "description": { + "type": "string", + "maxLength": 100, + "minLength": 0 + }, + "name": { + "type": "string" + }, + "phone": { + "type": "string" + } + } + }, + "github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateReponse": { + "type": "object", + "properties": { + "id": { + "type": "string", + "example": "d98ef5f1-4a68-4047-a446-2207787ce3ff" + } + } + }, + "github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateRequest": { + "type": "object", + "properties": { + "deprecated": { + "type": "boolean", + "example": false + }, + "description": { + "type": "string", + "example": "이 정책은 ..." + }, + "kind": { + "type": "string", + "example": "K8sRequiredLabels" + }, + "libs": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "rego 코드" + ] + }, + "parametersSchema": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ParameterDef" + } + }, + "permittedOrganizationIds": { + "type": "array", + "items": { + "type": "string" + } }, - "tksInfraNodeType": { - "type": "string" + "rego": { + "type": "string", + "example": "rego 코드" }, - "tksUserNode": { - "type": "integer" + "severity": { + "type": "string", + "enum": [ + "low", + "medium", + "high" + ], + "example": "medium" }, - "tksUserNodeMax": { - "type": "integer" + "target": { + "type": "string", + "example": "admission.k8s.gatekeeper.sh" }, - "tksUserNodeType": { - "type": "string" + "templateName": { + "type": "string", + "example": "필수 Label 검사" } } }, - "github_com_openinfradev_tks-api_pkg_domain.CreateClusterResponse": { + "github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateVersionRequest": { "type": "object", "properties": { - "id": { - "type": "string" + "currentVersion": { + "type": "string", + "example": "v1.0.0" + }, + "expectedVersion": { + "type": "string", + "example": "v1.1.0" + }, + "libs": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "rego 코드" + ] + }, + "parametersSchema": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ParameterDef" + } + }, + "rego": { + "type": "string", + "example": "rego 코드" + }, + "versionUpType": { + "type": "string", + "enum": [ + "major", + "minor", + "patch" + ], + "example": "minor" } } }, - "github_com_openinfradev_tks-api_pkg_domain.CreateOrganizationRequest": { + "github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateVersionResponse": { "type": "object", - "required": [ - "Email", - "name" - ], "properties": { - "Email": { - "type": "string" - }, - "description": { + "version": { "type": "string", - "maxLength": 100, - "minLength": 0 - }, - "name": { - "type": "string" - }, - "phone": { - "type": "string" + "example": "v1.1.1" } } }, @@ -7746,6 +8433,9 @@ const docTemplate = `{ } } }, + "github_com_openinfradev_tks-api_pkg_domain.ExistsPolicyTemplateKindResponse": { + "type": "object" + }, "github_com_openinfradev_tks-api_pkg_domain.FilterResponse": { "type": "object", "properties": { @@ -8107,6 +8797,33 @@ const docTemplate = `{ } } }, + "github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateDeployResponse": { + "type": "object", + "properties": { + "deployVersion": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateResponse": { + "type": "object", + "properties": { + "policyTemplate": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.PolicyTemplateResponse" + } + } + }, + "github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateVersionResponse": { + "type": "object", + "properties": { + "policyTemplate": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.PolicyTemplateResponse" + } + } + }, "github_com_openinfradev_tks-api_pkg_domain.GetProjectKubeconfigResponse": { "type": "object", "properties": { @@ -8447,6 +9164,47 @@ const docTemplate = `{ } } }, + "github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateResponse": { + "type": "object", + "properties": { + "pagination": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.PaginationResponse" + }, + "policyTemplates": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.PolicyTemplateResponse" + } + } + } + }, + "github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateStatisticsResponse": { + "type": "object", + "properties": { + "policyTemplateStatistics": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.PolicyTemplateStatistics" + } + } + } + }, + "github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateVersionsResponse": { + "type": "object", + "properties": { + "versions": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "v1.1.0", + "v1.0.1", + "v1.0.0" + ] + } + } + }, "github_com_openinfradev_tks-api_pkg_domain.ListTksRoleResponse": { "type": "object", "properties": { @@ -8653,6 +9411,29 @@ const docTemplate = `{ } } }, + "github_com_openinfradev_tks-api_pkg_domain.ParameterDef": { + "type": "object", + "properties": { + "children": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ParameterDef" + } + }, + "defaultValue": { + "type": "string" + }, + "isArray": { + "type": "boolean" + }, + "key": { + "type": "string" + }, + "type": { + "type": "string" + } + } + }, "github_com_openinfradev_tks-api_pkg_domain.Permission": { "type": "object", "properties": { @@ -8726,6 +9507,20 @@ const docTemplate = `{ } } }, + "github_com_openinfradev_tks-api_pkg_domain.PermittedOrganization": { + "type": "object", + "properties": { + "organizationId": { + "type": "string" + }, + "organizationName": { + "type": "string" + }, + "permitted": { + "type": "boolean" + } + } + }, "github_com_openinfradev_tks-api_pkg_domain.PingTokenRequest": { "type": "object", "required": [ @@ -8752,6 +9547,103 @@ const docTemplate = `{ } } }, + "github_com_openinfradev_tks-api_pkg_domain.PolicyTemplateResponse": { + "type": "object", + "properties": { + "createdAt": { + "type": "string" + }, + "creator": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.SimpleUserResponse" + }, + "deprecated": { + "type": "boolean", + "example": false + }, + "description": { + "type": "string", + "example": "이 정책은 ..." + }, + "id": { + "type": "string", + "example": "d98ef5f1-4a68-4047-a446-2207787ce3ff" + }, + "kind": { + "type": "string", + "example": "K8sRequiredLabels" + }, + "libs": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "rego 코드" + ] + }, + "parametersSchema": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ParameterDef" + } + }, + "permittedOrganizations": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.PermittedOrganization" + } + }, + "rego": { + "type": "string", + "example": "rego 코드" + }, + "severity": { + "type": "string", + "enum": [ + "low", + "medium", + "high" + ], + "example": "medium" + }, + "templateName": { + "type": "string", + "example": "필수 Label 검사" + }, + "type": { + "type": "string", + "enum": [ + "tks", + "organization" + ], + "example": "tks" + }, + "updatedAt": { + "type": "string" + }, + "updator": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.SimpleUserResponse" + }, + "version": { + "type": "string", + "example": "v1.0.1" + } + } + }, + "github_com_openinfradev_tks-api_pkg_domain.PolicyTemplateStatistics": { + "type": "object", + "properties": { + "organizationId": { + "type": "string" + }, + "organizationName": { + "type": "string" + }, + "usageCount": { + "type": "integer" + } + } + }, "github_com_openinfradev_tks-api_pkg_domain.ProjectDetailResponse": { "type": "object", "properties": { @@ -8990,6 +9882,53 @@ const docTemplate = `{ } } }, + "github_com_openinfradev_tks-api_pkg_domain.RegoCompieError": { + "type": "object", + "properties": { + "code": { + "type": "string", + "example": "P_INVALID_REGO_SYNTAX" + }, + "message": { + "type": "string", + "example": "Invalid rego syntax" + }, + "status": { + "type": "integer", + "example": 400 + }, + "text": { + "type": "string", + "example": "Rego 문법 에러입니다. 라인:2 컬럼:1 에러메시지: var testnum is not safe" + } + } + }, + "github_com_openinfradev_tks-api_pkg_domain.RegoCompileRequest": { + "type": "object", + "properties": { + "rego": { + "type": "string", + "example": "Rego 코드" + } + } + }, + "github_com_openinfradev_tks-api_pkg_domain.RegoCompileResponse": { + "type": "object", + "properties": { + "errors": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.RegoCompieError" + } + }, + "parametersSchema": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ParameterDef" + } + } + } + }, "github_com_openinfradev_tks-api_pkg_domain.RemoveProjectMemberRequest": { "type": "object", "properties": { @@ -9734,6 +10673,37 @@ const docTemplate = `{ } } }, + "github_com_openinfradev_tks-api_pkg_domain.UpdatePolicyTemplateRequest": { + "type": "object", + "properties": { + "deprecated": { + "type": "boolean", + "example": false + }, + "description": { + "type": "string" + }, + "permittedOrganizationIds": { + "type": "array", + "items": { + "type": "string" + } + }, + "severity": { + "type": "string", + "enum": [ + "low", + "medium", + "high" + ], + "example": "medium" + }, + "templateName": { + "type": "string", + "example": "필수 Label 검사" + } + } + }, "github_com_openinfradev_tks-api_pkg_domain.UpdatePrimaryClusterRequest": { "type": "object", "properties": { diff --git a/api/swagger/swagger.json b/api/swagger/swagger.json index 855a8c0f..42ee1952 100644 --- a/api/swagger/swagger.json +++ b/api/swagger/swagger.json @@ -476,6 +476,529 @@ } } }, + "/api/1.0/admin/policytemplates": { + "get": { + "security": [ + { + "JWT": [] + } + ], + "description": "정책 템플릿 목록을 조회한다. 정책 템플릿 목록 조회 결과는 최신 템플릿 버전 목록만 조회된다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[ListPolicyTemplate] 정책 템플릿 목록 조회", + "parameters": [ + { + "type": "string", + "description": "pageSize", + "name": "limit", + "in": "query" + }, + { + "type": "string", + "description": "pageNumber", + "name": "page", + "in": "query" + }, + { + "type": "string", + "description": "sortColumn", + "name": "soertColumn", + "in": "query" + }, + { + "type": "string", + "description": "sortOrder", + "name": "sortOrder", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "filters", + "name": "filters", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateResponse" + } + } + } + }, + "post": { + "security": [ + { + "JWT": [] + } + ], + "description": "정책 템플릿을 신규 생성(v1.0.0을 생성)한다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[CreatePolicyTemplate] 정책 템플릿 신규 생성", + "parameters": [ + { + "description": "create policy template request", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateReponse" + } + } + } + } + }, + "/api/1.0/admin/policytemplates/kind/{policyTemplateKind}/existence": { + "get": { + "security": [ + { + "JWT": [] + } + ], + "description": "해당 유형을 가진 정책 템플릿이 이미 존재하는지 확인한다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[ExistsPolicyTemplateKind] 정책 템플릿 유형 존재 여부 확인", + "parameters": [ + { + "type": "string", + "description": "정책 템플릿 이름", + "name": "policyTemplateKind", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ExistsPolicyTemplateKindResponse" + } + } + } + } + }, + "/api/1.0/admin/policytemplates/name/{policyTemplateName}/existence": { + "get": { + "security": [ + { + "JWT": [] + } + ], + "description": "해당 이름을 가진 정책 템플릿이 이미 존재하는지 확인한다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[ExistsPolicyTemplateName] 정책 템플릿 아름 존재 여부 확인", + "parameters": [ + { + "type": "string", + "description": "정책 템플릿 이름", + "name": "policyTemplateName", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CheckExistedResponse" + } + } + } + } + }, + "/api/1.0/admin/policytemplates/{policyTemplateId}": { + "get": { + "security": [ + { + "JWT": [] + } + ], + "description": "해당 식별자를 가진 정책 템플릿의 최신 버전을 조회한다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[GetPolicyTemplate] 정책 템플릿 조회(최신 버전)", + "parameters": [ + { + "type": "string", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateResponse" + } + } + } + }, + "delete": { + "security": [ + { + "JWT": [] + } + ], + "description": "정책 템플릿을 삭제한다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[DeletePolicyTemplate] 정책 템플릿 삭제", + "parameters": [ + { + "type": "string", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "patch": { + "security": [ + { + "JWT": [] + } + ], + "description": "정책 템플릿의 업데이트 가능한 필드들을 업데이트한다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[UpdatePolicyTemplate] 정책 템플릿 업데이트", + "parameters": [ + { + "type": "string", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true + }, + { + "description": "update policy template request", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.UpdatePolicyTemplateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/api/1.0/admin/policytemplates/{policyTemplateId}/deploy": { + "get": { + "security": [ + { + "JWT": [] + } + ], + "description": "해당 식별자를 가진 정책 템플릿의 정책 템플릿 클러스터 별 설치 버전을 조회한다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[GetPolicyTemplateDeploy] 정책 템플릿 클러스터 별 설치 버전 조회", + "parameters": [ + { + "type": "string", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateDeployResponse" + } + } + } + } + }, + "/api/1.0/admin/policytemplates/{policyTemplateId}/statistics": { + "get": { + "security": [ + { + "JWT": [] + } + ], + "description": "해당 식별자를 가진 정책 템플릿의 최신 버전을 조회한다. 전체 조직의 통계를 조회하려면 organizationId를 tks로 설정한다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[ListPolicyTemplateStatistics] 정책 템플릿 사용 카운트 조회", + "parameters": [ + { + "type": "string", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateStatisticsResponse" + } + } + } + } + }, + "/api/1.0/admin/policytemplates/{policyTemplateId}/versions": { + "get": { + "security": [ + { + "JWT": [] + } + ], + "description": "해당 식별자를 가진 정책 템플릿의 최신 버전을 조회한다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[ListPolicyTemplateVersions] 정책 템플릿 버전목록 조회", + "parameters": [ + { + "type": "string", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateVersionsResponse" + } + } + } + }, + "post": { + "security": [ + { + "JWT": [] + } + ], + "description": "해당 식별자를 가진 정책 템플릿의 특정 버전을 저장한다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[CreatePolicyTemplateVersion] 정책 템플릿 특정 버전 저장", + "parameters": [ + { + "type": "string", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true + }, + { + "description": "create policy template version request", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateVersionRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateVersionResponse" + } + } + } + } + }, + "/api/1.0/admin/policytemplates/{policyTemplateId}/versions/{version}": { + "get": { + "security": [ + { + "JWT": [] + } + ], + "description": "해당 식별자를 가진 정책 템플릿의 특정 버전을 조회한다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[GetPolicyTemplateVersion] 정책 템플릿 특정 버전 조회", + "parameters": [ + { + "type": "string", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "조회할 버전(v0.0.0 형식)", + "name": "version", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateVersionResponse" + } + } + } + }, + "delete": { + "security": [ + { + "JWT": [] + } + ], + "description": "해당 식별자를 가진 정책 템플릿의 특정 버전을 삭제한다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "PolicyTemplate" + ], + "summary": "[DeletePolicyTemplateVersion] 정책 템플릿 특정 버전 삭제", + "parameters": [ + { + "type": "string", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "삭제할 버전(v0.0.0 형식)", + "name": "version", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/app-groups": { "get": { "security": [ @@ -6042,6 +6565,52 @@ } } } + }, + "/utility/rego-compile": { + "post": { + "security": [ + { + "JWT": [] + } + ], + "description": "Rego 코드 컴파일 및 파라미터 파싱을 수행한다. 파라미터 파싱을 위해서는 먼저 컴파일이 성공해야 하며, parseParameter를 false로 하면 컴파일만 수행할 수 있다.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Rego" + ], + "summary": "[CompileRego] Rego 코드 컴파일 및 파라미터 파싱", + "parameters": [ + { + "type": "boolean", + "description": "파라미터 파싱 여부", + "name": "parseParameter", + "in": "query", + "required": true + }, + { + "description": "Rego 코드", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.RegoCompileRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.RegoCompileResponse" + } + } + } + } } }, "definitions": { @@ -7290,51 +7859,169 @@ "tksInfraNode": { "type": "integer" }, - "tksInfraNodeMax": { - "type": "integer" + "tksInfraNodeMax": { + "type": "integer" + }, + "tksInfraNodeType": { + "type": "string" + }, + "tksUserNode": { + "type": "integer" + }, + "tksUserNodeMax": { + "type": "integer" + }, + "tksUserNodeType": { + "type": "string" + } + } + }, + "github_com_openinfradev_tks-api_pkg_domain.CreateClusterResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + } + }, + "github_com_openinfradev_tks-api_pkg_domain.CreateOrganizationRequest": { + "type": "object", + "required": [ + "Email", + "name" + ], + "properties": { + "Email": { + "type": "string" + }, + "description": { + "type": "string", + "maxLength": 100, + "minLength": 0 + }, + "name": { + "type": "string" + }, + "phone": { + "type": "string" + } + } + }, + "github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateReponse": { + "type": "object", + "properties": { + "id": { + "type": "string", + "example": "d98ef5f1-4a68-4047-a446-2207787ce3ff" + } + } + }, + "github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateRequest": { + "type": "object", + "properties": { + "deprecated": { + "type": "boolean", + "example": false + }, + "description": { + "type": "string", + "example": "이 정책은 ..." + }, + "kind": { + "type": "string", + "example": "K8sRequiredLabels" + }, + "libs": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "rego 코드" + ] + }, + "parametersSchema": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ParameterDef" + } + }, + "permittedOrganizationIds": { + "type": "array", + "items": { + "type": "string" + } }, - "tksInfraNodeType": { - "type": "string" + "rego": { + "type": "string", + "example": "rego 코드" }, - "tksUserNode": { - "type": "integer" + "severity": { + "type": "string", + "enum": [ + "low", + "medium", + "high" + ], + "example": "medium" }, - "tksUserNodeMax": { - "type": "integer" + "target": { + "type": "string", + "example": "admission.k8s.gatekeeper.sh" }, - "tksUserNodeType": { - "type": "string" + "templateName": { + "type": "string", + "example": "필수 Label 검사" } } }, - "github_com_openinfradev_tks-api_pkg_domain.CreateClusterResponse": { + "github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateVersionRequest": { "type": "object", "properties": { - "id": { - "type": "string" + "currentVersion": { + "type": "string", + "example": "v1.0.0" + }, + "expectedVersion": { + "type": "string", + "example": "v1.1.0" + }, + "libs": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "rego 코드" + ] + }, + "parametersSchema": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ParameterDef" + } + }, + "rego": { + "type": "string", + "example": "rego 코드" + }, + "versionUpType": { + "type": "string", + "enum": [ + "major", + "minor", + "patch" + ], + "example": "minor" } } }, - "github_com_openinfradev_tks-api_pkg_domain.CreateOrganizationRequest": { + "github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateVersionResponse": { "type": "object", - "required": [ - "Email", - "name" - ], "properties": { - "Email": { - "type": "string" - }, - "description": { + "version": { "type": "string", - "maxLength": 100, - "minLength": 0 - }, - "name": { - "type": "string" - }, - "phone": { - "type": "string" + "example": "v1.1.1" } } }, @@ -7740,6 +8427,9 @@ } } }, + "github_com_openinfradev_tks-api_pkg_domain.ExistsPolicyTemplateKindResponse": { + "type": "object" + }, "github_com_openinfradev_tks-api_pkg_domain.FilterResponse": { "type": "object", "properties": { @@ -8101,6 +8791,33 @@ } } }, + "github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateDeployResponse": { + "type": "object", + "properties": { + "deployVersion": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateResponse": { + "type": "object", + "properties": { + "policyTemplate": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.PolicyTemplateResponse" + } + } + }, + "github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateVersionResponse": { + "type": "object", + "properties": { + "policyTemplate": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.PolicyTemplateResponse" + } + } + }, "github_com_openinfradev_tks-api_pkg_domain.GetProjectKubeconfigResponse": { "type": "object", "properties": { @@ -8441,6 +9158,47 @@ } } }, + "github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateResponse": { + "type": "object", + "properties": { + "pagination": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.PaginationResponse" + }, + "policyTemplates": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.PolicyTemplateResponse" + } + } + } + }, + "github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateStatisticsResponse": { + "type": "object", + "properties": { + "policyTemplateStatistics": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.PolicyTemplateStatistics" + } + } + } + }, + "github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateVersionsResponse": { + "type": "object", + "properties": { + "versions": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "v1.1.0", + "v1.0.1", + "v1.0.0" + ] + } + } + }, "github_com_openinfradev_tks-api_pkg_domain.ListTksRoleResponse": { "type": "object", "properties": { @@ -8647,6 +9405,29 @@ } } }, + "github_com_openinfradev_tks-api_pkg_domain.ParameterDef": { + "type": "object", + "properties": { + "children": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ParameterDef" + } + }, + "defaultValue": { + "type": "string" + }, + "isArray": { + "type": "boolean" + }, + "key": { + "type": "string" + }, + "type": { + "type": "string" + } + } + }, "github_com_openinfradev_tks-api_pkg_domain.Permission": { "type": "object", "properties": { @@ -8720,6 +9501,20 @@ } } }, + "github_com_openinfradev_tks-api_pkg_domain.PermittedOrganization": { + "type": "object", + "properties": { + "organizationId": { + "type": "string" + }, + "organizationName": { + "type": "string" + }, + "permitted": { + "type": "boolean" + } + } + }, "github_com_openinfradev_tks-api_pkg_domain.PingTokenRequest": { "type": "object", "required": [ @@ -8746,6 +9541,103 @@ } } }, + "github_com_openinfradev_tks-api_pkg_domain.PolicyTemplateResponse": { + "type": "object", + "properties": { + "createdAt": { + "type": "string" + }, + "creator": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.SimpleUserResponse" + }, + "deprecated": { + "type": "boolean", + "example": false + }, + "description": { + "type": "string", + "example": "이 정책은 ..." + }, + "id": { + "type": "string", + "example": "d98ef5f1-4a68-4047-a446-2207787ce3ff" + }, + "kind": { + "type": "string", + "example": "K8sRequiredLabels" + }, + "libs": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "rego 코드" + ] + }, + "parametersSchema": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ParameterDef" + } + }, + "permittedOrganizations": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.PermittedOrganization" + } + }, + "rego": { + "type": "string", + "example": "rego 코드" + }, + "severity": { + "type": "string", + "enum": [ + "low", + "medium", + "high" + ], + "example": "medium" + }, + "templateName": { + "type": "string", + "example": "필수 Label 검사" + }, + "type": { + "type": "string", + "enum": [ + "tks", + "organization" + ], + "example": "tks" + }, + "updatedAt": { + "type": "string" + }, + "updator": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.SimpleUserResponse" + }, + "version": { + "type": "string", + "example": "v1.0.1" + } + } + }, + "github_com_openinfradev_tks-api_pkg_domain.PolicyTemplateStatistics": { + "type": "object", + "properties": { + "organizationId": { + "type": "string" + }, + "organizationName": { + "type": "string" + }, + "usageCount": { + "type": "integer" + } + } + }, "github_com_openinfradev_tks-api_pkg_domain.ProjectDetailResponse": { "type": "object", "properties": { @@ -8984,6 +9876,53 @@ } } }, + "github_com_openinfradev_tks-api_pkg_domain.RegoCompieError": { + "type": "object", + "properties": { + "code": { + "type": "string", + "example": "P_INVALID_REGO_SYNTAX" + }, + "message": { + "type": "string", + "example": "Invalid rego syntax" + }, + "status": { + "type": "integer", + "example": 400 + }, + "text": { + "type": "string", + "example": "Rego 문법 에러입니다. 라인:2 컬럼:1 에러메시지: var testnum is not safe" + } + } + }, + "github_com_openinfradev_tks-api_pkg_domain.RegoCompileRequest": { + "type": "object", + "properties": { + "rego": { + "type": "string", + "example": "Rego 코드" + } + } + }, + "github_com_openinfradev_tks-api_pkg_domain.RegoCompileResponse": { + "type": "object", + "properties": { + "errors": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.RegoCompieError" + } + }, + "parametersSchema": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ParameterDef" + } + } + } + }, "github_com_openinfradev_tks-api_pkg_domain.RemoveProjectMemberRequest": { "type": "object", "properties": { @@ -9728,6 +10667,37 @@ } } }, + "github_com_openinfradev_tks-api_pkg_domain.UpdatePolicyTemplateRequest": { + "type": "object", + "properties": { + "deprecated": { + "type": "boolean", + "example": false + }, + "description": { + "type": "string" + }, + "permittedOrganizationIds": { + "type": "array", + "items": { + "type": "string" + } + }, + "severity": { + "type": "string", + "enum": [ + "low", + "medium", + "high" + ], + "example": "medium" + }, + "templateName": { + "type": "string", + "example": "필수 Label 검사" + } + } + }, "github_com_openinfradev_tks-api_pkg_domain.UpdatePrimaryClusterRequest": { "type": "object", "properties": { diff --git a/api/swagger/swagger.yaml b/api/swagger/swagger.yaml index 6c544727..0f3906d9 100644 --- a/api/swagger/swagger.yaml +++ b/api/swagger/swagger.yaml @@ -892,6 +892,89 @@ definitions: - Email - name type: object + github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateReponse: + properties: + id: + example: d98ef5f1-4a68-4047-a446-2207787ce3ff + type: string + type: object + github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateRequest: + properties: + deprecated: + example: false + type: boolean + description: + example: 이 정책은 ... + type: string + kind: + example: K8sRequiredLabels + type: string + libs: + example: + - rego 코드 + items: + type: string + type: array + parametersSchema: + items: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.ParameterDef' + type: array + permittedOrganizationIds: + items: + type: string + type: array + rego: + example: rego 코드 + type: string + severity: + enum: + - low + - medium + - high + example: medium + type: string + target: + example: admission.k8s.gatekeeper.sh + type: string + templateName: + example: 필수 Label 검사 + type: string + type: object + github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateVersionRequest: + properties: + currentVersion: + example: v1.0.0 + type: string + expectedVersion: + example: v1.1.0 + type: string + libs: + example: + - rego 코드 + items: + type: string + type: array + parametersSchema: + items: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.ParameterDef' + type: array + rego: + example: rego 코드 + type: string + versionUpType: + enum: + - major + - minor + - patch + example: minor + type: string + type: object + github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateVersionResponse: + properties: + version: + example: v1.1.1 + type: string + type: object github_com_openinfradev_tks-api_pkg_domain.CreateProjectNamespaceRequest: properties: description: @@ -1164,6 +1247,8 @@ definitions: name: type: string type: object + github_com_openinfradev_tks-api_pkg_domain.ExistsPolicyTemplateKindResponse: + type: object github_com_openinfradev_tks-api_pkg_domain.FilterResponse: properties: column: @@ -1398,6 +1483,23 @@ definitions: type: string type: object type: object + github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateDeployResponse: + properties: + deployVersion: + additionalProperties: + type: string + type: object + type: object + github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateResponse: + properties: + policyTemplate: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.PolicyTemplateResponse' + type: object + github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateVersionResponse: + properties: + policyTemplate: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.PolicyTemplateResponse' + type: object github_com_openinfradev_tks-api_pkg_domain.GetProjectKubeconfigResponse: properties: kubeconfig: @@ -1617,6 +1719,33 @@ definitions: updatedAt: type: string type: object + github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateResponse: + properties: + pagination: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.PaginationResponse' + policyTemplates: + items: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.PolicyTemplateResponse' + type: array + type: object + github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateStatisticsResponse: + properties: + policyTemplateStatistics: + items: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.PolicyTemplateStatistics' + type: array + type: object + github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateVersionsResponse: + properties: + versions: + example: + - v1.1.0 + - v1.0.1 + - v1.0.0 + items: + type: string + type: array + type: object github_com_openinfradev_tks-api_pkg_domain.ListTksRoleResponse: properties: pagination: @@ -1757,6 +1886,21 @@ definitions: totalRows: type: integer type: object + github_com_openinfradev_tks-api_pkg_domain.ParameterDef: + properties: + children: + items: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.ParameterDef' + type: array + defaultValue: + type: string + isArray: + type: boolean + key: + type: string + type: + type: string + type: object github_com_openinfradev_tks-api_pkg_domain.Permission: properties: ID: @@ -1805,6 +1949,15 @@ definitions: stack: $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.Permission' type: object + github_com_openinfradev_tks-api_pkg_domain.PermittedOrganization: + properties: + organizationId: + type: string + organizationName: + type: string + permitted: + type: boolean + type: object github_com_openinfradev_tks-api_pkg_domain.PingTokenRequest: properties: organizationId: @@ -1822,6 +1975,74 @@ definitions: value: type: integer type: object + github_com_openinfradev_tks-api_pkg_domain.PolicyTemplateResponse: + properties: + createdAt: + type: string + creator: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.SimpleUserResponse' + deprecated: + example: false + type: boolean + description: + example: 이 정책은 ... + type: string + id: + example: d98ef5f1-4a68-4047-a446-2207787ce3ff + type: string + kind: + example: K8sRequiredLabels + type: string + libs: + example: + - rego 코드 + items: + type: string + type: array + parametersSchema: + items: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.ParameterDef' + type: array + permittedOrganizations: + items: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.PermittedOrganization' + type: array + rego: + example: rego 코드 + type: string + severity: + enum: + - low + - medium + - high + example: medium + type: string + templateName: + example: 필수 Label 검사 + type: string + type: + enum: + - tks + - organization + example: tks + type: string + updatedAt: + type: string + updator: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.SimpleUserResponse' + version: + example: v1.0.1 + type: string + type: object + github_com_openinfradev_tks-api_pkg_domain.PolicyTemplateStatistics: + properties: + organizationId: + type: string + organizationName: + type: string + usageCount: + type: integer + type: object github_com_openinfradev_tks-api_pkg_domain.ProjectDetailResponse: properties: createdAt: @@ -1982,6 +2203,38 @@ definitions: updatedAt: type: string type: object + github_com_openinfradev_tks-api_pkg_domain.RegoCompieError: + properties: + code: + example: P_INVALID_REGO_SYNTAX + type: string + message: + example: Invalid rego syntax + type: string + status: + example: 400 + type: integer + text: + example: 'Rego 문법 에러입니다. 라인:2 컬럼:1 에러메시지: var testnum is not safe' + type: string + type: object + github_com_openinfradev_tks-api_pkg_domain.RegoCompileRequest: + properties: + rego: + example: Rego 코드 + type: string + type: object + github_com_openinfradev_tks-api_pkg_domain.RegoCompileResponse: + properties: + errors: + items: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.RegoCompieError' + type: array + parametersSchema: + items: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.ParameterDef' + type: array + type: object github_com_openinfradev_tks-api_pkg_domain.RemoveProjectMemberRequest: properties: projectMembers: @@ -2473,6 +2726,28 @@ definitions: $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.Permission' type: array type: object + github_com_openinfradev_tks-api_pkg_domain.UpdatePolicyTemplateRequest: + properties: + deprecated: + example: false + type: boolean + description: + type: string + permittedOrganizationIds: + items: + type: string + type: array + severity: + enum: + - low + - medium + - high + example: medium + type: string + templateName: + example: 필수 Label 검사 + type: string + type: object github_com_openinfradev_tks-api_pkg_domain.UpdatePrimaryClusterRequest: properties: primaryClusterId: @@ -3080,6 +3355,336 @@ paths: summary: Get GetStackTemplateServices tags: - StackTemplates + /api/1.0/admin/policytemplates: + get: + consumes: + - application/json + description: 정책 템플릿 목록을 조회한다. 정책 템플릿 목록 조회 결과는 최신 템플릿 버전 목록만 조회된다. + parameters: + - description: pageSize + in: query + name: limit + type: string + - description: pageNumber + in: query + name: page + type: string + - description: sortColumn + in: query + name: soertColumn + type: string + - description: sortOrder + in: query + name: sortOrder + type: string + - collectionFormat: csv + description: filters + in: query + items: + type: string + name: filters + type: array + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateResponse' + security: + - JWT: [] + summary: '[ListPolicyTemplate] 정책 템플릿 목록 조회' + tags: + - PolicyTemplate + post: + consumes: + - application/json + description: 정책 템플릿을 신규 생성(v1.0.0을 생성)한다. + parameters: + - description: create policy template request + in: body + name: body + required: true + schema: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateReponse' + security: + - JWT: [] + summary: '[CreatePolicyTemplate] 정책 템플릿 신규 생성' + tags: + - PolicyTemplate + /api/1.0/admin/policytemplates/{policyTemplateId}: + delete: + consumes: + - application/json + description: 정책 템플릿을 삭제한다. + parameters: + - description: 정책 템플릿 식별자(uuid) + in: path + name: policyTemplateId + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + security: + - JWT: [] + summary: '[DeletePolicyTemplate] 정책 템플릿 삭제' + tags: + - PolicyTemplate + get: + consumes: + - application/json + description: 해당 식별자를 가진 정책 템플릿의 최신 버전을 조회한다. + parameters: + - description: 정책 템플릿 식별자(uuid) + in: path + name: policyTemplateId + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateResponse' + security: + - JWT: [] + summary: '[GetPolicyTemplate] 정책 템플릿 조회(최신 버전)' + tags: + - PolicyTemplate + patch: + consumes: + - application/json + description: 정책 템플릿의 업데이트 가능한 필드들을 업데이트한다. + parameters: + - description: 정책 템플릿 식별자(uuid) + in: path + name: policyTemplateId + required: true + type: string + - description: update policy template request + in: body + name: body + required: true + schema: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.UpdatePolicyTemplateRequest' + produces: + - application/json + responses: + "200": + description: OK + security: + - JWT: [] + summary: '[UpdatePolicyTemplate] 정책 템플릿 업데이트' + tags: + - PolicyTemplate + /api/1.0/admin/policytemplates/{policyTemplateId}/deploy: + get: + consumes: + - application/json + description: 해당 식별자를 가진 정책 템플릿의 정책 템플릿 클러스터 별 설치 버전을 조회한다. + parameters: + - description: 정책 템플릿 식별자(uuid) + in: path + name: policyTemplateId + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateDeployResponse' + security: + - JWT: [] + summary: '[GetPolicyTemplateDeploy] 정책 템플릿 클러스터 별 설치 버전 조회' + tags: + - PolicyTemplate + /api/1.0/admin/policytemplates/{policyTemplateId}/statistics: + get: + consumes: + - application/json + description: 해당 식별자를 가진 정책 템플릿의 최신 버전을 조회한다. 전체 조직의 통계를 조회하려면 organizationId를 + tks로 설정한다. + parameters: + - description: 정책 템플릿 식별자(uuid) + in: path + name: policyTemplateId + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateStatisticsResponse' + security: + - JWT: [] + summary: '[ListPolicyTemplateStatistics] 정책 템플릿 사용 카운트 조회' + tags: + - PolicyTemplate + /api/1.0/admin/policytemplates/{policyTemplateId}/versions: + get: + consumes: + - application/json + description: 해당 식별자를 가진 정책 템플릿의 최신 버전을 조회한다. + parameters: + - description: 정책 템플릿 식별자(uuid) + in: path + name: policyTemplateId + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateVersionsResponse' + security: + - JWT: [] + summary: '[ListPolicyTemplateVersions] 정책 템플릿 버전목록 조회' + tags: + - PolicyTemplate + post: + consumes: + - application/json + description: 해당 식별자를 가진 정책 템플릿의 특정 버전을 저장한다. + parameters: + - description: 정책 템플릿 식별자(uuid) + in: path + name: policyTemplateId + required: true + type: string + - description: create policy template version request + in: body + name: body + required: true + schema: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateVersionRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateVersionResponse' + security: + - JWT: [] + summary: '[CreatePolicyTemplateVersion] 정책 템플릿 특정 버전 저장' + tags: + - PolicyTemplate + /api/1.0/admin/policytemplates/{policyTemplateId}/versions/{version}: + delete: + consumes: + - application/json + description: 해당 식별자를 가진 정책 템플릿의 특정 버전을 삭제한다. + parameters: + - description: 정책 템플릿 식별자(uuid) + in: path + name: policyTemplateId + required: true + type: string + - description: 삭제할 버전(v0.0.0 형식) + in: path + name: version + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + security: + - JWT: [] + summary: '[DeletePolicyTemplateVersion] 정책 템플릿 특정 버전 삭제' + tags: + - PolicyTemplate + get: + consumes: + - application/json + description: 해당 식별자를 가진 정책 템플릿의 특정 버전을 조회한다. + parameters: + - description: 정책 템플릿 식별자(uuid) + in: path + name: policyTemplateId + required: true + type: string + - description: 조회할 버전(v0.0.0 형식) + in: path + name: version + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateVersionResponse' + security: + - JWT: [] + summary: '[GetPolicyTemplateVersion] 정책 템플릿 특정 버전 조회' + tags: + - PolicyTemplate + /api/1.0/admin/policytemplates/kind/{policyTemplateKind}/existence: + get: + consumes: + - application/json + description: 해당 유형을 가진 정책 템플릿이 이미 존재하는지 확인한다. + parameters: + - description: 정책 템플릿 이름 + in: path + name: policyTemplateKind + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.ExistsPolicyTemplateKindResponse' + security: + - JWT: [] + summary: '[ExistsPolicyTemplateKind] 정책 템플릿 유형 존재 여부 확인' + tags: + - PolicyTemplate + /api/1.0/admin/policytemplates/name/{policyTemplateName}/existence: + get: + consumes: + - application/json + description: 해당 이름을 가진 정책 템플릿이 이미 존재하는지 확인한다. + parameters: + - description: 정책 템플릿 이름 + in: path + name: policyTemplateName + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.CheckExistedResponse' + security: + - JWT: [] + summary: '[ExistsPolicyTemplateName] 정책 템플릿 아름 존재 여부 확인' + tags: + - PolicyTemplate /app-groups: delete: consumes: @@ -6651,6 +7256,36 @@ paths: summary: Create alert. ADMIN ONLY tags: - Alerts + /utility/rego-compile: + post: + consumes: + - application/json + description: Rego 코드 컴파일 및 파라미터 파싱을 수행한다. 파라미터 파싱을 위해서는 먼저 컴파일이 성공해야 하며, parseParameter를 + false로 하면 컴파일만 수행할 수 있다. + parameters: + - description: 파라미터 파싱 여부 + in: query + name: parseParameter + required: true + type: boolean + - description: Rego 코드 + in: body + name: body + required: true + schema: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.RegoCompileRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.RegoCompileResponse' + security: + - JWT: [] + summary: '[CompileRego] Rego 코드 컴파일 및 파라미터 파싱' + tags: + - Rego securityDefinitions: JWT: in: header diff --git a/go.mod b/go.mod index 0674b4e6..4f2e46d4 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/openinfradev/tks-api go 1.21 require ( + github.com/Masterminds/semver/v3 v3.2.0 github.com/Nerzal/gocloak/v13 v13.9.0 github.com/aws/aws-sdk-go-v2 v1.25.0 github.com/aws/aws-sdk-go-v2/config v1.27.0 @@ -24,6 +25,7 @@ require ( github.com/gorilla/handlers v1.5.2 github.com/gorilla/mux v1.8.1 github.com/gorilla/websocket v1.5.1 + github.com/open-policy-agent/opa v0.62.1 github.com/opentracing/opentracing-go v1.2.0 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pkg/errors v0.9.1 @@ -34,8 +36,8 @@ require ( github.com/swaggo/swag v1.16.3 github.com/thoas/go-funk v0.9.3 github.com/vmware-tanzu/cluster-api-provider-bringyourownhost v0.5.0 - golang.org/x/crypto v0.19.0 - golang.org/x/net v0.21.0 + golang.org/x/crypto v0.21.0 + golang.org/x/net v0.22.0 golang.org/x/oauth2 v0.17.0 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gopkg.in/yaml.v3 v3.0.1 @@ -52,6 +54,7 @@ require ( require ( github.com/Code-Hex/uniseg v0.2.0 // indirect github.com/KyleBanks/depth v1.2.1 // indirect + github.com/OneOfOne/xxhash v1.2.8 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.0 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.0 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.0 // indirect @@ -63,14 +66,14 @@ require ( github.com/aws/smithy-go v1.20.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver v3.5.1+incompatible // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.9.0 // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect - github.com/felixge/httpsnoop v1.0.3 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect - github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/logr v1.4.1 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonreference v0.20.0 // indirect github.com/go-openapi/spec v0.20.6 // indirect @@ -82,7 +85,7 @@ require ( github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/gnostic v0.6.9 // indirect - github.com/google/go-cmp v0.5.9 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/imdario/mergo v0.3.15 // indirect @@ -97,17 +100,17 @@ require ( github.com/leodido/go-urn v1.4.0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang v1.14.0 // indirect - github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.37.0 // indirect - github.com/prometheus/procfs v0.8.0 // indirect + github.com/prometheus/client_golang v1.19.0 // indirect + github.com/prometheus/client_model v0.5.0 // indirect + github.com/prometheus/common v0.48.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect + github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/segmentio/ksuid v1.0.4 // indirect @@ -117,17 +120,19 @@ require ( github.com/stretchr/testify v1.8.4 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/swaggo/files v0.0.0-20220610200504-28940afbdbfe // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/sys v0.17.0 // indirect - golang.org/x/term v0.17.0 // indirect + golang.org/x/sys v0.18.0 // indirect + golang.org/x/term v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.13.0 // indirect + golang.org/x/tools v0.15.0 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.31.0 // indirect + google.golang.org/protobuf v1.32.0 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect @@ -141,7 +146,7 @@ require ( sigs.k8s.io/controller-runtime v0.14.5 // indirect sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect - sigs.k8s.io/yaml v1.3.0 // indirect + sigs.k8s.io/yaml v1.4.0 // indirect ) replace github.com/openinfradev/tks-api => ./ diff --git a/go.sum b/go.sum index fc216539..99f38a76 100644 --- a/go.sum +++ b/go.sum @@ -1,50 +1,17 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Code-Hex/uniseg v0.2.0 h1:QB/2UJFvEuRLSZqe+Sb1XQBTWjqGVbZoC6oSWzQRKws= github.com/Code-Hex/uniseg v0.2.0/go.mod h1:/ndS2tP+X1lk2HUOcXWGtVTxVq0lWilwgMa4CbzdRsg= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= +github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g= +github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Nerzal/gocloak/v13 v13.9.0 h1:YWsJsdM5b0yhM2Ba3MLydiOlujkBry4TtdzfIzSVZhw= github.com/Nerzal/gocloak/v13 v13.9.0/go.mod h1:YYuDcXZ7K2zKECyVP7pPqjKxx2AzYSpKDj8d6GuyM10= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= +github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/aws/aws-sdk-go-v2 v1.25.0 h1:sv7+1JVJxOu/dD/sz/csHX7jFqmP001TIY7aytBWDSQ= github.com/aws/aws-sdk-go-v2 v1.25.0/go.mod h1:G104G1Aho5WqF+SR3mDIobTABQzpYV0WxMsKxlMggOA= @@ -84,8 +51,6 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.27.0 h1:cjTRjh700H36MQ8M0LnDn33W3Jmw github.com/aws/aws-sdk-go-v2/service/sts v1.27.0/go.mod h1:nXfOBMWPokIbOY+Gi7a1psWMSvskUCemZzI+SMB7Akc= github.com/aws/smithy-go v1.20.0 h1:6+kZsCXZwKxZS9RfISnPc4EXlHoyAkm2hPuM8X2BrrQ= github.com/aws/smithy-go v1.20.0/go.mod h1:uo5RKksAl4PzhqaAbjd4rLgFoq5koTsQKYuGe7dklGc= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= @@ -93,12 +58,8 @@ github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -124,8 +85,8 @@ github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCv github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= -github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= -github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= @@ -134,20 +95,9 @@ github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyT github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= @@ -174,12 +124,10 @@ github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSM github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gobuffalo/flect v1.0.2 h1:eqjPGSo2WmjgY2XlpGwo2NXgL3RucAKo4k4qQMNA5sA= github.com/gobuffalo/flect v1.0.2/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= @@ -191,26 +139,15 @@ github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2V github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -223,41 +160,25 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= @@ -265,11 +186,8 @@ github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWS github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= @@ -289,21 +207,10 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -323,9 +230,6 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/microsoft/go-mssqldb v0.21.0 h1:p2rpHIL7TlSv1QrbXJUAcbyRKnIT0C9rRkH2E4OjLn8= github.com/microsoft/go-mssqldb v0.21.0/go.mod h1:+4wZTUnz/SV6nffv+RRRB/ss8jPng5Sho2SmM1l2ts4= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -333,71 +237,49 @@ github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU= github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= github.com/onsi/gomega v1.27.5 h1:T/X6I0RNFw/kTqgfkZPcQ5KU6vCnWNBGdtrIx2dpGeQ= github.com/onsi/gomega v1.27.5/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/open-policy-agent/opa v0.62.1 h1:UcxBQ0fe6NEjkYc775j4PWoUFFhx4f6yXKIKSTAuTVk= +github.com/open-policy-agent/opa v0.62.1/go.mod h1:YqiSIIuvKwyomtnnXkJvy0E3KtVKbavjPJ/hNMuOmeM= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= +github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= +github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ= +github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c= github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= @@ -413,10 +295,8 @@ github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -439,18 +319,14 @@ github.com/thoas/go-funk v0.9.3/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xz github.com/vmware-tanzu/cluster-api-provider-bringyourownhost v0.5.0 h1:BBu+4LBAa6kMzOwhA5hchMa8NVW2JlyUMldoRrcd67g= github.com/vmware-tanzu/cluster-api-provider-bringyourownhost v0.5.0/go.mod h1:4N15SpYBrqBFtblYzwp3RkRXVYlT69UZIZKbpU96FTQ= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -460,287 +336,103 @@ go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8= +golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= @@ -752,14 +444,12 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -768,20 +458,15 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE= gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -804,12 +489,7 @@ gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= goyave.dev/goyave/v4 v4.4.11 h1:HdJJ82ZWrkB7sBsituVRgQhcDvmAavfVbd6xynaUN8Y= goyave.dev/goyave/v4 v4.4.11/go.mod h1:kMbB3bf7ZhUD4Cq1Zy6nM4fHBHYO5mPSkTF6WStf4ik= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.26.1 h1:f+SWYiPd/GsiWwVRz+NbFyCgvv75Pk9NK6dlkZgpCRQ= k8s.io/api v0.26.1/go.mod h1:xd/GBNgR0f707+ATNyPmQ1oyKSgndzXij81FzWGsejg= k8s.io/apiextensions-apiserver v0.26.1 h1:cB8h1SRk6e/+i3NOrQgSFij1B2S0Y0wDoNl66bn8RMI= @@ -828,9 +508,6 @@ k8s.io/kubectl v0.25.2 h1:2993lTeVimxKSWx/7z2PiJxUILygRa3tmC4QhFaeioA= k8s.io/kubectl v0.25.2/go.mod h1:eoBGJtKUj7x38KXelz+dqVtbtbKwCqyKzJWmBHU0prg= k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 h1:KTgPnR10d5zhztWptI952TNtt/4u5h3IzDXkdIMuo2Y= k8s.io/utils v0.0.0-20221128185143-99ec85e7a448/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/cluster-api v1.4.4 h1:+V+mzDe+gsWYclosvWlH0wadC8vIUsBvZLcWOYnVWRA= sigs.k8s.io/cluster-api v1.4.4/go.mod h1:/SeFds4NXJ+Gp2etqHyoNuO6yoxTfVq6Zmd2OGxd/qM= sigs.k8s.io/controller-runtime v0.14.5 h1:6xaWFqzT5KuAQ9ufgUaj1G/+C4Y1GRkhrxl+BJ9i+5s= @@ -839,5 +516,5 @@ sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= -sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/internal/database/database.go b/internal/database/database.go index 2e9ad696..1fd29171 100644 --- a/internal/database/database.go +++ b/internal/database/database.go @@ -186,5 +186,14 @@ func EnsureDefaultRows(db *gorm.DB) error { return err } + // PolicyTemplate + if err := db.AutoMigrate(&repository.PolicyTemplateSupportedVersion{}); err != nil { + return err + } + + if err := db.AutoMigrate(&repository.PolicyTemplate{}); err != nil { + return err + } + return nil } diff --git a/internal/delivery/api/endpoint.go b/internal/delivery/api/endpoint.go index e53bca40..9d7c0966 100644 --- a/internal/delivery/api/endpoint.go +++ b/internal/delivery/api/endpoint.go @@ -185,4 +185,58 @@ const ( // Admin Project Admin_GetProjects + // PolicyTemplate + ListPolicyTemplate + CreatePolicyTemplate + DeletePolicyTemplate + GetPolicyTemplate + UpdatePolicyTemplate + GetPolicyTemplateDeploy + ListPolicyTemplateStatistics + ListPolicyTemplateVersions + CreatePolicyTemplateVersion + DeletePolicyTemplateVersion + GetPolicyTemplateVersion + ExistsPolicyTemplateKind + ExistsPolicyTemplateName + + // ClusterPolicyStatus + ListClusterPolicyStatus + GetClusterPolicyTemplateStatus + UpdateClusterPolicyTemplateStatus + + // Policy + GetMandatoryPolicies + SetMandatoryPolicies + ListPolicy + CreatePolicy + DeletePolicy + GetPolicy + UpdatePolicy + UpdatePolicyTargetClusters + ExistsPolicyName + + // OrganizationPolicyTemplate + ListOrganizationPolicyTemplate + CreateOrganizationPolicyTemplate + DeleteOrganizationPolicyTemplate + GetOrganizationPolicyTemplate + UpdateOrganizationPolicyTemplate + GetOrganizationPolicyTemplateDeploy + ListOrganizationPolicyTemplateStatistics + ListOrganizationPolicyTemplateVersions + CreateOrganizationPolicyTemplateVersion + DeleteOrganizationPolicyTemplateVersion + GetOrganizationPolicyTemplateVersion + ExistsOrganizationPolicyTemplateKind + ExistsOrganizationPolicyTemplateName + + // PolicyTemplateExample + ListPolicyTemplateExample + GetPolicyTemplateExample + UpdatePolicyTemplateExample + DeletePolicyTemplateExample + + // Utility + CompileRego ) diff --git a/internal/delivery/api/generated_endpoints.go.go b/internal/delivery/api/generated_endpoints.go.go index ca6fb98c..aeea2305 100644 --- a/internal/delivery/api/generated_endpoints.go.go +++ b/internal/delivery/api/generated_endpoints.go.go @@ -555,6 +555,178 @@ var ApiMap = map[Endpoint]EndpointInfo{ Name: "Admin_GetProjects", Group: "Admin Project", }, + ListPolicyTemplate: { + Name: "ListPolicyTemplate", + Group: "PolicyTemplate", + }, + CreatePolicyTemplate: { + Name: "CreatePolicyTemplate", + Group: "PolicyTemplate", + }, + DeletePolicyTemplate: { + Name: "DeletePolicyTemplate", + Group: "PolicyTemplate", + }, + GetPolicyTemplate: { + Name: "GetPolicyTemplate", + Group: "PolicyTemplate", + }, + UpdatePolicyTemplate: { + Name: "UpdatePolicyTemplate", + Group: "PolicyTemplate", + }, + GetPolicyTemplateDeploy: { + Name: "GetPolicyTemplateDeploy", + Group: "PolicyTemplate", + }, + ListPolicyTemplateStatistics: { + Name: "ListPolicyTemplateStatistics", + Group: "PolicyTemplate", + }, + ListPolicyTemplateVersions: { + Name: "ListPolicyTemplateVersions", + Group: "PolicyTemplate", + }, + CreatePolicyTemplateVersion: { + Name: "CreatePolicyTemplateVersion", + Group: "PolicyTemplate", + }, + DeletePolicyTemplateVersion: { + Name: "DeletePolicyTemplateVersion", + Group: "PolicyTemplate", + }, + GetPolicyTemplateVersion: { + Name: "GetPolicyTemplateVersion", + Group: "PolicyTemplate", + }, + ExistsPolicyTemplateKind: { + Name: "ExistsPolicyTemplateKind", + Group: "PolicyTemplate", + }, + ExistsPolicyTemplateName: { + Name: "ExistsPolicyTemplateName", + Group: "PolicyTemplate", + }, + ListClusterPolicyStatus: { + Name: "ListClusterPolicyStatus", + Group: "ClusterPolicyStatus", + }, + GetClusterPolicyTemplateStatus: { + Name: "GetClusterPolicyTemplateStatus", + Group: "ClusterPolicyStatus", + }, + UpdateClusterPolicyTemplateStatus: { + Name: "UpdateClusterPolicyTemplateStatus", + Group: "ClusterPolicyStatus", + }, + GetMandatoryPolicies: { + Name: "GetMandatoryPolicies", + Group: "Policy", + }, + SetMandatoryPolicies: { + Name: "SetMandatoryPolicies", + Group: "Policy", + }, + ListPolicy: { + Name: "ListPolicy", + Group: "Policy", + }, + CreatePolicy: { + Name: "CreatePolicy", + Group: "Policy", + }, + DeletePolicy: { + Name: "DeletePolicy", + Group: "Policy", + }, + GetPolicy: { + Name: "GetPolicy", + Group: "Policy", + }, + UpdatePolicy: { + Name: "UpdatePolicy", + Group: "Policy", + }, + UpdatePolicyTargetClusters: { + Name: "UpdatePolicyTargetClusters", + Group: "Policy", + }, + ExistsPolicyName: { + Name: "ExistsPolicyName", + Group: "Policy", + }, + ListOrganizationPolicyTemplate: { + Name: "ListOrganizationPolicyTemplate", + Group: "OrganizationPolicyTemplate", + }, + CreateOrganizationPolicyTemplate: { + Name: "CreateOrganizationPolicyTemplate", + Group: "OrganizationPolicyTemplate", + }, + DeleteOrganizationPolicyTemplate: { + Name: "DeleteOrganizationPolicyTemplate", + Group: "OrganizationPolicyTemplate", + }, + GetOrganizationPolicyTemplate: { + Name: "GetOrganizationPolicyTemplate", + Group: "OrganizationPolicyTemplate", + }, + UpdateOrganizationPolicyTemplate: { + Name: "UpdateOrganizationPolicyTemplate", + Group: "OrganizationPolicyTemplate", + }, + GetOrganizationPolicyTemplateDeploy: { + Name: "GetOrganizationPolicyTemplateDeploy", + Group: "OrganizationPolicyTemplate", + }, + ListOrganizationPolicyTemplateStatistics: { + Name: "ListOrganizationPolicyTemplateStatistics", + Group: "OrganizationPolicyTemplate", + }, + ListOrganizationPolicyTemplateVersions: { + Name: "ListOrganizationPolicyTemplateVersions", + Group: "OrganizationPolicyTemplate", + }, + CreateOrganizationPolicyTemplateVersion: { + Name: "CreateOrganizationPolicyTemplateVersion", + Group: "OrganizationPolicyTemplate", + }, + DeleteOrganizationPolicyTemplateVersion: { + Name: "DeleteOrganizationPolicyTemplateVersion", + Group: "OrganizationPolicyTemplate", + }, + GetOrganizationPolicyTemplateVersion: { + Name: "GetOrganizationPolicyTemplateVersion", + Group: "OrganizationPolicyTemplate", + }, + ExistsOrganizationPolicyTemplateKind: { + Name: "ExistsOrganizationPolicyTemplateKind", + Group: "OrganizationPolicyTemplate", + }, + ExistsOrganizationPolicyTemplateName: { + Name: "ExistsOrganizationPolicyTemplateName", + Group: "OrganizationPolicyTemplate", + }, + ListPolicyTemplateExample: { + Name: "ListPolicyTemplateExample", + Group: "PolicyTemplateExample", + }, + GetPolicyTemplateExample: { + Name: "GetPolicyTemplateExample", + Group: "PolicyTemplateExample", + }, + UpdatePolicyTemplateExample: { + Name: "UpdatePolicyTemplateExample", + Group: "PolicyTemplateExample", + }, + DeletePolicyTemplateExample: { + Name: "DeletePolicyTemplateExample", + Group: "PolicyTemplateExample", + }, + CompileRego: { + Name: "CompileRego", + Group: "Utility", + }, } func (e Endpoint) String() string { switch e { @@ -834,6 +1006,92 @@ func (e Endpoint) String() string { return "Admin_GetTksRole" case Admin_GetProjects: return "Admin_GetProjects" + case ListPolicyTemplate: + return "ListPolicyTemplate" + case CreatePolicyTemplate: + return "CreatePolicyTemplate" + case DeletePolicyTemplate: + return "DeletePolicyTemplate" + case GetPolicyTemplate: + return "GetPolicyTemplate" + case UpdatePolicyTemplate: + return "UpdatePolicyTemplate" + case GetPolicyTemplateDeploy: + return "GetPolicyTemplateDeploy" + case ListPolicyTemplateStatistics: + return "ListPolicyTemplateStatistics" + case ListPolicyTemplateVersions: + return "ListPolicyTemplateVersions" + case CreatePolicyTemplateVersion: + return "CreatePolicyTemplateVersion" + case DeletePolicyTemplateVersion: + return "DeletePolicyTemplateVersion" + case GetPolicyTemplateVersion: + return "GetPolicyTemplateVersion" + case ExistsPolicyTemplateKind: + return "ExistsPolicyTemplateKind" + case ExistsPolicyTemplateName: + return "ExistsPolicyTemplateName" + case ListClusterPolicyStatus: + return "ListClusterPolicyStatus" + case GetClusterPolicyTemplateStatus: + return "GetClusterPolicyTemplateStatus" + case UpdateClusterPolicyTemplateStatus: + return "UpdateClusterPolicyTemplateStatus" + case GetMandatoryPolicies: + return "GetMandatoryPolicies" + case SetMandatoryPolicies: + return "SetMandatoryPolicies" + case ListPolicy: + return "ListPolicy" + case CreatePolicy: + return "CreatePolicy" + case DeletePolicy: + return "DeletePolicy" + case GetPolicy: + return "GetPolicy" + case UpdatePolicy: + return "UpdatePolicy" + case UpdatePolicyTargetClusters: + return "UpdatePolicyTargetClusters" + case ExistsPolicyName: + return "ExistsPolicyName" + case ListOrganizationPolicyTemplate: + return "ListOrganizationPolicyTemplate" + case CreateOrganizationPolicyTemplate: + return "CreateOrganizationPolicyTemplate" + case DeleteOrganizationPolicyTemplate: + return "DeleteOrganizationPolicyTemplate" + case GetOrganizationPolicyTemplate: + return "GetOrganizationPolicyTemplate" + case UpdateOrganizationPolicyTemplate: + return "UpdateOrganizationPolicyTemplate" + case GetOrganizationPolicyTemplateDeploy: + return "GetOrganizationPolicyTemplateDeploy" + case ListOrganizationPolicyTemplateStatistics: + return "ListOrganizationPolicyTemplateStatistics" + case ListOrganizationPolicyTemplateVersions: + return "ListOrganizationPolicyTemplateVersions" + case CreateOrganizationPolicyTemplateVersion: + return "CreateOrganizationPolicyTemplateVersion" + case DeleteOrganizationPolicyTemplateVersion: + return "DeleteOrganizationPolicyTemplateVersion" + case GetOrganizationPolicyTemplateVersion: + return "GetOrganizationPolicyTemplateVersion" + case ExistsOrganizationPolicyTemplateKind: + return "ExistsOrganizationPolicyTemplateKind" + case ExistsOrganizationPolicyTemplateName: + return "ExistsOrganizationPolicyTemplateName" + case ListPolicyTemplateExample: + return "ListPolicyTemplateExample" + case GetPolicyTemplateExample: + return "GetPolicyTemplateExample" + case UpdatePolicyTemplateExample: + return "UpdatePolicyTemplateExample" + case DeletePolicyTemplateExample: + return "DeletePolicyTemplateExample" + case CompileRego: + return "CompileRego" default: return "" } @@ -1116,6 +1374,92 @@ func GetEndpoint(name string) Endpoint { return Admin_GetTksRole case "Admin_GetProjects": return Admin_GetProjects + case "ListPolicyTemplate": + return ListPolicyTemplate + case "CreatePolicyTemplate": + return CreatePolicyTemplate + case "DeletePolicyTemplate": + return DeletePolicyTemplate + case "GetPolicyTemplate": + return GetPolicyTemplate + case "UpdatePolicyTemplate": + return UpdatePolicyTemplate + case "GetPolicyTemplateDeploy": + return GetPolicyTemplateDeploy + case "ListPolicyTemplateStatistics": + return ListPolicyTemplateStatistics + case "ListPolicyTemplateVersions": + return ListPolicyTemplateVersions + case "CreatePolicyTemplateVersion": + return CreatePolicyTemplateVersion + case "DeletePolicyTemplateVersion": + return DeletePolicyTemplateVersion + case "GetPolicyTemplateVersion": + return GetPolicyTemplateVersion + case "ExistsPolicyTemplateKind": + return ExistsPolicyTemplateKind + case "ExistsPolicyTemplateName": + return ExistsPolicyTemplateName + case "ListClusterPolicyStatus": + return ListClusterPolicyStatus + case "GetClusterPolicyTemplateStatus": + return GetClusterPolicyTemplateStatus + case "UpdateClusterPolicyTemplateStatus": + return UpdateClusterPolicyTemplateStatus + case "GetMandatoryPolicies": + return GetMandatoryPolicies + case "SetMandatoryPolicies": + return SetMandatoryPolicies + case "ListPolicy": + return ListPolicy + case "CreatePolicy": + return CreatePolicy + case "DeletePolicy": + return DeletePolicy + case "GetPolicy": + return GetPolicy + case "UpdatePolicy": + return UpdatePolicy + case "UpdatePolicyTargetClusters": + return UpdatePolicyTargetClusters + case "ExistsPolicyName": + return ExistsPolicyName + case "ListOrganizationPolicyTemplate": + return ListOrganizationPolicyTemplate + case "CreateOrganizationPolicyTemplate": + return CreateOrganizationPolicyTemplate + case "DeleteOrganizationPolicyTemplate": + return DeleteOrganizationPolicyTemplate + case "GetOrganizationPolicyTemplate": + return GetOrganizationPolicyTemplate + case "UpdateOrganizationPolicyTemplate": + return UpdateOrganizationPolicyTemplate + case "GetOrganizationPolicyTemplateDeploy": + return GetOrganizationPolicyTemplateDeploy + case "ListOrganizationPolicyTemplateStatistics": + return ListOrganizationPolicyTemplateStatistics + case "ListOrganizationPolicyTemplateVersions": + return ListOrganizationPolicyTemplateVersions + case "CreateOrganizationPolicyTemplateVersion": + return CreateOrganizationPolicyTemplateVersion + case "DeleteOrganizationPolicyTemplateVersion": + return DeleteOrganizationPolicyTemplateVersion + case "GetOrganizationPolicyTemplateVersion": + return GetOrganizationPolicyTemplateVersion + case "ExistsOrganizationPolicyTemplateKind": + return ExistsOrganizationPolicyTemplateKind + case "ExistsOrganizationPolicyTemplateName": + return ExistsOrganizationPolicyTemplateName + case "ListPolicyTemplateExample": + return ListPolicyTemplateExample + case "GetPolicyTemplateExample": + return GetPolicyTemplateExample + case "UpdatePolicyTemplateExample": + return UpdatePolicyTemplateExample + case "DeletePolicyTemplateExample": + return DeletePolicyTemplateExample + case "CompileRego": + return CompileRego default: return -1 } diff --git a/internal/delivery/http/policy-template.go b/internal/delivery/http/policy-template.go new file mode 100644 index 00000000..3206545c --- /dev/null +++ b/internal/delivery/http/policy-template.go @@ -0,0 +1,647 @@ +package http + +import ( + "fmt" + "net/http" + "strings" + + "github.com/google/uuid" + "github.com/gorilla/mux" + "github.com/openinfradev/tks-api/internal/pagination" + "github.com/openinfradev/tks-api/internal/serializer" + "github.com/openinfradev/tks-api/internal/usecase" + "github.com/openinfradev/tks-api/pkg/domain" + "github.com/openinfradev/tks-api/pkg/httpErrors" + "github.com/openinfradev/tks-api/pkg/log" + + "github.com/Masterminds/semver/v3" +) + +type PolicyTemplateHandler struct { + usecase usecase.IPolicyTemplateUsecase +} + +type IPolicyTemplateHandler interface { + CreatePolicyTemplate(w http.ResponseWriter, r *http.Request) + UpdatePolicyTemplate(w http.ResponseWriter, r *http.Request) + DeletePolicyTemplate(w http.ResponseWriter, r *http.Request) + GetPolicyTemplate(w http.ResponseWriter, r *http.Request) + ListPolicyTemplate(w http.ResponseWriter, r *http.Request) + ExistsPolicyTemplateName(w http.ResponseWriter, r *http.Request) + ExistsPolicyTemplateKind(w http.ResponseWriter, r *http.Request) + ListPolicyTemplateStatistics(w http.ResponseWriter, r *http.Request) + GetPolicyTemplateDeploy(w http.ResponseWriter, r *http.Request) + CreatePolicyTemplateVersion(w http.ResponseWriter, r *http.Request) + GetPolicyTemplateVersion(w http.ResponseWriter, r *http.Request) + DeletePolicyTemplateVersion(w http.ResponseWriter, r *http.Request) + ListPolicyTemplateVersions(w http.ResponseWriter, r *http.Request) +} + +func NewPolicyTemplateHandler(u usecase.Usecase) IPolicyTemplateHandler { + return &PolicyTemplateHandler{ + usecase: u.PolicyTemplate, + } +} + +// CreatePolicyTemplate godoc +// +// @Tags PolicyTemplate +// @Summary [CreatePolicyTemplate] 정책 템플릿 신규 생성 +// @Description 정책 템플릿을 신규 생성(v1.0.0을 생성)한다. +// @Accept json +// @Produce json +// @Param body body domain.CreatePolicyTemplateRequest true "create policy template request" +// @Success 200 {object} domain.CreatePolicyTemplateReponse +// @Router /api/1.0/admin/policytemplates [post] +// @Security JWT +func (h *PolicyTemplateHandler) CreatePolicyTemplate(w http.ResponseWriter, r *http.Request) { + input := domain.CreatePolicyTemplateRequest{} + + err := UnmarshalRequestInput(r, &input) + + if err != nil { + log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) + ErrorJSON(w, r, err) + return + } + + var dto domain.PolicyTemplate + if err = serializer.Map(input, &dto); err != nil { + log.InfoWithContext(r.Context(), err) + } + + policyTemplateId, err := h.usecase.Create(r.Context(), dto) + if err != nil { + ErrorJSON(w, r, err) + return + } + + var out domain.CreatePolicyTemplateReponse + out.ID = domain.PolicyTemplateId(policyTemplateId) + + ResponseJSON(w, r, http.StatusOK, out) +} + +// UpdatePolicyTemplate godoc +// +// @Tags PolicyTemplate +// @Summary [UpdatePolicyTemplate] 정책 템플릿 업데이트 +// @Description 정책 템플릿의 업데이트 가능한 필드들을 업데이트한다. +// @Accept json +// @Produce json +// @Param policyTemplateId path string true "정책 템플릿 식별자(uuid)" +// @Param body body domain.UpdatePolicyTemplateRequest true "update policy template request" +// @Success 200 {object} nil +// @Router /api/1.0/admin/policytemplates/{policyTemplateId} [patch] +// @Security JWT +func (h *PolicyTemplateHandler) UpdatePolicyTemplate(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + policyTemplateId, ok := vars["policyTemplateId"] + if !ok { + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("Invalid policyTemplateId"), "C_INVALID_ORGANIZATION_ID", "")) + return + } + + id, err := uuid.Parse(policyTemplateId) + if err != nil { + log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) + if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound { + ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "", "")) + return + } + + ErrorJSON(w, r, err) + return + } + + input := domain.UpdatePolicyTemplateRequest{} + + err = UnmarshalRequestInput(r, &input) + + if err != nil { + log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) + ErrorJSON(w, r, err) + return + } + + err = h.usecase.Update(r.Context(), id, input) + + if err != nil { + log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) + if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound { + ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "", "")) + return + } + + ErrorJSON(w, r, err) + return + } + + ResponseJSON(w, r, http.StatusOK, "") +} + +// DeletePolicyTemplate godoc +// +// @Tags PolicyTemplate +// @Summary [DeletePolicyTemplate] 정책 템플릿 삭제 +// @Description 정책 템플릿을 삭제한다. +// @Accept json +// @Produce json +// @Param policyTemplateId path string true "정책 템플릿 식별자(uuid)" +// @Success 200 {object} nil +// @Router /api/1.0/admin/policytemplates/{policyTemplateId} [delete] +// @Security JWT +func (h *PolicyTemplateHandler) DeletePolicyTemplate(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + policyTemplateId, ok := vars["policyTemplateId"] + if !ok { + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("Invalid policyTemplateId"), "C_INVALID_POLICY_TEMPLATE_ID", "")) + return + } + + id, err := uuid.Parse(policyTemplateId) + if err != nil { + log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) + if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound { + ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "", "")) + return + } + + ErrorJSON(w, r, err) + return + } + + err = h.usecase.Delete(r.Context(), id) + + if err != nil { + log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) + if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound { + ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "", "")) + return + } + + ErrorJSON(w, r, err) + return + } + + ResponseJSON(w, r, http.StatusOK, "") +} + +// GetPolicyTemplate godoc +// +// @Tags PolicyTemplate +// @Summary [GetPolicyTemplate] 정책 템플릿 조회(최신 버전) +// @Description 해당 식별자를 가진 정책 템플릿의 최신 버전을 조회한다. +// @Accept json +// @Produce json +// @Param policyTemplateId path string true "정책 템플릿 식별자(uuid)" +// @Success 200 {object} domain.GetPolicyTemplateResponse +// @Router /api/1.0/admin/policytemplates/{policyTemplateId} [get] +// @Security JWT +func (h *PolicyTemplateHandler) GetPolicyTemplate(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + policyTemplateId, ok := vars["policyTemplateId"] + if !ok { + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("Invalid policyTemplateId"), "C_INVALID_ORGANIZATION_ID", "")) + return + } + + id, err := uuid.Parse(policyTemplateId) + if err != nil { + log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) + if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound { + ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "", "")) + return + } + + ErrorJSON(w, r, err) + return + } + + policyTemplate, err := h.usecase.Get(r.Context(), id) + if err != nil { + log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) + if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound { + ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "", "")) + return + } + + ErrorJSON(w, r, err) + return + } + + var out domain.GetPolicyTemplateResponse + if err = serializer.Map(*policyTemplate, &out.PolicyTemplate); err != nil { + log.ErrorWithContext(r.Context(), err) + } + + ResponseJSON(w, r, http.StatusOK, out) +} + +// ListPolicyTemplate godoc +// +// @Tags PolicyTemplate +// @Summary [ListPolicyTemplate] 정책 템플릿 목록 조회 +// @Description 정책 템플릿 목록을 조회한다. 정책 템플릿 목록 조회 결과는 최신 템플릿 버전 목록만 조회된다. +// @Accept json +// @Produce json +// @Param limit query string false "pageSize" +// @Param page query string false "pageNumber" +// @Param soertColumn query string false "sortColumn" +// @Param sortOrder query string false "sortOrder" +// @Param filters query []string false "filters" +// @Success 200 {object} domain.ListPolicyTemplateResponse +// @Router /api/1.0/admin/policytemplates [get] +// @Security JWT +func (h *PolicyTemplateHandler) ListPolicyTemplate(w http.ResponseWriter, r *http.Request) { + urlParams := r.URL.Query() + + pg := pagination.NewPagination(&urlParams) + + policyTemplates, err := h.usecase.Fetch(r.Context(), pg) + if err != nil { + ErrorJSON(w, r, err) + return + } + + var out domain.ListPolicyTemplateResponse + out.PolicyTemplates = make([]domain.PolicyTemplateResponse, len(policyTemplates)) + for i, policyTemplate := range policyTemplates { + if err := serializer.Map(policyTemplate, &out.PolicyTemplates[i]); err != nil { + log.InfoWithContext(r.Context(), err) + continue + } + } + + if out.Pagination, err = pg.Response(); err != nil { + log.InfoWithContext(r.Context(), err) + } + + ResponseJSON(w, r, http.StatusOK, out) +} + +// ListPolicyTemplateVersions godoc +// +// @Tags PolicyTemplate +// @Summary [ListPolicyTemplateVersions] 정책 템플릿 버전목록 조회 +// @Description 해당 식별자를 가진 정책 템플릿의 최신 버전을 조회한다. +// @Accept json +// @Produce json +// @Param policyTemplateId path string true "정책 템플릿 식별자(uuid)" +// @Success 200 {object} domain.ListPolicyTemplateVersionsResponse +// @Router /api/1.0/admin/policytemplates/{policyTemplateId}/versions [get] +// @Security JWT +func (h *PolicyTemplateHandler) ListPolicyTemplateVersions(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + + policyTemplateId, ok := vars["policyTemplateId"] + if !ok { + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("Invalid policyTemplateId"), "C_INVALID_ORGANIZATION_ID", "")) + return + } + + id, err := uuid.Parse(policyTemplateId) + if err != nil { + log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) + if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound { + ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "", "")) + return + } + + ErrorJSON(w, r, err) + return + } + + policyTemplateVersions, err := h.usecase.ListPolicyTemplateVersions(r.Context(), id) + + if err != nil { + log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) + if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound { + ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "", "")) + return + } + + ErrorJSON(w, r, err) + return + } + + var out domain.ListPolicyTemplateVersionsResponse + if err = serializer.Map(*policyTemplateVersions, &out); err != nil { + log.ErrorWithContext(r.Context(), err) + } + + ResponseJSON(w, r, http.StatusOK, out) +} + +// ListPolicyTemplateStatistics godoc +// +// @Tags PolicyTemplate +// @Summary [ListPolicyTemplateStatistics] 정책 템플릿 사용 카운트 조회 +// @Description 해당 식별자를 가진 정책 템플릿의 최신 버전을 조회한다. 전체 조직의 통계를 조회하려면 organizationId를 tks로 설정한다. +// @Accept json +// @Produce json +// @Param policyTemplateId path string true "정책 템플릿 식별자(uuid)" +// @Success 200 {object} domain.ListPolicyTemplateStatisticsResponse +// @Router /api/1.0/admin/policytemplates/{policyTemplateId}/statistics [get] +// @Security JWT +func (h *PolicyTemplateHandler) ListPolicyTemplateStatistics(w http.ResponseWriter, r *http.Request) { + // result := domain.ListPolicyTemplateStatisticsResponse{ + // PolicyTemplateStatistics: []domain.PolicyTemplateStatistics{ + // { + // OrganizationId: util.UUIDGen(), + // OrganizationName: "개발팀", + // UsageCount: 10, + // }, + // { + // OrganizationId: util.UUIDGen(), + // OrganizationName: "운영팀", + // UsageCount: 5, + // }, + // }, + // } + // util.JsonResponse(w, result) +} + +// GetPolicyTemplateDeploy godoc +// +// @Tags PolicyTemplate +// @Summary [GetPolicyTemplateDeploy] 정책 템플릿 클러스터 별 설치 버전 조회 +// @Description 해당 식별자를 가진 정책 템플릿의 정책 템플릿 클러스터 별 설치 버전을 조회한다. +// @Accept json +// @Produce json +// @Param policyTemplateId path string true "정책 템플릿 식별자(uuid)" +// @Success 200 {object} domain.GetPolicyTemplateDeployResponse +// @Router /api/1.0/admin/policytemplates/{policyTemplateId}/deploy [get] +// @Security JWT +func (h *PolicyTemplateHandler) GetPolicyTemplateDeploy(w http.ResponseWriter, r *http.Request) { + // c1 := util.UUIDGen() + // c2 := util.UUIDGen() + // c3 := util.UUIDGen() + + // result := domain.GetPolicyTemplateDeployResponse{ + // DeployVersion: map[string]string{ + // c1: "v1.0.1", + // c2: "v1.1.0", + // c3: "v1.1.0", + // }, + // } + // util.JsonResponse(w, result) +} + +// GetPolicyTemplateVersion godoc +// +// @Tags PolicyTemplate +// @Summary [GetPolicyTemplateVersion] 정책 템플릿 특정 버전 조회 +// @Description 해당 식별자를 가진 정책 템플릿의 특정 버전을 조회한다. +// @Accept json +// @Produce json +// @Param policyTemplateId path string true "정책 템플릿 식별자(uuid)" +// @Param version path string true "조회할 버전(v0.0.0 형식)" +// @Success 200 {object} domain.GetPolicyTemplateVersionResponse +// @Router /api/1.0/admin/policytemplates/{policyTemplateId}/versions/{version} [get] +// @Security JWT +func (h *PolicyTemplateHandler) GetPolicyTemplateVersion(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + policyTemplateId, ok := vars["policyTemplateId"] + if !ok { + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("Invalid policyTemplateId"), "C_INVALID_ORGANIZATION_ID", "")) + return + } + + version, ok := vars["version"] + if !ok { + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("Invalid version"), "C_INVALID_ORGANIZATION_ID", "")) + return + } + + id, err := uuid.Parse(policyTemplateId) + if err != nil { + log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) + if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound { + ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "", "")) + return + } + + ErrorJSON(w, r, err) + return + } + + policyTemplate, err := h.usecase.GetPolicyTemplateVersion(r.Context(), id, version) + if err != nil { + log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) + if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound { + ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "", "")) + return + } + + ErrorJSON(w, r, err) + return + } + + var out domain.GetPolicyTemplateVersionResponse + if err = serializer.Map(*policyTemplate, &out.PolicyTemplate); err != nil { + log.ErrorWithContext(r.Context(), err) + } + + ResponseJSON(w, r, http.StatusOK, out) +} + +// CreatePolicyTemplateVersion godoc +// +// @Tags PolicyTemplate +// @Summary [CreatePolicyTemplateVersion] 정책 템플릿 특정 버전 저장 +// @Description 해당 식별자를 가진 정책 템플릿의 특정 버전을 저장한다. +// @Accept json +// @Produce json +// @Param policyTemplateId path string true "정책 템플릿 식별자(uuid)" +// @Param body body domain.CreatePolicyTemplateVersionRequest true "create policy template version request" +// @Success 200 {object} domain.CreatePolicyTemplateVersionResponse +// @Router /api/1.0/admin/policytemplates/{policyTemplateId}/versions [post] +// @Security JWT +func (h *PolicyTemplateHandler) CreatePolicyTemplateVersion(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + policyTemplateId, ok := vars["policyTemplateId"] + if !ok { + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("Invalid policyTemplateId"), "C_INVALID_POLICY_TEMPLATE_ID", "")) + return + } + + id, err := uuid.Parse(policyTemplateId) + if err != nil { + log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) + if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound { + ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "", "")) + return + } + + ErrorJSON(w, r, err) + return + } + + input := domain.CreatePolicyTemplateVersionRequest{} + + err = UnmarshalRequestInput(r, &input) + + if err != nil { + log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) + ErrorJSON(w, r, err) + return + } + + currentVer, err := semver.NewVersion(input.CurrentVersion) + if err != nil { + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("Invalid currentVersion"), "C_INVALID_CURRENT_VERSION", fmt.Sprintf("invalid version format '%s'", input.CurrentVersion))) + return + } + + versionUpType := strings.ToLower(input.VersionUpType) + + var expectedVersion string + + switch versionUpType { + case "major": + newVersion := currentVer.IncMajor() + expectedVersion = newVersion.Original() + case "minor": + newVersion := currentVer.IncMinor() + expectedVersion = newVersion.Original() + case "patch": + newVersion := currentVer.IncPatch() + expectedVersion = newVersion.Original() + } + + if expectedVersion != input.ExpectedVersion { + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("Invalid expectedVersion"), "C_INVALID_EXPECTED_VERSION", fmt.Sprintf("expected version mismatch '%s' != '%s'", + input.ExpectedVersion, expectedVersion))) + } + + createdVersion, err := h.usecase.CreatePolicyTemplateVersion(r.Context(), id, expectedVersion, input.ParametersSchema, input.Rego, input.Libs) + + if err != nil { + ErrorJSON(w, r, err) + return + } + + var out domain.CreatePolicyTemplateVersionResponse + out.Version = createdVersion + + ResponseJSON(w, r, http.StatusOK, out) +} + +// DeletePolicyTemplateVersion godoc +// +// @Tags PolicyTemplate +// @Summary [DeletePolicyTemplateVersion] 정책 템플릿 특정 버전 삭제 +// @Description 해당 식별자를 가진 정책 템플릿의 특정 버전을 삭제한다. +// @Accept json +// @Produce json +// @Param policyTemplateId path string true "정책 템플릿 식별자(uuid)" +// @Param version path string true "삭제할 버전(v0.0.0 형식)" +// @Success 200 {object} nil +// @Router /api/1.0/admin/policytemplates/{policyTemplateId}/versions/{version} [delete] +// @Security JWT +func (h *PolicyTemplateHandler) DeletePolicyTemplateVersion(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + policyTemplateId, ok := vars["policyTemplateId"] + if !ok { + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("Invalid policyTemplateId"), "C_INVALID_POLICY_TEMPLATE_ID", "")) + return + } + + version, ok := vars["version"] + if !ok { + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("Invalid version"), "C_INVALID_VERSION", "")) + return + } + + id, err := uuid.Parse(policyTemplateId) + if err != nil { + log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) + if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound { + ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "", "")) + return + } + + ErrorJSON(w, r, err) + return + } + + err = h.usecase.DeletePolicyTemplateVersion(r.Context(), id, version) + + if err != nil { + log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) + if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound { + ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "", "")) + return + } + + ErrorJSON(w, r, err) + return + } + + ResponseJSON(w, r, http.StatusOK, "") +} + +// ExistsPolicyTemplateName godoc +// +// @Tags PolicyTemplate +// @Summary [ExistsPolicyTemplateName] 정책 템플릿 아름 존재 여부 확인 +// @Description 해당 이름을 가진 정책 템플릿이 이미 존재하는지 확인한다. +// @Accept json +// @Produce json +// @Param policyTemplateName path string true "정책 템플릿 이름" +// @Success 200 {object} domain.CheckExistedResponse +// @Router /api/1.0/admin/policytemplates/name/{policyTemplateName}/existence [get] +// @Security JWT +func (h *PolicyTemplateHandler) ExistsPolicyTemplateName(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + policyTemplateName, ok := vars["policyTemplateName"] + if !ok { + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("policyTemplateName not found in path"), + "C_INVALID_POLICYTEMPLATE_NAME", "")) + return + } + + exist, err := h.usecase.IsPolicyTemplateNameExist(r.Context(), policyTemplateName) + if err != nil { + ErrorJSON(w, r, err) + return + } + + var out domain.CheckExistedResponse + out.Existed = exist + + ResponseJSON(w, r, http.StatusOK, out) +} + +// ExistsPolicyTemplateKind godoc +// +// @Tags PolicyTemplate +// @Summary [ExistsPolicyTemplateKind] 정책 템플릿 유형 존재 여부 확인 +// @Description 해당 유형을 가진 정책 템플릿이 이미 존재하는지 확인한다. +// @Accept json +// @Produce json +// @Param policyTemplateKind path string true "정책 템플릿 이름" +// @Success 200 {object} domain.ExistsPolicyTemplateKindResponse +// @Router /api/1.0/admin/policytemplates/kind/{policyTemplateKind}/existence [get] +// @Security JWT +func (h *PolicyTemplateHandler) ExistsPolicyTemplateKind(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + policyTemplateKind, ok := vars["policyTemplateKind"] + if !ok { + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("policyTemplateKind not found in path"), + "C_INVALID_POLICY_TEMPLATE_KIND", "")) + return + } + + exist, err := h.usecase.IsPolicyTemplateKindExist(r.Context(), policyTemplateKind) + if err != nil { + ErrorJSON(w, r, err) + return + } + + var out domain.CheckExistedResponse + out.Existed = exist + + ResponseJSON(w, r, http.StatusOK, out) +} diff --git a/internal/delivery/http/utility.go b/internal/delivery/http/utility.go new file mode 100644 index 00000000..f22d18fc --- /dev/null +++ b/internal/delivery/http/utility.go @@ -0,0 +1,73 @@ +package http + +import ( + "fmt" + "net/http" + "strconv" + + "github.com/gorilla/mux" + "github.com/openinfradev/tks-api/internal/usecase" + "github.com/openinfradev/tks-api/pkg/domain" + "github.com/openinfradev/tks-api/pkg/httpErrors" + "github.com/openinfradev/tks-api/pkg/log" +) + +type UtilityHandler struct { + usecase usecase.IUtilityUsecase +} + +type IUtilityHandler interface { + RegoCompile(w http.ResponseWriter, r *http.Request) +} + +func NewUtilityHandler(u usecase.Usecase) IUtilityHandler { + return &UtilityHandler{ + usecase: u.Utility, + } +} + +// CompileRego godoc +// +// @Tags Rego +// @Summary [CompileRego] Rego 코드 컴파일 및 파라미터 파싱 +// @Description Rego 코드 컴파일 및 파라미터 파싱을 수행한다. 파라미터 파싱을 위해서는 먼저 컴파일이 성공해야 하며, parseParameter를 false로 하면 컴파일만 수행할 수 있다. +// @Accept json +// @Produce json +// @Param parseParameter query bool true "파라미터 파싱 여부" +// @Param body body domain.RegoCompileRequest true "Rego 코드" +// @Success 200 {object} domain.RegoCompileResponse +// @Router /utility/rego-compile [post] +// @Security JWT +func (h *UtilityHandler) RegoCompile(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + parseParameter := false + + parse, ok := vars["parseParameter"] + if ok { + parsedBool, err := strconv.ParseBool(parse) + if err != nil { + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("invalid parseParameter: '%s'", parse), "U_INVALID_REGO_PARSEPARAM", "")) + return + } + parseParameter = parsedBool + } + + input := domain.RegoCompileRequest{} + err := UnmarshalRequestInput(r, &input) + if err != nil { + log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) + + ErrorJSON(w, r, err) + return + } + + response, err := h.usecase.RegoCompile(&input, parseParameter) + if err != nil { + log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) + + ErrorJSON(w, r, err) + return + } + + ResponseJSON(w, r, http.StatusCreated, response) +} diff --git a/internal/repository/policy-template.go b/internal/repository/policy-template.go new file mode 100644 index 00000000..bc12f8fe --- /dev/null +++ b/internal/repository/policy-template.go @@ -0,0 +1,553 @@ +package repository + +import ( + "encoding/json" + "fmt" + "strings" + + "github.com/google/uuid" + "github.com/openinfradev/tks-api/internal/pagination" + "github.com/openinfradev/tks-api/internal/serializer" + "github.com/openinfradev/tks-api/pkg/domain" + "github.com/openinfradev/tks-api/pkg/log" + "github.com/pkg/errors" + "gorm.io/gorm" + "gorm.io/gorm/clause" +) + +type IPolicyTemplateRepository interface { + Create(dto domain.PolicyTemplate) (policyTemplateId uuid.UUID, err error) + Update(dto domain.UpdatePolicyTemplateUpdate) (err error) + Fetch(pg *pagination.Pagination) (out []domain.PolicyTemplate, err error) + GetByName(policyTemplateName string) (out *domain.PolicyTemplate, err error) + GetByKind(policyTemplateKind string) (out *domain.PolicyTemplate, err error) + GetByID(policyTemplateId uuid.UUID) (out *domain.PolicyTemplate, err error) + Delete(policyTemplateId uuid.UUID) (err error) + ExistByName(policyTemplateName string) (exist bool, err error) + ExistByKind(policyTemplateKind string) (exist bool, err error) + ExistByID(policyTemplateId uuid.UUID) (exist bool, err error) + ListPolicyTemplateVersions(policyTemplateId uuid.UUID) (policyTemplateVersionsReponse *domain.ListPolicyTemplateVersionsResponse, err error) + GetPolicyTemplateVersion(policyTemplateId uuid.UUID, version string) (policyTemplateVersionsReponse *domain.PolicyTemplate, err error) + DeletePolicyTemplateVersion(policyTemplateId uuid.UUID, version string) (err error) + CreatePolicyTemplateVersion(policyTemplateId uuid.UUID, newVersion string, schema []domain.ParameterDef, rego string, libs []string) (version string, err error) +} + +type PolicyTemplateRepository struct { + db *gorm.DB +} + +func NewPolicyTemplateRepository(db *gorm.DB) IPolicyTemplateRepository { + return &PolicyTemplateRepository{ + db: db, + } +} + +type PolicyTemplateSupportedVersion struct { + gorm.Model + + PolicyTemplateId uuid.UUID `gorm:"index:template_version,unique"` + Version string `gorm:"index:template_version,unique"` + + ParameterSchema string `gorm:"type:text"` + Rego string `gorm:"type:text"` + Libs string `gorm:"type:text"` +} + +type PolicyTemplate struct { + gorm.Model + + ID uuid.UUID `gorm:"primarykey;type:varchar(36);not null"` + Type string // Org or Tks + Name string + Version string + SupportedVersions []PolicyTemplateSupportedVersion `gorm:"foreignKey:PolicyTemplateId"` + Description string + Kind string + Deprecated bool + Mandatory bool // Tks 인 경우에는 무시 + Severity string + PermittedOrganizations []domain.Organization `gorm:"many2many:policy_template_permitted_organiations;"` + CreatorId *uuid.UUID `gorm:"type:uuid"` + Creator domain.User `gorm:"foreignKey:CreatorId"` + UpdatorId *uuid.UUID `gorm:"type:uuid"` + Updator domain.User `gorm:"foreignKey:UpdatorId"` +} + +func (c *PolicyTemplate) BeforeCreate(tx *gorm.DB) (err error) { + c.ID = uuid.New() + return nil +} + +func (r *PolicyTemplateRepository) Create(dto domain.PolicyTemplate) (policyTemplateId uuid.UUID, err error) { + jsonByte, err := json.Marshal(dto.ParametersSchema) + + if err != nil { + return uuid.Nil, err + } + + policyTemplate := PolicyTemplate{ + Type: "tks", + Name: dto.TemplateName, + Version: "v1.0.0", + SupportedVersions: []PolicyTemplateSupportedVersion{ + { + Version: "v1.0.0", + ParameterSchema: string(jsonByte), + Rego: dto.Rego, + }, + }, + Description: dto.Description, + Kind: dto.Kind, + Deprecated: false, + Mandatory: false, // Tks 인 경우에는 무시 + Severity: dto.Severity, + } + + err = r.db.Transaction(func(tx *gorm.DB) error { + err := tx.Create(&policyTemplate).Error + + if err != nil { + return err + } + + if dto.PermittedOrganizationIds != nil { + permittedOrganizations := make([]domain.Organization, len(dto.PermittedOrganizationIds)) + for i, permittedOrganizationId := range dto.PermittedOrganizationIds { + permittedOrganizations[i] = domain.Organization{ID: permittedOrganizationId} + } + + err = tx.Model(&policyTemplate).Association("PermittedOrganizations").Replace(permittedOrganizations) + + if err != nil { + return err + } + } + + return nil + }) + + if err != nil { + return uuid.Nil, err + } + + return policyTemplate.ID, nil +} + +func (r *PolicyTemplateRepository) Update(dto domain.UpdatePolicyTemplateUpdate) (err error) { + updateMap := make(map[string]interface{}) + + updateMap["updator_id"] = dto.UpdatorId + + if dto.Description != nil { + updateMap["description"] = dto.Description + } + + if dto.Deprecated != nil { + updateMap["deprecated"] = dto.Deprecated + } + + if dto.Severity != nil { + updateMap["severity"] = dto.Severity + } + + if dto.TemplateName != nil { + updateMap["name"] = dto.TemplateName + } + + fmt.Printf("--updateMap=%+v\n--", updateMap) + + var policyTemplate PolicyTemplate + policyTemplate.ID = dto.ID + + return r.db.Transaction(func(tx *gorm.DB) error { + if dto.PermittedOrganizationIds != nil { + permittedOrganizations := make([]domain.Organization, len(*dto.PermittedOrganizationIds)) + for i, permittedOrganizationId := range *dto.PermittedOrganizationIds { + permittedOrganizations[i] = domain.Organization{ID: permittedOrganizationId} + } + + err = r.db.Model(&policyTemplate).Limit(1). + Association("PermittedOrganizations").Replace(permittedOrganizations) + + if err != nil { + return err + } + } + + if len(updateMap) > 0 { + err = r.db.Model(&policyTemplate).Limit(1). + Where("id = ? and type = 'tks'", dto.ID). + Updates(updateMap).Error + + if err != nil { + return err + } + } + + // return nil will commit the whole transaction + return nil + }) +} + +func (r *PolicyTemplateRepository) Fetch(pg *pagination.Pagination) (out []domain.PolicyTemplate, err error) { + var policyTemplates []PolicyTemplate + if pg == nil { + pg = pagination.NewPagination(nil) + } + + _, res := pg.Fetch(r.db.Preload(clause.Associations).Model(&PolicyTemplate{}). + Where("type = 'tks'"), &policyTemplates) + if res.Error != nil { + return nil, res.Error + } + + for _, policyTemplate := range policyTemplates { + var policyTemplateVersion PolicyTemplateSupportedVersion + res = r.db. + Where("policy_template_id = ? and version = ?", policyTemplate.ID, policyTemplate.Version). + First(&policyTemplateVersion) + + if res.Error != nil { + if errors.Is(res.Error, gorm.ErrRecordNotFound) { + log.Info("Not found policyTemplate version") + } else { + log.Error(res.Error) + } + } + + outPolicyTemplate := r.reflectPolicyTemplate(policyTemplate, policyTemplateVersion) + out = append(out, outPolicyTemplate) + } + return out, nil +} + +func (r *PolicyTemplateRepository) reflectPolicyTemplate(policyTemplate PolicyTemplate, policyTemplateVersion PolicyTemplateSupportedVersion) (out domain.PolicyTemplate) { + if err := serializer.Map(policyTemplate.Model, &out); err != nil { + log.Error(err) + } + if err := serializer.Map(policyTemplate, &out); err != nil { + log.Error(err) + } + out.TemplateName = policyTemplate.Name + out.ID = domain.PolicyTemplateId(policyTemplate.ID.String()) + + var schemas []domain.ParameterDef + + if len(policyTemplateVersion.ParameterSchema) > 0 { + if err := json.Unmarshal([]byte(policyTemplateVersion.ParameterSchema), &schemas); err != nil { + log.Error(err) + } else { + out.ParametersSchema = schemas + } + } + + out.PermittedOrganizations = make([]domain.PermittedOrganization, len(policyTemplate.PermittedOrganizations)) + for i, org := range policyTemplate.PermittedOrganizations { + out.PermittedOrganizations[i] = domain.PermittedOrganization{ + OrganizationId: org.ID, + OrganizationName: org.Name, + Permitted: true, + } + } + + out.Rego = policyTemplateVersion.Rego + out.Libs = strings.Split(policyTemplateVersion.Libs, "---\n") + + return +} + +func (r *PolicyTemplateRepository) ExistsBy(key string, value interface{}) (exists bool, err error) { + query := fmt.Sprintf("%s = ?", key) + + var policyTemplate PolicyTemplate + res := r.db.Where(query, value). + First(&policyTemplate) + + if res.Error != nil { + if errors.Is(res.Error, gorm.ErrRecordNotFound) { + log.Infof("Not found policyTemplate %s='%v'", key, value) + return false, nil + } else { + log.Error(res.Error) + return false, res.Error + } + } + + return true, nil +} + +func (r *PolicyTemplateRepository) ExistByName(policyTemplateName string) (exist bool, err error) { + return r.ExistsBy("name", policyTemplateName) +} + +func (r *PolicyTemplateRepository) ExistByKind(policyTemplateKind string) (exist bool, err error) { + return r.ExistsBy("kind", policyTemplateKind) +} + +func (r *PolicyTemplateRepository) ExistByID(policyTemplateId uuid.UUID) (exist bool, err error) { + return r.ExistsBy("id", policyTemplateId) +} + +func (r *PolicyTemplateRepository) GetBy(key string, value interface{}) (out *domain.PolicyTemplate, err error) { + query := fmt.Sprintf("%s = ?", key) + + var policyTemplate PolicyTemplate + res := r.db.Preload(clause.Associations).Where(query, value). + First(&policyTemplate) + + if res.Error != nil { + if errors.Is(res.Error, gorm.ErrRecordNotFound) { + log.Infof("Not found policyTemplate %s='%v'", key, value) + return nil, nil + } else { + log.Error(res.Error) + return nil, res.Error + } + } + + var policyTemplateVersion PolicyTemplateSupportedVersion + res = r.db.Limit(1). + Where("policy_template_id = ? and version = ?", policyTemplate.ID, policyTemplate.Version). + First(&policyTemplateVersion) + if res.Error != nil { + if errors.Is(res.Error, gorm.ErrRecordNotFound) { + log.Info("Not found policyTemplate version") + return nil, nil + } else { + log.Error(res.Error) + return nil, res.Error + } + } + + fmt.Printf("BBBB %+v\n", policyTemplate.PermittedOrganizations) + + result := r.reflectPolicyTemplate(policyTemplate, policyTemplateVersion) + fmt.Printf("2222BBBB %+v\n", result.PermittedOrganizations) + + return &result, nil +} + +func (r *PolicyTemplateRepository) GetByID(policyTemplateId uuid.UUID) (out *domain.PolicyTemplate, err error) { + return r.GetBy("id", policyTemplateId) + + // var policyTemplate PolicyTemplate + // res := r.db.Preload(clause.Associations).Where("id = ?", policyTemplateId). + // First(&policyTemplate) + + // if res.Error != nil { + // if errors.Is(res.Error, gorm.ErrRecordNotFound) { + // log.Info("Not found policyTemplate id") + // return nil, nil + // } else { + // log.Error(res.Error) + // return nil, res.Error + // } + // } + + // result := r.reflect(policyTemplate) + + // return &result, nil +} + +func (r *PolicyTemplateRepository) GetByName(policyTemplateName string) (out *domain.PolicyTemplate, err error) { + return r.GetBy("name", policyTemplateName) + + // var policyTemplate PolicyTemplate + // res := r.db.Limit(1). + // Where("name = ?", policyTemplateName). + // First(&policyTemplate) + // if res.Error != nil { + // if errors.Is(res.Error, gorm.ErrRecordNotFound) { + // log.Info("Not found policyTemplate name") + // return nil, nil + // } else { + // log.Error(res.Error) + // return nil, res.Error + // } + // } + + // result := r.reflect(policyTemplate) + + // return &result, nil +} + +func (r *PolicyTemplateRepository) GetByKind(policyTemplateKind string) (out *domain.PolicyTemplate, err error) { + return r.GetBy("kind", policyTemplateKind) +} + +func (r *PolicyTemplateRepository) Delete(policyTemplateId uuid.UUID) (err error) { + return r.db.Transaction(func(tx *gorm.DB) error { + if err := tx.Where("policy_template_id = ?", policyTemplateId).Delete(&PolicyTemplateSupportedVersion{}).Error; err != nil { + return err + } + + if err := tx.Model(&PolicyTemplate{ID: policyTemplateId}).Association("PermittedOrganizations").Clear(); err != nil { + return err + } + + if err := tx.Where("id = ?", policyTemplateId).Delete(&PolicyTemplate{}).Error; err != nil { + return err + } + + return nil + }) +} + +func (r *PolicyTemplateRepository) ListPolicyTemplateVersions(policyTemplateId uuid.UUID) (policyTemplateVersionsReponse *domain.ListPolicyTemplateVersionsResponse, err error) { + var supportedVersions []PolicyTemplateSupportedVersion + res := r.db.Where("policy_template_id = ?", policyTemplateId).Find(&supportedVersions) + + if res.Error != nil { + if errors.Is(res.Error, gorm.ErrRecordNotFound) { + log.Info("Not found policyTemplate kind") + return nil, nil + } else { + log.Error(res.Error) + return nil, res.Error + } + } + + versions := make([]string, len(supportedVersions)) + + for i, supportedVersion := range supportedVersions { + versions[i] = supportedVersion.Version + } + + result := &domain.ListPolicyTemplateVersionsResponse{ + Versions: versions, + } + + return result, nil +} + +func (r *PolicyTemplateRepository) GetPolicyTemplateVersion(policyTemplateId uuid.UUID, version string) (policyTemplateVersionsReponse *domain.PolicyTemplate, err error) { + var policyTemplateVersion PolicyTemplateSupportedVersion + res := r.db. + Where("policy_template_id = ? and version = ?", policyTemplateId, version). + First(&policyTemplateVersion) + if res.Error != nil { + if errors.Is(res.Error, gorm.ErrRecordNotFound) { + log.Info("Not found policyTemplate version") + return nil, nil + } else { + log.Error(res.Error) + return nil, res.Error + } + } + + var policyTemplate PolicyTemplate + res = r.db. + Where("id = ?", policyTemplateId). + First(&policyTemplate) + if res.Error != nil { + if errors.Is(res.Error, gorm.ErrRecordNotFound) { + log.Info("Not found policyTemplate id") + return nil, nil + } else { + log.Error(res.Error) + return nil, res.Error + } + } + + result := r.reflectPolicyTemplate(policyTemplate, policyTemplateVersion) + + return &result, nil +} + +func (r *PolicyTemplateRepository) DeletePolicyTemplateVersion(policyTemplateId uuid.UUID, version string) (err error) { + var policyTemplate PolicyTemplate + res := r.db.Select("version").First(&policyTemplate) + + if res.Error != nil { + if errors.Is(res.Error, gorm.ErrRecordNotFound) { + log.Info("Not found policyTemplate id") + return nil + } else { + log.Error(res.Error) + return res.Error + } + } + + // 현재 버전이 템플릿에서 최신 버전으로 사용 중이면 삭제 금지 + if policyTemplate.Version == version { + return fmt.Errorf("version '%s' is currently in use", version) + } + + // TODO: Operator에 현재 버전 사용중인 정책이 있는지 체크 필요 + + var policyTemplateVersion PolicyTemplateSupportedVersion + res = r.db.Where("policy_template_id = ? and version = ?", policyTemplateId, version). + Delete(&policyTemplateVersion) + if res.Error != nil { + if errors.Is(res.Error, gorm.ErrRecordNotFound) { + log.Info("Not found policyTemplate version") + return nil + } else { + log.Error(res.Error) + return res.Error + } + } + + return nil +} + +func (r *PolicyTemplateRepository) CreatePolicyTemplateVersion(policyTemplateId uuid.UUID, newVersion string, schema []domain.ParameterDef, rego string, libs []string) (version string, err error) { + var policyTemplateVersion PolicyTemplateSupportedVersion + res := r.db.Limit(1). + Where("policy_template_id = ? and version = ?", policyTemplateId, version). + First(&policyTemplateVersion) + + if res.Error == nil { + err = errors.Errorf("Version %s already exists for the policyTemplate", newVersion) + + log.Error(res.Error) + + return "", err + } + + if !errors.Is(res.Error, gorm.ErrRecordNotFound) { + log.Error(res.Error) + return "", res.Error + } + + libsString := "" + if len(libs) > 0 { + libsString = strings.Join(libs, "---\n") + } + + jsonBytes, err := json.Marshal(schema) + + if err != nil { + parseErr := errors.Errorf("Unable to parse parameter schema: %v", err) + + log.Error(parseErr) + + return "", parseErr + } + + newPolicyTemplateVersion := &PolicyTemplateSupportedVersion{ + PolicyTemplateId: policyTemplateId, + Version: newVersion, + Rego: rego, + Libs: libsString, + ParameterSchema: string(jsonBytes), + } + + err = r.db.Transaction(func(tx *gorm.DB) error { + if err := tx.Create(newPolicyTemplateVersion).Error; err != nil { + return err + } + + if err := tx.Model(&PolicyTemplate{}).Where("id = ?", policyTemplateId).Update("version", newVersion).Error; err != nil { + return err + } + + return nil + }) + + if err != nil { + return "", err + } + + return newVersion, nil +} diff --git a/internal/repository/repository.go b/internal/repository/repository.go index 46138c9d..7190cf18 100644 --- a/internal/repository/repository.go +++ b/internal/repository/repository.go @@ -12,20 +12,21 @@ import ( type FilterFunc func(user *gorm.DB) *gorm.DB type Repository struct { - Auth IAuthRepository - User IUserRepository - Cluster IClusterRepository - Organization IOrganizationRepository - AppGroup IAppGroupRepository - AppServeApp IAppServeAppRepository - CloudAccount ICloudAccountRepository - StackTemplate IStackTemplateRepository - Alert IAlertRepository - Role IRoleRepository - Permission IPermissionRepository - Endpoint IEndpointRepository - Project IProjectRepository - Audit IAuditRepository + Auth IAuthRepository + User IUserRepository + Cluster IClusterRepository + Organization IOrganizationRepository + AppGroup IAppGroupRepository + AppServeApp IAppServeAppRepository + CloudAccount ICloudAccountRepository + StackTemplate IStackTemplateRepository + Alert IAlertRepository + Role IRoleRepository + Permission IPermissionRepository + Endpoint IEndpointRepository + Project IProjectRepository + Audit IAuditRepository + PolicyTemplate IPolicyTemplateRepository } func CombinedGormFilter(table string, filters []pagination.Filter, combinedFilter pagination.CombinedFilter) FilterFunc { diff --git a/internal/route/route.go b/internal/route/route.go index 98dce40b..76106a23 100644 --- a/internal/route/route.go +++ b/internal/route/route.go @@ -41,38 +41,41 @@ func SetupRouter(db *gorm.DB, argoClient argowf.ArgoClient, kc keycloak.IKeycloa cache := gcache.New(5*time.Minute, 10*time.Minute) repoFactory := repository.Repository{ - Auth: repository.NewAuthRepository(db), - User: repository.NewUserRepository(db), - Cluster: repository.NewClusterRepository(db), - Organization: repository.NewOrganizationRepository(db), - AppGroup: repository.NewAppGroupRepository(db), - AppServeApp: repository.NewAppServeAppRepository(db), - CloudAccount: repository.NewCloudAccountRepository(db), - StackTemplate: repository.NewStackTemplateRepository(db), - Alert: repository.NewAlertRepository(db), - Role: repository.NewRoleRepository(db), - Project: repository.NewProjectRepository(db), - Permission: repository.NewPermissionRepository(db), - Endpoint: repository.NewEndpointRepository(db), - Audit: repository.NewAuditRepository(db), + Auth: repository.NewAuthRepository(db), + User: repository.NewUserRepository(db), + Cluster: repository.NewClusterRepository(db), + Organization: repository.NewOrganizationRepository(db), + AppGroup: repository.NewAppGroupRepository(db), + AppServeApp: repository.NewAppServeAppRepository(db), + CloudAccount: repository.NewCloudAccountRepository(db), + StackTemplate: repository.NewStackTemplateRepository(db), + Alert: repository.NewAlertRepository(db), + Role: repository.NewRoleRepository(db), + Project: repository.NewProjectRepository(db), + Permission: repository.NewPermissionRepository(db), + Endpoint: repository.NewEndpointRepository(db), + Audit: repository.NewAuditRepository(db), + PolicyTemplate: repository.NewPolicyTemplateRepository(db), } usecaseFactory := usecase.Usecase{ - Auth: usecase.NewAuthUsecase(repoFactory, kc), - User: usecase.NewUserUsecase(repoFactory, kc), - Cluster: usecase.NewClusterUsecase(repoFactory, argoClient, cache), - Organization: usecase.NewOrganizationUsecase(repoFactory, argoClient, kc), - AppGroup: usecase.NewAppGroupUsecase(repoFactory, argoClient), - AppServeApp: usecase.NewAppServeAppUsecase(repoFactory, argoClient), - CloudAccount: usecase.NewCloudAccountUsecase(repoFactory, argoClient), - StackTemplate: usecase.NewStackTemplateUsecase(repoFactory), - Dashboard: usecase.NewDashboardUsecase(repoFactory, cache), - Alert: usecase.NewAlertUsecase(repoFactory), - Stack: usecase.NewStackUsecase(repoFactory, argoClient, usecase.NewDashboardUsecase(repoFactory, cache)), - Project: usecase.NewProjectUsecase(repoFactory, kc, argoClient), - Audit: usecase.NewAuditUsecase(repoFactory), - Role: usecase.NewRoleUsecase(repoFactory), - Permission: usecase.NewPermissionUsecase(repoFactory), + Auth: usecase.NewAuthUsecase(repoFactory, kc), + User: usecase.NewUserUsecase(repoFactory, kc), + Cluster: usecase.NewClusterUsecase(repoFactory, argoClient, cache), + Organization: usecase.NewOrganizationUsecase(repoFactory, argoClient, kc), + AppGroup: usecase.NewAppGroupUsecase(repoFactory, argoClient), + AppServeApp: usecase.NewAppServeAppUsecase(repoFactory, argoClient), + CloudAccount: usecase.NewCloudAccountUsecase(repoFactory, argoClient), + StackTemplate: usecase.NewStackTemplateUsecase(repoFactory), + Dashboard: usecase.NewDashboardUsecase(repoFactory, cache), + Alert: usecase.NewAlertUsecase(repoFactory), + Stack: usecase.NewStackUsecase(repoFactory, argoClient, usecase.NewDashboardUsecase(repoFactory, cache)), + Project: usecase.NewProjectUsecase(repoFactory, kc, argoClient), + Audit: usecase.NewAuditUsecase(repoFactory), + Role: usecase.NewRoleUsecase(repoFactory), + Permission: usecase.NewPermissionUsecase(repoFactory), + PolicyTemplate: usecase.NewPolicyTemplateUsecase(repoFactory), + Utility: usecase.NewUtilityUsecase(repoFactory), } customMiddleware := internalMiddleware.NewMiddleware( @@ -264,6 +267,25 @@ func SetupRouter(db *gorm.DB, argoClient argowf.ArgoClient, kc keycloak.IKeycloa r.Handle(API_PREFIX+API_VERSION+"/organizations/{organizationId}/roles/{roleId}/permissions", customMiddleware.Handle(internalApi.UpdatePermissionsByRoleId, http.HandlerFunc(permissionHandler.UpdatePermissionsByRoleId))).Methods(http.MethodPut) r.HandleFunc(API_PREFIX+API_VERSION+"/alerttest", alertHandler.CreateAlert).Methods(http.MethodPost) + + policyTemplateHandler := delivery.NewPolicyTemplateHandler(usecaseFactory) + r.Handle(API_PREFIX+API_VERSION+ADMINAPI_PREFIX+"/policytemplates", customMiddleware.Handle(internalApi.ListPolicyTemplate, http.HandlerFunc(policyTemplateHandler.ListPolicyTemplate))).Methods(http.MethodGet) + r.Handle(API_PREFIX+API_VERSION+ADMINAPI_PREFIX+"/policytemplates", customMiddleware.Handle(internalApi.CreatePolicyTemplate, http.HandlerFunc(policyTemplateHandler.CreatePolicyTemplate))).Methods(http.MethodPost) + r.Handle(API_PREFIX+API_VERSION+ADMINAPI_PREFIX+"/policytemplates/{policyTemplateId}", customMiddleware.Handle(internalApi.DeletePolicyTemplate, http.HandlerFunc(policyTemplateHandler.DeletePolicyTemplate))).Methods(http.MethodDelete) + r.Handle(API_PREFIX+API_VERSION+ADMINAPI_PREFIX+"/policytemplates/{policyTemplateId}", customMiddleware.Handle(internalApi.GetPolicyTemplate, http.HandlerFunc(policyTemplateHandler.GetPolicyTemplate))).Methods(http.MethodGet) + r.Handle(API_PREFIX+API_VERSION+ADMINAPI_PREFIX+"/policytemplates/{policyTemplateId}", customMiddleware.Handle(internalApi.UpdatePolicyTemplate, http.HandlerFunc(policyTemplateHandler.UpdatePolicyTemplate))).Methods(http.MethodPatch) + r.Handle(API_PREFIX+API_VERSION+ADMINAPI_PREFIX+"/policytemplates/{policyTemplateId}/deploy ", customMiddleware.Handle(internalApi.GetPolicyTemplateDeploy, http.HandlerFunc(policyTemplateHandler.GetPolicyTemplateDeploy))).Methods(http.MethodGet) + r.Handle(API_PREFIX+API_VERSION+ADMINAPI_PREFIX+"/policytemplates/{policyTemplateId}/statistics", customMiddleware.Handle(internalApi.ListPolicyTemplateStatistics, http.HandlerFunc(policyTemplateHandler.ListPolicyTemplateStatistics))).Methods(http.MethodGet) + r.Handle(API_PREFIX+API_VERSION+ADMINAPI_PREFIX+"/policytemplates/{policyTemplateId}/versions", customMiddleware.Handle(internalApi.ListPolicyTemplateVersions, http.HandlerFunc(policyTemplateHandler.ListPolicyTemplateVersions))).Methods(http.MethodGet) + r.Handle(API_PREFIX+API_VERSION+ADMINAPI_PREFIX+"/policytemplates/{policyTemplateId}/versions", customMiddleware.Handle(internalApi.CreatePolicyTemplateVersion, http.HandlerFunc(policyTemplateHandler.CreatePolicyTemplateVersion))).Methods(http.MethodPost) + r.Handle(API_PREFIX+API_VERSION+ADMINAPI_PREFIX+"/policytemplates/{policyTemplateId}/versions/{version}", customMiddleware.Handle(internalApi.DeletePolicyTemplateVersion, http.HandlerFunc(policyTemplateHandler.DeletePolicyTemplateVersion))).Methods(http.MethodDelete) + r.Handle(API_PREFIX+API_VERSION+ADMINAPI_PREFIX+"/policytemplates/{policyTemplateId}/versions/{version}", customMiddleware.Handle(internalApi.GetPolicyTemplateVersion, http.HandlerFunc(policyTemplateHandler.GetPolicyTemplateVersion))).Methods(http.MethodGet) + r.Handle(API_PREFIX+API_VERSION+ADMINAPI_PREFIX+"/policytemplates/kind/{policyTemplateKind}/existence", customMiddleware.Handle(internalApi.ExistsPolicyTemplateKind, http.HandlerFunc(policyTemplateHandler.ExistsPolicyTemplateKind))).Methods(http.MethodGet) + r.Handle(API_PREFIX+API_VERSION+ADMINAPI_PREFIX+"/policytemplates/name/{policyTemplateName}/existence", customMiddleware.Handle(internalApi.ExistsPolicyTemplateName, http.HandlerFunc(policyTemplateHandler.ExistsPolicyTemplateName))).Methods(http.MethodGet) + + utilityHandler := delivery.NewUtilityHandler(usecaseFactory) + r.Handle(API_PREFIX+API_VERSION+"/utility/rego-compile", customMiddleware.Handle(internalApi.CompileRego, http.HandlerFunc(utilityHandler.RegoCompile))).Methods(http.MethodPost) + // assets r.PathPrefix("/api/").HandlerFunc(http.NotFound) r.PathPrefix("/").Handler(httpSwagger.WrapHandler).Methods(http.MethodGet) diff --git a/internal/usecase/policy-template.go b/internal/usecase/policy-template.go new file mode 100644 index 00000000..2b48af42 --- /dev/null +++ b/internal/usecase/policy-template.go @@ -0,0 +1,228 @@ +package usecase + +import ( + "context" + "fmt" + + "github.com/google/uuid" + "github.com/openinfradev/tks-api/internal/middleware/auth/request" + "github.com/openinfradev/tks-api/internal/pagination" + "github.com/openinfradev/tks-api/internal/repository" + "github.com/openinfradev/tks-api/pkg/domain" + "github.com/openinfradev/tks-api/pkg/httpErrors" +) + +type IPolicyTemplateUsecase interface { + Create(ctx context.Context, policyTemplate domain.PolicyTemplate) (policyTemplateId string, err error) + Fetch(ctx context.Context, pg *pagination.Pagination) (policyTemplates []domain.PolicyTemplate, err error) + Update(ctx context.Context, policyTemplateId uuid.UUID, update domain.UpdatePolicyTemplateRequest) (err error) + Get(ctx context.Context, policyTemplateId uuid.UUID) (policyTemplates *domain.PolicyTemplate, err error) + Delete(ctx context.Context, policyTemplateId uuid.UUID) (err error) + IsPolicyTemplateNameExist(ctx context.Context, policyTemplateName string) (bool, error) + IsPolicyTemplateKindExist(ctx context.Context, policyTemplateKind string) (bool, error) + GetPolicyTemplateVersion(ctx context.Context, policyTemplateId uuid.UUID, version string) (policyTemplateVersionsReponse *domain.PolicyTemplate, err error) + ListPolicyTemplateVersions(ctx context.Context, policyTemplateId uuid.UUID) (policyTemplateVersionsReponse *domain.ListPolicyTemplateVersionsResponse, err error) + DeletePolicyTemplateVersion(ctx context.Context, policyTemplateId uuid.UUID, version string) (err error) + CreatePolicyTemplateVersion(ctx context.Context, policyTemplateId uuid.UUID, newVersion string, schema []domain.ParameterDef, rego string, libs []string) (version string, err error) +} + +type PolicyTemplateUsecase struct { + organizationRepo repository.IOrganizationRepository + clusterRepo repository.IClusterRepository + repo repository.IPolicyTemplateRepository +} + +func NewPolicyTemplateUsecase(r repository.Repository) IPolicyTemplateUsecase { + return &PolicyTemplateUsecase{ + repo: r.PolicyTemplate, + organizationRepo: r.Organization, + clusterRepo: r.Cluster, + } +} + +func (u *PolicyTemplateUsecase) Create(ctx context.Context, dto domain.PolicyTemplate) (policyTemplateId string, err error) { + user, ok := request.UserFrom(ctx) + if !ok { + return "", httpErrors.NewUnauthorizedError(fmt.Errorf("Invalid token"), "P_INVALID_TOKEN", "") + } + + exists, err := u.repo.ExistByName(dto.TemplateName) + if err == nil && exists { + return "", httpErrors.NewBadRequestError(httpErrors.DuplicateResource, "P_INVALID_POLICY_TEMPLATE_NAME", "policy template name already exists") + } + + exists, err = u.repo.ExistByKind(dto.Kind) + if err == nil && exists { + return "", httpErrors.NewBadRequestError(httpErrors.DuplicateResource, "P_INVALID_POLICY_TEMPLATE_KIND", "policy template kind already exists") + } + + for _, organizationId := range dto.PermittedOrganizationIds { + _, err = u.organizationRepo.Get(organizationId) + if err != nil { + return "", httpErrors.NewBadRequestError(fmt.Errorf("Invalid organizationId"), "", "") + } + } + + userId := user.GetUserId() + dto.CreatorId = &userId + id, err := u.repo.Create(dto) + + if err != nil { + return "", err + } + + return id.String(), nil +} + +func (u *PolicyTemplateUsecase) Fetch(ctx context.Context, pg *pagination.Pagination) (policyTemplates []domain.PolicyTemplate, err error) { + policyTemplates, err = u.repo.Fetch(pg) + + if err != nil { + return nil, err + } + + organizations, err := u.organizationRepo.Fetch(nil) + if err == nil { + for i, policyTemplate := range policyTemplates { + permittedOrgIdSet := u.getPermittedOrganiationIdSet(&policyTemplate) + + u.updatePermittedOrganizations(organizations, permittedOrgIdSet, &policyTemplates[i]) + } + } + + return policyTemplates, nil + +} + +func (u *PolicyTemplateUsecase) Get(ctx context.Context, policyTemplateID uuid.UUID) (policyTemplates *domain.PolicyTemplate, err error) { + policyTemplate, err := u.repo.GetByID(policyTemplateID) + + if err != nil { + return nil, err + } + + permittedOrgIdSet := u.getPermittedOrganiationIdSet(policyTemplate) + + organizations, err := u.organizationRepo.Fetch(nil) + if err == nil { + u.updatePermittedOrganizations(organizations, permittedOrgIdSet, policyTemplate) + } + + return policyTemplate, nil +} + +func (u *PolicyTemplateUsecase) Update(ctx context.Context, policyTemplateId uuid.UUID, update domain.UpdatePolicyTemplateRequest) (err error) { + user, ok := request.UserFrom(ctx) + if !ok { + return httpErrors.NewBadRequestError(fmt.Errorf("Invalid token"), "", "") + } + + _, err = u.repo.GetByID(policyTemplateId) + if err != nil { + return httpErrors.NewNotFoundError(err, "P_FAILED_FETCH_POLICY_TEMPLATE", "") + } + + exists, err := u.repo.ExistByName(*update.TemplateName) + if err == nil && exists { + return httpErrors.NewBadRequestError(httpErrors.DuplicateResource, "P_INVALID_POLICY_TEMPLATE_NAME", "policy template name already exists") + } + + if update.PermittedOrganizationIds != nil { + for _, organizationId := range *update.PermittedOrganizationIds { + _, err = u.organizationRepo.Get(organizationId) + if err != nil { + return httpErrors.NewBadRequestError(fmt.Errorf("Invalid organizationId"), "", "") + } + } + } + + updatorId := user.GetUserId() + dto := domain.UpdatePolicyTemplateUpdate{ + ID: policyTemplateId, + Type: "tks", + UpdatorId: updatorId, + TemplateName: update.TemplateName, + Description: update.Description, + Severity: update.Severity, + Deprecated: update.Deprecated, + PermittedOrganizationIds: update.PermittedOrganizationIds, + } + + err = u.repo.Update(dto) + if err != nil { + return err + } + + return nil +} + +func (u *PolicyTemplateUsecase) Delete(ctx context.Context, policyTemplateId uuid.UUID) (err error) { + return u.repo.Delete(policyTemplateId) +} + +func (u *PolicyTemplateUsecase) IsPolicyTemplateNameExist(ctx context.Context, policyTemplateName string) (bool, error) { + return u.repo.ExistByName(policyTemplateName) +} + +func (u *PolicyTemplateUsecase) IsPolicyTemplateKindExist(ctx context.Context, policyTemplateKind string) (bool, error) { + return u.repo.ExistByKind(policyTemplateKind) +} + +func (u *PolicyTemplateUsecase) GetPolicyTemplateVersion(ctx context.Context, policyTemplateId uuid.UUID, version string) (policyTemplateVersionsReponse *domain.PolicyTemplate, err error) { + policyTemplate, err := u.repo.GetPolicyTemplateVersion(policyTemplateId, version) + + if err != nil { + return nil, err + } + + permittedOrgIdSet := u.getPermittedOrganiationIdSet(policyTemplate) + + organizations, err := u.organizationRepo.Fetch(nil) + if err == nil { + u.updatePermittedOrganizations(organizations, permittedOrgIdSet, policyTemplate) + } + + return policyTemplate, nil +} + +func (*PolicyTemplateUsecase) updatePermittedOrganizations(organizations *[]domain.Organization, permittedOrgIdSet map[string]string, policyTemplate *domain.PolicyTemplate) { + // 허용리스트가 비어있으면 모든 Org에 대해서 허용 + permitted := len(permittedOrgIdSet) == 0 + + for _, organization := range *organizations { + + _, ok := permittedOrgIdSet[organization.ID] + + if !ok { + policyTemplate.PermittedOrganizations = append( + policyTemplate.PermittedOrganizations, + domain.PermittedOrganization{ + OrganizationId: organization.ID, + OrganizationName: organization.Name, + Permitted: permitted, + }) + } + } +} + +func (*PolicyTemplateUsecase) getPermittedOrganiationIdSet(policyTemplate *domain.PolicyTemplate) map[string]string { + permittedOrgIdSet := make(map[string]string) + + for _, permittedOrg := range policyTemplate.PermittedOrganizations { + // Set 처리를 위해서 키만 사용, 값은 아무거나 + permittedOrgIdSet[permittedOrg.OrganizationId] = "1" + } + return permittedOrgIdSet +} + +func (u *PolicyTemplateUsecase) ListPolicyTemplateVersions(ctx context.Context, policyTemplateId uuid.UUID) (policyTemplateVersionsReponse *domain.ListPolicyTemplateVersionsResponse, err error) { + return u.repo.ListPolicyTemplateVersions(policyTemplateId) +} + +func (u *PolicyTemplateUsecase) DeletePolicyTemplateVersion(ctx context.Context, policyTemplateId uuid.UUID, version string) (err error) { + return u.repo.DeletePolicyTemplateVersion(policyTemplateId, version) +} + +func (u *PolicyTemplateUsecase) CreatePolicyTemplateVersion(ctx context.Context, policyTemplateId uuid.UUID, newVersion string, schema []domain.ParameterDef, rego string, libs []string) (version string, err error) { + return u.repo.CreatePolicyTemplateVersion(policyTemplateId, newVersion, schema, rego, libs) +} diff --git a/internal/usecase/usecase.go b/internal/usecase/usecase.go index 4e7da85b..48f47ae2 100644 --- a/internal/usecase/usecase.go +++ b/internal/usecase/usecase.go @@ -1,19 +1,21 @@ package usecase type Usecase struct { - Auth IAuthUsecase - User IUserUsecase - Cluster IClusterUsecase - Organization IOrganizationUsecase - AppGroup IAppGroupUsecase - AppServeApp IAppServeAppUsecase - CloudAccount ICloudAccountUsecase - StackTemplate IStackTemplateUsecase - Dashboard IDashboardUsecase - Alert IAlertUsecase - Stack IStackUsecase - Project IProjectUsecase - Role IRoleUsecase - Permission IPermissionUsecase - Audit IAuditUsecase + Auth IAuthUsecase + User IUserUsecase + Cluster IClusterUsecase + Organization IOrganizationUsecase + AppGroup IAppGroupUsecase + AppServeApp IAppServeAppUsecase + CloudAccount ICloudAccountUsecase + StackTemplate IStackTemplateUsecase + Dashboard IDashboardUsecase + Alert IAlertUsecase + Stack IStackUsecase + Project IProjectUsecase + Role IRoleUsecase + Permission IPermissionUsecase + Audit IAuditUsecase + PolicyTemplate IPolicyTemplateUsecase + Utility IUtilityUsecase } diff --git a/internal/usecase/utility.go b/internal/usecase/utility.go new file mode 100644 index 00000000..c7f421f9 --- /dev/null +++ b/internal/usecase/utility.go @@ -0,0 +1,161 @@ +package usecase + +import ( + "fmt" + "regexp" + "strings" + + "github.com/open-policy-agent/opa/ast" + "github.com/openinfradev/tks-api/internal/repository" + "github.com/openinfradev/tks-api/pkg/domain" +) + +type IUtilityUsecase interface { + RegoCompile(request *domain.RegoCompileRequest, parseParameter bool) (response *domain.RegoCompileResponse, err error) +} + +type UtilityUsecase struct { +} + +func NewUtilityUsecase(r repository.Repository) IUtilityUsecase { + return &UtilityUsecase{} +} + +func (u *UtilityUsecase) RegoCompile(request *domain.RegoCompileRequest, parseParameter bool) (response *domain.RegoCompileResponse, err error) { + modules := map[string]*ast.Module{} + + response = &domain.RegoCompileResponse{} + response.Errors = []domain.RegoCompieError{} + + mod, err := ast.ParseModuleWithOpts("rego", request.Rego, ast.ParserOptions{}) + if err != nil { + return nil, err + } + modules["rego"] = mod + + compiler := ast.NewCompiler() + compiler.Compile(modules) + + if compiler.Failed() { + for _, compileError := range compiler.Errors { + response.Errors = append(response.Errors, domain.RegoCompieError{ + Status: 400, + Code: "P_INVALID_REGO_SYNTAX", + Message: "Invalid rego syntax", + Text: fmt.Sprintf("[%d:%d] %s", + compileError.Location.Row, compileError.Location.Col, + compileError.Message), + }) + } + } + + if parseParameter { + response.ParametersSchema = extractParameter(request.Rego) + } + + return response, nil +} + +func extractParameter(rego string) []*domain.ParameterDef { + pattern := `input\.parameters\.[\w\.\[\]]+` + + prefix := "input.parameters." + + // Compile the regex pattern + regex := regexp.MustCompile(pattern) + + matches := regex.FindAllString(rego, -1) + + defStore := NewParamDefStore() + + for _, match := range matches { + remainder := match[len(prefix):] + + // 문법 변환: aa["a"]["B"][_]->aa.a.B[_] + regex := regexp.MustCompile(`\[\"(\w+)\"\]`) + remainder = regex.ReplaceAllString(remainder, ".$1") + + params := strings.Split(remainder, ".") + + if len(params) == 0 { + continue + } + + defStore.AddDefinition(params) + } + + return defStore.store +} + +type ParamDefStore struct { + store []*domain.ParameterDef +} + +func NewParamDefStore() *ParamDefStore { + return &ParamDefStore{store: []*domain.ParameterDef{}} +} + +func (s *ParamDefStore) GetStore() []*domain.ParameterDef { + return s.store +} + +func (s *ParamDefStore) AddDefinition(params []string) { + init := &s.store + + for i, param := range params { + isLast := i == len(params)-1 + + key := findKey(s.store, param) + + if key == nil { + key = createKey(param, isLast) + *init = append(*init, key) + } + + init = &key.Children + } +} + +func findKey(defs []*domain.ParameterDef, key string) *domain.ParameterDef { + for _, def := range defs { + if def.Key == key || def.Key+"[_]" == key { + return def + } + } + + return nil +} + +func createKey(key string, isLast bool) *domain.ParameterDef { + finalType := "any" + + pKey := key + isArray := false + + if strings.HasSuffix(pKey, "[_]") { + pKey, _ = strings.CutSuffix(pKey, "[_]") + isArray = true + } + + if isLast { + if isArray { + finalType = "any[]" + } else { + finalType = "any" + } + } else { + if isArray { + finalType = "object[]" + } else { + finalType = "object" + } + } + + newDef := &domain.ParameterDef{ + Key: pKey, + Type: finalType, + Children: []*domain.ParameterDef{}, + } + + return newDef +} diff --git a/pkg/domain/policy-template.go b/pkg/domain/policy-template.go new file mode 100644 index 00000000..acea768d --- /dev/null +++ b/pkg/domain/policy-template.go @@ -0,0 +1,278 @@ +package domain + +import ( + "time" + + "github.com/google/uuid" +) + +type PolicyTemplateId string + +func (pp PolicyTemplateId) String() string { + return string(pp) +} + +func (pp PolicyTemplateId) Validate() bool { + // return helper.ValidatePolicyTemplateId(pp.String()) + return true +} + +type CommonPolicyTemplate struct { + ID PolicyTemplateId `json:"id" example:"d98ef5f1-4a68-4047-a446-2207787ce3ff"` + Type string `json:"type" enums:"tks,organization" example:"tks"` + Creator SimpleUserResponse `json:"creator,omitempty"` + Updator SimpleUserResponse `json:"updator,omitempty"` + CreatedAt time.Time `json:"createdAt" format:"date-time"` + UpdatedAt time.Time `json:"updatedAt" format:"date-time"` + + TemplateName string `json:"templateName" example:"필수 Label 검사"` + Kind string `json:"kind" example:"K8sRequiredLabels"` + Severity string `json:"severity" enums:"low,medium,high" example:"medium"` + Deprecated bool `json:"deprecated" example:"false"` + Version string `json:"version,omitempty" example:"v1.0.1"` + Description string `json:"description,omitempty" example:"이 정책은 ..."` + ParametersSchema []ParameterDef `json:"parametersSchema,omitempty"` + // Target string `json:"target,omitempty" example:"admission.k8s.gatekeeper.sh"` + // "type: object\nproperties: message:\n type: string\n labels:\n type: array\n items:\n type: object\n properties:\n key:\n type: string\n allowedRegex:\n type: string" + + Rego string `json:"rego" example:"rego 코드"` + Libs []string `json:"libs" example:"rego 코드"` + + // Tags []string `json:"tags,omitempty" example:"k8s,label"` +} + +type OrganizationPolicyTemplate struct { + Mandatory bool `json:"mandatory"` + CommonPolicyTemplate +} + +type PermittedOrganization struct { + OrganizationId string `json:"organizationId"` + OrganizationName string `json:"organizationName"` + Permitted bool `json:"permitted"` +} + +type PolicyTemplateResponse struct { + ID PolicyTemplateId `json:"id" example:"d98ef5f1-4a68-4047-a446-2207787ce3ff"` + Type string `json:"type" enums:"tks,organization" example:"tks"` + Creator SimpleUserResponse `json:"creator"` + Updator SimpleUserResponse `json:"updator"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` + + TemplateName string `json:"templateName" example:"필수 Label 검사"` + Kind string `json:"kind" example:"K8sRequiredLabels"` + Severity string `json:"severity" enums:"low,medium,high" example:"medium"` + Deprecated bool `json:"deprecated" example:"false"` + Version string `json:"version,omitempty" example:"v1.0.1"` + Description string `json:"description,omitempty" example:"이 정책은 ..."` + ParametersSchema []ParameterDef `json:"parametersSchema,omitempty"` + Rego string `json:"rego" example:"rego 코드"` + Libs []string `json:"libs" example:"rego 코드"` + + PermittedOrganizations []PermittedOrganization `json:"permittedOrganizations"` +} + +type PolicyTemplate struct { + ID PolicyTemplateId + Type string + CreatorId *uuid.UUID + Creator User + UpdatorId *uuid.UUID + Updator User + CreatedAt time.Time + UpdatedAt time.Time + + TemplateName string + Kind string + Severity string + Deprecated bool + Version string + Description string + ParametersSchema []ParameterDef + + Rego string + Libs []string + + PermittedOrganizationIds []string // 생성 시에만 사용 + PermittedOrganizations []PermittedOrganization +} + +type CreateCommonPolicyTemplateRequest struct { + TemplateName string `json:"templateName" example:"필수 Label 검사"` + Kind string `json:"kind" example:"K8sRequiredLabels"` + Severity string `json:"severity" enums:"low,medium,high" example:"medium"` + Deprecated bool `json:"deprecated" example:"false"` + Description string `json:"description,omitempty" example:"이 정책은 ..."` + ParametersSchema []ParameterDef `json:"parametersSchema,omitempty"` + // "type: object\nproperties: message:\n type: string\n labels:\n type: array\n items:\n type: object\n properties:\n key:\n type: string\n allowedRegex:\n type: string" + + Rego string `json:"rego" example:"rego 코드"` + Libs []string `json:"libs" example:"rego 코드"` + + // Tags []string `json:"tags,omitempty" example:"k8s,label"` +} + +type CreatePolicyTemplateRequest struct { + TemplateName string `json:"templateName" example:"필수 Label 검사"` + Kind string `json:"kind" example:"K8sRequiredLabels"` + Severity string `json:"severity" enums:"low,medium,high" example:"medium"` + Deprecated bool `json:"deprecated" example:"false"` + Target string `json:"target,omitempty" example:"admission.k8s.gatekeeper.sh"` + Description string `json:"description,omitempty" example:"이 정책은 ..."` + ParametersSchema []ParameterDef `json:"parametersSchema,omitempty"` + // "type: object\nproperties: message:\n type: string\n labels:\n type: array\n items:\n type: object\n properties:\n key:\n type: string\n allowedRegex:\n type: string" + + Rego string `json:"rego" example:"rego 코드"` + Libs []string `json:"libs" example:"rego 코드"` + + PermittedOrganizationIds []string `json:"permittedOrganizationIds"` +} + +type CreateOrganizationPolicyTemplateRequest struct { + CreateCommonPolicyTemplateRequest + Mandatory bool `json:"mandatory"` +} + +type CreatePolicyTemplateReponse struct { + ID PolicyTemplateId `json:"id" example:"d98ef5f1-4a68-4047-a446-2207787ce3ff"` +} + +type CreateOrganizationPolicyTemplateReponse struct { + ID PolicyTemplateId `json:"id" example:"d98ef5f1-4a68-4047-a446-2207787ce3ff"` +} + +type UpdateCommmonPolicyTemplateRequest struct { + TemplateName string `json:"templateName" example:"필수 Label 검사"` + Description string `json:"description,omitempty"` + Severity string `json:"severity" enums:"low,medium,high" example:"medium"` + Deprecated bool `json:"deprecated" example:"false"` + // Tags []string `json:"tags,omitempty"` +} + +type UpdatePolicyTemplateUpdate struct { + ID uuid.UUID + Type string + UpdatorId uuid.UUID + TemplateName *string + Description *string + Severity *string + Deprecated *bool + PermittedOrganizationIds *[]string +} + +func (dto *UpdatePolicyTemplateUpdate) IsNothingToUpdate() bool { + return dto.TemplateName == nil && + dto.Description == nil && + dto.Severity == nil && + dto.Deprecated == nil && + dto.PermittedOrganizationIds == nil +} + +type UpdatePolicyTemplateRequest struct { + TemplateName *string `json:"templateName,omitempty" example:"필수 Label 검사"` + Description *string `json:"description,omitempty"` + Severity *string `json:"severity,omitempty" enums:"low,medium,high" example:"medium"` + Deprecated *bool `json:"deprecated,omitempty" example:"false"` + PermittedOrganizationIds *[]string `json:"permittedOrganizationIds,omitempty"` +} + +type UpdateOrganizationPolicyTemplateRequest struct { + UpdateCommmonPolicyTemplateRequest + Mandatory bool `json:"mandatory"` +} + +// type GetPolicyTemplateVersionResponse struct { +// PolicyTemplate PolicyTemplate `json:"policyTemplate"` +// } +type GetPolicyTemplateDeployResponse struct { + DeployVersion map[string]string `json:"deployVersion"` +} + +type GetOrganizationPolicyTemplateDeployResponse struct { + DeployVersion map[string]string `json:"deployVersion"` +} + +type ListPolicyTemplateVersionsResponse struct { + Versions []string `json:"versions" example:"v1.1.0,v1.0.1,v1.0.0"` +} + +type ListOrganizationPolicyTemplateVersionsResponse struct { + Versions []string `json:"versions" example:"v1.1.0,v1.0.1,v1.0.0"` +} + +type GetPolicyTemplateVersionResponse struct { + PolicyTemplate PolicyTemplateResponse `json:"policyTemplate"` +} + +type GetOrganizationPolicyTemplateVersionResponse struct { + PolicyTemplate OrganizationPolicyTemplate `json:"policyTemplate"` +} + +type CreatePolicyTemplateVersionRequest struct { + VersionUpType string `json:"versionUpType" enums:"major,minor,patch" example:"minor"` + CurrentVersion string `json:"currentVersion" example:"v1.0.0"` + ExpectedVersion string `json:"expectedVersion" example:"v1.1.0"` + + ParametersSchema []ParameterDef `json:"parametersSchema,omitempty"` + // "type: object\nproperties: message:\n type: string\n labels:\n type: array\n items:\n type: object\n properties:\n key:\n type: string\n allowedRegex:\n type: string" + + Rego string `json:"rego" example:"rego 코드"` + Libs []string `json:"libs" example:"rego 코드"` +} + +type CreateOrganizationPolicyTemplateVersionRequest struct { + CreatePolicyTemplateVersionRequest +} + +type CreatePolicyTemplateVersionResponse struct { + Version string `json:"version" example:"v1.1.1"` +} + +type CreateOrganizationPolicyTemplateVersionResponse struct { + Version string `json:"version" example:"v1.1.1"` +} + +type GetPolicyTemplateResponse struct { + PolicyTemplate PolicyTemplateResponse `json:"policyTemplate"` +} + +type GetOrganizationPolicyTemplateResponse struct { + PolicyTemplate OrganizationPolicyTemplate `json:"policyTemplate"` +} + +type ListPolicyTemplateResponse struct { + PolicyTemplates []PolicyTemplateResponse `json:"policyTemplates"` + Pagination PaginationResponse `json:"pagination"` +} + +type ListOrganizationPolicyTemplateResponse struct { + PolicyTemplates []OrganizationPolicyTemplate `json:"policyTemplates"` + Pagination PaginationResponse `json:"pagination"` +} + +type PolicyTemplateStatistics struct { + OrganizationId string `json:"organizationId"` + OrganizationName string `json:"organizationName"` + UsageCount int `json:"usageCount"` +} + +type OrganizationPolicyTemplateStatistics struct { + OrganizationId string `json:"organizationId"` + OrganizationName string `json:"organizationName"` + UsageCount int `json:"usageCount"` +} + +type ListPolicyTemplateStatisticsResponse struct { + PolicyTemplateStatistics []PolicyTemplateStatistics `json:"policyTemplateStatistics"` +} + +type ListOrganizationPolicyTemplateStatisticsResponse struct { + PolicyTemplateStatistics []OrganizationPolicyTemplateStatistics `json:"policyTemplateStatistics"` +} + +type ExistsPolicyTemplateNameResponse struct { +} + +type ExistsPolicyTemplateKindResponse struct { +} diff --git a/pkg/domain/rego.go b/pkg/domain/rego.go new file mode 100644 index 00000000..056111bb --- /dev/null +++ b/pkg/domain/rego.go @@ -0,0 +1,25 @@ +package domain + +type ParameterDef struct { + Key string `json:"key"` + Type string `json:"type"` + DefaultValue string `json:"defaultValue"` + Children []*ParameterDef `json:"children"` + IsArray bool +} + +type RegoCompileRequest struct { + Rego string `json:"rego" example:"Rego 코드"` +} + +type RegoCompieError struct { + Status int `json:"status" example:"400"` + Code string `json:"code" example:"P_INVALID_REGO_SYNTAX"` + Message string `json:"message" example:"Invalid rego syntax"` + Text string `json:"text" example:"Rego 문법 에러입니다. 라인:2 컬럼:1 에러메시지: var testnum is not safe"` +} + +type RegoCompileResponse struct { + ParametersSchema []*ParameterDef `json:"parametersSchema,omitempty"` + Errors []RegoCompieError `json:"errors,omitempty"` +} From 4bc7ecbdea9731cd16f38008b2991b50badadf89 Mon Sep 17 00:00:00 2001 From: sangkenlee Date: Mon, 11 Mar 2024 11:59:37 +0900 Subject: [PATCH 2/4] rego-compile: utility->policytemplates, /ap1/1.0 prefix duplication removal --- api/swagger/docs.go | 506 +++++++++++----------- api/swagger/swagger.json | 506 +++++++++++----------- api/swagger/swagger.yaml | 396 ++++++++--------- internal/delivery/http/policy-template.go | 74 +++- internal/delivery/http/utility.go | 73 ---- internal/route/route.go | 5 +- internal/usecase/policy-template.go | 144 ++++++ internal/usecase/usecase.go | 1 - internal/usecase/utility.go | 161 ------- pkg/domain/policy-template.go | 24 + pkg/domain/rego.go | 25 -- 11 files changed, 934 insertions(+), 981 deletions(-) delete mode 100644 internal/delivery/http/utility.go delete mode 100644 internal/usecase/utility.go delete mode 100644 pkg/domain/rego.go diff --git a/api/swagger/docs.go b/api/swagger/docs.go index 47e43b6b..b40b355d 100644 --- a/api/swagger/docs.go +++ b/api/swagger/docs.go @@ -214,14 +214,14 @@ const docTemplate = `{ } } }, - "/admin/stack-templates": { + "/admin/policytemplates": { "get": { "security": [ { "JWT": [] } ], - "description": "Get StackTemplates", + "description": "정책 템플릿 목록을 조회한다. 정책 템플릿 목록 조회 결과는 최신 템플릿 버전 목록만 조회된다.", "consumes": [ "application/json" ], @@ -229,9 +229,9 @@ const docTemplate = `{ "application/json" ], "tags": [ - "StackTemplates" + "PolicyTemplate" ], - "summary": "Get StackTemplates", + "summary": "[ListPolicyTemplate] 정책 템플릿 목록 조회", "parameters": [ { "type": "string", @@ -272,7 +272,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetStackTemplatesResponse" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateResponse" } } } @@ -283,7 +283,7 @@ const docTemplate = `{ "JWT": [] } ], - "description": "Create StackTemplate", + "description": "정책 템플릿을 신규 생성(v1.0.0을 생성)한다.", "consumes": [ "application/json" ], @@ -291,17 +291,17 @@ const docTemplate = `{ "application/json" ], "tags": [ - "StackTemplates" + "PolicyTemplate" ], - "summary": "Create StackTemplate 'NOT IMPLEMENTED'", + "summary": "[CreatePolicyTemplate] 정책 템플릿 신규 생성", "parameters": [ { - "description": "create stack template request", + "description": "create policy template request", "name": "body", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreateStackTemplateRequest" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateRequest" } } ], @@ -309,20 +309,20 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreateStackTemplateResponse" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateReponse" } } } } }, - "/admin/stack-templates/services": { + "/admin/policytemplates/kind/{policyTemplateKind}/existence": { "get": { "security": [ { "JWT": [] } ], - "description": "Get GetStackTemplateServices", + "description": "해당 유형을 가진 정책 템플릿이 이미 존재하는지 확인한다.", "consumes": [ "application/json" ], @@ -330,27 +330,36 @@ const docTemplate = `{ "application/json" ], "tags": [ - "StackTemplates" + "PolicyTemplate" + ], + "summary": "[ExistsPolicyTemplateKind] 정책 템플릿 유형 존재 여부 확인", + "parameters": [ + { + "type": "string", + "description": "정책 템플릿 이름", + "name": "policyTemplateKind", + "in": "path", + "required": true + } ], - "summary": "Get GetStackTemplateServices", "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetStackTemplateServicesResponse" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ExistsPolicyTemplateKindResponse" } } } } }, - "/admin/stack-templates/{stackTemplateId}": { + "/admin/policytemplates/name/{policyTemplateName}/existence": { "get": { "security": [ { "JWT": [] } ], - "description": "Get StackTemplate", + "description": "해당 이름을 가진 정책 템플릿이 이미 존재하는지 확인한다.", "consumes": [ "application/json" ], @@ -358,14 +367,14 @@ const docTemplate = `{ "application/json" ], "tags": [ - "StackTemplates" + "PolicyTemplate" ], - "summary": "Get StackTemplate", + "summary": "[ExistsPolicyTemplateName] 정책 템플릿 아름 존재 여부 확인", "parameters": [ { "type": "string", - "description": "stackTemplateId", - "name": "stackTemplateId", + "description": "정책 템플릿 이름", + "name": "policyTemplateName", "in": "path", "required": true } @@ -374,18 +383,20 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetStackTemplateResponse" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CheckExistedResponse" } } } - }, - "put": { + } + }, + "/admin/policytemplates/{policyTemplateId}": { + "get": { "security": [ { "JWT": [] } ], - "description": "Update StackTemplate", + "description": "해당 식별자를 가진 정책 템플릿의 최신 버전을 조회한다.", "consumes": [ "application/json" ], @@ -393,23 +404,24 @@ const docTemplate = `{ "application/json" ], "tags": [ - "StackTemplates" + "PolicyTemplate" ], - "summary": "Update StackTemplate 'NOT IMPLEMENTED'", + "summary": "[GetPolicyTemplate] 정책 템플릿 조회(최신 버전)", "parameters": [ { - "description": "Update stack template request", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.UpdateStackTemplateRequest" - } + "type": "string", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true } ], "responses": { "200": { - "description": "OK" + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateResponse" + } } } }, @@ -419,7 +431,7 @@ const docTemplate = `{ "JWT": [] } ], - "description": "Delete StackTemplate", + "description": "정책 템플릿을 삭제한다.", "consumes": [ "application/json" ], @@ -427,14 +439,14 @@ const docTemplate = `{ "application/json" ], "tags": [ - "StackTemplates" + "PolicyTemplate" ], - "summary": "Delete StackTemplate 'NOT IMPLEMENTED'", + "summary": "[DeletePolicyTemplate] 정책 템플릿 삭제", "parameters": [ { "type": "string", - "description": "stackTemplateId", - "name": "stackTemplateId", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", "in": "path", "required": true } @@ -444,16 +456,14 @@ const docTemplate = `{ "description": "OK" } } - } - }, - "/admin/stack-templates/{stackTemplateId}/organizations": { - "put": { + }, + "patch": { "security": [ { "JWT": [] } ], - "description": "Update StackTemplate organizations", + "description": "정책 템플릿의 업데이트 가능한 필드들을 업데이트한다.", "consumes": [ "application/json" ], @@ -461,17 +471,24 @@ const docTemplate = `{ "application/json" ], "tags": [ - "StackTemplates" + "PolicyTemplate" ], - "summary": "Update StackTemplate organizations", + "summary": "[UpdatePolicyTemplate] 정책 템플릿 업데이트", "parameters": [ { - "description": "Update stack template organizations request", + "type": "string", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true + }, + { + "description": "update policy template request", "name": "body", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.UpdateStackTemplateOrganizationsRequest" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.UpdatePolicyTemplateRequest" } } ], @@ -482,14 +499,14 @@ const docTemplate = `{ } } }, - "/api/1.0/admin/policytemplates": { + "/admin/policytemplates/{policyTemplateId}/deploy": { "get": { "security": [ { "JWT": [] } ], - "description": "정책 템플릿 목록을 조회한다. 정책 템플릿 목록 조회 결과는 최신 템플릿 버전 목록만 조회된다.", + "description": "해당 식별자를 가진 정책 템플릿의 정책 템플릿 클러스터 별 설치 버전을 조회한다.", "consumes": [ "application/json" ], @@ -499,59 +516,34 @@ const docTemplate = `{ "tags": [ "PolicyTemplate" ], - "summary": "[ListPolicyTemplate] 정책 템플릿 목록 조회", + "summary": "[GetPolicyTemplateDeploy] 정책 템플릿 클러스터 별 설치 버전 조회", "parameters": [ { "type": "string", - "description": "pageSize", - "name": "limit", - "in": "query" - }, - { - "type": "string", - "description": "pageNumber", - "name": "page", - "in": "query" - }, - { - "type": "string", - "description": "sortColumn", - "name": "soertColumn", - "in": "query" - }, - { - "type": "string", - "description": "sortOrder", - "name": "sortOrder", - "in": "query" - }, - { - "type": "array", - "items": { - "type": "string" - }, - "collectionFormat": "csv", - "description": "filters", - "name": "filters", - "in": "query" + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateResponse" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateDeployResponse" } } } - }, - "post": { + } + }, + "/admin/policytemplates/{policyTemplateId}/statistics": { + "get": { "security": [ { "JWT": [] } ], - "description": "정책 템플릿을 신규 생성(v1.0.0을 생성)한다.", + "description": "해당 식별자를 가진 정책 템플릿의 최신 버전을 조회한다. 전체 조직의 통계를 조회하려면 organizationId를 tks로 설정한다.", "consumes": [ "application/json" ], @@ -561,36 +553,34 @@ const docTemplate = `{ "tags": [ "PolicyTemplate" ], - "summary": "[CreatePolicyTemplate] 정책 템플릿 신규 생성", + "summary": "[ListPolicyTemplateStatistics] 정책 템플릿 사용 카운트 조회", "parameters": [ { - "description": "create policy template request", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateRequest" - } + "type": "string", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateReponse" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateStatisticsResponse" } } } } }, - "/api/1.0/admin/policytemplates/kind/{policyTemplateKind}/existence": { + "/admin/policytemplates/{policyTemplateId}/versions": { "get": { "security": [ { "JWT": [] } ], - "description": "해당 유형을 가진 정책 템플릿이 이미 존재하는지 확인한다.", + "description": "해당 식별자를 가진 정책 템플릿의 최신 버전을 조회한다.", "consumes": [ "application/json" ], @@ -600,12 +590,12 @@ const docTemplate = `{ "tags": [ "PolicyTemplate" ], - "summary": "[ExistsPolicyTemplateKind] 정책 템플릿 유형 존재 여부 확인", + "summary": "[ListPolicyTemplateVersions] 정책 템플릿 버전목록 조회", "parameters": [ { "type": "string", - "description": "정책 템플릿 이름", - "name": "policyTemplateKind", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", "in": "path", "required": true } @@ -614,20 +604,18 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ExistsPolicyTemplateKindResponse" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateVersionsResponse" } } } - } - }, - "/api/1.0/admin/policytemplates/name/{policyTemplateName}/existence": { - "get": { + }, + "post": { "security": [ { "JWT": [] } ], - "description": "해당 이름을 가진 정책 템플릿이 이미 존재하는지 확인한다.", + "description": "해당 식별자를 가진 정책 템플릿의 특정 버전을 저장한다.", "consumes": [ "application/json" ], @@ -637,34 +625,43 @@ const docTemplate = `{ "tags": [ "PolicyTemplate" ], - "summary": "[ExistsPolicyTemplateName] 정책 템플릿 아름 존재 여부 확인", + "summary": "[CreatePolicyTemplateVersion] 정책 템플릿 특정 버전 저장", "parameters": [ { "type": "string", - "description": "정책 템플릿 이름", - "name": "policyTemplateName", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", "in": "path", "required": true + }, + { + "description": "create policy template version request", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateVersionRequest" + } } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CheckExistedResponse" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateVersionResponse" } } } } }, - "/api/1.0/admin/policytemplates/{policyTemplateId}": { + "/admin/policytemplates/{policyTemplateId}/versions/{version}": { "get": { "security": [ { "JWT": [] } ], - "description": "해당 식별자를 가진 정책 템플릿의 최신 버전을 조회한다.", + "description": "해당 식별자를 가진 정책 템플릿의 특정 버전을 조회한다.", "consumes": [ "application/json" ], @@ -674,7 +671,7 @@ const docTemplate = `{ "tags": [ "PolicyTemplate" ], - "summary": "[GetPolicyTemplate] 정책 템플릿 조회(최신 버전)", + "summary": "[GetPolicyTemplateVersion] 정책 템플릿 특정 버전 조회", "parameters": [ { "type": "string", @@ -682,13 +679,20 @@ const docTemplate = `{ "name": "policyTemplateId", "in": "path", "required": true + }, + { + "type": "string", + "description": "조회할 버전(v0.0.0 형식)", + "name": "version", + "in": "path", + "required": true } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateResponse" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateVersionResponse" } } } @@ -699,7 +703,7 @@ const docTemplate = `{ "JWT": [] } ], - "description": "정책 템플릿을 삭제한다.", + "description": "해당 식별자를 가진 정책 템플릿의 특정 버전을 삭제한다.", "consumes": [ "application/json" ], @@ -709,7 +713,7 @@ const docTemplate = `{ "tags": [ "PolicyTemplate" ], - "summary": "[DeletePolicyTemplate] 정책 템플릿 삭제", + "summary": "[DeletePolicyTemplateVersion] 정책 템플릿 특정 버전 삭제", "parameters": [ { "type": "string", @@ -717,6 +721,13 @@ const docTemplate = `{ "name": "policyTemplateId", "in": "path", "required": true + }, + { + "type": "string", + "description": "삭제할 버전(v0.0.0 형식)", + "name": "version", + "in": "path", + "required": true } ], "responses": { @@ -724,14 +735,16 @@ const docTemplate = `{ "description": "OK" } } - }, - "patch": { + } + }, + "/admin/stack-templates": { + "get": { "security": [ { "JWT": [] } ], - "description": "정책 템플릿의 업데이트 가능한 필드들을 업데이트한다.", + "description": "Get StackTemplates", "consumes": [ "application/json" ], @@ -739,42 +752,61 @@ const docTemplate = `{ "application/json" ], "tags": [ - "PolicyTemplate" + "StackTemplates" ], - "summary": "[UpdatePolicyTemplate] 정책 템플릿 업데이트", + "summary": "Get StackTemplates", "parameters": [ { "type": "string", - "description": "정책 템플릿 식별자(uuid)", - "name": "policyTemplateId", - "in": "path", - "required": true + "description": "pageSize", + "name": "limit", + "in": "query" }, { - "description": "update policy template request", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.UpdatePolicyTemplateRequest" - } + "type": "string", + "description": "pageNumber", + "name": "page", + "in": "query" + }, + { + "type": "string", + "description": "sortColumn", + "name": "soertColumn", + "in": "query" + }, + { + "type": "string", + "description": "sortOrder", + "name": "sortOrder", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "filters", + "name": "filters", + "in": "query" } ], "responses": { "200": { - "description": "OK" + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetStackTemplatesResponse" + } } } - } - }, - "/api/1.0/admin/policytemplates/{policyTemplateId}/deploy": { - "get": { + }, + "post": { "security": [ { "JWT": [] } ], - "description": "해당 식별자를 가진 정책 템플릿의 정책 템플릿 클러스터 별 설치 버전을 조회한다.", + "description": "Create StackTemplate", "consumes": [ "application/json" ], @@ -782,36 +814,38 @@ const docTemplate = `{ "application/json" ], "tags": [ - "PolicyTemplate" + "StackTemplates" ], - "summary": "[GetPolicyTemplateDeploy] 정책 템플릿 클러스터 별 설치 버전 조회", + "summary": "Create StackTemplate 'NOT IMPLEMENTED'", "parameters": [ { - "type": "string", - "description": "정책 템플릿 식별자(uuid)", - "name": "policyTemplateId", - "in": "path", - "required": true + "description": "create stack template request", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreateStackTemplateRequest" + } } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateDeployResponse" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreateStackTemplateResponse" } } } } }, - "/api/1.0/admin/policytemplates/{policyTemplateId}/statistics": { + "/admin/stack-templates/services": { "get": { "security": [ { "JWT": [] } ], - "description": "해당 식별자를 가진 정책 템플릿의 최신 버전을 조회한다. 전체 조직의 통계를 조회하려면 organizationId를 tks로 설정한다.", + "description": "Get GetStackTemplateServices", "consumes": [ "application/json" ], @@ -819,36 +853,27 @@ const docTemplate = `{ "application/json" ], "tags": [ - "PolicyTemplate" - ], - "summary": "[ListPolicyTemplateStatistics] 정책 템플릿 사용 카운트 조회", - "parameters": [ - { - "type": "string", - "description": "정책 템플릿 식별자(uuid)", - "name": "policyTemplateId", - "in": "path", - "required": true - } + "StackTemplates" ], + "summary": "Get GetStackTemplateServices", "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateStatisticsResponse" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetStackTemplateServicesResponse" } } } } }, - "/api/1.0/admin/policytemplates/{policyTemplateId}/versions": { + "/admin/stack-templates/{stackTemplateId}": { "get": { "security": [ { "JWT": [] } ], - "description": "해당 식별자를 가진 정책 템플릿의 최신 버전을 조회한다.", + "description": "Get StackTemplate", "consumes": [ "application/json" ], @@ -856,14 +881,14 @@ const docTemplate = `{ "application/json" ], "tags": [ - "PolicyTemplate" + "StackTemplates" ], - "summary": "[ListPolicyTemplateVersions] 정책 템플릿 버전목록 조회", + "summary": "Get StackTemplate", "parameters": [ { "type": "string", - "description": "정책 템플릿 식별자(uuid)", - "name": "policyTemplateId", + "description": "stackTemplateId", + "name": "stackTemplateId", "in": "path", "required": true } @@ -872,18 +897,18 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateVersionsResponse" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetStackTemplateResponse" } } } }, - "post": { + "put": { "security": [ { "JWT": [] } ], - "description": "해당 식별자를 가진 정책 템플릿의 특정 버전을 저장한다.", + "description": "Update StackTemplate", "consumes": [ "application/json" ], @@ -891,45 +916,33 @@ const docTemplate = `{ "application/json" ], "tags": [ - "PolicyTemplate" + "StackTemplates" ], - "summary": "[CreatePolicyTemplateVersion] 정책 템플릿 특정 버전 저장", + "summary": "Update StackTemplate 'NOT IMPLEMENTED'", "parameters": [ { - "type": "string", - "description": "정책 템플릿 식별자(uuid)", - "name": "policyTemplateId", - "in": "path", - "required": true - }, - { - "description": "create policy template version request", + "description": "Update stack template request", "name": "body", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateVersionRequest" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.UpdateStackTemplateRequest" } } ], "responses": { "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateVersionResponse" - } + "description": "OK" } } - } - }, - "/api/1.0/admin/policytemplates/{policyTemplateId}/versions/{version}": { - "get": { + }, + "delete": { "security": [ { "JWT": [] } ], - "description": "해당 식별자를 가진 정책 템플릿의 특정 버전을 조회한다.", + "description": "Delete StackTemplate", "consumes": [ "application/json" ], @@ -937,41 +950,33 @@ const docTemplate = `{ "application/json" ], "tags": [ - "PolicyTemplate" + "StackTemplates" ], - "summary": "[GetPolicyTemplateVersion] 정책 템플릿 특정 버전 조회", + "summary": "Delete StackTemplate 'NOT IMPLEMENTED'", "parameters": [ { "type": "string", - "description": "정책 템플릿 식별자(uuid)", - "name": "policyTemplateId", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "조회할 버전(v0.0.0 형식)", - "name": "version", + "description": "stackTemplateId", + "name": "stackTemplateId", "in": "path", "required": true } ], "responses": { "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateVersionResponse" - } + "description": "OK" } } - }, - "delete": { + } + }, + "/admin/stack-templates/{stackTemplateId}/organizations": { + "put": { "security": [ { "JWT": [] } ], - "description": "해당 식별자를 가진 정책 템플릿의 특정 버전을 삭제한다.", + "description": "Update StackTemplate organizations", "consumes": [ "application/json" ], @@ -979,23 +984,18 @@ const docTemplate = `{ "application/json" ], "tags": [ - "PolicyTemplate" + "StackTemplates" ], - "summary": "[DeletePolicyTemplateVersion] 정책 템플릿 특정 버전 삭제", + "summary": "Update StackTemplate organizations", "parameters": [ { - "type": "string", - "description": "정책 템플릿 식별자(uuid)", - "name": "policyTemplateId", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "삭제할 버전(v0.0.0 형식)", - "name": "version", - "in": "path", - "required": true + "description": "Update stack template organizations request", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.UpdateStackTemplateOrganizationsRequest" + } } ], "responses": { @@ -6538,14 +6538,14 @@ const docTemplate = `{ } } }, - "/system-api/organizations/{organizationId}/alerts": { + "/policytemplates/rego-compile": { "post": { "security": [ { "JWT": [] } ], - "description": "Create alert. ADMIN ONLY", + "description": "Rego 코드 컴파일 및 파라미터 파싱을 수행한다. 파라미터 파싱을 위해서는 먼저 컴파일이 성공해야 하며, parseParameter를 false로 하면 컴파일만 수행할 수 있다.", "consumes": [ "application/json" ], @@ -6553,33 +6553,45 @@ const docTemplate = `{ "application/json" ], "tags": [ - "Alerts" + "PolicyTemplate" ], - "summary": "Create alert. ADMIN ONLY", + "summary": "[CompileRego] Rego 코드 컴파일 및 파라미터 파싱", "parameters": [ { - "type": "string", - "description": "organizationId", - "name": "organizationId", - "in": "path", + "type": "boolean", + "description": "파라미터 파싱 여부", + "name": "parseParameter", + "in": "query", "required": true + }, + { + "description": "Rego 코드", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.RegoCompileRequest" + } } ], "responses": { "200": { - "description": "OK" + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.RegoCompileResponse" + } } } } }, - "/utility/rego-compile": { + "/system-api/organizations/{organizationId}/alerts": { "post": { "security": [ { "JWT": [] } ], - "description": "Rego 코드 컴파일 및 파라미터 파싱을 수행한다. 파라미터 파싱을 위해서는 먼저 컴파일이 성공해야 하며, parseParameter를 false로 하면 컴파일만 수행할 수 있다.", + "description": "Create alert. ADMIN ONLY", "consumes": [ "application/json" ], @@ -6587,33 +6599,21 @@ const docTemplate = `{ "application/json" ], "tags": [ - "Rego" + "Alerts" ], - "summary": "[CompileRego] Rego 코드 컴파일 및 파라미터 파싱", + "summary": "Create alert. ADMIN ONLY", "parameters": [ { - "type": "boolean", - "description": "파라미터 파싱 여부", - "name": "parseParameter", - "in": "query", + "type": "string", + "description": "organizationId", + "name": "organizationId", + "in": "path", "required": true - }, - { - "description": "Rego 코드", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.RegoCompileRequest" - } } ], "responses": { "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.RegoCompileResponse" - } + "description": "OK" } } } diff --git a/api/swagger/swagger.json b/api/swagger/swagger.json index 42ee1952..647962a1 100644 --- a/api/swagger/swagger.json +++ b/api/swagger/swagger.json @@ -208,14 +208,14 @@ } } }, - "/admin/stack-templates": { + "/admin/policytemplates": { "get": { "security": [ { "JWT": [] } ], - "description": "Get StackTemplates", + "description": "정책 템플릿 목록을 조회한다. 정책 템플릿 목록 조회 결과는 최신 템플릿 버전 목록만 조회된다.", "consumes": [ "application/json" ], @@ -223,9 +223,9 @@ "application/json" ], "tags": [ - "StackTemplates" + "PolicyTemplate" ], - "summary": "Get StackTemplates", + "summary": "[ListPolicyTemplate] 정책 템플릿 목록 조회", "parameters": [ { "type": "string", @@ -266,7 +266,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetStackTemplatesResponse" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateResponse" } } } @@ -277,7 +277,7 @@ "JWT": [] } ], - "description": "Create StackTemplate", + "description": "정책 템플릿을 신규 생성(v1.0.0을 생성)한다.", "consumes": [ "application/json" ], @@ -285,17 +285,17 @@ "application/json" ], "tags": [ - "StackTemplates" + "PolicyTemplate" ], - "summary": "Create StackTemplate 'NOT IMPLEMENTED'", + "summary": "[CreatePolicyTemplate] 정책 템플릿 신규 생성", "parameters": [ { - "description": "create stack template request", + "description": "create policy template request", "name": "body", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreateStackTemplateRequest" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateRequest" } } ], @@ -303,20 +303,20 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreateStackTemplateResponse" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateReponse" } } } } }, - "/admin/stack-templates/services": { + "/admin/policytemplates/kind/{policyTemplateKind}/existence": { "get": { "security": [ { "JWT": [] } ], - "description": "Get GetStackTemplateServices", + "description": "해당 유형을 가진 정책 템플릿이 이미 존재하는지 확인한다.", "consumes": [ "application/json" ], @@ -324,27 +324,36 @@ "application/json" ], "tags": [ - "StackTemplates" + "PolicyTemplate" + ], + "summary": "[ExistsPolicyTemplateKind] 정책 템플릿 유형 존재 여부 확인", + "parameters": [ + { + "type": "string", + "description": "정책 템플릿 이름", + "name": "policyTemplateKind", + "in": "path", + "required": true + } ], - "summary": "Get GetStackTemplateServices", "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetStackTemplateServicesResponse" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ExistsPolicyTemplateKindResponse" } } } } }, - "/admin/stack-templates/{stackTemplateId}": { + "/admin/policytemplates/name/{policyTemplateName}/existence": { "get": { "security": [ { "JWT": [] } ], - "description": "Get StackTemplate", + "description": "해당 이름을 가진 정책 템플릿이 이미 존재하는지 확인한다.", "consumes": [ "application/json" ], @@ -352,14 +361,14 @@ "application/json" ], "tags": [ - "StackTemplates" + "PolicyTemplate" ], - "summary": "Get StackTemplate", + "summary": "[ExistsPolicyTemplateName] 정책 템플릿 아름 존재 여부 확인", "parameters": [ { "type": "string", - "description": "stackTemplateId", - "name": "stackTemplateId", + "description": "정책 템플릿 이름", + "name": "policyTemplateName", "in": "path", "required": true } @@ -368,18 +377,20 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetStackTemplateResponse" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CheckExistedResponse" } } } - }, - "put": { + } + }, + "/admin/policytemplates/{policyTemplateId}": { + "get": { "security": [ { "JWT": [] } ], - "description": "Update StackTemplate", + "description": "해당 식별자를 가진 정책 템플릿의 최신 버전을 조회한다.", "consumes": [ "application/json" ], @@ -387,23 +398,24 @@ "application/json" ], "tags": [ - "StackTemplates" + "PolicyTemplate" ], - "summary": "Update StackTemplate 'NOT IMPLEMENTED'", + "summary": "[GetPolicyTemplate] 정책 템플릿 조회(최신 버전)", "parameters": [ { - "description": "Update stack template request", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.UpdateStackTemplateRequest" - } + "type": "string", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true } ], "responses": { "200": { - "description": "OK" + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateResponse" + } } } }, @@ -413,7 +425,7 @@ "JWT": [] } ], - "description": "Delete StackTemplate", + "description": "정책 템플릿을 삭제한다.", "consumes": [ "application/json" ], @@ -421,14 +433,14 @@ "application/json" ], "tags": [ - "StackTemplates" + "PolicyTemplate" ], - "summary": "Delete StackTemplate 'NOT IMPLEMENTED'", + "summary": "[DeletePolicyTemplate] 정책 템플릿 삭제", "parameters": [ { "type": "string", - "description": "stackTemplateId", - "name": "stackTemplateId", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", "in": "path", "required": true } @@ -438,16 +450,14 @@ "description": "OK" } } - } - }, - "/admin/stack-templates/{stackTemplateId}/organizations": { - "put": { + }, + "patch": { "security": [ { "JWT": [] } ], - "description": "Update StackTemplate organizations", + "description": "정책 템플릿의 업데이트 가능한 필드들을 업데이트한다.", "consumes": [ "application/json" ], @@ -455,17 +465,24 @@ "application/json" ], "tags": [ - "StackTemplates" + "PolicyTemplate" ], - "summary": "Update StackTemplate organizations", + "summary": "[UpdatePolicyTemplate] 정책 템플릿 업데이트", "parameters": [ { - "description": "Update stack template organizations request", + "type": "string", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true + }, + { + "description": "update policy template request", "name": "body", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.UpdateStackTemplateOrganizationsRequest" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.UpdatePolicyTemplateRequest" } } ], @@ -476,14 +493,14 @@ } } }, - "/api/1.0/admin/policytemplates": { + "/admin/policytemplates/{policyTemplateId}/deploy": { "get": { "security": [ { "JWT": [] } ], - "description": "정책 템플릿 목록을 조회한다. 정책 템플릿 목록 조회 결과는 최신 템플릿 버전 목록만 조회된다.", + "description": "해당 식별자를 가진 정책 템플릿의 정책 템플릿 클러스터 별 설치 버전을 조회한다.", "consumes": [ "application/json" ], @@ -493,59 +510,34 @@ "tags": [ "PolicyTemplate" ], - "summary": "[ListPolicyTemplate] 정책 템플릿 목록 조회", + "summary": "[GetPolicyTemplateDeploy] 정책 템플릿 클러스터 별 설치 버전 조회", "parameters": [ { "type": "string", - "description": "pageSize", - "name": "limit", - "in": "query" - }, - { - "type": "string", - "description": "pageNumber", - "name": "page", - "in": "query" - }, - { - "type": "string", - "description": "sortColumn", - "name": "soertColumn", - "in": "query" - }, - { - "type": "string", - "description": "sortOrder", - "name": "sortOrder", - "in": "query" - }, - { - "type": "array", - "items": { - "type": "string" - }, - "collectionFormat": "csv", - "description": "filters", - "name": "filters", - "in": "query" + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateResponse" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateDeployResponse" } } } - }, - "post": { + } + }, + "/admin/policytemplates/{policyTemplateId}/statistics": { + "get": { "security": [ { "JWT": [] } ], - "description": "정책 템플릿을 신규 생성(v1.0.0을 생성)한다.", + "description": "해당 식별자를 가진 정책 템플릿의 최신 버전을 조회한다. 전체 조직의 통계를 조회하려면 organizationId를 tks로 설정한다.", "consumes": [ "application/json" ], @@ -555,36 +547,34 @@ "tags": [ "PolicyTemplate" ], - "summary": "[CreatePolicyTemplate] 정책 템플릿 신규 생성", + "summary": "[ListPolicyTemplateStatistics] 정책 템플릿 사용 카운트 조회", "parameters": [ { - "description": "create policy template request", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateRequest" - } + "type": "string", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", + "in": "path", + "required": true } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateReponse" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateStatisticsResponse" } } } } }, - "/api/1.0/admin/policytemplates/kind/{policyTemplateKind}/existence": { + "/admin/policytemplates/{policyTemplateId}/versions": { "get": { "security": [ { "JWT": [] } ], - "description": "해당 유형을 가진 정책 템플릿이 이미 존재하는지 확인한다.", + "description": "해당 식별자를 가진 정책 템플릿의 최신 버전을 조회한다.", "consumes": [ "application/json" ], @@ -594,12 +584,12 @@ "tags": [ "PolicyTemplate" ], - "summary": "[ExistsPolicyTemplateKind] 정책 템플릿 유형 존재 여부 확인", + "summary": "[ListPolicyTemplateVersions] 정책 템플릿 버전목록 조회", "parameters": [ { "type": "string", - "description": "정책 템플릿 이름", - "name": "policyTemplateKind", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", "in": "path", "required": true } @@ -608,20 +598,18 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ExistsPolicyTemplateKindResponse" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateVersionsResponse" } } } - } - }, - "/api/1.0/admin/policytemplates/name/{policyTemplateName}/existence": { - "get": { + }, + "post": { "security": [ { "JWT": [] } ], - "description": "해당 이름을 가진 정책 템플릿이 이미 존재하는지 확인한다.", + "description": "해당 식별자를 가진 정책 템플릿의 특정 버전을 저장한다.", "consumes": [ "application/json" ], @@ -631,34 +619,43 @@ "tags": [ "PolicyTemplate" ], - "summary": "[ExistsPolicyTemplateName] 정책 템플릿 아름 존재 여부 확인", + "summary": "[CreatePolicyTemplateVersion] 정책 템플릿 특정 버전 저장", "parameters": [ { "type": "string", - "description": "정책 템플릿 이름", - "name": "policyTemplateName", + "description": "정책 템플릿 식별자(uuid)", + "name": "policyTemplateId", "in": "path", "required": true + }, + { + "description": "create policy template version request", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateVersionRequest" + } } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CheckExistedResponse" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateVersionResponse" } } } } }, - "/api/1.0/admin/policytemplates/{policyTemplateId}": { + "/admin/policytemplates/{policyTemplateId}/versions/{version}": { "get": { "security": [ { "JWT": [] } ], - "description": "해당 식별자를 가진 정책 템플릿의 최신 버전을 조회한다.", + "description": "해당 식별자를 가진 정책 템플릿의 특정 버전을 조회한다.", "consumes": [ "application/json" ], @@ -668,7 +665,7 @@ "tags": [ "PolicyTemplate" ], - "summary": "[GetPolicyTemplate] 정책 템플릿 조회(최신 버전)", + "summary": "[GetPolicyTemplateVersion] 정책 템플릿 특정 버전 조회", "parameters": [ { "type": "string", @@ -676,13 +673,20 @@ "name": "policyTemplateId", "in": "path", "required": true + }, + { + "type": "string", + "description": "조회할 버전(v0.0.0 형식)", + "name": "version", + "in": "path", + "required": true } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateResponse" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateVersionResponse" } } } @@ -693,7 +697,7 @@ "JWT": [] } ], - "description": "정책 템플릿을 삭제한다.", + "description": "해당 식별자를 가진 정책 템플릿의 특정 버전을 삭제한다.", "consumes": [ "application/json" ], @@ -703,7 +707,7 @@ "tags": [ "PolicyTemplate" ], - "summary": "[DeletePolicyTemplate] 정책 템플릿 삭제", + "summary": "[DeletePolicyTemplateVersion] 정책 템플릿 특정 버전 삭제", "parameters": [ { "type": "string", @@ -711,6 +715,13 @@ "name": "policyTemplateId", "in": "path", "required": true + }, + { + "type": "string", + "description": "삭제할 버전(v0.0.0 형식)", + "name": "version", + "in": "path", + "required": true } ], "responses": { @@ -718,14 +729,16 @@ "description": "OK" } } - }, - "patch": { + } + }, + "/admin/stack-templates": { + "get": { "security": [ { "JWT": [] } ], - "description": "정책 템플릿의 업데이트 가능한 필드들을 업데이트한다.", + "description": "Get StackTemplates", "consumes": [ "application/json" ], @@ -733,42 +746,61 @@ "application/json" ], "tags": [ - "PolicyTemplate" + "StackTemplates" ], - "summary": "[UpdatePolicyTemplate] 정책 템플릿 업데이트", + "summary": "Get StackTemplates", "parameters": [ { "type": "string", - "description": "정책 템플릿 식별자(uuid)", - "name": "policyTemplateId", - "in": "path", - "required": true + "description": "pageSize", + "name": "limit", + "in": "query" }, { - "description": "update policy template request", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.UpdatePolicyTemplateRequest" - } + "type": "string", + "description": "pageNumber", + "name": "page", + "in": "query" + }, + { + "type": "string", + "description": "sortColumn", + "name": "soertColumn", + "in": "query" + }, + { + "type": "string", + "description": "sortOrder", + "name": "sortOrder", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "filters", + "name": "filters", + "in": "query" } ], "responses": { "200": { - "description": "OK" + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetStackTemplatesResponse" + } } } - } - }, - "/api/1.0/admin/policytemplates/{policyTemplateId}/deploy": { - "get": { + }, + "post": { "security": [ { "JWT": [] } ], - "description": "해당 식별자를 가진 정책 템플릿의 정책 템플릿 클러스터 별 설치 버전을 조회한다.", + "description": "Create StackTemplate", "consumes": [ "application/json" ], @@ -776,36 +808,38 @@ "application/json" ], "tags": [ - "PolicyTemplate" + "StackTemplates" ], - "summary": "[GetPolicyTemplateDeploy] 정책 템플릿 클러스터 별 설치 버전 조회", + "summary": "Create StackTemplate 'NOT IMPLEMENTED'", "parameters": [ { - "type": "string", - "description": "정책 템플릿 식별자(uuid)", - "name": "policyTemplateId", - "in": "path", - "required": true + "description": "create stack template request", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreateStackTemplateRequest" + } } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateDeployResponse" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreateStackTemplateResponse" } } } } }, - "/api/1.0/admin/policytemplates/{policyTemplateId}/statistics": { + "/admin/stack-templates/services": { "get": { "security": [ { "JWT": [] } ], - "description": "해당 식별자를 가진 정책 템플릿의 최신 버전을 조회한다. 전체 조직의 통계를 조회하려면 organizationId를 tks로 설정한다.", + "description": "Get GetStackTemplateServices", "consumes": [ "application/json" ], @@ -813,36 +847,27 @@ "application/json" ], "tags": [ - "PolicyTemplate" - ], - "summary": "[ListPolicyTemplateStatistics] 정책 템플릿 사용 카운트 조회", - "parameters": [ - { - "type": "string", - "description": "정책 템플릿 식별자(uuid)", - "name": "policyTemplateId", - "in": "path", - "required": true - } + "StackTemplates" ], + "summary": "Get GetStackTemplateServices", "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateStatisticsResponse" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetStackTemplateServicesResponse" } } } } }, - "/api/1.0/admin/policytemplates/{policyTemplateId}/versions": { + "/admin/stack-templates/{stackTemplateId}": { "get": { "security": [ { "JWT": [] } ], - "description": "해당 식별자를 가진 정책 템플릿의 최신 버전을 조회한다.", + "description": "Get StackTemplate", "consumes": [ "application/json" ], @@ -850,14 +875,14 @@ "application/json" ], "tags": [ - "PolicyTemplate" + "StackTemplates" ], - "summary": "[ListPolicyTemplateVersions] 정책 템플릿 버전목록 조회", + "summary": "Get StackTemplate", "parameters": [ { "type": "string", - "description": "정책 템플릿 식별자(uuid)", - "name": "policyTemplateId", + "description": "stackTemplateId", + "name": "stackTemplateId", "in": "path", "required": true } @@ -866,18 +891,18 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.ListPolicyTemplateVersionsResponse" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetStackTemplateResponse" } } } }, - "post": { + "put": { "security": [ { "JWT": [] } ], - "description": "해당 식별자를 가진 정책 템플릿의 특정 버전을 저장한다.", + "description": "Update StackTemplate", "consumes": [ "application/json" ], @@ -885,45 +910,33 @@ "application/json" ], "tags": [ - "PolicyTemplate" + "StackTemplates" ], - "summary": "[CreatePolicyTemplateVersion] 정책 템플릿 특정 버전 저장", + "summary": "Update StackTemplate 'NOT IMPLEMENTED'", "parameters": [ { - "type": "string", - "description": "정책 템플릿 식별자(uuid)", - "name": "policyTemplateId", - "in": "path", - "required": true - }, - { - "description": "create policy template version request", + "description": "Update stack template request", "name": "body", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateVersionRequest" + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.UpdateStackTemplateRequest" } } ], "responses": { "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateVersionResponse" - } + "description": "OK" } } - } - }, - "/api/1.0/admin/policytemplates/{policyTemplateId}/versions/{version}": { - "get": { + }, + "delete": { "security": [ { "JWT": [] } ], - "description": "해당 식별자를 가진 정책 템플릿의 특정 버전을 조회한다.", + "description": "Delete StackTemplate", "consumes": [ "application/json" ], @@ -931,41 +944,33 @@ "application/json" ], "tags": [ - "PolicyTemplate" + "StackTemplates" ], - "summary": "[GetPolicyTemplateVersion] 정책 템플릿 특정 버전 조회", + "summary": "Delete StackTemplate 'NOT IMPLEMENTED'", "parameters": [ { "type": "string", - "description": "정책 템플릿 식별자(uuid)", - "name": "policyTemplateId", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "조회할 버전(v0.0.0 형식)", - "name": "version", + "description": "stackTemplateId", + "name": "stackTemplateId", "in": "path", "required": true } ], "responses": { "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetPolicyTemplateVersionResponse" - } + "description": "OK" } } - }, - "delete": { + } + }, + "/admin/stack-templates/{stackTemplateId}/organizations": { + "put": { "security": [ { "JWT": [] } ], - "description": "해당 식별자를 가진 정책 템플릿의 특정 버전을 삭제한다.", + "description": "Update StackTemplate organizations", "consumes": [ "application/json" ], @@ -973,23 +978,18 @@ "application/json" ], "tags": [ - "PolicyTemplate" + "StackTemplates" ], - "summary": "[DeletePolicyTemplateVersion] 정책 템플릿 특정 버전 삭제", + "summary": "Update StackTemplate organizations", "parameters": [ { - "type": "string", - "description": "정책 템플릿 식별자(uuid)", - "name": "policyTemplateId", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "삭제할 버전(v0.0.0 형식)", - "name": "version", - "in": "path", - "required": true + "description": "Update stack template organizations request", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.UpdateStackTemplateOrganizationsRequest" + } } ], "responses": { @@ -6532,14 +6532,14 @@ } } }, - "/system-api/organizations/{organizationId}/alerts": { + "/policytemplates/rego-compile": { "post": { "security": [ { "JWT": [] } ], - "description": "Create alert. ADMIN ONLY", + "description": "Rego 코드 컴파일 및 파라미터 파싱을 수행한다. 파라미터 파싱을 위해서는 먼저 컴파일이 성공해야 하며, parseParameter를 false로 하면 컴파일만 수행할 수 있다.", "consumes": [ "application/json" ], @@ -6547,33 +6547,45 @@ "application/json" ], "tags": [ - "Alerts" + "PolicyTemplate" ], - "summary": "Create alert. ADMIN ONLY", + "summary": "[CompileRego] Rego 코드 컴파일 및 파라미터 파싱", "parameters": [ { - "type": "string", - "description": "organizationId", - "name": "organizationId", - "in": "path", + "type": "boolean", + "description": "파라미터 파싱 여부", + "name": "parseParameter", + "in": "query", "required": true + }, + { + "description": "Rego 코드", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.RegoCompileRequest" + } } ], "responses": { "200": { - "description": "OK" + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.RegoCompileResponse" + } } } } }, - "/utility/rego-compile": { + "/system-api/organizations/{organizationId}/alerts": { "post": { "security": [ { "JWT": [] } ], - "description": "Rego 코드 컴파일 및 파라미터 파싱을 수행한다. 파라미터 파싱을 위해서는 먼저 컴파일이 성공해야 하며, parseParameter를 false로 하면 컴파일만 수행할 수 있다.", + "description": "Create alert. ADMIN ONLY", "consumes": [ "application/json" ], @@ -6581,33 +6593,21 @@ "application/json" ], "tags": [ - "Rego" + "Alerts" ], - "summary": "[CompileRego] Rego 코드 컴파일 및 파라미터 파싱", + "summary": "Create alert. ADMIN ONLY", "parameters": [ { - "type": "boolean", - "description": "파라미터 파싱 여부", - "name": "parseParameter", - "in": "query", + "type": "string", + "description": "organizationId", + "name": "organizationId", + "in": "path", "required": true - }, - { - "description": "Rego 코드", - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.RegoCompileRequest" - } } ], "responses": { "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/github_com_openinfradev_tks-api_pkg_domain.RegoCompileResponse" - } + "description": "OK" } } } diff --git a/api/swagger/swagger.yaml b/api/swagger/swagger.yaml index 0f3906d9..60216b96 100644 --- a/api/swagger/swagger.yaml +++ b/api/swagger/swagger.yaml @@ -3188,174 +3188,7 @@ paths: summary: Update user by admin tags: - Admin - /admin/stack-templates: - get: - consumes: - - application/json - description: Get StackTemplates - parameters: - - description: pageSize - in: query - name: limit - type: string - - description: pageNumber - in: query - name: page - type: string - - description: sortColumn - in: query - name: soertColumn - type: string - - description: sortOrder - in: query - name: sortOrder - type: string - - collectionFormat: csv - description: filters - in: query - items: - type: string - name: filters - type: array - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetStackTemplatesResponse' - security: - - JWT: [] - summary: Get StackTemplates - tags: - - StackTemplates - post: - consumes: - - application/json - description: Create StackTemplate - parameters: - - description: create stack template request - in: body - name: body - required: true - schema: - $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreateStackTemplateRequest' - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreateStackTemplateResponse' - security: - - JWT: [] - summary: Create StackTemplate 'NOT IMPLEMENTED' - tags: - - StackTemplates - /admin/stack-templates/{stackTemplateId}: - delete: - consumes: - - application/json - description: Delete StackTemplate - parameters: - - description: stackTemplateId - in: path - name: stackTemplateId - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - security: - - JWT: [] - summary: Delete StackTemplate 'NOT IMPLEMENTED' - tags: - - StackTemplates - get: - consumes: - - application/json - description: Get StackTemplate - parameters: - - description: stackTemplateId - in: path - name: stackTemplateId - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetStackTemplateResponse' - security: - - JWT: [] - summary: Get StackTemplate - tags: - - StackTemplates - put: - consumes: - - application/json - description: Update StackTemplate - parameters: - - description: Update stack template request - in: body - name: body - required: true - schema: - $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.UpdateStackTemplateRequest' - produces: - - application/json - responses: - "200": - description: OK - security: - - JWT: [] - summary: Update StackTemplate 'NOT IMPLEMENTED' - tags: - - StackTemplates - /admin/stack-templates/{stackTemplateId}/organizations: - put: - consumes: - - application/json - description: Update StackTemplate organizations - parameters: - - description: Update stack template organizations request - in: body - name: body - required: true - schema: - $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.UpdateStackTemplateOrganizationsRequest' - produces: - - application/json - responses: - "200": - description: OK - security: - - JWT: [] - summary: Update StackTemplate organizations - tags: - - StackTemplates - /admin/stack-templates/services: - get: - consumes: - - application/json - description: Get GetStackTemplateServices - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetStackTemplateServicesResponse' - security: - - JWT: [] - summary: Get GetStackTemplateServices - tags: - - StackTemplates - /api/1.0/admin/policytemplates: + /admin/policytemplates: get: consumes: - application/json @@ -3419,7 +3252,7 @@ paths: summary: '[CreatePolicyTemplate] 정책 템플릿 신규 생성' tags: - PolicyTemplate - /api/1.0/admin/policytemplates/{policyTemplateId}: + /admin/policytemplates/{policyTemplateId}: delete: consumes: - application/json @@ -3488,7 +3321,7 @@ paths: summary: '[UpdatePolicyTemplate] 정책 템플릿 업데이트' tags: - PolicyTemplate - /api/1.0/admin/policytemplates/{policyTemplateId}/deploy: + /admin/policytemplates/{policyTemplateId}/deploy: get: consumes: - application/json @@ -3511,7 +3344,7 @@ paths: summary: '[GetPolicyTemplateDeploy] 정책 템플릿 클러스터 별 설치 버전 조회' tags: - PolicyTemplate - /api/1.0/admin/policytemplates/{policyTemplateId}/statistics: + /admin/policytemplates/{policyTemplateId}/statistics: get: consumes: - application/json @@ -3535,7 +3368,7 @@ paths: summary: '[ListPolicyTemplateStatistics] 정책 템플릿 사용 카운트 조회' tags: - PolicyTemplate - /api/1.0/admin/policytemplates/{policyTemplateId}/versions: + /admin/policytemplates/{policyTemplateId}/versions: get: consumes: - application/json @@ -3586,7 +3419,7 @@ paths: summary: '[CreatePolicyTemplateVersion] 정책 템플릿 특정 버전 저장' tags: - PolicyTemplate - /api/1.0/admin/policytemplates/{policyTemplateId}/versions/{version}: + /admin/policytemplates/{policyTemplateId}/versions/{version}: delete: consumes: - application/json @@ -3639,7 +3472,7 @@ paths: summary: '[GetPolicyTemplateVersion] 정책 템플릿 특정 버전 조회' tags: - PolicyTemplate - /api/1.0/admin/policytemplates/kind/{policyTemplateKind}/existence: + /admin/policytemplates/kind/{policyTemplateKind}/existence: get: consumes: - application/json @@ -3662,7 +3495,7 @@ paths: summary: '[ExistsPolicyTemplateKind] 정책 템플릿 유형 존재 여부 확인' tags: - PolicyTemplate - /api/1.0/admin/policytemplates/name/{policyTemplateName}/existence: + /admin/policytemplates/name/{policyTemplateName}/existence: get: consumes: - application/json @@ -3685,6 +3518,173 @@ paths: summary: '[ExistsPolicyTemplateName] 정책 템플릿 아름 존재 여부 확인' tags: - PolicyTemplate + /admin/stack-templates: + get: + consumes: + - application/json + description: Get StackTemplates + parameters: + - description: pageSize + in: query + name: limit + type: string + - description: pageNumber + in: query + name: page + type: string + - description: sortColumn + in: query + name: soertColumn + type: string + - description: sortOrder + in: query + name: sortOrder + type: string + - collectionFormat: csv + description: filters + in: query + items: + type: string + name: filters + type: array + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetStackTemplatesResponse' + security: + - JWT: [] + summary: Get StackTemplates + tags: + - StackTemplates + post: + consumes: + - application/json + description: Create StackTemplate + parameters: + - description: create stack template request + in: body + name: body + required: true + schema: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreateStackTemplateRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.CreateStackTemplateResponse' + security: + - JWT: [] + summary: Create StackTemplate 'NOT IMPLEMENTED' + tags: + - StackTemplates + /admin/stack-templates/{stackTemplateId}: + delete: + consumes: + - application/json + description: Delete StackTemplate + parameters: + - description: stackTemplateId + in: path + name: stackTemplateId + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + security: + - JWT: [] + summary: Delete StackTemplate 'NOT IMPLEMENTED' + tags: + - StackTemplates + get: + consumes: + - application/json + description: Get StackTemplate + parameters: + - description: stackTemplateId + in: path + name: stackTemplateId + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetStackTemplateResponse' + security: + - JWT: [] + summary: Get StackTemplate + tags: + - StackTemplates + put: + consumes: + - application/json + description: Update StackTemplate + parameters: + - description: Update stack template request + in: body + name: body + required: true + schema: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.UpdateStackTemplateRequest' + produces: + - application/json + responses: + "200": + description: OK + security: + - JWT: [] + summary: Update StackTemplate 'NOT IMPLEMENTED' + tags: + - StackTemplates + /admin/stack-templates/{stackTemplateId}/organizations: + put: + consumes: + - application/json + description: Update StackTemplate organizations + parameters: + - description: Update stack template organizations request + in: body + name: body + required: true + schema: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.UpdateStackTemplateOrganizationsRequest' + produces: + - application/json + responses: + "200": + description: OK + security: + - JWT: [] + summary: Update StackTemplate organizations + tags: + - StackTemplates + /admin/stack-templates/services: + get: + consumes: + - application/json + description: Get GetStackTemplateServices + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/github_com_openinfradev_tks-api_pkg_domain.GetStackTemplateServicesResponse' + security: + - JWT: [] + summary: Get GetStackTemplateServices + tags: + - StackTemplates /app-groups: delete: consumes: @@ -7235,28 +7235,7 @@ paths: summary: Get Permission Templates tags: - Permission - /system-api/organizations/{organizationId}/alerts: - post: - consumes: - - application/json - description: Create alert. ADMIN ONLY - parameters: - - description: organizationId - in: path - name: organizationId - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - security: - - JWT: [] - summary: Create alert. ADMIN ONLY - tags: - - Alerts - /utility/rego-compile: + /policytemplates/rego-compile: post: consumes: - application/json @@ -7285,7 +7264,28 @@ paths: - JWT: [] summary: '[CompileRego] Rego 코드 컴파일 및 파라미터 파싱' tags: - - Rego + - PolicyTemplate + /system-api/organizations/{organizationId}/alerts: + post: + consumes: + - application/json + description: Create alert. ADMIN ONLY + parameters: + - description: organizationId + in: path + name: organizationId + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + security: + - JWT: [] + summary: Create alert. ADMIN ONLY + tags: + - Alerts securityDefinitions: JWT: in: header diff --git a/internal/delivery/http/policy-template.go b/internal/delivery/http/policy-template.go index 3206545c..2e4a4202 100644 --- a/internal/delivery/http/policy-template.go +++ b/internal/delivery/http/policy-template.go @@ -3,6 +3,7 @@ package http import ( "fmt" "net/http" + "strconv" "strings" "github.com/google/uuid" @@ -35,6 +36,7 @@ type IPolicyTemplateHandler interface { GetPolicyTemplateVersion(w http.ResponseWriter, r *http.Request) DeletePolicyTemplateVersion(w http.ResponseWriter, r *http.Request) ListPolicyTemplateVersions(w http.ResponseWriter, r *http.Request) + RegoCompile(w http.ResponseWriter, r *http.Request) } func NewPolicyTemplateHandler(u usecase.Usecase) IPolicyTemplateHandler { @@ -52,7 +54,7 @@ func NewPolicyTemplateHandler(u usecase.Usecase) IPolicyTemplateHandler { // @Produce json // @Param body body domain.CreatePolicyTemplateRequest true "create policy template request" // @Success 200 {object} domain.CreatePolicyTemplateReponse -// @Router /api/1.0/admin/policytemplates [post] +// @Router /admin/policytemplates [post] // @Security JWT func (h *PolicyTemplateHandler) CreatePolicyTemplate(w http.ResponseWriter, r *http.Request) { input := domain.CreatePolicyTemplateRequest{} @@ -92,7 +94,7 @@ func (h *PolicyTemplateHandler) CreatePolicyTemplate(w http.ResponseWriter, r *h // @Param policyTemplateId path string true "정책 템플릿 식별자(uuid)" // @Param body body domain.UpdatePolicyTemplateRequest true "update policy template request" // @Success 200 {object} nil -// @Router /api/1.0/admin/policytemplates/{policyTemplateId} [patch] +// @Router /admin/policytemplates/{policyTemplateId} [patch] // @Security JWT func (h *PolicyTemplateHandler) UpdatePolicyTemplate(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) @@ -149,7 +151,7 @@ func (h *PolicyTemplateHandler) UpdatePolicyTemplate(w http.ResponseWriter, r *h // @Produce json // @Param policyTemplateId path string true "정책 템플릿 식별자(uuid)" // @Success 200 {object} nil -// @Router /api/1.0/admin/policytemplates/{policyTemplateId} [delete] +// @Router /admin/policytemplates/{policyTemplateId} [delete] // @Security JWT func (h *PolicyTemplateHandler) DeletePolicyTemplate(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) @@ -196,7 +198,7 @@ func (h *PolicyTemplateHandler) DeletePolicyTemplate(w http.ResponseWriter, r *h // @Produce json // @Param policyTemplateId path string true "정책 템플릿 식별자(uuid)" // @Success 200 {object} domain.GetPolicyTemplateResponse -// @Router /api/1.0/admin/policytemplates/{policyTemplateId} [get] +// @Router /admin/policytemplates/{policyTemplateId} [get] // @Security JWT func (h *PolicyTemplateHandler) GetPolicyTemplate(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) @@ -251,7 +253,7 @@ func (h *PolicyTemplateHandler) GetPolicyTemplate(w http.ResponseWriter, r *http // @Param sortOrder query string false "sortOrder" // @Param filters query []string false "filters" // @Success 200 {object} domain.ListPolicyTemplateResponse -// @Router /api/1.0/admin/policytemplates [get] +// @Router /admin/policytemplates [get] // @Security JWT func (h *PolicyTemplateHandler) ListPolicyTemplate(w http.ResponseWriter, r *http.Request) { urlParams := r.URL.Query() @@ -289,7 +291,7 @@ func (h *PolicyTemplateHandler) ListPolicyTemplate(w http.ResponseWriter, r *htt // @Produce json // @Param policyTemplateId path string true "정책 템플릿 식별자(uuid)" // @Success 200 {object} domain.ListPolicyTemplateVersionsResponse -// @Router /api/1.0/admin/policytemplates/{policyTemplateId}/versions [get] +// @Router /admin/policytemplates/{policyTemplateId}/versions [get] // @Security JWT func (h *PolicyTemplateHandler) ListPolicyTemplateVersions(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) @@ -342,7 +344,7 @@ func (h *PolicyTemplateHandler) ListPolicyTemplateVersions(w http.ResponseWriter // @Produce json // @Param policyTemplateId path string true "정책 템플릿 식별자(uuid)" // @Success 200 {object} domain.ListPolicyTemplateStatisticsResponse -// @Router /api/1.0/admin/policytemplates/{policyTemplateId}/statistics [get] +// @Router /admin/policytemplates/{policyTemplateId}/statistics [get] // @Security JWT func (h *PolicyTemplateHandler) ListPolicyTemplateStatistics(w http.ResponseWriter, r *http.Request) { // result := domain.ListPolicyTemplateStatisticsResponse{ @@ -371,7 +373,7 @@ func (h *PolicyTemplateHandler) ListPolicyTemplateStatistics(w http.ResponseWrit // @Produce json // @Param policyTemplateId path string true "정책 템플릿 식별자(uuid)" // @Success 200 {object} domain.GetPolicyTemplateDeployResponse -// @Router /api/1.0/admin/policytemplates/{policyTemplateId}/deploy [get] +// @Router /admin/policytemplates/{policyTemplateId}/deploy [get] // @Security JWT func (h *PolicyTemplateHandler) GetPolicyTemplateDeploy(w http.ResponseWriter, r *http.Request) { // c1 := util.UUIDGen() @@ -398,7 +400,7 @@ func (h *PolicyTemplateHandler) GetPolicyTemplateDeploy(w http.ResponseWriter, r // @Param policyTemplateId path string true "정책 템플릿 식별자(uuid)" // @Param version path string true "조회할 버전(v0.0.0 형식)" // @Success 200 {object} domain.GetPolicyTemplateVersionResponse -// @Router /api/1.0/admin/policytemplates/{policyTemplateId}/versions/{version} [get] +// @Router /admin/policytemplates/{policyTemplateId}/versions/{version} [get] // @Security JWT func (h *PolicyTemplateHandler) GetPolicyTemplateVersion(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) @@ -456,7 +458,7 @@ func (h *PolicyTemplateHandler) GetPolicyTemplateVersion(w http.ResponseWriter, // @Param policyTemplateId path string true "정책 템플릿 식별자(uuid)" // @Param body body domain.CreatePolicyTemplateVersionRequest true "create policy template version request" // @Success 200 {object} domain.CreatePolicyTemplateVersionResponse -// @Router /api/1.0/admin/policytemplates/{policyTemplateId}/versions [post] +// @Router /admin/policytemplates/{policyTemplateId}/versions [post] // @Security JWT func (h *PolicyTemplateHandler) CreatePolicyTemplateVersion(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) @@ -538,7 +540,7 @@ func (h *PolicyTemplateHandler) CreatePolicyTemplateVersion(w http.ResponseWrite // @Param policyTemplateId path string true "정책 템플릿 식별자(uuid)" // @Param version path string true "삭제할 버전(v0.0.0 형식)" // @Success 200 {object} nil -// @Router /api/1.0/admin/policytemplates/{policyTemplateId}/versions/{version} [delete] +// @Router /admin/policytemplates/{policyTemplateId}/versions/{version} [delete] // @Security JWT func (h *PolicyTemplateHandler) DeletePolicyTemplateVersion(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) @@ -591,7 +593,7 @@ func (h *PolicyTemplateHandler) DeletePolicyTemplateVersion(w http.ResponseWrite // @Produce json // @Param policyTemplateName path string true "정책 템플릿 이름" // @Success 200 {object} domain.CheckExistedResponse -// @Router /api/1.0/admin/policytemplates/name/{policyTemplateName}/existence [get] +// @Router /admin/policytemplates/name/{policyTemplateName}/existence [get] // @Security JWT func (h *PolicyTemplateHandler) ExistsPolicyTemplateName(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) @@ -623,7 +625,7 @@ func (h *PolicyTemplateHandler) ExistsPolicyTemplateName(w http.ResponseWriter, // @Produce json // @Param policyTemplateKind path string true "정책 템플릿 이름" // @Success 200 {object} domain.ExistsPolicyTemplateKindResponse -// @Router /api/1.0/admin/policytemplates/kind/{policyTemplateKind}/existence [get] +// @Router /admin/policytemplates/kind/{policyTemplateKind}/existence [get] // @Security JWT func (h *PolicyTemplateHandler) ExistsPolicyTemplateKind(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) @@ -645,3 +647,49 @@ func (h *PolicyTemplateHandler) ExistsPolicyTemplateKind(w http.ResponseWriter, ResponseJSON(w, r, http.StatusOK, out) } + +// CompileRego godoc +// +// @Tags PolicyTemplate +// @Summary [CompileRego] Rego 코드 컴파일 및 파라미터 파싱 +// @Description Rego 코드 컴파일 및 파라미터 파싱을 수행한다. 파라미터 파싱을 위해서는 먼저 컴파일이 성공해야 하며, parseParameter를 false로 하면 컴파일만 수행할 수 있다. +// @Accept json +// @Produce json +// @Param parseParameter query bool true "파라미터 파싱 여부" +// @Param body body domain.RegoCompileRequest true "Rego 코드" +// @Success 200 {object} domain.RegoCompileResponse +// @Router /policytemplates/rego-compile [post] +// @Security JWT +func (h *PolicyTemplateHandler) RegoCompile(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + parseParameter := false + + parse, ok := vars["parseParameter"] + if ok { + parsedBool, err := strconv.ParseBool(parse) + if err != nil { + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("invalid parseParameter: '%s'", parse), "U_INVALID_REGO_PARSEPARAM", "")) + return + } + parseParameter = parsedBool + } + + input := domain.RegoCompileRequest{} + err := UnmarshalRequestInput(r, &input) + if err != nil { + log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) + + ErrorJSON(w, r, err) + return + } + + response, err := h.usecase.RegoCompile(&input, parseParameter) + if err != nil { + log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) + + ErrorJSON(w, r, err) + return + } + + ResponseJSON(w, r, http.StatusCreated, response) +} diff --git a/internal/delivery/http/utility.go b/internal/delivery/http/utility.go deleted file mode 100644 index f22d18fc..00000000 --- a/internal/delivery/http/utility.go +++ /dev/null @@ -1,73 +0,0 @@ -package http - -import ( - "fmt" - "net/http" - "strconv" - - "github.com/gorilla/mux" - "github.com/openinfradev/tks-api/internal/usecase" - "github.com/openinfradev/tks-api/pkg/domain" - "github.com/openinfradev/tks-api/pkg/httpErrors" - "github.com/openinfradev/tks-api/pkg/log" -) - -type UtilityHandler struct { - usecase usecase.IUtilityUsecase -} - -type IUtilityHandler interface { - RegoCompile(w http.ResponseWriter, r *http.Request) -} - -func NewUtilityHandler(u usecase.Usecase) IUtilityHandler { - return &UtilityHandler{ - usecase: u.Utility, - } -} - -// CompileRego godoc -// -// @Tags Rego -// @Summary [CompileRego] Rego 코드 컴파일 및 파라미터 파싱 -// @Description Rego 코드 컴파일 및 파라미터 파싱을 수행한다. 파라미터 파싱을 위해서는 먼저 컴파일이 성공해야 하며, parseParameter를 false로 하면 컴파일만 수행할 수 있다. -// @Accept json -// @Produce json -// @Param parseParameter query bool true "파라미터 파싱 여부" -// @Param body body domain.RegoCompileRequest true "Rego 코드" -// @Success 200 {object} domain.RegoCompileResponse -// @Router /utility/rego-compile [post] -// @Security JWT -func (h *UtilityHandler) RegoCompile(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - parseParameter := false - - parse, ok := vars["parseParameter"] - if ok { - parsedBool, err := strconv.ParseBool(parse) - if err != nil { - ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("invalid parseParameter: '%s'", parse), "U_INVALID_REGO_PARSEPARAM", "")) - return - } - parseParameter = parsedBool - } - - input := domain.RegoCompileRequest{} - err := UnmarshalRequestInput(r, &input) - if err != nil { - log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) - - ErrorJSON(w, r, err) - return - } - - response, err := h.usecase.RegoCompile(&input, parseParameter) - if err != nil { - log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) - - ErrorJSON(w, r, err) - return - } - - ResponseJSON(w, r, http.StatusCreated, response) -} diff --git a/internal/route/route.go b/internal/route/route.go index 76106a23..c28e1da8 100644 --- a/internal/route/route.go +++ b/internal/route/route.go @@ -75,7 +75,6 @@ func SetupRouter(db *gorm.DB, argoClient argowf.ArgoClient, kc keycloak.IKeycloa Role: usecase.NewRoleUsecase(repoFactory), Permission: usecase.NewPermissionUsecase(repoFactory), PolicyTemplate: usecase.NewPolicyTemplateUsecase(repoFactory), - Utility: usecase.NewUtilityUsecase(repoFactory), } customMiddleware := internalMiddleware.NewMiddleware( @@ -282,9 +281,7 @@ func SetupRouter(db *gorm.DB, argoClient argowf.ArgoClient, kc keycloak.IKeycloa r.Handle(API_PREFIX+API_VERSION+ADMINAPI_PREFIX+"/policytemplates/{policyTemplateId}/versions/{version}", customMiddleware.Handle(internalApi.GetPolicyTemplateVersion, http.HandlerFunc(policyTemplateHandler.GetPolicyTemplateVersion))).Methods(http.MethodGet) r.Handle(API_PREFIX+API_VERSION+ADMINAPI_PREFIX+"/policytemplates/kind/{policyTemplateKind}/existence", customMiddleware.Handle(internalApi.ExistsPolicyTemplateKind, http.HandlerFunc(policyTemplateHandler.ExistsPolicyTemplateKind))).Methods(http.MethodGet) r.Handle(API_PREFIX+API_VERSION+ADMINAPI_PREFIX+"/policytemplates/name/{policyTemplateName}/existence", customMiddleware.Handle(internalApi.ExistsPolicyTemplateName, http.HandlerFunc(policyTemplateHandler.ExistsPolicyTemplateName))).Methods(http.MethodGet) - - utilityHandler := delivery.NewUtilityHandler(usecaseFactory) - r.Handle(API_PREFIX+API_VERSION+"/utility/rego-compile", customMiddleware.Handle(internalApi.CompileRego, http.HandlerFunc(utilityHandler.RegoCompile))).Methods(http.MethodPost) + r.Handle(API_PREFIX+API_VERSION+"/policytemplates/rego-compile", customMiddleware.Handle(internalApi.CompileRego, http.HandlerFunc(policyTemplateHandler.RegoCompile))).Methods(http.MethodPost) // assets r.PathPrefix("/api/").HandlerFunc(http.NotFound) diff --git a/internal/usecase/policy-template.go b/internal/usecase/policy-template.go index 2b48af42..46f647fe 100644 --- a/internal/usecase/policy-template.go +++ b/internal/usecase/policy-template.go @@ -3,8 +3,11 @@ package usecase import ( "context" "fmt" + "regexp" + "strings" "github.com/google/uuid" + "github.com/open-policy-agent/opa/ast" "github.com/openinfradev/tks-api/internal/middleware/auth/request" "github.com/openinfradev/tks-api/internal/pagination" "github.com/openinfradev/tks-api/internal/repository" @@ -24,6 +27,8 @@ type IPolicyTemplateUsecase interface { ListPolicyTemplateVersions(ctx context.Context, policyTemplateId uuid.UUID) (policyTemplateVersionsReponse *domain.ListPolicyTemplateVersionsResponse, err error) DeletePolicyTemplateVersion(ctx context.Context, policyTemplateId uuid.UUID, version string) (err error) CreatePolicyTemplateVersion(ctx context.Context, policyTemplateId uuid.UUID, newVersion string, schema []domain.ParameterDef, rego string, libs []string) (version string, err error) + + RegoCompile(request *domain.RegoCompileRequest, parseParameter bool) (response *domain.RegoCompileResponse, err error) } type PolicyTemplateUsecase struct { @@ -226,3 +231,142 @@ func (u *PolicyTemplateUsecase) DeletePolicyTemplateVersion(ctx context.Context, func (u *PolicyTemplateUsecase) CreatePolicyTemplateVersion(ctx context.Context, policyTemplateId uuid.UUID, newVersion string, schema []domain.ParameterDef, rego string, libs []string) (version string, err error) { return u.repo.CreatePolicyTemplateVersion(policyTemplateId, newVersion, schema, rego, libs) } + +func (u *PolicyTemplateUsecase) RegoCompile(request *domain.RegoCompileRequest, parseParameter bool) (response *domain.RegoCompileResponse, err error) { + modules := map[string]*ast.Module{} + + response = &domain.RegoCompileResponse{} + response.Errors = []domain.RegoCompieError{} + + mod, err := ast.ParseModuleWithOpts("rego", request.Rego, ast.ParserOptions{}) + if err != nil { + return nil, err + } + modules["rego"] = mod + + compiler := ast.NewCompiler() + compiler.Compile(modules) + + if compiler.Failed() { + for _, compileError := range compiler.Errors { + response.Errors = append(response.Errors, domain.RegoCompieError{ + Status: 400, + Code: "P_INVALID_REGO_SYNTAX", + Message: "Invalid rego syntax", + Text: fmt.Sprintf("[%d:%d] %s", + compileError.Location.Row, compileError.Location.Col, + compileError.Message), + }) + } + } + + if parseParameter { + response.ParametersSchema = extractParameter(request.Rego) + } + + return response, nil +} + +func extractParameter(rego string) []*domain.ParameterDef { + pattern := `input\.parameters\.[\w\.\[\]]+` + + prefix := "input.parameters." + + // Compile the regex pattern + regex := regexp.MustCompile(pattern) + + matches := regex.FindAllString(rego, -1) + + defStore := NewParamDefStore() + + for _, match := range matches { + remainder := match[len(prefix):] + + // 문법 변환: aa["a"]["B"][_]->aa.a.B[_] + regex := regexp.MustCompile(`\[\"(\w+)\"\]`) + remainder = regex.ReplaceAllString(remainder, ".$1") + + params := strings.Split(remainder, ".") + + if len(params) == 0 { + continue + } + + defStore.AddDefinition(params) + } + + return defStore.store +} + +type ParamDefStore struct { + store []*domain.ParameterDef +} + +func NewParamDefStore() *ParamDefStore { + return &ParamDefStore{store: []*domain.ParameterDef{}} +} + +func (s *ParamDefStore) GetStore() []*domain.ParameterDef { + return s.store +} + +func (s *ParamDefStore) AddDefinition(params []string) { + init := &s.store + + for i, param := range params { + isLast := i == len(params)-1 + + key := findKey(s.store, param) + + if key == nil { + key = createKey(param, isLast) + *init = append(*init, key) + } + + init = &key.Children + } +} + +func findKey(defs []*domain.ParameterDef, key string) *domain.ParameterDef { + for _, def := range defs { + if def.Key == key || def.Key+"[_]" == key { + return def + } + } + + return nil +} + +func createKey(key string, isLast bool) *domain.ParameterDef { + finalType := "any" + + pKey := key + isArray := false + + if strings.HasSuffix(pKey, "[_]") { + pKey, _ = strings.CutSuffix(pKey, "[_]") + isArray = true + } + + if isLast { + if isArray { + finalType = "any[]" + } else { + finalType = "any" + } + } else { + if isArray { + finalType = "object[]" + } else { + finalType = "object" + } + } + + newDef := &domain.ParameterDef{ + Key: pKey, + Type: finalType, + Children: []*domain.ParameterDef{}, + } + + return newDef +} diff --git a/internal/usecase/usecase.go b/internal/usecase/usecase.go index 48f47ae2..f0ad4014 100644 --- a/internal/usecase/usecase.go +++ b/internal/usecase/usecase.go @@ -17,5 +17,4 @@ type Usecase struct { Permission IPermissionUsecase Audit IAuditUsecase PolicyTemplate IPolicyTemplateUsecase - Utility IUtilityUsecase } diff --git a/internal/usecase/utility.go b/internal/usecase/utility.go deleted file mode 100644 index c7f421f9..00000000 --- a/internal/usecase/utility.go +++ /dev/null @@ -1,161 +0,0 @@ -package usecase - -import ( - "fmt" - "regexp" - "strings" - - "github.com/open-policy-agent/opa/ast" - "github.com/openinfradev/tks-api/internal/repository" - "github.com/openinfradev/tks-api/pkg/domain" -) - -type IUtilityUsecase interface { - RegoCompile(request *domain.RegoCompileRequest, parseParameter bool) (response *domain.RegoCompileResponse, err error) -} - -type UtilityUsecase struct { -} - -func NewUtilityUsecase(r repository.Repository) IUtilityUsecase { - return &UtilityUsecase{} -} - -func (u *UtilityUsecase) RegoCompile(request *domain.RegoCompileRequest, parseParameter bool) (response *domain.RegoCompileResponse, err error) { - modules := map[string]*ast.Module{} - - response = &domain.RegoCompileResponse{} - response.Errors = []domain.RegoCompieError{} - - mod, err := ast.ParseModuleWithOpts("rego", request.Rego, ast.ParserOptions{}) - if err != nil { - return nil, err - } - modules["rego"] = mod - - compiler := ast.NewCompiler() - compiler.Compile(modules) - - if compiler.Failed() { - for _, compileError := range compiler.Errors { - response.Errors = append(response.Errors, domain.RegoCompieError{ - Status: 400, - Code: "P_INVALID_REGO_SYNTAX", - Message: "Invalid rego syntax", - Text: fmt.Sprintf("[%d:%d] %s", - compileError.Location.Row, compileError.Location.Col, - compileError.Message), - }) - } - } - - if parseParameter { - response.ParametersSchema = extractParameter(request.Rego) - } - - return response, nil -} - -func extractParameter(rego string) []*domain.ParameterDef { - pattern := `input\.parameters\.[\w\.\[\]]+` - - prefix := "input.parameters." - - // Compile the regex pattern - regex := regexp.MustCompile(pattern) - - matches := regex.FindAllString(rego, -1) - - defStore := NewParamDefStore() - - for _, match := range matches { - remainder := match[len(prefix):] - - // 문법 변환: aa["a"]["B"][_]->aa.a.B[_] - regex := regexp.MustCompile(`\[\"(\w+)\"\]`) - remainder = regex.ReplaceAllString(remainder, ".$1") - - params := strings.Split(remainder, ".") - - if len(params) == 0 { - continue - } - - defStore.AddDefinition(params) - } - - return defStore.store -} - -type ParamDefStore struct { - store []*domain.ParameterDef -} - -func NewParamDefStore() *ParamDefStore { - return &ParamDefStore{store: []*domain.ParameterDef{}} -} - -func (s *ParamDefStore) GetStore() []*domain.ParameterDef { - return s.store -} - -func (s *ParamDefStore) AddDefinition(params []string) { - init := &s.store - - for i, param := range params { - isLast := i == len(params)-1 - - key := findKey(s.store, param) - - if key == nil { - key = createKey(param, isLast) - *init = append(*init, key) - } - - init = &key.Children - } -} - -func findKey(defs []*domain.ParameterDef, key string) *domain.ParameterDef { - for _, def := range defs { - if def.Key == key || def.Key+"[_]" == key { - return def - } - } - - return nil -} - -func createKey(key string, isLast bool) *domain.ParameterDef { - finalType := "any" - - pKey := key - isArray := false - - if strings.HasSuffix(pKey, "[_]") { - pKey, _ = strings.CutSuffix(pKey, "[_]") - isArray = true - } - - if isLast { - if isArray { - finalType = "any[]" - } else { - finalType = "any" - } - } else { - if isArray { - finalType = "object[]" - } else { - finalType = "object" - } - } - - newDef := &domain.ParameterDef{ - Key: pKey, - Type: finalType, - Children: []*domain.ParameterDef{}, - } - - return newDef -} diff --git a/pkg/domain/policy-template.go b/pkg/domain/policy-template.go index acea768d..169714ef 100644 --- a/pkg/domain/policy-template.go +++ b/pkg/domain/policy-template.go @@ -276,3 +276,27 @@ type ExistsPolicyTemplateNameResponse struct { type ExistsPolicyTemplateKindResponse struct { } + +type ParameterDef struct { + Key string `json:"key"` + Type string `json:"type"` + DefaultValue string `json:"defaultValue"` + Children []*ParameterDef `json:"children"` + IsArray bool +} + +type RegoCompileRequest struct { + Rego string `json:"rego" example:"Rego 코드"` +} + +type RegoCompieError struct { + Status int `json:"status" example:"400"` + Code string `json:"code" example:"P_INVALID_REGO_SYNTAX"` + Message string `json:"message" example:"Invalid rego syntax"` + Text string `json:"text" example:"Rego 문법 에러입니다. 라인:2 컬럼:1 에러메시지: var testnum is not safe"` +} + +type RegoCompileResponse struct { + ParametersSchema []*ParameterDef `json:"parametersSchema,omitempty"` + Errors []RegoCompieError `json:"errors,omitempty"` +} diff --git a/pkg/domain/rego.go b/pkg/domain/rego.go deleted file mode 100644 index 056111bb..00000000 --- a/pkg/domain/rego.go +++ /dev/null @@ -1,25 +0,0 @@ -package domain - -type ParameterDef struct { - Key string `json:"key"` - Type string `json:"type"` - DefaultValue string `json:"defaultValue"` - Children []*ParameterDef `json:"children"` - IsArray bool -} - -type RegoCompileRequest struct { - Rego string `json:"rego" example:"Rego 코드"` -} - -type RegoCompieError struct { - Status int `json:"status" example:"400"` - Code string `json:"code" example:"P_INVALID_REGO_SYNTAX"` - Message string `json:"message" example:"Invalid rego syntax"` - Text string `json:"text" example:"Rego 문법 에러입니다. 라인:2 컬럼:1 에러메시지: var testnum is not safe"` -} - -type RegoCompileResponse struct { - ParametersSchema []*ParameterDef `json:"parametersSchema,omitempty"` - Errors []RegoCompieError `json:"errors,omitempty"` -} From d84d983dcf128977b1af15f6b555167c38c35dee Mon Sep 17 00:00:00 2001 From: sangkenlee Date: Mon, 11 Mar 2024 15:00:55 +0900 Subject: [PATCH 3/4] errCode fix --- internal/delivery/http/policy-template.go | 75 ++++++++--------------- internal/usecase/policy-template.go | 18 +++--- pkg/httpErrors/errorCode.go | 42 ++++++++----- 3 files changed, 61 insertions(+), 74 deletions(-) diff --git a/internal/delivery/http/policy-template.go b/internal/delivery/http/policy-template.go index 2e4a4202..8126e00f 100644 --- a/internal/delivery/http/policy-template.go +++ b/internal/delivery/http/policy-template.go @@ -100,19 +100,14 @@ func (h *PolicyTemplateHandler) UpdatePolicyTemplate(w http.ResponseWriter, r *h vars := mux.Vars(r) policyTemplateId, ok := vars["policyTemplateId"] if !ok { - ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("Invalid policyTemplateId"), "C_INVALID_ORGANIZATION_ID", "")) + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("invalid policyTemplateId"), "C_INVALID_POLICY_TEMPLATE_ID", "")) return } id, err := uuid.Parse(policyTemplateId) if err != nil { log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) - if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound { - ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "", "")) - return - } - - ErrorJSON(w, r, err) + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("invalid policyTemplateId"), "C_INVALID_POLICY_TEMPLATE_ID", "")) return } @@ -157,7 +152,7 @@ func (h *PolicyTemplateHandler) DeletePolicyTemplate(w http.ResponseWriter, r *h vars := mux.Vars(r) policyTemplateId, ok := vars["policyTemplateId"] if !ok { - ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("Invalid policyTemplateId"), "C_INVALID_POLICY_TEMPLATE_ID", "")) + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("invalid policyTemplateId"), "C_INVALID_POLICY_TEMPLATE_ID", "")) return } @@ -204,7 +199,7 @@ func (h *PolicyTemplateHandler) GetPolicyTemplate(w http.ResponseWriter, r *http vars := mux.Vars(r) policyTemplateId, ok := vars["policyTemplateId"] if !ok { - ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("Invalid policyTemplateId"), "C_INVALID_ORGANIZATION_ID", "")) + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("invalid policyTemplateId"), "C_INVALID_POLICY_TEMPLATE_ID", "")) return } @@ -212,7 +207,7 @@ func (h *PolicyTemplateHandler) GetPolicyTemplate(w http.ResponseWriter, r *http if err != nil { log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound { - ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "", "")) + ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "C_INVALID_POLICY_TEMPLATE_ID", "")) return } @@ -224,7 +219,7 @@ func (h *PolicyTemplateHandler) GetPolicyTemplate(w http.ResponseWriter, r *http if err != nil { log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound { - ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "", "")) + ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "PT_NOT_FOUND_POLICY_TEMPLATE", "")) return } @@ -298,19 +293,14 @@ func (h *PolicyTemplateHandler) ListPolicyTemplateVersions(w http.ResponseWriter policyTemplateId, ok := vars["policyTemplateId"] if !ok { - ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("Invalid policyTemplateId"), "C_INVALID_ORGANIZATION_ID", "")) + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("invalid policyTemplateId"), "C_INVALID_POLICY_TEMPLATE_ID", "")) return } id, err := uuid.Parse(policyTemplateId) if err != nil { log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) - if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound { - ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "", "")) - return - } - - ErrorJSON(w, r, err) + ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "C_INVALID_POLICY_TEMPLATE_ID", "")) return } @@ -319,7 +309,7 @@ func (h *PolicyTemplateHandler) ListPolicyTemplateVersions(w http.ResponseWriter if err != nil { log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound { - ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "", "")) + ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "PT_NOT_FOUND_POLICY_TEMPLATE_VERSION", "")) return } @@ -406,25 +396,19 @@ func (h *PolicyTemplateHandler) GetPolicyTemplateVersion(w http.ResponseWriter, vars := mux.Vars(r) policyTemplateId, ok := vars["policyTemplateId"] if !ok { - ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("Invalid policyTemplateId"), "C_INVALID_ORGANIZATION_ID", "")) + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("invalid policyTemplateId"), "C_INVALID_POLICY_TEMPLATE_ID", "")) return } version, ok := vars["version"] if !ok { - ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("Invalid version"), "C_INVALID_ORGANIZATION_ID", "")) + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("invalid version"), "PT_INVALID_POLICY_TEMPLATE_VERSION", "")) return } id, err := uuid.Parse(policyTemplateId) if err != nil { - log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) - if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound { - ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "", "")) - return - } - - ErrorJSON(w, r, err) + ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "C_INVALID_POLICY_TEMPLATE_ID", "")) return } @@ -432,7 +416,7 @@ func (h *PolicyTemplateHandler) GetPolicyTemplateVersion(w http.ResponseWriter, if err != nil { log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound { - ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "", "")) + ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "PT_NOT_FOUND_POLICY_TEMPLATE_VERSION", "")) return } @@ -464,19 +448,13 @@ func (h *PolicyTemplateHandler) CreatePolicyTemplateVersion(w http.ResponseWrite vars := mux.Vars(r) policyTemplateId, ok := vars["policyTemplateId"] if !ok { - ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("Invalid policyTemplateId"), "C_INVALID_POLICY_TEMPLATE_ID", "")) + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("invalid policyTemplateId"), "C_INVALID_POLICY_TEMPLATE_ID", "")) return } id, err := uuid.Parse(policyTemplateId) if err != nil { - log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) - if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound { - ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "", "")) - return - } - - ErrorJSON(w, r, err) + ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "C_INVALID_POLICY_TEMPLATE_ID", "")) return } @@ -492,7 +470,7 @@ func (h *PolicyTemplateHandler) CreatePolicyTemplateVersion(w http.ResponseWrite currentVer, err := semver.NewVersion(input.CurrentVersion) if err != nil { - ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("Invalid currentVersion"), "C_INVALID_CURRENT_VERSION", fmt.Sprintf("invalid version format '%s'", input.CurrentVersion))) + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("invalid currentVersion"), "PT_INVALID_POLICY_TEMPLATE_VERSION", fmt.Sprintf("invalid version format '%s'", input.CurrentVersion))) return } @@ -513,7 +491,7 @@ func (h *PolicyTemplateHandler) CreatePolicyTemplateVersion(w http.ResponseWrite } if expectedVersion != input.ExpectedVersion { - ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("Invalid expectedVersion"), "C_INVALID_EXPECTED_VERSION", fmt.Sprintf("expected version mismatch '%s' != '%s'", + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("invalid expectedVersion"), "PT_INVALID_POLICY_TEMPLATE_VERSION", fmt.Sprintf("expected version mismatch '%s' != '%s'", input.ExpectedVersion, expectedVersion))) } @@ -546,25 +524,20 @@ func (h *PolicyTemplateHandler) DeletePolicyTemplateVersion(w http.ResponseWrite vars := mux.Vars(r) policyTemplateId, ok := vars["policyTemplateId"] if !ok { - ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("Invalid policyTemplateId"), "C_INVALID_POLICY_TEMPLATE_ID", "")) + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("invalid policyTemplateId"), "C_INVALID_POLICY_TEMPLATE_ID", "")) return } version, ok := vars["version"] if !ok { - ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("Invalid version"), "C_INVALID_VERSION", "")) + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("invalid version"), "PT_INVALID_POLICY_TEMPLATE_VERSION", "")) return } id, err := uuid.Parse(policyTemplateId) if err != nil { log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) - if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound { - ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "", "")) - return - } - - ErrorJSON(w, r, err) + ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "PT_INVALID_POLICY_TEMPLATE_VERSION", "")) return } @@ -573,7 +546,7 @@ func (h *PolicyTemplateHandler) DeletePolicyTemplateVersion(w http.ResponseWrite if err != nil { log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound { - ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "", "")) + ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "PT_NOT_FOUND_POLICY_TEMPLATE_VERSION", "")) return } @@ -600,7 +573,7 @@ func (h *PolicyTemplateHandler) ExistsPolicyTemplateName(w http.ResponseWriter, policyTemplateName, ok := vars["policyTemplateName"] if !ok { ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("policyTemplateName not found in path"), - "C_INVALID_POLICYTEMPLATE_NAME", "")) + "PT_INVALID_POLICY_TEMPLATE_NAME", "")) return } @@ -632,7 +605,7 @@ func (h *PolicyTemplateHandler) ExistsPolicyTemplateKind(w http.ResponseWriter, policyTemplateKind, ok := vars["policyTemplateKind"] if !ok { ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("policyTemplateKind not found in path"), - "C_INVALID_POLICY_TEMPLATE_KIND", "")) + "PT_INVALID_POLICY_TEMPLATE_KIND", "")) return } @@ -668,7 +641,7 @@ func (h *PolicyTemplateHandler) RegoCompile(w http.ResponseWriter, r *http.Reque if ok { parsedBool, err := strconv.ParseBool(parse) if err != nil { - ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("invalid parseParameter: '%s'", parse), "U_INVALID_REGO_PARSEPARAM", "")) + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("invalid parseParameter: '%s'", parse), "PT_INVALID_REGO_PARSEPARAMETER", "")) return } parseParameter = parsedBool diff --git a/internal/usecase/policy-template.go b/internal/usecase/policy-template.go index 46f647fe..9f1b8263 100644 --- a/internal/usecase/policy-template.go +++ b/internal/usecase/policy-template.go @@ -48,23 +48,23 @@ func NewPolicyTemplateUsecase(r repository.Repository) IPolicyTemplateUsecase { func (u *PolicyTemplateUsecase) Create(ctx context.Context, dto domain.PolicyTemplate) (policyTemplateId string, err error) { user, ok := request.UserFrom(ctx) if !ok { - return "", httpErrors.NewUnauthorizedError(fmt.Errorf("Invalid token"), "P_INVALID_TOKEN", "") + return "", httpErrors.NewUnauthorizedError(fmt.Errorf("invalid token"), "A_INVALID_TOKEN", "") } exists, err := u.repo.ExistByName(dto.TemplateName) if err == nil && exists { - return "", httpErrors.NewBadRequestError(httpErrors.DuplicateResource, "P_INVALID_POLICY_TEMPLATE_NAME", "policy template name already exists") + return "", httpErrors.NewBadRequestError(httpErrors.DuplicateResource, "PT_CREATE_ALREADY_EXISTED_NAME", "policy template name already exists") } exists, err = u.repo.ExistByKind(dto.Kind) if err == nil && exists { - return "", httpErrors.NewBadRequestError(httpErrors.DuplicateResource, "P_INVALID_POLICY_TEMPLATE_KIND", "policy template kind already exists") + return "", httpErrors.NewBadRequestError(httpErrors.DuplicateResource, "PT_CREATE_ALREADY_EXISTED_KIND", "policy template kind already exists") } for _, organizationId := range dto.PermittedOrganizationIds { _, err = u.organizationRepo.Get(organizationId) if err != nil { - return "", httpErrors.NewBadRequestError(fmt.Errorf("Invalid organizationId"), "", "") + return "", httpErrors.NewBadRequestError(fmt.Errorf("invalid organizationId"), "C_INVALID_ORGANIZATION_ID", "") } } @@ -119,12 +119,12 @@ func (u *PolicyTemplateUsecase) Get(ctx context.Context, policyTemplateID uuid.U func (u *PolicyTemplateUsecase) Update(ctx context.Context, policyTemplateId uuid.UUID, update domain.UpdatePolicyTemplateRequest) (err error) { user, ok := request.UserFrom(ctx) if !ok { - return httpErrors.NewBadRequestError(fmt.Errorf("Invalid token"), "", "") + return httpErrors.NewBadRequestError(fmt.Errorf("invalid token"), "A_INVALID_TOKEN", "") } _, err = u.repo.GetByID(policyTemplateId) if err != nil { - return httpErrors.NewNotFoundError(err, "P_FAILED_FETCH_POLICY_TEMPLATE", "") + return httpErrors.NewNotFoundError(err, "PT_FAILED_FETCH_POLICY_TEMPLATE", "") } exists, err := u.repo.ExistByName(*update.TemplateName) @@ -136,7 +136,7 @@ func (u *PolicyTemplateUsecase) Update(ctx context.Context, policyTemplateId uui for _, organizationId := range *update.PermittedOrganizationIds { _, err = u.organizationRepo.Get(organizationId) if err != nil { - return httpErrors.NewBadRequestError(fmt.Errorf("Invalid organizationId"), "", "") + return httpErrors.NewBadRequestError(fmt.Errorf("invalid organizationId"), "C_INVALID_ORGANIZATION_ID", "") } } } @@ -251,8 +251,8 @@ func (u *PolicyTemplateUsecase) RegoCompile(request *domain.RegoCompileRequest, for _, compileError := range compiler.Errors { response.Errors = append(response.Errors, domain.RegoCompieError{ Status: 400, - Code: "P_INVALID_REGO_SYNTAX", - Message: "Invalid rego syntax", + Code: "PT_INVALID_REGO_SYNTAX", + Message: "invalid rego syntax", Text: fmt.Sprintf("[%d:%d] %s", compileError.Location.Row, compileError.Location.Col, compileError.Message), diff --git a/pkg/httpErrors/errorCode.go b/pkg/httpErrors/errorCode.go index 3a7a7e30..342fecc5 100644 --- a/pkg/httpErrors/errorCode.go +++ b/pkg/httpErrors/errorCode.go @@ -4,20 +4,21 @@ type ErrorCode string var errorMap = map[ErrorCode]string{ // Common - "C_INTERNAL_ERROR": "예상하지 못한 오류가 발생했습니다. 문제가 계속되면 관리자에게 문의해주세요.", - "C_INVALID_ACCOUNT_ID": "유효하지 않은 어카운트 아이디입니다. 어카운트 아이디를 확인하세요.", - "C_INVALID_STACK_ID": "유효하지 않은 스택 아이디입니다. 스택 아이디를 확인하세요.", - "C_INVALID_CLUSTER_ID": "유효하지 않은 클러스터 아이디입니다. 클러스터 아이디를 확인하세요.", - "C_INVALID_APPGROUP_ID": "유효하지 않은 앱그룹 아이디입니다. 앱그룹 아이디를 확인하세요.", - "C_INVALID_ORGANIZATION_ID": "유효하지 않은 조직 아이디입니다. 조직 아이디를 확인하세요.", - "C_INVALID_PROJECT_ID": "유효하지 않은 프로젝트 아이디입니다. 아이디를 확인하세요.", - "C_INVALID_CLOUD_ACCOUNT_ID": "유효하지 않은 클라우드어카운트 아이디입니다. 클라우드어카운트 아이디를 확인하세요.", - "C_INVALID_STACK_TEMPLATE_ID": "유효하지 않은 스택템플릿 아이디입니다. 스택템플릿 아이디를 확인하세요.", - "C_INVALID_ASA_ID": "유효하지 않은 앱서빙앱 아이디입니다. 앱서빙앱 아이디를 확인하세요.", - "C_INVALID_ASA_TASK_ID": "유효하지 않은 테스크 아이디입니다. 테스크 아이디를 확인하세요.", - "C_INVALID_CLOUD_SERVICE": "유효하지 않은 클라우드서비스입니다.", - "C_INVALID_AUDIT_ID": "유효하지 않은 로그 아이디입니다. 로그 아이디를 확인하세요.", - "C_FAILED_TO_CALL_WORKFLOW": "워크플로우 호출에 실패했습니다.", + "C_INTERNAL_ERROR": "예상하지 못한 오류가 발생했습니다. 문제가 계속되면 관리자에게 문의해주세요.", + "C_INVALID_ACCOUNT_ID": "유효하지 않은 어카운트 아이디입니다. 어카운트 아이디를 확인하세요.", + "C_INVALID_STACK_ID": "유효하지 않은 스택 아이디입니다. 스택 아이디를 확인하세요.", + "C_INVALID_CLUSTER_ID": "유효하지 않은 클러스터 아이디입니다. 클러스터 아이디를 확인하세요.", + "C_INVALID_APPGROUP_ID": "유효하지 않은 앱그룹 아이디입니다. 앱그룹 아이디를 확인하세요.", + "C_INVALID_ORGANIZATION_ID": "유효하지 않은 조직 아이디입니다. 조직 아이디를 확인하세요.", + "C_INVALID_PROJECT_ID": "유효하지 않은 프로젝트 아이디입니다. 아이디를 확인하세요.", + "C_INVALID_CLOUD_ACCOUNT_ID": "유효하지 않은 클라우드어카운트 아이디입니다. 클라우드어카운트 아이디를 확인하세요.", + "C_INVALID_STACK_TEMPLATE_ID": "유효하지 않은 스택템플릿 아이디입니다. 스택템플릿 아이디를 확인하세요.", + "C_INVALID_ASA_ID": "유효하지 않은 앱서빙앱 아이디입니다. 앱서빙앱 아이디를 확인하세요.", + "C_INVALID_ASA_TASK_ID": "유효하지 않은 테스크 아이디입니다. 테스크 아이디를 확인하세요.", + "C_INVALID_CLOUD_SERVICE": "유효하지 않은 클라우드서비스입니다.", + "C_INVALID_AUDIT_ID": "유효하지 않은 로그 아이디입니다. 로그 아이디를 확인하세요.", + "C_INVALID_POLICY_TEMPLATE_ID": "유효하지 않은 정책 템플릿 아이디입니다. 정책 템플릿 아이디를 확인하세요.", + "C_FAILED_TO_CALL_WORKFLOW": "워크플로우 호출에 실패했습니다.", // Auth "A_INVALID_ID": "아이디가 존재하지 않습니다.", @@ -82,6 +83,19 @@ var errorMap = map[ErrorCode]string{ "ST_CREATE_ALREADY_EXISTED_NAME": "스택 템플릿에 이미 존재하는 이름입니다.", "ST_FAILED_UPDATE_ORGANIZATION": "스택 템플릿에 조직을 설정하는데 실패했습니다.", "ST_NOT_EXISTED_STACK_TEMPLATE": "업데이트할 스택템플릿이 존재하지 않습니다.", + + // PolicyTemplate + "PT_CREATE_ALREADY_EXISTED_NAME": "정첵 템플릿에 이미 존재하는 이름입니다.", + "PT_CREATE_ALREADY_EXISTED_KIND": "정책 템플릿에 이미 존재하는 유형입니다.", + "PT_NOT_FOUND_POLICY_TEMPLATE": "정책 템플릿이 존재하지 않습니다.", + "PT_INVALID_KIND": "유효하지 않은 정책 템플릿 유형입니다. 정책 템플릿 유형을 확인하세요.", + "PT_FAILED_FETCH_POLICY_TEMPLATE": "정책 템플릿 ID에 해당하는 정책 템플릿을 가져오는데 실패했습니다.", + "PT_INVALID_REGO_SYNTAX": "Rego 문법 오류입니다.", + "PT_INVALID_POLICY_TEMPLATE_VERSION": "유효하지 않은 정책 템플릿 버전닙니다. 정책 템플릿 버전을 확인하세요.", + "PT_NOT_FOUND_POLICY_TEMPLATE_VERSION": "정책 템플릿 버전이 존재하지 않습니다.", + "PT_INVALID_POLICY_TEMPLATE_NAME": "유효하지 않은 정책 템플릿 이름입니다. 정책 템플릿 이름을 확인하세요.", + "PT_INVALID_POLICY_TEMPLATE_KIND": "유효하지 않은 정책 템플릿 유형입니다. 정책 템플릿 유형을 확인하세요.", + "PT_INVALID_REGO_PARSEPARAMETER": "유효하지 않은 Rego 파싱 설정입니다. Rego 파싱 설정을 확인하세요.", } func (m ErrorCode) GetText() string { From 03333a25eabda083ad0d9e42bfd2b6a40aff0519 Mon Sep 17 00:00:00 2001 From: sangkenlee Date: Mon, 11 Mar 2024 15:42:13 +0900 Subject: [PATCH 4/4] add validation on request --- api/swagger/docs.go | 17 +++++++++++++---- api/swagger/swagger.json | 17 +++++++++++++---- api/swagger/swagger.yaml | 13 ++++++++++--- pkg/domain/policy-template.go | 23 +++++++++++------------ 4 files changed, 47 insertions(+), 23 deletions(-) diff --git a/api/swagger/docs.go b/api/swagger/docs.go index b40b355d..4464bf58 100644 --- a/api/swagger/docs.go +++ b/api/swagger/docs.go @@ -7924,6 +7924,10 @@ const docTemplate = `{ }, "github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateRequest": { "type": "object", + "required": [ + "kind", + "rego" + ], "properties": { "deprecated": { "type": "boolean", @@ -7971,10 +7975,6 @@ const docTemplate = `{ ], "example": "medium" }, - "target": { - "type": "string", - "example": "admission.k8s.gatekeeper.sh" - }, "templateName": { "type": "string", "example": "필수 Label 검사" @@ -7983,6 +7983,12 @@ const docTemplate = `{ }, "github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateVersionRequest": { "type": "object", + "required": [ + "currentVersion", + "expectedVersion", + "rego", + "versionUpType" + ], "properties": { "currentVersion": { "type": "string", @@ -9905,6 +9911,9 @@ const docTemplate = `{ }, "github_com_openinfradev_tks-api_pkg_domain.RegoCompileRequest": { "type": "object", + "required": [ + "rego" + ], "properties": { "rego": { "type": "string", diff --git a/api/swagger/swagger.json b/api/swagger/swagger.json index 647962a1..86d8b058 100644 --- a/api/swagger/swagger.json +++ b/api/swagger/swagger.json @@ -7918,6 +7918,10 @@ }, "github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateRequest": { "type": "object", + "required": [ + "kind", + "rego" + ], "properties": { "deprecated": { "type": "boolean", @@ -7965,10 +7969,6 @@ ], "example": "medium" }, - "target": { - "type": "string", - "example": "admission.k8s.gatekeeper.sh" - }, "templateName": { "type": "string", "example": "필수 Label 검사" @@ -7977,6 +7977,12 @@ }, "github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateVersionRequest": { "type": "object", + "required": [ + "currentVersion", + "expectedVersion", + "rego", + "versionUpType" + ], "properties": { "currentVersion": { "type": "string", @@ -9899,6 +9905,9 @@ }, "github_com_openinfradev_tks-api_pkg_domain.RegoCompileRequest": { "type": "object", + "required": [ + "rego" + ], "properties": { "rego": { "type": "string", diff --git a/api/swagger/swagger.yaml b/api/swagger/swagger.yaml index 60216b96..188af9fd 100644 --- a/api/swagger/swagger.yaml +++ b/api/swagger/swagger.yaml @@ -933,12 +933,12 @@ definitions: - high example: medium type: string - target: - example: admission.k8s.gatekeeper.sh - type: string templateName: example: 필수 Label 검사 type: string + required: + - kind + - rego type: object github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateVersionRequest: properties: @@ -968,6 +968,11 @@ definitions: - patch example: minor type: string + required: + - currentVersion + - expectedVersion + - rego + - versionUpType type: object github_com_openinfradev_tks-api_pkg_domain.CreatePolicyTemplateVersionResponse: properties: @@ -2223,6 +2228,8 @@ definitions: rego: example: Rego 코드 type: string + required: + - rego type: object github_com_openinfradev_tks-api_pkg_domain.RegoCompileResponse: properties: diff --git a/pkg/domain/policy-template.go b/pkg/domain/policy-template.go index 169714ef..baf8990f 100644 --- a/pkg/domain/policy-template.go +++ b/pkg/domain/policy-template.go @@ -99,31 +99,30 @@ type PolicyTemplate struct { } type CreateCommonPolicyTemplateRequest struct { - TemplateName string `json:"templateName" example:"필수 Label 검사"` - Kind string `json:"kind" example:"K8sRequiredLabels"` + TemplateName string `json:"templateName" example:"필수 Label 검사" validate:"name"` + Kind string `json:"kind" example:"K8sRequiredLabels" validate:"required"` Severity string `json:"severity" enums:"low,medium,high" example:"medium"` Deprecated bool `json:"deprecated" example:"false"` Description string `json:"description,omitempty" example:"이 정책은 ..."` ParametersSchema []ParameterDef `json:"parametersSchema,omitempty"` // "type: object\nproperties: message:\n type: string\n labels:\n type: array\n items:\n type: object\n properties:\n key:\n type: string\n allowedRegex:\n type: string" - Rego string `json:"rego" example:"rego 코드"` + Rego string `json:"rego" example:"rego 코드" validate:"required"` Libs []string `json:"libs" example:"rego 코드"` // Tags []string `json:"tags,omitempty" example:"k8s,label"` } type CreatePolicyTemplateRequest struct { - TemplateName string `json:"templateName" example:"필수 Label 검사"` - Kind string `json:"kind" example:"K8sRequiredLabels"` + TemplateName string `json:"templateName" example:"필수 Label 검사" validate:"name"` + Kind string `json:"kind" example:"K8sRequiredLabels" validate:"required"` Severity string `json:"severity" enums:"low,medium,high" example:"medium"` Deprecated bool `json:"deprecated" example:"false"` - Target string `json:"target,omitempty" example:"admission.k8s.gatekeeper.sh"` Description string `json:"description,omitempty" example:"이 정책은 ..."` ParametersSchema []ParameterDef `json:"parametersSchema,omitempty"` // "type: object\nproperties: message:\n type: string\n labels:\n type: array\n items:\n type: object\n properties:\n key:\n type: string\n allowedRegex:\n type: string" - Rego string `json:"rego" example:"rego 코드"` + Rego string `json:"rego" example:"rego 코드" validate:"required"` Libs []string `json:"libs" example:"rego 코드"` PermittedOrganizationIds []string `json:"permittedOrganizationIds"` @@ -210,14 +209,14 @@ type GetOrganizationPolicyTemplateVersionResponse struct { } type CreatePolicyTemplateVersionRequest struct { - VersionUpType string `json:"versionUpType" enums:"major,minor,patch" example:"minor"` - CurrentVersion string `json:"currentVersion" example:"v1.0.0"` - ExpectedVersion string `json:"expectedVersion" example:"v1.1.0"` + VersionUpType string `json:"versionUpType" enums:"major,minor,patch" example:"minor" validate:"required"` + CurrentVersion string `json:"currentVersion" example:"v1.0.0" validate:"required"` + ExpectedVersion string `json:"expectedVersion" example:"v1.1.0" validate:"required"` ParametersSchema []ParameterDef `json:"parametersSchema,omitempty"` // "type: object\nproperties: message:\n type: string\n labels:\n type: array\n items:\n type: object\n properties:\n key:\n type: string\n allowedRegex:\n type: string" - Rego string `json:"rego" example:"rego 코드"` + Rego string `json:"rego" example:"rego 코드" validate:"required"` Libs []string `json:"libs" example:"rego 코드"` } @@ -286,7 +285,7 @@ type ParameterDef struct { } type RegoCompileRequest struct { - Rego string `json:"rego" example:"Rego 코드"` + Rego string `json:"rego" example:"Rego 코드" validate:"required"` } type RegoCompieError struct {