From 429d73d562721b6149cae7d6c42217c8960a219e Mon Sep 17 00:00:00 2001 From: shreddedbacon Date: Wed, 17 Aug 2022 15:26:47 +1000 Subject: [PATCH 1/2] chore: remove the creation of harbor projects on lagoon project creation --- .../api/src/migrations/2-harbor/harborSync.ts | 103 ---- .../api/src/resources/project/harborSetup.ts | 451 ------------------ .../api/src/resources/project/resolvers.ts | 14 - 3 files changed, 568 deletions(-) delete mode 100644 services/api/src/migrations/2-harbor/harborSync.ts delete mode 100644 services/api/src/resources/project/harborSetup.ts diff --git a/services/api/src/migrations/2-harbor/harborSync.ts b/services/api/src/migrations/2-harbor/harborSync.ts deleted file mode 100644 index d4f2ec58c8..0000000000 --- a/services/api/src/migrations/2-harbor/harborSync.ts +++ /dev/null @@ -1,103 +0,0 @@ -import * as R from 'ramda'; -import { logger } from '@lagoon/commons/dist/logs/local-logger'; -import { sqlClientPool } from '../../clients/sqlClient'; -import { createHarborOperations } from '../../resources/project/harborSetup'; -import { Helpers as projectHelpers } from '../../resources/project/helpers'; -import { query, knex } from '../../util/db'; - -const defaultHarborUrl = R.propOr( - 'http://harbor-harbor-core.harbor.svc.cluster.local:80', - 'HARBOR_URL', - process.env -); - -const lagoonHarborRoute = R.compose( - R.defaultTo(defaultHarborUrl), - R.find(R.test(/harbor-nginx/)), - R.split(','), - R.propOr('', 'LAGOON_ROUTES') -)(process.env); - -const projectRegex = process.env.PROJECT_REGEX - ? new RegExp(process.env.PROJECT_REGEX) - : /.*/; - -(async () => { - const harborClient = createHarborOperations(sqlClientPool); - - logger.info('Syncing Harbor projects with Lagoon projects'); - - // Get a list of all Lagoon projects - const projects = await projectHelpers(sqlClientPool).getAllProjects(); - const timestamp = Math.floor(Date.now() / 1000); - for (var i = 0; i < projects.length; i++) { - var project = projects[i]; - - if (!R.test(projectRegex, project.name)) { - logger.info(`Skipping ${project.name}`); - continue; - } - - // Get project's env vars from db - let queryBuilder = knex('env_vars') - .where('project', '=', project.id) - .andWhere('scope', '=', 'internal_container_registry'); - - var envVars = await query(sqlClientPool, queryBuilder.toString()); - - var hasURL = false; - var hasUser = false; - var hasPass = false; - var localLagoonURL = ''; - - // Check for Harbor variables - for (var j = 0; j < envVars.length; j++) { - if (envVars[j].name == 'INTERNAL_REGISTRY_URL') { - hasURL = true; - localLagoonURL = envVars[j].value; - } else if (envVars[j].name == 'INTERNAL_REGISTRY_USERNAME') { - hasUser = true; - } else if (envVars[j].name == 'INTERNAL_REGISTRY_PASSWORD') { - hasPass = true; - } - } - - // Filter for projects using this Lagoon's Harbor route - if (localLagoonURL == lagoonHarborRoute) { - logger.info( - 'Lagoon project: ', - project.name, - " is using this Lagoon's Harbor; syncing new robot account for it." - ); - await harborClient.addProject(project.name, project.id); - logger.info( - 'New robot account creation for Lagoon project: ', - project.name, - ' completed.' - ); - } - // No registry URL means this project doesn't have a Harbor project set up - else if (localLagoonURL == '') { - logger.info( - 'No Harbor URL found for Lagoon project: ', - project.name, - '. Creating new Harbor project using the Lagoon Harbor.' - ); - await harborClient.addProject(project.name, project.id); - logger.info('Added Harbor project for Lagoon project: ', project.name); - } - // Project not using the Harbor local to this Lagoon; do nothing - else { - logger.info( - 'Skipping processing of Lagoon project ', - project.name, - ', as it is setup to use another Harbor: ', - localLagoonURL - ); - } - } - - logger.info('Harbor project sync completed'); - - return; -})(); diff --git a/services/api/src/resources/project/harborSetup.ts b/services/api/src/resources/project/harborSetup.ts deleted file mode 100644 index 60457d8d4e..0000000000 --- a/services/api/src/resources/project/harborSetup.ts +++ /dev/null @@ -1,451 +0,0 @@ -import * as R from 'ramda'; -import { Pool } from 'mariadb'; -import { - config as harborConfig, - harborClient -} from '../../clients/harborClient'; -import { logger } from '../../loggers/logger'; -import { Sql as PSql } from './sql'; -import { Sql } from '../env-variables/sql'; -import { getConfigFromEnv, getLagoonRouteFromEnv } from '../../util/config'; -import { query, knex } from '../../util/db'; - -const lagoonWebhookAddress = getLagoonRouteFromEnv( - /webhook-handler/, - getConfigFromEnv('WEBHOOK_URL', 'http://webhook-handler:3000') -); - -const apiVersion = R.propOr('v2.0', 'HARBOR_API_VERSION', process.env); -// Use an empty string for backwards compatibility with Harbor version 1.x.x - -async function createHarborProject(harborClient, lagoonProjectName: string) { - // Returns an empty string on an error and a string on a success - - // Create harbor project - try { - var res = await harborClient.post(`projects`, { - body: { - count_limit: -1, - project_name: lagoonProjectName, - storage_limit: -1, - metadata: { - auto_scan: 'true', - reuse_sys_cve_whitelist: 'true', - public: 'false' - } - } - }); - logger.debug(`Harbor project ${lagoonProjectName} created!`); - } catch (err) { - if (err.statusCode == 409) { - // 409 means project already exists - logger.debug( - `Unable to create the harbor project "${lagoonProjectName}", as it already exists in harbor; continuing with existing project` - ); - } else { - logger.error( - `Unable to create the harbor project "${lagoonProjectName}", error: ${err}` - ); - return ''; - } - } - - // Get new harbor project's id - try { - // Grab paginated project list results - const pageSize = 100; - let results = []; - let res = await harborClient.get( - `projects?name=${lagoonProjectName}&page_size=${pageSize}` - ); - - if (parseInt(res.headers['x-total-count']) > pageSize) { - let i = 1; - while (res.body != null) { - results = results.concat(res.body); - i++; - res = await harborClient.get( - `projects?name=${lagoonProjectName}&page_size=${pageSize}&page=${i}` - ); - } - } else { - results = res.body; - } - - // Search array of objects for correct project - for (let proj of results) { - if (proj.name == lagoonProjectName) { - var harborProjectID = proj.project_id; - break; - } - } - - logger.debug( - `Harbor project id for ${lagoonProjectName} is: ${harborProjectID}` - ); - } catch (err) { - if (err.statusCode == 404) { - logger.error( - `Unable to get the harbor project id of "${lagoonProjectName}", as it does not exist in harbor!` - ); - return; - } else { - logger.error( - `Unable to get the harbor project id of "${lagoonProjectName}", error: ${err}` - ); - return ''; - } - } - return harborProjectID; -} - -async function createRobot( - harborClient, - lagoonProjectName: string, - harborProjectID: string -) { - // Returns false on an error and a token object on a success - - // Create robot account for new harbor project - try { - const timestamp = Math.floor(Date.now() / 1000); - var robotName = `${lagoonProjectName}-${timestamp}`; - - const res = await harborClient.post(`projects/${harborProjectID}/robots`, { - body: { - name: robotName, - access: [ - { - resource: `/project/${harborProjectID}/repository`, - action: 'push' - } - ] - } - }); - var harborTokenInfo = res.body; - logger.debug( - `Robot ${robotName} was created for Harbor project ${lagoonProjectName} !` - ); - } catch (err) { - // 409 means project already exists - // 201 means project created successfully - if (err.statusCode == 409) { - logger.debug( - `Unable to create a robot account for harbor project "${lagoonProjectName}", as a robot account of the same name already exists!` - ); - } else { - logger.error( - `Unable to create a robot account for harbor project "${lagoonProjectName}", error: ${err}` - ); - return false; - } - } - return harborTokenInfo; -} - -async function removeHarborEnvVars( - sqlClientPool: Pool, - lagoonProjectName: string -) { - // Returns false on an error and true on a success - - // Find any currently set env vars - var old_env_vars = []; - try { - const result = await query( - sqlClientPool, - PSql.selectProjectByName(lagoonProjectName) - ); - let queryBuilder = knex('env_vars') - .where('project', '=', result[0].id) - .andWhere('scope', '=', 'internal_container_registry'); - - const env_vars = await query(sqlClientPool, queryBuilder.toString()); - - for (var i = 0; i < env_vars.length; i++) { - old_env_vars.push(env_vars[i]); - } - } catch (err) { - logger.error( - `Unable to get current env vars for project: ${lagoonProjectName}`, - err - ); - } - - // Remove any previously set internal_container_registry env vars - try { - for (var j = 0; j < old_env_vars.length; j++) { - await query(sqlClientPool, Sql.deleteEnvVariable(old_env_vars[j].id)); - logger.debug( - `Removed ${old_env_vars[j].name} env var from project ${lagoonProjectName}` - ); - } - } catch (err) { - logger.error( - `Unable to remove ${old_env_vars[j].name} env var from project ${lagoonProjectName}`, - err - ); - return false; - } - - return true; -} - -async function addEnvVar( - sqlClientPool: Pool, - lagoonProjectName: string, - name: string, - value: string, - scope: string, - project: string -) { - // Returns false on an error and true on a success - try { - await query( - sqlClientPool, - Sql.insertEnvVariable({ - name: name, - value: value, - scope: scope, - project: parseInt(project, 10) - }) - ); - logger.debug( - `Environment variable ${name} for ${lagoonProjectName} created!` - ); - } catch (err) { - logger.error( - `Error while setting ${name} variable for ${lagoonProjectName}, error: ${err}` - ); - return false; - } - return true; -} - -async function resetHarborWebhook( - harborClient, - lagoonProjectName: string, - lagoonWebhookAddress: string, - harborProjectID: string -) { - // Returns false on an error and true on a success - - // Get current webhooks for Harbor project - let old_webhooks = []; - try { - const res = await harborClient.get( - `projects/${harborProjectID}/webhook/policies` - ); - - for (var i = 0; i < res.body.length; i++) { - old_webhooks.push(res.body[i]); - } - } catch (err) { - logger.error( - `Unable to retrieve list of current webhooks for Harbor Project: ${lagoonProjectName}`, - err - ); - } - - // Remove old webhooks from Harbor project - try { - for (var j = 0; j < old_webhooks.length; j++) { - var result = await harborClient.delete( - `projects/${harborProjectID}/webhook/policies/${old_webhooks[j].id}`, - { - body: { - project_id: harborProjectID, - policy_id: old_webhooks[j].id - } - } - ); - logger.debug( - `Removed ${old_webhooks[j].name} webhook from Harbor project ${lagoonProjectName}` - ); - } - } catch (err) { - logger.error( - `Unable to remove ${old_webhooks[j].name} webhook from Harbor project ${lagoonProjectName}`, - err - ); - return false; - } - - // Set webhook for Harbor Project - try { - var res = await harborClient.post( - `projects/${harborProjectID}/webhook/policies`, - { - body: { - targets: [ - { - type: 'http', - skip_cert_verify: true, - address: lagoonWebhookAddress - } - ], - event_types: (apiVersion == "v2.0") ? ["SCANNING_FAILED","SCANNING_COMPLETED"] : ["scanningFailed","scanningCompleted"], - name: 'Lagoon Default Webhook', - enabled: true - } - } - ); - logger.debug( - `Created Lagoon default webhook for Harbor project: ${lagoonProjectName}` - ); - } catch (err) { - logger.error( - `Error while creating a webhook in the Harbor project for ${lagoonProjectName}, error: ${err}` - ); - return false; - } - return true; -} - -export const createHarborOperations = (sqlClientPool: Pool) => ({ - addProject: async (lagoonProjectName, projectID) => { - // Create harbor project - const harborProjectID = await createHarborProject( - harborClient, - lagoonProjectName - ); - if (harborProjectID == '') { - return; - } - - // Create robot account for new harbor project - var harborTokenInfo = await createRobot( - harborClient, - lagoonProjectName, - harborProjectID - ); - if (harborTokenInfo == false) { - return; - } - - // Remove previously set internal registry env vars - if (!(await removeHarborEnvVars(sqlClientPool, lagoonProjectName))) { - return; - } - - // Set required Lagoon env vars to enable Harbor on this project - if ( - !(await addEnvVar( - sqlClientPool, - lagoonProjectName, - 'INTERNAL_REGISTRY_URL', - harborConfig.publicRoute, - 'INTERNAL_CONTAINER_REGISTRY', - projectID - )) - ) { - return; - } - if ( - !(await addEnvVar( - sqlClientPool, - lagoonProjectName, - 'INTERNAL_REGISTRY_USERNAME', - harborTokenInfo.name, - 'INTERNAL_CONTAINER_REGISTRY', - projectID - )) - ) { - return; - } - if ( - !(await addEnvVar( - sqlClientPool, - lagoonProjectName, - 'INTERNAL_REGISTRY_PASSWORD', - harborTokenInfo.token, - 'INTERNAL_CONTAINER_REGISTRY', - projectID - )) - ) { - return; - } - - // Reset harbor project webhook to point to this Lagoon's Harbor - if ( - !(await resetHarborWebhook( - harborClient, - lagoonProjectName, - lagoonWebhookAddress, - harborProjectID - )) - ) { - return; - } - }, - - deleteProject: async lagoonProjectName => { - const harborRepos = []; - - // Get existing harbor project's id - try { - const res = await harborClient.get(`projects?name=${lagoonProjectName}`); - var harborProjectID = res.body[0].project_id; - logger.debug( - `Got the harbor project id for project ${lagoonProjectName} successfully!` - ); - } catch (err) { - if (err.statusCode == 404) { - // This case could come to pass if a project was created - // before we began using Harbor as our container registry - logger.warn( - `Unable to get the harbor project id of "${lagoonProjectName}", as it does not exist in harbor!` - ); - return; - } else { - logger.error( - `Unable to get the harbor project id of "${lagoonProjectName}", error: ${err}` - ); - return; - } - } - logger.debug( - `Harbor project id for ${lagoonProjectName}: ${harborProjectID}` - ); - - // Check for existing repositories within the project - try { - const res = await harborClient.get(`search?name=${lagoonProjectName}`); - for (var i = 0; i < res.repository.length; i++) { - if (res.repository[i].project_name == lagoonProjectName) { - harborRepos.push(res.repository[i]); - } - } - } catch (err) { - logger.error( - `Unable to search for repositories within the harbor project "${lagoonProjectName}", error: ${err}` - ); - } - - // Delete any repositories within this project - try { - for (var i = 0; i < harborRepos.length; i++) { - var res = await harborClient.delete( - `repositories/${harborRepos[i].repository_name}` - ); - } - } catch (err) { - logger.error( - `Unable to delete repositories within the harbor project "${lagoonProjectName}", error: ${err}` - ); - } - - // Delete harbor project - try { - var res = await harborClient.delete(`projects/${harborProjectID}`); - logger.debug(`Harbor project ${lagoonProjectName} deleted!`); - } catch (err) { - // 400 means the project id is invalid - // 404 means project doesn't exist - // 412 means project still contains repositories - logger.error( - `Unable to delete the harbor project "${lagoonProjectName}", error: ${err}` - ); - } - } -}); diff --git a/services/api/src/resources/project/resolvers.ts b/services/api/src/resources/project/resolvers.ts index e87fe56fc3..0735422ffd 100644 --- a/services/api/src/resources/project/resolvers.ts +++ b/services/api/src/resources/project/resolvers.ts @@ -12,15 +12,12 @@ import { Sql as SshKeySql} from '../sshKey/sql'; import * as OS from '../openshift/sql'; import { generatePrivateKey, getSshKeyFingerprint } from '../sshKey'; import { Sql as sshKeySql } from '../sshKey/sql'; -import { createHarborOperations } from './harborSetup'; import { Helpers as organizationHelpers } from '../organization/helpers'; import { Helpers as notificationHelpers } from '../notification/helpers'; import { Helpers as groupHelpers } from '../group/helpers'; import { getUserProjectIdsFromRoleProjectIds } from '../../util/auth'; import GitUrlParse from 'git-url-parse'; -const DISABLE_CORE_HARBOR = process.env.DISABLE_CORE_HARBOR || "false" - const DISABLE_NON_ORGANIZATION_PROJECT_CREATION = process.env.DISABLE_NON_ORGANIZATION_PROJECT_CREATION || "false" const isValidGitUrl = value => { @@ -481,11 +478,6 @@ export const addProject = async ( } } - if (DISABLE_CORE_HARBOR == "false") { - const harborOperations = createHarborOperations(sqlClientPool); - await harborOperations.addProject(project.name, project.id); - } - userActivityLogger(`User added a project '${project.name}'`, { project: '', event: 'api:addProject', @@ -594,12 +586,6 @@ export const deleteProject: ResolverFn = async ( ); } - // @TODO discuss if we want to delete projects in harbor or not - // if (DISABLE_CORE_HARBOR == "false") { - // const harborOperations = createHarborOperations(sqlClientPool); - // const harborResults = await harborOperations.deleteProject(project.name) - // } - userActivityLogger(`User deleted a project '${project.name}'`, { project: '', event: 'api:deleteProject', From 02dffe2ec862ff44853ce7dc14a3b315f5cbdd93 Mon Sep 17 00:00:00 2001 From: shreddedbacon Date: Thu, 6 Jun 2024 15:40:00 +1000 Subject: [PATCH 2/2] chore: remove remaining harbor integrations --- node-packages/commons/src/api.ts | 14 ----- node-packages/commons/src/harborApi.ts | 48 ----------------- services/api/Dockerfile | 4 +- services/api/package.json | 1 - services/api/src/clients/harborClient.ts | 24 --------- services/api/src/resolvers.js | 6 --- .../api/src/resources/problem/resolvers.ts | 33 ------------ services/api/src/resources/problem/sql.ts | 10 ---- services/api/src/typeDefs.js | 29 ----------- .../keycloak/lagoon-realm-base-import.json | 51 ------------------- .../startup-scripts/00-configure-lagoon.sh | 26 ++++++++++ .../webhooks2tasks/src/webhooks/problems.ts | 10 ---- .../internal/lagoonclient/schema.graphql | 34 ------------- 13 files changed, 27 insertions(+), 263 deletions(-) delete mode 100644 node-packages/commons/src/harborApi.ts delete mode 100644 services/api/src/clients/harborClient.ts diff --git a/node-packages/commons/src/api.ts b/node-packages/commons/src/api.ts index 05c1a20848..b7c4e24be5 100644 --- a/node-packages/commons/src/api.ts +++ b/node-packages/commons/src/api.ts @@ -1386,17 +1386,3 @@ export const getProblemsforProjectEnvironment = async ( }); return response.environmentByName.problems; }; - -export const getProblemHarborScanMatches = () => graphqlapi.query( - `query getProblemHarborScanMatches { - allProblemHarborScanMatchers { - id - name - description - defaultLagoonProject - defaultLagoonEnvironment - defaultLagoonService - regex - } - }` -); diff --git a/node-packages/commons/src/harborApi.ts b/node-packages/commons/src/harborApi.ts deleted file mode 100644 index 2b8a80c570..0000000000 --- a/node-packages/commons/src/harborApi.ts +++ /dev/null @@ -1,48 +0,0 @@ -// @flow - -import axios from 'axios'; - -const HARBOR_BASE_API_URL = - process.env.HARBOR_BASE_API_URL || - 'https://harbor-nginx-lagoon-master.ch.amazee.io'; -const HARBOR_BASE_URL_POSTFIX = '/tags/latest/scan'; -const HARBOR_ACCEPT_HEADER = - 'application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0'; -const HARBOR_USERNAME = process.env.HARBOR_USERNAME || 'admin'; -const HARBOR_PASSWORD = process.env.HARBOR_ADMIN_PASSWORD; -const HARBOR_API_VERSION = process.env.HARBOR_API_VERSION || 'v2.0'; - -export const getVulnerabilitiesPayloadFromHarbor = async (repository, configOverrides) => { - - let endpoint = `${HARBOR_BASE_API_URL}/api/repositories/${repository.repo_full_name}/tags/latest/scan`; //assume v1 by default - if(HARBOR_API_VERSION != 'v1.0') { - endpoint = `${HARBOR_BASE_API_URL}/api/v2.0/projects/${repository.namespace}/repositories/${encodeURIComponent(repository.name)}/artifacts/latest/additions/vulnerabilities` - } - - return await getVulnerabilitiesPayloadFromHarborDriver(endpoint, configOverrides) -} - -/** - * - * @param repoFullName - * @param configOverrides allows us to override call details {authUsername, authPassword, acceptHeader} - * @returns - */ -const getVulnerabilitiesPayloadFromHarborDriver = async (endpoint, configOverrides) => { - - const username = configOverrides.authUsername || HARBOR_USERNAME; - const password = configOverrides.authPassword || HARBOR_PASSWORD; - const acceptHeader = configOverrides.acceptHeader || HARBOR_ACCEPT_HEADER; - const options = { - timeout: 30000, - headers: { - Accept: acceptHeader, - Authorization: - 'Basic ' + - Buffer.from(username + ':' + (password)).toString('base64'), - }, - }; - - const response = await axios.get(endpoint, options); - return response.data; -}; diff --git a/services/api/Dockerfile b/services/api/Dockerfile index 559df98678..bf6a9a4ce3 100644 --- a/services/api/Dockerfile +++ b/services/api/Dockerfile @@ -33,9 +33,7 @@ ENV NODE_ENV=production \ KEYCLOAK_ADMIN_PASSWORD=admin \ ELASTICSEARCH_URL=http://logs-db-service:9200 \ KEYCLOAK_API_CLIENT_SECRET=39d5282d-3684-4026-b4ed-04bbc034b61a \ - HARBOR_ADMIN_PASSWORD=Harbor12345 \ - REDIS_PASSWORD=admin \ - HARBOR_API_VERSION=v2.0 + REDIS_PASSWORD=admin # The API is not very resilient to sudden mariadb restarts which can happen when the api and mariadb are starting # at the same time. So we have a small entrypoint which waits for mariadb to be fully ready. diff --git a/services/api/package.json b/services/api/package.json index d04391a03b..75b1cbfb36 100644 --- a/services/api/package.json +++ b/services/api/package.json @@ -15,7 +15,6 @@ "sync:gitlab:all": "yarn run sync:gitlab:users && yarn run sync:gitlab:groups && yarn run sync:gitlab:projects", "sync:opendistro-security": "node --max-http-header-size=80000 dist/helpers/sync-groups-opendistro-security", "sync:bitbucket:repo-permissions": "node dist/bitbucket-sync/repo-permissions", - "sync:harbor:projects": "node dist/migrations/2-harbor/harborSync.js", "migrations:lagoon": "node dist/migrations/lagoon/migrations.js" }, "keywords": [], diff --git a/services/api/src/clients/harborClient.ts b/services/api/src/clients/harborClient.ts deleted file mode 100644 index c9927da118..0000000000 --- a/services/api/src/clients/harborClient.ts +++ /dev/null @@ -1,24 +0,0 @@ -import got from 'got'; -import { getConfigFromEnv, getLagoonRouteFromEnv } from '../util/config'; - -export const config = { - origin: getConfigFromEnv( - 'HARBOR_URL', - 'http://harbor-harbor-core.harbor.svc.cluster.local:80' - ), - user: 'admin', - pass: getConfigFromEnv('HARBOR_ADMIN_PASSWORD', 'Harbor12345'), - // Use an empty string for backwards compatibility with Harbor version 1.x.x - apiVersion: getConfigFromEnv('HARBOR_API_VERSION', 'v2.0'), - get publicRoute() { - return getLagoonRouteFromEnv(/harbor-nginx/, this.origin); - } -}; - -export const harborClient = got.extend({ - baseUrl: `${config.publicRoute}/api/${ - config.apiVersion ? config.apiVersion.concat('/') : '' - }`, - json: true, - auth: `${config.user}:${config.pass}` -}); diff --git a/services/api/src/resolvers.js b/services/api/src/resolvers.js index dc0556b0d7..333bffe2fc 100644 --- a/services/api/src/resolvers.js +++ b/services/api/src/resolvers.js @@ -10,9 +10,6 @@ const { deleteProblemsFromSource, addProblemsFromSource, getProblemSources, - getProblemHarborScanMatches, - addProblemHarborScanMatch, - deleteProblemHarborScanMatch } = require('./resources/problem/resolvers'); const { @@ -581,7 +578,6 @@ const resolvers = { allProblems: getAllProblems, allGroups: getAllGroups, allProjectsInGroup: getAllProjectsInGroup, - allProblemHarborScanMatchers: getProblemHarborScanMatches, allUsers: getAllUsers, allNotifications: getAllNotifications, userByEmail: getUserByEmail, @@ -601,10 +597,8 @@ const resolvers = { }, Mutation: { addProblem, - addProblemHarborScanMatch, deleteProblem, deleteProblemsFromSource, - deleteProblemHarborScanMatch, addFact, addFacts, addFactsByName, diff --git a/services/api/src/resources/problem/resolvers.ts b/services/api/src/resources/problem/resolvers.ts index bfe3454a5b..3d41f7f07a 100644 --- a/services/api/src/resources/problem/resolvers.ts +++ b/services/api/src/resources/problem/resolvers.ts @@ -278,36 +278,3 @@ export const deleteProblemsFromSource: ResolverFn = async ( return 'success'; }; - -export const getProblemHarborScanMatches: ResolverFn = async ( - root, - args, - { sqlClientPool, hasPermission } -) => { - throw new Error('Harbor-Trivy integration with core removed in Lagoon 2') -}; - -export const addProblemHarborScanMatch: ResolverFn = async ( - root, - { - input: { - name, - description, - defaultLagoonProject, - defaultLagoonEnvironment, - defaultLagoonService, - regex - } - }, - { sqlClientPool, hasPermission, userActivityLogger } -) => { - throw new Error('Harbor-Trivy integration with core removed in Lagoon 2') -}; - -export const deleteProblemHarborScanMatch: ResolverFn = async ( - root, - { input: { id } }, - { sqlClientPool, hasPermission, userActivityLogger } -) => { - throw new Error('Harbor-Trivy integration with core removed in Lagoon 2') -}; diff --git a/services/api/src/resources/problem/sql.ts b/services/api/src/resources/problem/sql.ts index be641e9e30..93972dafe7 100644 --- a/services/api/src/resources/problem/sql.ts +++ b/services/api/src/resources/problem/sql.ts @@ -18,16 +18,6 @@ const standardEnvironmentReturn = { deleted: 'deleted' }; -const standardProblemHarborScanMatchReturn = { - id: 'id', - name: 'name', - description: 'description', - default_lagoon_project: 'defaultLagoonProject', - default_lagoon_environment: 'defaultLagoonEnvironment', - default_lagoon_service: 'defaultLagoonServiceName', - regex: 'regex' -}; - export const Sql = { selectAllProblems: ({ source = [], diff --git a/services/api/src/typeDefs.js b/services/api/src/typeDefs.js index c10f70919f..475a4f13ea 100644 --- a/services/api/src/typeDefs.js +++ b/services/api/src/typeDefs.js @@ -268,29 +268,6 @@ const typeDefs = gql` deleted: String } - type ProblemHarborScanMatch { - id: Int - name: String - description: String - defaultLagoonProject: String - defaultLagoonEnvironment: String - defaultLagoonService: String - regex: String - } - - input AddProblemHarborScanMatchInput { - name: String! - description: String! - defaultLagoonProject: String - defaultLagoonEnvironment: String - defaultLagoonService: String - regex: String! - } - - input DeleteProblemHarborScanMatchInput { - id: Int! - } - input AddProblemInput { id: Int environment: Int! @@ -1401,10 +1378,6 @@ const typeDefs = gql` """ lagoonVersion: JSON """ - Returns all ProblemHarborScanMatchers - """ - allProblemHarborScanMatchers: [ProblemHarborScanMatch] @deprecated(reason: "Harbor-Trivy integration with core removed in Lagoon 2") - """ Returns all AdvancedTaskDefinitions """ allAdvancedTaskDefinitions: [AdvancedTaskDefinition] @@ -2420,10 +2393,8 @@ const typeDefs = gql` cancelDeployment(input: CancelDeploymentInput!): String addBackup(input: AddBackupInput!): Backup addProblem(input: AddProblemInput!): Problem - addProblemHarborScanMatch(input: AddProblemHarborScanMatchInput!): ProblemHarborScanMatch @deprecated(reason: "Harbor-Trivy integration with core removed in Lagoon 2") deleteProblem(input: DeleteProblemInput!): String deleteProblemsFromSource(input: DeleteProblemsFromSourceInput!): String - deleteProblemHarborScanMatch(input: DeleteProblemHarborScanMatchInput!): String @deprecated(reason: "Harbor-Trivy integration with core removed in Lagoon 2") addFact(input: AddFactInput!): Fact addFacts(input: AddFactsInput!): [Fact] @deprecated(reason: "Use addFactsByName instead") addFactsByName(input: AddFactsByNameInput!): [Fact] diff --git a/services/keycloak/lagoon-realm-base-import.json b/services/keycloak/lagoon-realm-base-import.json index 239dc06677..3d1fbe9a56 100644 --- a/services/keycloak/lagoon-realm-base-import.json +++ b/services/keycloak/lagoon-realm-base-import.json @@ -891,24 +891,6 @@ } ] }, - { - "name": "harbor_scan_match", - "ownerManagedAccess": false, - "displayName": "Harbor scan match", - "attributes": {}, - "uris": [], - "scopes": [ - { - "name": "add" - }, - { - "name": "view" - }, - { - "name": "delete" - } - ] - }, { "name": "advanced_task", "ownerManagedAccess": false, @@ -2147,17 +2129,6 @@ "applyPolicies": "[\"[Lagoon] Users role for realm is Platform Owner\"]" } }, - { - "name": "Add Harbor Scan Match", - "type": "scope", - "logic": "POSITIVE", - "decisionStrategy": "UNANIMOUS", - "config": { - "resources": "[\"harbor_scan_match\"]", - "scopes": "[\"add\"]", - "applyPolicies": "[\"[Lagoon] Users role for realm is Admin\"]" - } - }, { "name": "Delete Production Environment", "type": "scope", @@ -2466,17 +2437,6 @@ "applyPolicies": "[\"[Lagoon] User has access to own data\",\"[Lagoon] Users role for realm is Platform Owner\"]" } }, - { - "name": "Delete Harbor Scan Match", - "type": "scope", - "logic": "POSITIVE", - "decisionStrategy": "UNANIMOUS", - "config": { - "resources": "[\"harbor_scan_match\"]", - "scopes": "[\"delete\"]", - "applyPolicies": "[\"[Lagoon] Users role for realm is Admin\"]" - } - }, { "name": "View All Openshifts", "type": "scope", @@ -2741,17 +2701,6 @@ "applyPolicies": "[\"[Lagoon] User has access to project\",\"[Lagoon] Users role for project is Guest\"]" } }, - { - "name": "View Harbor Scan Match", - "type": "scope", - "logic": "POSITIVE", - "decisionStrategy": "UNANIMOUS", - "config": { - "resources": "[\"harbor_scan_match\"]", - "scopes": "[\"view\"]", - "applyPolicies": "[\"[Lagoon] Users role for realm is Admin\"]" - } - }, { "name": "Run Drush sql-sync to Production Environment", "type": "scope", diff --git a/services/keycloak/startup-scripts/00-configure-lagoon.sh b/services/keycloak/startup-scripts/00-configure-lagoon.sh index 93f61562df..34116c560e 100755 --- a/services/keycloak/startup-scripts/00-configure-lagoon.sh +++ b/services/keycloak/startup-scripts/00-configure-lagoon.sh @@ -332,6 +332,31 @@ EOF EOF } +function migrate_remove_harbor_scan_permissions { + # The changes here match the changes that are made in the realm import script + # fresh installs will not need to perform this migration as the changes will already be in the import + # this will only run on existing installations to get it into a state that matches the realm import + CLIENT_ID=$(/opt/keycloak/bin/kcadm.sh get -r lagoon clients?clientId=api --config $CONFIG_PATH | jq -r '.[0]["id"]') + view_harbor_scan_match=$(/opt/keycloak/bin/kcadm.sh get -r lagoon clients/$CLIENT_ID/authz/resource-server/permission?name=View+Harbor+Scan+Match --config $CONFIG_PATH) + + if [ "$view_harbor_scan_match" == "[ ]" ]; then + echo "view_harbor_scan_match already removed" + return 0 + fi + + echo Removing old harbor permissions + + echo Delete view_harbor_scan_match permission + view_harbor_scan_match_id=$(/opt/keycloak/bin/kcadm.sh get -r lagoon clients/$CLIENT_ID/authz/resource-server/permission?name=View+Harbor+Scan+Match --config $CONFIG_PATH | jq -r '.[0]["id"]') + /opt/keycloak/bin/kcadm.sh delete -r lagoon clients/$CLIENT_ID/authz/resource-server/permission/$view_harbor_scan_match_id --config $CONFIG_PATH + echo Delete add_harbor_scan_match permission + add_harbor_scan_match_id=$(/opt/keycloak/bin/kcadm.sh get -r lagoon clients/$CLIENT_ID/authz/resource-server/permission?name=Add+Harbor+Scan+Match --config $CONFIG_PATH | jq -r '.[0]["id"]') + /opt/keycloak/bin/kcadm.sh delete -r lagoon clients/$CLIENT_ID/authz/resource-server/permission/$add_harbor_scan_match_id --config $CONFIG_PATH + echo Delete delete_harbor_scan_match permission + delete_harbor_scan_match_id=$(/opt/keycloak/bin/kcadm.sh get -r lagoon clients/$CLIENT_ID/authz/resource-server/permission?name=Delete+Harbor+Scan+Match --config $CONFIG_PATH | jq -r '.[0]["id"]') + /opt/keycloak/bin/kcadm.sh delete -r lagoon clients/$CLIENT_ID/authz/resource-server/permission/$delete_harbor_scan_match_id --config $CONFIG_PATH +} + ################## # Initialization # ################## @@ -362,6 +387,7 @@ function configure_keycloak { service-api_add_query-groups_permission add_notification_view_all migrate_admin_organization_permissions + migrate_remove_harbor_scan_permissions # always run last sync_client_secrets diff --git a/services/webhooks2tasks/src/webhooks/problems.ts b/services/webhooks2tasks/src/webhooks/problems.ts index 14fc64cd26..e463bf2411 100644 --- a/services/webhooks2tasks/src/webhooks/problems.ts +++ b/services/webhooks2tasks/src/webhooks/problems.ts @@ -10,16 +10,6 @@ import { Project } from '../types'; -// NOTE: Here we are going through the process of deprecating the Trivy integration -const enableHarborIntegration = (() => { - if(process.env.ENABLE_DEPRECATED_TRIVY_INTEGRATION && process.env.ENABLE_DEPRECATED_TRIVY_INTEGRATION == "true") { - console.log("ENABLE_DEPRECATED_TRIVY_INTEGRATION is 'true' -- enabling Harbor/Trivy"); - return true; - } - console.log("ENABLE_DEPRECATED_TRIVY_INTEGRATION is not 'true' -- Harbor/Trivy integration is not enabled"); - return false; -})(); - export async function processProblems( rabbitMsg, channelWrapperWebhooks diff --git a/services/workflows/internal/lagoonclient/schema.graphql b/services/workflows/internal/lagoonclient/schema.graphql index c951d05ce9..0c41bb17a9 100644 --- a/services/workflows/internal/lagoonclient/schema.graphql +++ b/services/workflows/internal/lagoonclient/schema.graphql @@ -208,15 +208,6 @@ input AddOrUpdateEnvironmentStorageInput { updated: String } -input AddProblemHarborScanMatchInput { - name: String! - description: String! - defaultLagoonProject: String - defaultLagoonEnvironment: String - defaultLagoonService: String - regex: String! -} - input AddProblemInput { id: Int environment: Int! @@ -556,10 +547,6 @@ input DeleteOpenshiftInput { name: String! } -input DeleteProblemHarborScanMatchInput { - id: Int! -} - input DeleteProblemInput { environment: Int! identifier: String! @@ -1072,14 +1059,8 @@ type Mutation { cancelDeployment(input: CancelDeploymentInput!): String addBackup(input: AddBackupInput!): Backup addProblem(input: AddProblemInput!): Problem - addProblemHarborScanMatch( - input: AddProblemHarborScanMatchInput! - ): ProblemHarborScanMatch deleteProblem(input: DeleteProblemInput!): String deleteProblemsFromSource(input: DeleteProblemsFromSourceInput!): String - deleteProblemHarborScanMatch( - input: DeleteProblemHarborScanMatchInput! - ): String addFact(input: AddFactInput!): Fact addFacts(input: AddFactsInput!): [Fact] deleteFact(input: DeleteFactInput!): String @@ -1259,16 +1240,6 @@ type Problem { deleted: String } -type ProblemHarborScanMatch { - id: Int - name: String - description: String - defaultLagoonProject: String - defaultLagoonEnvironment: String - defaultLagoonService: String - regex: String -} - enum ProblemSeverityRating { NONE UNKNOWN @@ -1696,11 +1667,6 @@ type Query { """ lagoonVersion: JSON - """ - Returns all ProblemHarborScanMatchers - """ - allProblemHarborScanMatchers: [ProblemHarborScanMatch] - """ Returns all AdvancedTaskDefinitions """