import type {CloudProvider, FieldSchema, ServiceSchema, TableColumnSchema} from './types' export const CDN_ORIGIN_TYPES = ['s3', 'custom'] as const export const CDN_VIEWER_PROTOCOLS = ['redirect-to-https', 'allow-all', 'https-only'] as const export const CDN_ORIGIN_PROTOCOLS = ['https-only', 'http-only', 'match-viewer'] as const export const CDN_ALLOWED_METHODS = ['read', 'all'] as const /** An S3 bucket name as S3 allows it for new buckets. */ export const CDN_BUCKET_PATTERN = '^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$' /** A host name, optionally with a port, as a custom origin's DomainName. */ export const CDN_ORIGIN_DOMAIN_PATTERN = '^[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$' const distributionColumns: TableColumnSchema[] = [ {name: 'id', label: 'Distribution ID', format: 'code'}, {name: 'viewerUrl', label: 'Local URL', path: 'metadata.viewerUrl', format: 'code'}, {name: 'status', label: 'Status', format: 'badge'}, {name: 'enabled', label: 'Enabled', path: 'metadata.enabled', format: 'boolean'}, {name: 'origins', label: 'Origins', path: 'metadata.originDomains', format: 'list'}, {name: 'comment', label: 'Description', path: 'metadata.comment', emptyText: '—'}, ] const distributionFilters: FieldSchema[] = [{name: 'search', label: 'Search', type: 'text', required: false}] export function awsCdnSchema(): ServiceSchema { return { cloud: 'aws', service: 'cdn', displayName: 'Amazon CloudFront distributions', fields: [ { name: 'originType', label: 'Origin', type: 'select', required: true, defaultValue: 's3', options: [{label: 'S3 bucket', value: 's3'}, {label: 'Custom origin (a web server or API)', value: 'custom'}], }, { name: 'bucket', label: 'S3 bucket', type: 'text', required: false, requiredWhen: {field: 'originType', equals: 's3'}, visibleWhen: {field: 'originType', values: ['s3']}, validation: {pattern: CDN_BUCKET_PATTERN, message: 'Use the name of an existing bucket'}, }, { name: 'originDomain', label: 'Origin domain', type: 'text', required: false, requiredWhen: {field: 'originType', equals: 'custom'}, visibleWhen: {field: 'originType', values: ['custom']}, description: 'For example api.example.com. A local server needs FLOCI_SERVICES_CLOUDFRONT_ALLOWED_PRIVATE_ORIGIN_HOSTS on the runtime.', validation: {pattern: CDN_ORIGIN_DOMAIN_PATTERN, message: 'Use a host name such as api.example.com'}, }, { name: 'originProtocol', label: 'Origin protocol', type: 'select', required: false, defaultValue: 'https-only', visibleWhen: {field: 'originType', values: ['custom']}, options: [ {label: 'HTTPS only', value: 'https-only'}, {label: 'HTTP only', value: 'http-only'}, {label: 'Match the viewer', value: 'match-viewer'}, ], }, { name: 'originPort', label: 'Origin port', type: 'text', required: false, visibleWhen: {field: 'originType', values: ['custom']}, description: 'Leave empty for 443 (HTTPS) and 80 (HTTP).', validation: {pattern: '^\\d{1,5}$', message: 'Use a port number'}, }, { name: 'defaultRootObject', label: 'Default root object', type: 'text', required: false, defaultValue: 'index.html', description: 'What the distribution serves for a request to /.', }, { name: 'viewerProtocol', label: 'Viewer protocol', type: 'select', required: false, defaultValue: 'allow-all', options: [ {label: 'HTTP and HTTPS', value: 'allow-all'}, {label: 'Redirect HTTP to HTTPS', value: 'redirect-to-https'}, {label: 'HTTPS only', value: 'https-only'}, ], }, { name: 'allowedMethods', label: 'Allowed methods', type: 'select', required: false, defaultValue: 'read', options: [ {label: 'GET and HEAD (a website or files)', value: 'read'}, {label: 'All methods (an API)', value: 'all'}, ], }, {name: 'comment', label: 'Description', type: 'text', required: false}, ], actions: ['list', 'create', 'delete', 'inspect'], capabilities: { resourceActions: [ {name: 'list', label: 'List distributions', enabled: true, status: 'available', runtimeRequired: true}, {name: 'create', label: 'Create distribution', enabled: true, status: 'available', runtimeRequired: true}, {name: 'delete', label: 'Disable and delete distribution', enabled: true, status: 'available', runtimeRequired: true}, {name: 'inspect', label: 'Inspect distribution', enabled: true, status: 'available', runtimeRequired: true}, ], distributionActions: [ {name: 'setEnabled', label: 'Enable or disable a distribution', enabled: true, status: 'available', runtimeRequired: true}, {name: 'createInvalidation', label: 'Invalidate cached paths', enabled: true, status: 'available', runtimeRequired: true}, ], }, filters: distributionFilters, columns: distributionColumns, } } export function cdnSchemaFor(cloud: CloudProvider): ServiceSchema | null { return cloud === 'aws' ? awsCdnSchema() : null }