Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/manager/.changeset/pr-13176-tests-1765218851864.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Tests
---

Mock Destination data update values ([#13176](https://github.com/linode/manager/pull/13176))
4 changes: 2 additions & 2 deletions packages/manager/cypress/support/constants/delivery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ export const mockDestinationPayload: CreateDestinationPayload = {
label: randomLabel(),
type: destinationType.AkamaiObjectStorage,
details: {
host: randomString(),
bucket_name: randomLabel(),
host: 'test-bucket-name.host.com',
bucket_name: 'test-bucket-name',
access_key_id: randomString(),
access_key_secret: randomString(),
path: '/',
Expand Down
2 changes: 1 addition & 1 deletion packages/manager/src/factories/delivery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const destinationFactory = Factory.Sync.makeFactory<Destination>({
details: {
access_key_id: 'Access Id',
bucket_name: 'destinations-bucket-name',
host: '3000',
host: 'destinations-bucket-name.host.com',
path: 'file',
},
id: Factory.each((id) => id),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ describe('DestinationEdit', () => {
await waitFor(() => {
assertInputHasValue('Destination Name', 'Destination 123');
});
assertInputHasValue('Host', '3000');
assertInputHasValue('Host', 'destinations-bucket-name.host.com');
assertInputHasValue('Bucket', 'destinations-bucket-name');
assertInputHasValue('Access Key ID', 'Access Id');
assertInputHasValue('Secret Access Key', '');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ describe('StreamEdit', () => {
assertInputHasValue('Destination Name', 'Destination 1');

// Host:
expect(screen.getByText('3000')).toBeVisible();
expect(screen.getByText('destinations-bucket-name.host.com')).toBeVisible();
// Bucket:
expect(screen.getByText('destinations-bucket-name')).toBeVisible();
// Access Key ID:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/validation": Changed
---

Logs Destination Form - add matching host and bucket name validation ([#13176](https://github.com/linode/manager/pull/13176))
34 changes: 32 additions & 2 deletions packages/validation/src/delivery.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,26 @@ const customHTTPsDetailsSchema = object({
endpoint_url: string().max(maxLength, maxLengthMessage).required(),
});

const hostRgx =
// eslint-disable-next-line sonarjs/slow-regex
/(?<bucket>[a-z0-9-.]+)\.(?:s3(?:-accesspoint)?\.[a-z0-9-]+\.amazonaws\.com|(?!devcloud\.)[a-z0-9-]+\.(?:devcloud\.)?linodeobjects\.com)/;

const akamaiObjectStorageDetailsBaseSchema = object({
host: string().max(maxLength, maxLengthMessage).required('Host is required.'),
host: string()
.max(maxLength, maxLengthMessage)
.required('Host is required.')
.test(
'host-must-match-with-bucket-name-if-provided',
'Bucket name provided as a part of the host must be the same as the bucket.',
(value, ctx) => {
if (ctx.parent.bucket_name) {
const groups = hostRgx.exec(value)?.groups;
return groups ? groups.bucket === ctx.parent.bucket_name : true;
}

return true;
},
),
bucket_name: string()
.required('Bucket name is required.')
.min(3, 'Bucket name must be between 3 and 63 characters.')
Expand All @@ -71,7 +89,19 @@ const akamaiObjectStorageDetailsBaseSchema = object({
/^(?!.*[.-]{2})[a-z0-9.-]+$/,
'Bucket name must contain only lowercase letters, numbers, periods (.), and hyphens (-). Adjacent periods and hyphens are not allowed.',
)
.max(63, 'Bucket name must be between 3 and 63 characters.'),
.max(63, 'Bucket name must be between 3 and 63 characters.')
.test(
'bucket-name-same-in-host-if-provided',
'Bucket must match the bucket name used in the host prefix.',
(value, ctx) => {
if (ctx.parent.host) {
const groups = hostRgx.exec(ctx.parent.host)?.groups;
return groups ? groups.bucket === value : true;
}

return true;
},
),
path: string().max(maxLength, maxLengthMessage).defined(),
access_key_id: string()
.max(maxLength, maxLengthMessage)
Expand Down