UNPKG

n8n-nodes-ionos

Version:

n8n nodes for IONOS DNS, Domain, SSL/Certificate management, Cloud AI, Cloud Infrastructure, Container Registry, Database as a Service, CDN, VPN Gateway, Activity Log, Billing, Logging, Monitoring, Object Storage Management, Network File Storage, Identity

801 lines (800 loc) 34.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.IonosCloudContainerRegistry = void 0; const baseUrl = 'https://api.ionos.com/containerregistries'; class IonosCloudContainerRegistry { description = { displayName: 'IONOS Cloud Container Registry', name: 'ionosCloudContainerRegistry', icon: 'file:ionos.svg', group: ['transform'], version: 1, subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"] }}', description: 'Manage IONOS Cloud Container Registry for Docker and OCI artifacts. Developped with Love by Ascenzia (ascenzia.fr)', defaults: { name: 'IONOS Cloud Container Registry', }, inputs: ['main'], outputs: ['main'], credentials: [ { name: 'ionosCloud', required: true, }, ], properties: [ { displayName: 'Resource', name: 'resource', type: 'options', noDataExpression: true, options: [ { name: 'Registry', value: 'registry', description: 'Manage container registries', }, { name: 'Token', value: 'token', description: 'Manage registry access tokens', }, { name: 'Repository', value: 'repository', description: 'View registry repositories', }, { name: 'Artifact', value: 'artifact', description: 'View repository artifacts', }, { name: 'Location', value: 'location', description: 'Get available registry locations', }, { name: 'Name', value: 'name', description: 'Check registry name availability', }, ], default: 'registry', }, { displayName: 'Operation', name: 'operation', type: 'options', noDataExpression: true, displayOptions: { show: { resource: ['registry'], }, }, options: [ { name: 'Create', value: 'create', description: 'Create a container registry', action: 'Create a registry', }, { name: 'Get', value: 'get', description: 'Get a registry', action: 'Get a registry', }, { name: 'Get Many', value: 'getMany', description: 'Get many registries', action: 'Get many registries', }, { name: 'Update', value: 'update', description: 'Update a registry', action: 'Update a registry', }, { name: 'Delete', value: 'delete', description: 'Delete a registry', action: 'Delete a registry', }, ], default: 'create', }, { displayName: 'Operation', name: 'operation', type: 'options', noDataExpression: true, displayOptions: { show: { resource: ['token'], }, }, options: [ { name: 'Create', value: 'create', description: 'Create a token', action: 'Create a token', }, { name: 'Get', value: 'get', description: 'Get a token', action: 'Get a token', }, { name: 'Get Many', value: 'getMany', description: 'Get many tokens', action: 'Get many tokens', }, { name: 'Update', value: 'update', description: 'Update a token', action: 'Update a token', }, { name: 'Delete', value: 'delete', description: 'Delete a token', action: 'Delete a token', }, ], default: 'create', }, { displayName: 'Operation', name: 'operation', type: 'options', noDataExpression: true, displayOptions: { show: { resource: ['repository'], }, }, options: [ { name: 'Get', value: 'get', description: 'Get a repository', action: 'Get a repository', }, { name: 'Get Many', value: 'getMany', description: 'Get many repositories', action: 'Get many repositories', }, { name: 'Delete', value: 'delete', description: 'Delete a repository', action: 'Delete a repository', }, ], default: 'getMany', }, { displayName: 'Operation', name: 'operation', type: 'options', noDataExpression: true, displayOptions: { show: { resource: ['artifact'], }, }, options: [ { name: 'Get', value: 'get', description: 'Get an artifact', action: 'Get an artifact', }, { name: 'Get Many', value: 'getMany', description: 'Get many artifacts', action: 'Get many artifacts', }, { name: 'Get Vulnerabilities', value: 'getVulnerabilities', description: 'Get artifact vulnerabilities', action: 'Get artifact vulnerabilities', }, ], default: 'getMany', }, { displayName: 'Operation', name: 'operation', type: 'options', noDataExpression: true, displayOptions: { show: { resource: ['location'], }, }, options: [ { name: 'Get Many', value: 'getMany', description: 'Get available locations', action: 'Get available locations', }, ], default: 'getMany', }, { displayName: 'Operation', name: 'operation', type: 'options', noDataExpression: true, displayOptions: { show: { resource: ['name'], }, }, options: [ { name: 'Check Availability', value: 'checkAvailability', description: 'Check if registry name is available', action: 'Check name availability', }, ], default: 'checkAvailability', }, { displayName: 'Registry ID', name: 'registryId', type: 'string', required: true, displayOptions: { show: { resource: ['registry', 'token', 'repository', 'artifact'], operation: ['get', 'update', 'delete'], }, }, default: '', description: 'The unique ID of the registry', }, { displayName: 'Registry ID', name: 'registryId', type: 'string', required: true, displayOptions: { show: { resource: ['token', 'repository', 'artifact'], operation: ['create', 'getMany', 'getVulnerabilities'], }, }, default: '', description: 'The unique ID of the registry', }, { displayName: 'Name', name: 'registryName', type: 'string', required: true, displayOptions: { show: { resource: ['registry'], operation: ['create'], }, }, default: '', description: 'The name of the registry (3-63 chars, lowercase, alphanumeric and hyphens)', placeholder: 'my-registry', }, { displayName: 'Location', name: 'location', type: 'string', required: true, displayOptions: { show: { resource: ['registry'], operation: ['create'], }, }, default: 'de/fra', description: 'The location ID where the registry will be created', }, { displayName: 'Garbage Collection Schedule', name: 'garbageCollectionSchedule', type: 'json', displayOptions: { show: { resource: ['registry'], operation: ['create'], }, }, default: '{"time":"04:00:00Z","days":["Sunday"]}', description: 'Schedule for automatic garbage collection', }, { displayName: 'Additional Fields', name: 'additionalFields', type: 'collection', placeholder: 'Add Field', default: {}, displayOptions: { show: { resource: ['registry'], operation: ['create', 'update'], }, }, options: [ { displayName: 'API Subnet Allow List', name: 'apiSubnetAllowList', type: 'string', default: '', description: 'Comma-separated list of CIDRs allowed to access the registry API', }, { displayName: 'Vulnerability Scanning Enabled', name: 'vulnerabilityScanningEnabled', type: 'boolean', default: true, description: 'Whether vulnerability scanning is enabled', }, ], }, { displayName: 'Token ID', name: 'tokenId', type: 'string', required: true, displayOptions: { show: { resource: ['token'], operation: ['get', 'update', 'delete'], }, }, default: '', description: 'The unique ID of the token', }, { displayName: 'Name', name: 'tokenName', type: 'string', required: true, displayOptions: { show: { resource: ['token'], operation: ['create'], }, }, default: '', description: 'The name of the token', }, { displayName: 'Scopes', name: 'scopes', type: 'json', required: true, displayOptions: { show: { resource: ['token'], operation: ['create'], }, }, default: '[{"actions":["pull"],"name":"*","type":"repository"}]', description: 'Array of scope objects defining token permissions', }, { displayName: 'Additional Fields', name: 'additionalFields', type: 'collection', placeholder: 'Add Field', default: {}, displayOptions: { show: { resource: ['token'], operation: ['create', 'update'], }, }, options: [ { displayName: 'Expiry Date', name: 'expiryDate', type: 'string', default: '', description: 'Token expiry date in ISO format (e.g., 2025-12-31T23:59:59Z)', }, { displayName: 'Status', name: 'status', type: 'options', options: [ { name: 'Enabled', value: 'enabled', }, { name: 'Disabled', value: 'disabled', }, ], default: 'enabled', description: 'Token status', }, ], }, { displayName: 'Repository Name', name: 'repositoryName', type: 'string', required: true, displayOptions: { show: { resource: ['repository', 'artifact'], operation: ['get', 'delete', 'getVulnerabilities'], }, }, default: '', description: 'The name of the repository', }, { displayName: 'Artifact Digest', name: 'digest', type: 'string', required: true, displayOptions: { show: { resource: ['artifact'], operation: ['get', 'getVulnerabilities'], }, }, default: '', description: 'The digest of the artifact (SHA256 hash)', placeholder: 'sha256:abc123...', }, { displayName: 'Name', name: 'nameToCheck', type: 'string', required: true, displayOptions: { show: { resource: ['name'], operation: ['checkAvailability'], }, }, default: '', description: 'The registry name to check for availability', placeholder: 'my-registry', }, { displayName: 'Filter by Name', name: 'filterName', type: 'string', displayOptions: { show: { resource: ['registry'], operation: ['getMany'], }, }, default: '', description: 'Filter registries by name', }, { displayName: 'Return All', name: 'returnAll', type: 'boolean', displayOptions: { show: { operation: ['getMany'], }, }, default: false, description: 'Whether to return all results or only up to a given limit', }, { displayName: 'Limit', name: 'limit', type: 'number', displayOptions: { show: { operation: ['getMany'], returnAll: [false], }, }, typeOptions: { minValue: 1, maxValue: 1000, }, default: 100, description: 'Max number of results to return', }, ], }; async execute() { const items = this.getInputData(); const returnData = []; const resource = this.getNodeParameter('resource', 0); const operation = this.getNodeParameter('operation', 0); for (let i = 0; i < items.length; i++) { try { let responseData = {}; if (resource === 'registry') { if (operation === 'create') { const name = this.getNodeParameter('registryName', i); const location = this.getNodeParameter('location', i); const garbageCollectionScheduleString = this.getNodeParameter('garbageCollectionSchedule', i); const additionalFields = this.getNodeParameter('additionalFields', i); const garbageCollectionSchedule = JSON.parse(garbageCollectionScheduleString); const body = { properties: { name, location, garbageCollectionSchedule, features: { vulnerabilityScanning: { enabled: additionalFields.vulnerabilityScanningEnabled !== false, }, }, ...(additionalFields.apiSubnetAllowList && { apiSubnetAllowList: additionalFields.apiSubnetAllowList .split(',') .map((cidr) => cidr.trim()), }), }, }; responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'ionosCloud', { method: 'POST', url: `${baseUrl}/registries`, body, headers: { 'Content-Type': 'application/json' }, }); } else if (operation === 'get') { const registryId = this.getNodeParameter('registryId', i); responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'ionosCloud', { method: 'GET', url: `${baseUrl}/registries/${registryId}`, }); } else if (operation === 'getMany') { const returnAll = this.getNodeParameter('returnAll', i); const limit = this.getNodeParameter('limit', i, 100); const filterName = this.getNodeParameter('filterName', i, ''); const qs = {}; if (filterName) { qs['filter.name'] = filterName; } if (!returnAll) { qs.limit = limit.toString(); } responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'ionosCloud', { method: 'GET', url: `${baseUrl}/registries`, qs, }); responseData = responseData.items; } else if (operation === 'update') { const registryId = this.getNodeParameter('registryId', i); const additionalFields = this.getNodeParameter('additionalFields', i); const body = { properties: {}, }; if (additionalFields.apiSubnetAllowList) { body.properties.apiSubnetAllowList = additionalFields.apiSubnetAllowList .split(',') .map((cidr) => cidr.trim()); } if (additionalFields.vulnerabilityScanningEnabled !== undefined) { body.properties.features = { vulnerabilityScanning: { enabled: additionalFields.vulnerabilityScanningEnabled, }, }; } responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'ionosCloud', { method: 'PATCH', url: `${baseUrl}/registries/${registryId}`, body, headers: { 'Content-Type': 'application/json' }, }); } else if (operation === 'delete') { const registryId = this.getNodeParameter('registryId', i); await this.helpers.httpRequestWithAuthentication.call(this, 'ionosCloud', { method: 'DELETE', url: `${baseUrl}/registries/${registryId}`, }); responseData = { success: true }; } } else if (resource === 'token') { const registryId = this.getNodeParameter('registryId', i); if (operation === 'create') { const name = this.getNodeParameter('tokenName', i); const scopesString = this.getNodeParameter('scopes', i); const additionalFields = this.getNodeParameter('additionalFields', i); const scopes = JSON.parse(scopesString); const body = { properties: { name, scopes, ...(additionalFields.expiryDate && { expiryDate: additionalFields.expiryDate }), ...(additionalFields.status && { status: additionalFields.status }), }, }; responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'ionosCloud', { method: 'POST', url: `${baseUrl}/registries/${registryId}/tokens`, body, headers: { 'Content-Type': 'application/json' }, }); } else if (operation === 'get') { const tokenId = this.getNodeParameter('tokenId', i); responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'ionosCloud', { method: 'GET', url: `${baseUrl}/registries/${registryId}/tokens/${tokenId}`, }); } else if (operation === 'getMany') { const returnAll = this.getNodeParameter('returnAll', i); const limit = this.getNodeParameter('limit', i, 100); const qs = {}; if (!returnAll) { qs.limit = limit.toString(); } responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'ionosCloud', { method: 'GET', url: `${baseUrl}/registries/${registryId}/tokens`, qs, }); responseData = responseData.items; } else if (operation === 'update') { const tokenId = this.getNodeParameter('tokenId', i); const additionalFields = this.getNodeParameter('additionalFields', i); const body = { properties: { ...(additionalFields.expiryDate && { expiryDate: additionalFields.expiryDate }), ...(additionalFields.status && { status: additionalFields.status }), }, }; responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'ionosCloud', { method: 'PATCH', url: `${baseUrl}/registries/${registryId}/tokens/${tokenId}`, body, headers: { 'Content-Type': 'application/vnd.profitbricks.partial-properties+json' }, }); } else if (operation === 'delete') { const tokenId = this.getNodeParameter('tokenId', i); await this.helpers.httpRequestWithAuthentication.call(this, 'ionosCloud', { method: 'DELETE', url: `${baseUrl}/registries/${registryId}/tokens/${tokenId}`, }); responseData = { success: true }; } } else if (resource === 'repository') { const registryId = this.getNodeParameter('registryId', i); if (operation === 'get') { const repositoryName = this.getNodeParameter('repositoryName', i); responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'ionosCloud', { method: 'GET', url: `${baseUrl}/registries/${registryId}/repositories/${repositoryName}`, }); } else if (operation === 'getMany') { const returnAll = this.getNodeParameter('returnAll', i); const limit = this.getNodeParameter('limit', i, 100); const qs = {}; if (!returnAll) { qs.limit = limit.toString(); } responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'ionosCloud', { method: 'GET', url: `${baseUrl}/registries/${registryId}/repositories`, qs, }); responseData = responseData.items; } else if (operation === 'delete') { const repositoryName = this.getNodeParameter('repositoryName', i); await this.helpers.httpRequestWithAuthentication.call(this, 'ionosCloud', { method: 'DELETE', url: `${baseUrl}/registries/${registryId}/repositories/${repositoryName}`, }); responseData = { success: true }; } } else if (resource === 'artifact') { const registryId = this.getNodeParameter('registryId', i); const repositoryName = this.getNodeParameter('repositoryName', i); if (operation === 'get') { const digest = this.getNodeParameter('digest', i); responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'ionosCloud', { method: 'GET', url: `${baseUrl}/registries/${registryId}/repositories/${repositoryName}/artifacts/${digest}`, }); } else if (operation === 'getMany') { const returnAll = this.getNodeParameter('returnAll', i); const limit = this.getNodeParameter('limit', i, 100); const qs = {}; if (!returnAll) { qs.limit = limit.toString(); } responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'ionosCloud', { method: 'GET', url: `${baseUrl}/registries/${registryId}/repositories/${repositoryName}/artifacts`, qs, }); responseData = responseData.items; } else if (operation === 'getVulnerabilities') { const digest = this.getNodeParameter('digest', i); responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'ionosCloud', { method: 'GET', url: `${baseUrl}/registries/${registryId}/repositories/${repositoryName}/artifacts/${digest}/vulnerabilities`, }); responseData = responseData.items; } } else if (resource === 'location') { if (operation === 'getMany') { responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'ionosCloud', { method: 'GET', url: `${baseUrl}/locations`, }); responseData = responseData.items; } } else if (resource === 'name') { if (operation === 'checkAvailability') { const nameToCheck = this.getNodeParameter('nameToCheck', i); try { await this.helpers.httpRequestWithAuthentication.call(this, 'ionosCloud', { method: 'HEAD', url: `${baseUrl}/names/${nameToCheck}`, }); responseData = { name: nameToCheck, available: false }; } catch (error) { if (error.statusCode === 404) { responseData = { name: nameToCheck, available: true }; } else { throw error; } } } } const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } }); returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray({ error: error.message }), { itemData: { item: i } }); returnData.push(...executionData); continue; } throw error; } } return [returnData]; } } exports.IonosCloudContainerRegistry = IonosCloudContainerRegistry;