Skip to content

Commit

Permalink
Merge branch 'release' into 'master'
Browse files Browse the repository at this point in the history
RELEASE 2.2.0

See merge request arenadata/development/adcm!3931
  • Loading branch information
a-alferov committed Jul 5, 2024
2 parents c43aa57 + 0347abe commit 9c8aab4
Show file tree
Hide file tree
Showing 723 changed files with 36,312 additions and 17,537 deletions.
18 changes: 10 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ APP_IMAGE ?= hub.adsw.io/adcm/adcm
APP_TAG ?= $(subst /,_,$(BRANCH_NAME))
SELENOID_HOST ?= 10.92.2.65
SELENOID_PORT ?= 4444
ADCM_VERSION = "2.1.2"
ADCM_VERSION = "2.2.0"
PY_FILES = python dev/linters conf/adcm/python_scripts

.PHONY: help

Expand Down Expand Up @@ -35,16 +36,17 @@ unittests_postgresql:

pretty:
poetry install --no-root --with lint
poetry run python license_checker.py --fix --folders python go
poetry run ruff format license_checker.py python
poetry run ruff check --fix license_checker.py python
poetry run ruff format license_checker.py python
poetry run ruff format $(PY_FILES)
poetry run ruff check --fix $(PY_FILES)
poetry run ruff format $(PY_FILES)
poetry run python dev/linters/license_checker.py --fix --folders $(PY_FILES) go

lint:
poetry install --no-root --with lint
poetry run python license_checker.py --folders python go
poetry run ruff check license_checker.py python
poetry run ruff format --check python
poetry run ruff check $(PY_FILES)
poetry run ruff format --check $(PY_FILES)
poetry run python dev/linters/license_checker.py --folders $(PY_FILES) go
poetry run python dev/linters/migrations_checker.py python

version:
@echo $(ADCM_VERSION)
8 changes: 8 additions & 0 deletions adcm-web/app/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
"django",
"dropdown",
"dom",
"ellipsed",
"enum",
"guid",
"gz",
Expand Down Expand Up @@ -135,6 +136,9 @@
"pathname",
"perf",
"pid",
"pointerdown",
"pointermove",
"pointerup",
"qs",
"quaternary",
"queueing",
Expand All @@ -153,6 +157,8 @@
"ssl",
"statusable",
"stderr",
"scrollend",
"scroller",
"stdout",
"str",
"svg",
Expand All @@ -174,12 +180,14 @@
"unmap",
"unmapped",
"unmount",
"unobserve",
"uncheck",
"upgradable",
"uri",
"yaml",
"user’s",
"vite",
"whitespace",
"ws",
"wss",
"xsrf"
Expand Down
2 changes: 1 addition & 1 deletion adcm-web/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
"vite": "4.4.1",
"vite-plugin-eslint": "1.8.1",
"vite-plugin-react-remove-attributes": "1.0.3",
"vite-plugin-svg-sprite": "0.3.2",
"vite-plugin-svg-spriter": "1.0.0",
"vite-plugin-svgr": "3.2.0",
"vite-tsconfig-paths": "4.2.0"
},
Expand Down
7 changes: 7 additions & 0 deletions adcm-web/app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import ServiceComponentConfigurationGroups from '@pages/cluster/service/componen
import ServiceComponentConfigGroupSingle from '@pages/cluster/service/component/ServiceComponentConfiguration/ServiceComponentConfigGroupSingle/ServiceComponentConfigGroupSingle';
import HostProviderConfigurationGroupSingle from '@pages/HostProviderPage/HostProviderConfigurationGroupSingle/HostProviderConfigurationGroupSingle';
import NotFoundPage from '@pages/NotFoundPage/NotFoundPage';
import ClusterAnsibleSettings from '@pages/cluster/ClusterConfiguration/ClusterAnsibleSettings/ClusterAnsibleSettings';

function App() {
return (
Expand Down Expand Up @@ -155,6 +156,11 @@ function App() {
path="/clusters/:clusterId/configuration/config-groups/:configGroupId/"
element={<ClusterConfigGroupSingle />}
/>
<Route index element={<Navigate to="ansible-settings" replace />} />
<Route
path="/clusters/:clusterId/configuration/ansible-settings"
element={<ClusterAnsibleSettings />}
/>
</Route>
<Route path="/clusters/:clusterId/import" element={<ClusterImport />}>
<Route index element={<Navigate to="cluster" replace />} />
Expand Down Expand Up @@ -189,6 +195,7 @@ function App() {
</Route>
<Route path="/jobs" element={<JobsPage />} />
<Route path="/jobs/:jobId" element={<JobPage />} />
<Route path="/jobs/:jobId/:withAutoStop" element={<JobPage />} />
<Route path="/access-manager" element={<AccessManagerPage />}>
<Route index element={<Navigate to="/access-manager/users" replace />} />
<Route path="/access-manager/users" element={<AccessManagerUsersPage />} />
Expand Down
36 changes: 36 additions & 0 deletions adcm-web/app/src/api/adcm/clusterAnsibleSettings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { httpClient } from '@api/httpClient';
import type { AdcmConfig, ConfigurationSchema } from '@models/adcm';

export interface GetClusterAnsibleSettingsArgs {
clusterId: number;
}

export interface GetClusterAnsibleSettingsSchemaArgs {
clusterId: number;
configGroupId: number;
}

export interface CreateClusterAnsibleSettingsArgs {
clusterId: number;
config: Partial<AdcmConfig>;
}

export class AdcmClusterAnsibleSettingsApi {
public static async getConfig(args: GetClusterAnsibleSettingsArgs) {
const response = await httpClient.get<AdcmConfig>(`/api/v2/clusters/${args.clusterId}/ansible-config/`);
return response.data;
}

public static async getConfigSchema(args: GetClusterAnsibleSettingsSchemaArgs) {
const response = await httpClient.get<ConfigurationSchema>(
`/api/v2/clusters/${args.clusterId}/ansible-config-schema/`,
);
return response.data;
}

public static async createConfiguration(args: CreateClusterAnsibleSettingsArgs) {
const { clusterId, config } = args;
const response = await httpClient.post<AdcmConfig>(`/api/v2/clusters/${clusterId}/ansible-config/`, config);
return response.data;
}
}
18 changes: 13 additions & 5 deletions adcm-web/app/src/api/adcm/clusterOverview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { httpClient } from '@api/httpClient';
import {
AdcmClusterOverviewStatusHost,
AdcmClusterOverviewStatusService,
AdcmClusterStatus,
AdcmHostStatus,
AdcmServiceStatus,
Batch,
} from '@models/adcm';
import { PaginationParams } from '@models/table';
Expand All @@ -13,21 +14,28 @@ export class AdcmClusterOverviewApi {
public static async getClusterServicesStatuses(
clusterId: number,
paginationParams: PaginationParams,
status?: AdcmClusterStatus,
status?: AdcmServiceStatus,
) {
const query = qs.stringify({ ...prepareLimitOffset(paginationParams), status });
const query = qs.stringify({
...prepareLimitOffset(paginationParams),
status,
});
const response = await httpClient.get<Batch<AdcmClusterOverviewStatusService>>(
`/api/v2/clusters/${clusterId}/statuses/services/?${query}`,
);

return response.data;
}

public static async getClusterHostsStatuses(
clusterId: number,
paginationParams: PaginationParams,
status?: AdcmClusterStatus,
status?: AdcmHostStatus,
) {
const query = qs.stringify({ ...prepareLimitOffset(paginationParams), status });
const query = qs.stringify({
...prepareLimitOffset(paginationParams),
status,
});
const response = await httpClient.get<Batch<AdcmClusterOverviewStatusHost>>(
`/api/v2/clusters/${clusterId}/statuses/hosts/?${query}`,
);
Expand Down
1 change: 1 addition & 0 deletions adcm-web/app/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@ export { AdcmClusterServiceConfigGroupConfigsApi } from './adcm/clusterServiceGr
export { AdcmProfileApi } from './adcm/profile';
export { AdcmClusterOverviewApi } from './adcm/clusterOverview';
export { AdcmSettingsApi } from './adcm/settings';
export { AdcmClusterAnsibleSettingsApi } from './adcm/clusterAnsibleSettings';
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { DynamicActionType } from '@commonComponents/DynamicActionDialog/DynamicAction.types';
import { AdcmDynamicActionDetails, AdcmDynamicActionRunConfig } from '@models/adcm/dynamicAction';
import { AdcmConfiguration, ConfigurationData } from '@models/adcm';
import { generateFromSchema } from '@utils/jsonSchemaUtils';
import { generateFromSchema } from '@utils/jsonSchema/jsonSchemaUtils';

export const getDynamicActionTypes = (actionDetails: AdcmDynamicActionDetails): DynamicActionType[] => {
const res = [] as DynamicActionType[];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React, { useEffect } from 'react';
import React, { useEffect, useMemo } from 'react';
import { useDispatch, useStore } from '@hooks';
import { Button, ButtonGroup, SearchInput, SpinnerPanel, ToolbarPanel } from '@uikit';
import { DynamicActionCommonOptions } from '@commonComponents/DynamicActionDialog/DynamicAction.types';
import s from '@commonComponents/DynamicActionDialog/DynamicActionDialog.module.scss';
import { useClusterMapping } from '@pages/cluster/ClusterMapping/useClusterMapping';
import ComponentContainer from '@pages/cluster/ClusterMapping/ComponentsMapping/ComponentContainer/ComponentContainer';
import { AdcmMappingComponent, AdcmMappingComponentService } from '@models/adcm';
import { getMappings } from '@store/adcm/clusters/clustersDynamicActionsSlice';
import { getComponentMapActions, getDisabledMappings } from './DynamicActionHostMapping.utils';
import { Link } from 'react-router-dom';
import { LoadState } from '@models/loadState';

Expand Down Expand Up @@ -41,8 +41,8 @@ const DynamicActionHostMapping: React.FC<DynamicActionHostMappingProps> = ({
servicesMapping,
mappingFilter,
handleMappingFilterChange,
mappingValidation,
handleMap,
mappingErrors,
handleMapHostsToComponent,
handleUnmap,
handleReset,
} = useClusterMapping(mapping, hosts, components, notAddedServicesDictionary, true);
Expand All @@ -53,16 +53,13 @@ const DynamicActionHostMapping: React.FC<DynamicActionHostMappingProps> = ({
onSubmit({ hostComponentMap: localMapping });
};

const getMapRules = (service: AdcmMappingComponentService, component: AdcmMappingComponent) => {
return actionDetails.hostComponentMapRules.filter(
(rule) => rule.service === service.name && rule.component === component.name,
);
};

const handleFilterChange = (event: React.ChangeEvent<HTMLInputElement>) => {
handleMappingFilterChange({ hostName: event.target.value });
};

const hasErrors = Object.keys(mappingErrors).length > 0;
const disabledMappings = useMemo(() => getDisabledMappings(mapping), [mapping]);

return (
<div>
<ToolbarPanel className={s.dynamicActionDialog__toolbar}>
Expand All @@ -72,11 +69,7 @@ const DynamicActionHostMapping: React.FC<DynamicActionHostMappingProps> = ({
<Button variant="secondary" onClick={onCancel}>
Cancel
</Button>
<Button
onClick={handleSubmit}
disabled={isServicesMappingEmpty || !mappingValidation.isAllMappingValid}
hasError={false}
>
<Button onClick={handleSubmit} disabled={isServicesMappingEmpty || hasErrors} hasError={false}>
{submitLabel}
</Button>
</ButtonGroup>
Expand All @@ -96,22 +89,20 @@ const DynamicActionHostMapping: React.FC<DynamicActionHostMappingProps> = ({
)}
{servicesMapping.flatMap(({ service, componentsMapping }) =>
componentsMapping.map((componentMapping) => {
const actions = getMapRules(service, componentMapping.component).map((rule) => rule.action);
const allowActions = [...new Set(actions)];
const allowActions = getComponentMapActions(actionDetails, service, componentMapping.component);
const componentMappingErrors = mappingErrors[componentMapping.component.id];

return (
<ComponentContainer
key={componentMapping.component.id}
componentMapping={componentMapping}
filter={mappingFilter}
allHosts={hosts}
notAddedServicesDictionary={notAddedServicesDictionary}
componentMappingValidation={mappingValidation.byComponents[componentMapping.component.id]}
onMap={handleMap}
disabledHosts={disabledMappings[componentMapping.component.id]}
mappingErrors={componentMappingErrors}
onMap={handleMapHostsToComponent}
onUnmap={handleUnmap}
allowActions={allowActions}
denyAddHostReason="Add host do not allow in config of action"
denyRemoveHostReason="Remove host do not allow in config of action"
/>
);
}),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import type {
AdcmDynamicActionDetails,
AdcmHostComponentMapRuleAction,
AdcmMapping,
AdcmMappingComponent,
AdcmMappingComponentService,
} from '@models/adcm';
import type { DisabledComponentsMappings } from '@pages/cluster/ClusterMapping/ClusterMapping.types';

export const getComponentMapActions = (
actionDetails: AdcmDynamicActionDetails,
service: AdcmMappingComponentService,
component: AdcmMappingComponent,
) => {
const result = new Set<AdcmHostComponentMapRuleAction>();

for (const rule of actionDetails.hostComponentMapRules) {
if (rule.service === service.name && rule.component === component.name) {
result.add(rule.action);
}
}

return result;
};

export const getDisabledMappings = (mapping: AdcmMapping[]) => {
const result: DisabledComponentsMappings = {};

for (const m of mapping) {
if (result[m.componentId] === undefined) {
result[m.componentId] = new Set();
}

result[m.componentId].add(m.hostId);
}

return result;
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export interface ErrorPageContentProps {

const ErrorPageContent = ({ errorCode, children }: ErrorPageContentProps) => {
return (
<div className={s.errorPageContent}>
<div className={s.errorPageContent} data-test={`error-${errorCode}`}>
<div className={s.errorPageContent__errorCode}>{errorCode}</div>
{children}
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.spinnerWrapper {
margin: auto 5%;
position: absolute;
top: 50%;
left: 50%;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import s from './PermissionsChecker.module.scss';
import { RequestState } from '@models/loadState';
import NotFoundPage from '@pages/NotFoundPage/NotFoundPage';
import AccessDeniedPage from '@pages/AccessDeniedPage/AccessDeniedPage';
import { Spinner } from '@uikit';

interface WithHttpResponseRouteProps {
children?: React.ReactNode;
requestState?: RequestState;
}

const PermissionsChecker = ({ children, requestState }: WithHttpResponseRouteProps) => {
if (requestState === RequestState.Pending) {
return (
<div className={s.spinnerWrapper}>
<Spinner />
</div>
);
}

if (requestState === RequestState.AccessDenied) {
return <AccessDeniedPage />;
}

if (requestState === RequestState.NotFound) {
return <NotFoundPage />;
}

if (requestState === RequestState.Completed) {
return <>{children}</>;
}
};

export default PermissionsChecker;
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export const jobStatusesIconsMap: { [key in AdcmJobStatus]: IconsNames } = {
[AdcmJobStatus.Running]: 'g2-running-10x10',
[AdcmJobStatus.Locked]: 'g2-locked-10x10',
[AdcmJobStatus.Aborted]: 'g2-aborted-10x10',
[AdcmJobStatus.Broken]: 'g2-failed-10x10',
};
Loading

0 comments on commit 9c8aab4

Please sign in to comment.