diff --git a/plugins/catalog-backend/migrations/20201005122705_add_entity_full_name.js b/plugins/catalog-backend/migrations/20201005122705_add_entity_full_name.js new file mode 100644 index 0000000000..26cc98e74e --- /dev/null +++ b/plugins/catalog-backend/migrations/20201005122705_add_entity_full_name.js @@ -0,0 +1,61 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param {import('knex')} knex + */ +exports.up = async function up(knex) { + await knex.schema.alterTable('entities', table => { + table.text('full_name').nullable(); + }); + + await knex('entities').update({ + full_name: knex.raw( + "LOWER(kind) || ':' || LOWER(COALESCE(namespace, 'default')) || '/' || LOWER(name)", + ), + }); + + try { + await knex.schema.alterTable('entities', table => { + table.text('full_name').notNullable().alter(); + }); + } catch (e) { + // SQLite does not support alter column, ignore + } + + await knex.schema.alterTable('entities', table => { + // https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#objectmeta-v1-meta + table.unique(['full_name'], 'entities_unique_full_name'); + table.dropUnique([], 'entities_unique_name'); + }); +}; + +/** + * @param {import('knex')} knex + */ +exports.down = async function down(knex) { + await knex.schema.alterTable('entities', table => { + // https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#objectmeta-v1-meta + table.dropUnique([], 'entities_unique_full_name'); + table.unique(['kind', 'namespace', 'name'], 'entities_unique_name'); + }); + + await knex.schema.alterTable('entities_search', table => { + table.dropColumn('full_name'); + }); +}; diff --git a/plugins/catalog-backend/src/database/CommonDatabase.ts b/plugins/catalog-backend/src/database/CommonDatabase.ts index 9d80b33940..5327384593 100644 --- a/plugins/catalog-backend/src/database/CommonDatabase.ts +++ b/plugins/catalog-backend/src/database/CommonDatabase.ts @@ -383,11 +383,18 @@ export class CommonDatabase implements Database { locationId: string | undefined, entity: Entity, ): DbEntitiesRow { + const lowerKind = entity.kind.toLowerCase(); + const lowerNamespace = ( + entity.metadata.namespace || ENTITY_DEFAULT_NAMESPACE + ).toLowerCase(); + const lowerName = entity.metadata.name.toLowerCase(); + return { id: entity.metadata.uid!, location_id: locationId || null, etag: entity.metadata.etag!, generation: entity.metadata.generation!, + full_name: `${lowerKind}:${lowerNamespace}/${lowerName}`, api_version: entity.apiVersion, kind: entity.kind, name: entity.metadata.name, diff --git a/plugins/catalog-backend/src/database/types.ts b/plugins/catalog-backend/src/database/types.ts index 8aaf212583..c0f5777743 100644 --- a/plugins/catalog-backend/src/database/types.ts +++ b/plugins/catalog-backend/src/database/types.ts @@ -25,6 +25,7 @@ export type DbEntitiesRow = { namespace: string | null; etag: string; generation: number; + full_name: string; metadata: string; spec: string | null; };