Skip to content

Commit

Permalink
Merge branch 'develop' into refactor/begin-react-queryifying-stackscr…
Browse files Browse the repository at this point in the history
…ipts
  • Loading branch information
bnussman committed Dec 2, 2024
2 parents 8946be2 + 8611b57 commit 807cc5b
Show file tree
Hide file tree
Showing 38 changed files with 821 additions and 81 deletions.
5 changes: 5 additions & 0 deletions packages/api-v4/.changeset/pr-11261-added-1732225555236.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/api-v4": Added
---

Placement Groups migrations Types ([#11261](https://github.com/linode/manager/pull/11261))
5 changes: 5 additions & 0 deletions packages/api-v4/.changeset/pr-11337-added-1732714186488.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/api-v4": Added
---

Linter rules for naming convention ([#11337](https://github.com/linode/manager/pull/11337))
45 changes: 36 additions & 9 deletions packages/api-v4/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,42 @@
"plugin:prettier/recommended"
],
"rules": {
"@typescript-eslint/naming-convention": [
"warn",
{
"format": ["camelCase", "UPPER_CASE", "PascalCase"],
"leadingUnderscore": "allow",
"selector": "variable",
"trailingUnderscore": "allow"
},
{
"format": null,
"modifiers": ["destructured"],
"selector": "variable"
},
{
"format": ["camelCase", "PascalCase"],
"selector": "function"
},
{
"format": ["camelCase"],
"leadingUnderscore": "allow",
"selector": "parameter"
},
{
"format": ["PascalCase"],
"selector": "typeLike"
}
],
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/no-inferrable-types": "off",
"@typescript-eslint/no-namespace": "warn",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-empty-interface": "warn",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/no-use-before-define": "off",
"@typescript-eslint/interface-name-prefix": "off",
"no-unused-vars": [
"warn",
{
Expand All @@ -33,15 +69,6 @@
"no-console": "error",
"no-undef-init": "off",
"radix": "error",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/no-inferrable-types": "off",
"@typescript-eslint/no-namespace": "warn",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-empty-interface": "warn",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/no-use-before-define": "off",
"@typescript-eslint/interface-name-prefix": "off",
"sonarjs/cognitive-complexity": "warn",
"sonarjs/no-duplicate-string": "warn",
"sonarjs/prefer-immediate-return": "warn",
Expand Down
4 changes: 2 additions & 2 deletions packages/api-v4/src/cloudpulse/alerts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import { BETA_API_ROOT as API_ROOT } from 'src/constants';

export const createAlertDefinition = (
data: CreateAlertDefinitionPayload,
service_type: AlertServiceType
serviceType: AlertServiceType
) =>
Request<Alert>(
setURL(
`${API_ROOT}/monitor/services/${encodeURIComponent(
service_type!
serviceType!
)}/alert-definitions`
),
setMethod('POST'),
Expand Down
5 changes: 3 additions & 2 deletions packages/api-v4/src/cloudpulse/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export interface ServiceTypesList {
export interface CreateAlertDefinitionPayload {
label: string;
description?: string;
resource_ids?: string[];
entity_ids?: string[];
severity: AlertSeverityType;
rule_criteria: {
rules: MetricCriteria[];
Expand Down Expand Up @@ -174,11 +174,12 @@ export interface Alert {
id: number;
label: string;
description: string;
has_more_resources: boolean;
status: AlertStatusType;
type: AlertDefinitionType;
severity: AlertSeverityType;
service_type: AlertServiceType;
resource_ids: string[];
entity_ids: string[];
rule_criteria: {
rules: MetricCriteria[];
};
Expand Down
4 changes: 2 additions & 2 deletions packages/api-v4/src/linodes/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Region, RegionSite } from '../regions';
import type { IPAddress, IPRange } from '../networking/types';
import type { SSHKey } from '../profile/types';
import type { PlacementGroupPayload } from '../placement-groups/types';
import type { LinodePlacementGroupPayload } from '../placement-groups/types';

export type Hypervisor = 'kvm' | 'zen';

Expand Down Expand Up @@ -30,7 +30,7 @@ export interface Linode {
ipv6: string | null;
label: string;
lke_cluster_id: number | null;
placement_group?: PlacementGroupPayload; // If not in a placement group, this will be excluded from the response.
placement_group?: LinodePlacementGroupPayload; // If not in a placement group, this will be excluded from the response.
type: string | null;
status: LinodeStatus;
updated: string;
Expand Down
17 changes: 12 additions & 5 deletions packages/api-v4/src/placement-groups/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,22 @@ export interface PlacementGroup {
is_compliant: boolean;
}[];
placement_group_policy: PlacementGroupPolicy;
migrations: {
inbound?: Array<{ linode_id: number }>;
outbound?: Array<{ linode_id: number }>;
} | null;
}

export type PlacementGroupPayload = Pick<
PlacementGroup,
'id' | 'label' | 'placement_group_type' | 'placement_group_policy'
>;
export interface LinodePlacementGroupPayload
extends Pick<
PlacementGroup,
'id' | 'label' | 'placement_group_type' | 'placement_group_policy'
> {
migrating_to: number | null;
}

export interface CreatePlacementGroupPayload
extends Omit<PlacementGroupPayload, 'id'> {
extends Omit<LinodePlacementGroupPayload, 'id' | 'migrating_to'> {
region: Region['id'];
}

Expand Down
5 changes: 5 additions & 0 deletions packages/manager/.changeset/pr-11261-changed-1732225439368.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Changed
---

Improve Placement Groups UI during Linode Migrations ([#11261](https://github.com/linode/manager/pull/11261))
5 changes: 5 additions & 0 deletions packages/manager/.changeset/pr-11327-tests-1732571554878.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Tests
---

Add test to create a mock accelerated Linode ([#11327](https://github.com/linode/manager/pull/11327))
5 changes: 5 additions & 0 deletions packages/manager/.changeset/pr-11331-added-1732627930598.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Added
---

ResourceMultiSelect component, along with UT. Changed case for few variables and properties ([#11331](https://github.com/linode/manager/pull/11331))
5 changes: 5 additions & 0 deletions packages/manager/.changeset/pr-11336-added-1732711112187.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Added
---

unit test cases for `DocsLink` component ([#11336](https://github.com/linode/manager/pull/11336))
5 changes: 5 additions & 0 deletions packages/manager/.changeset/pr-11337-added-1732714227095.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Added
---

Linter rules for naming convention ([#11337](https://github.com/linode/manager/pull/11337))
27 changes: 27 additions & 0 deletions packages/manager/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,33 @@ module.exports = {
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/naming-convention': [
'warn',
{
format: ['camelCase', 'UPPER_CASE', 'PascalCase'],
leadingUnderscore: 'allow',
selector: 'variable',
trailingUnderscore: 'allow',
},
{
format: null,
modifiers: ['destructured'],
selector: 'variable',
},
{
format: ['camelCase', 'PascalCase'],
selector: 'function',
},
{
format: ['camelCase'],
leadingUnderscore: 'allow',
selector: 'parameter',
},
{
format: ['PascalCase'],
selector: 'typeLike',
},
],
'@typescript-eslint/no-empty-interface': 'warn',
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/no-inferrable-types': 'off',
Expand Down
122 changes: 112 additions & 10 deletions packages/manager/cypress/e2e/core/linodes/create-linode.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,20 @@ import { authenticate } from 'support/api/authentication';
import {
interceptCreateLinode,
mockCreateLinodeError,
mockCreateLinode,
mockGetLinodeDisks,
mockGetLinodeType,
mockGetLinodeTypes,
mockGetLinodeVolumes,
} from 'support/intercepts/linodes';
import { interceptGetProfile } from 'support/intercepts/profile';
import { Region, VLAN, Config, Disk } from '@linode/api-v4';
import { getRegionById } from 'support/util/regions';
import {
accountFactory,
linodeFactory,
linodeConfigFactory,
linodeTypeFactory,
VLANFactory,
vpcFactory,
subnetFactory,
Expand All @@ -27,18 +34,11 @@ import {
LinodeConfigInterfaceFactoryWithVPC,
} from 'src/factories';
import { dcPricingMockLinodeTypes } from 'support/constants/dc-specific-pricing';
import {
mockGetLinodeType,
mockGetLinodeTypes,
} from 'support/intercepts/linodes';
import { mockGetAccount } from 'support/intercepts/account';
import { mockAppendFeatureFlags } from 'support/intercepts/feature-flags';
import { mockGetRegions } from 'support/intercepts/regions';
import { mockGetVLANs } from 'support/intercepts/vlans';
import { mockGetVPC, mockGetVPCs } from 'support/intercepts/vpc';
import {
mockCreateLinode,
mockGetLinodeDisks,
mockGetLinodeVolumes,
} from 'support/intercepts/linodes';
import { mockGetLinodeConfigs } from 'support/intercepts/configs';
import {
fbtClick,
Expand All @@ -47,7 +47,7 @@ import {
getVisible,
containsVisible,
} from 'support/helpers';
import {} from 'support/helpers';

let username: string;

authenticate();
Expand Down Expand Up @@ -85,6 +85,7 @@ describe('Create Linode', () => {
planId: 'g7-premium-2',
},
// TODO Include GPU plan types.
// TODO Include Accelerated plan types (when they're no longer as restricted)
].forEach((planConfig) => {
/*
* - Parameterized end-to-end test to create a Linode for each plan type.
Expand Down Expand Up @@ -170,6 +171,107 @@ describe('Create Linode', () => {
});
});

// Mocks creating an accelerated Linode due to accelerated linodes currently having limited deployment availability
// TODO: eventually transition this to an e2e test (in the above test)
it('creates a mock accelerated Linode and confirms response', () => {
// Create mocks
const linodeLabel = randomLabel();
const mockLinode = linodeFactory.build({
label: linodeLabel,
specs: {
accelerated_devices: 2,
disk: 51200,
gpus: 0,
memory: 2048,
transfer: 2000,
vcpus: 1,
},
type: 'accelerated-1',
});
const mockAcceleratedType = [
linodeTypeFactory.build({
id: 'accelerated-1',
label: 'accelerated-1',
class: 'accelerated',
}),
];
const mockRegions = [
regionFactory.build({
capabilities: ['Linodes', 'Kubernetes', 'NETINT Quadra T1U'],
id: 'us-east',
label: 'Newark, NJ',
}),
];
const linodeRegion = mockRegions[0];

// Create request intercepts
mockGetAccount(
accountFactory.build({
capabilities: ['NETINT Quadra T1U'],
})
).as('getAccount');
mockAppendFeatureFlags({
acceleratedPlans: {
linodePlans: true,
lkePlans: false,
},
}).as('getFeatureFlags');
mockGetRegions(mockRegions).as('getRegions');
mockGetLinodeTypes([...mockAcceleratedType]).as('getLinodeTypes');
mockCreateLinode(mockLinode).as('createLinode');

cy.visitWithLogin('/linodes/create');
cy.wait([
'@getRegions',
'@getLinodeTypes',
'@getAccount',
'@getFeatureFlags',
]);

// Set Linode label, OS, plan type, password, etc.
linodeCreatePage.setLabel(linodeLabel);
linodeCreatePage.selectImage('Debian 11');
linodeCreatePage.selectRegionById(linodeRegion.id);
linodeCreatePage.selectPlan('Accelerated', mockAcceleratedType[0].label);
linodeCreatePage.setRootPassword(randomString(32));

// Confirm information in summary is shown as expected.
cy.get('[data-qa-linode-create-summary]')
.scrollIntoView()
.within(() => {
cy.findByText('Debian 11').should('be.visible');
cy.findByText(`US, ${linodeRegion.label}`).should('be.visible');
cy.findByText(mockAcceleratedType[0].label).should('be.visible');
});

// Create Linode and confirm it's provisioned as expected.
ui.button
.findByTitle('Create Linode')
.should('be.visible')
.should('be.enabled')
.click();

cy.wait('@createLinode').then((xhr) => {
const requestPayload = xhr.request.body;
const responsePayload = xhr.response?.body;

// Confirm that API request and response contain expected data
expect(requestPayload['label']).to.equal(linodeLabel);
expect(requestPayload['region']).to.equal(linodeRegion.id);
expect(requestPayload['type']).to.equal(mockAcceleratedType[0].id);

expect(responsePayload['label']).to.equal(linodeLabel);
expect(responsePayload['region']).to.equal(linodeRegion.id);
expect(responsePayload['type']).to.equal(mockAcceleratedType[0].id);

// Accelerated linodes: Confirm accelerated_devices value is returned as expected
expect(responsePayload['specs']).has.property('accelerated_devices', 2);

// Confirm that Cloud redirects to details page
cy.url().should('endWith', `/linodes/${responsePayload['id']}`);
});
});

it('adds an SSH key to the linode during create flow', () => {
const rootpass = randomString(32);
const sshPublicKeyLabel = randomLabel();
Expand Down
Loading

0 comments on commit 807cc5b

Please sign in to comment.