diff --git a/awx/ui/src/screens/InstanceGroup/ContainerGroup.js b/awx/ui/src/screens/InstanceGroup/ContainerGroup.js
index 13df64e75f..1e1be0b88d 100644
--- a/awx/ui/src/screens/InstanceGroup/ContainerGroup.js
+++ b/awx/ui/src/screens/InstanceGroup/ContainerGroup.js
@@ -30,13 +30,16 @@ function ContainerGroup({ setBreadcrumb }) {
isLoading,
error: contentError,
request: fetchInstanceGroups,
- result: { instanceGroup, defaultExecution },
+ result: { instanceGroup, defaultControlPlane, defaultExecution },
} = useRequest(
useCallback(async () => {
const [
{ data },
{
- data: { DEFAULT_EXECUTION_QUEUE_NAME },
+ data: {
+ DEFAULT_EXECUTION_QUEUE_NAME,
+ DEFAULT_CONTROL_PLANE_QUEUE_NAME,
+ },
},
] = await Promise.all([
InstanceGroupsAPI.readDetail(id),
@@ -44,6 +47,7 @@ function ContainerGroup({ setBreadcrumb }) {
]);
return {
instanceGroup: data,
+ defaultControlPlane: DEFAULT_CONTROL_PLANE_QUEUE_NAME,
defaultExecution: DEFAULT_EXECUTION_QUEUE_NAME,
};
}, [id]),
@@ -123,6 +127,7 @@ function ContainerGroup({ setBreadcrumb }) {
diff --git a/awx/ui/src/screens/InstanceGroup/ContainerGroupAdd/ContainerGroupAdd.js b/awx/ui/src/screens/InstanceGroup/ContainerGroupAdd/ContainerGroupAdd.js
index 1cb608cfb4..4ddbf76abb 100644
--- a/awx/ui/src/screens/InstanceGroup/ContainerGroupAdd/ContainerGroupAdd.js
+++ b/awx/ui/src/screens/InstanceGroup/ContainerGroupAdd/ContainerGroupAdd.js
@@ -11,7 +11,7 @@ import { jsonToYaml, isJsonString } from 'util/yaml';
import ContainerGroupForm from '../shared/ContainerGroupForm';
-function ContainerGroupAdd() {
+function ContainerGroupAdd({ defaultExecution, defaultControlPlane }) {
const history = useHistory();
const [submitError, setSubmitError] = useState(null);
@@ -93,6 +93,8 @@ function ContainerGroupAdd() {
{
const {
- data: { IS_K8S },
+ data: {
+ IS_K8S,
+ DEFAULT_CONTROL_PLANE_QUEUE_NAME,
+ DEFAULT_EXECUTION_QUEUE_NAME,
+ },
} = await SettingsAPI.readCategory('all');
- return IS_K8S;
+ return {
+ isKubernetes: IS_K8S,
+ defaultControlPlane: DEFAULT_CONTROL_PLANE_QUEUE_NAME,
+ defaultExecution: DEFAULT_EXECUTION_QUEUE_NAME,
+ };
}, []),
{ isLoading: true }
);
@@ -75,16 +83,22 @@ function InstanceGroups() {
/>
-
+
- {!isSettingsRequestLoading && !isKubernetes ? (
+ {!isSettingsRequestLoading && !isKubernetes && (
-
+
- ) : null}
+ )}
diff --git a/awx/ui/src/screens/InstanceGroup/shared/ContainerGroupForm.js b/awx/ui/src/screens/InstanceGroup/shared/ContainerGroupForm.js
index 7a5e75d591..41d7d60ac5 100644
--- a/awx/ui/src/screens/InstanceGroup/shared/ContainerGroupForm.js
+++ b/awx/ui/src/screens/InstanceGroup/shared/ContainerGroupForm.js
@@ -11,7 +11,7 @@ import FormField, {
CheckboxField,
} from 'components/FormField';
import FormActionGroup from 'components/FormActionGroup';
-import { required } from 'util/validators';
+import { combine, required, protectedResourceName } from 'util/validators';
import {
FormColumnLayout,
FormFullWidthLayout,
@@ -21,12 +21,20 @@ import {
import CredentialLookup from 'components/Lookup/CredentialLookup';
import { VariablesField } from 'components/CodeEditor';
-function ContainerGroupFormFields({ instanceGroup }) {
+function ContainerGroupFormFields({
+ instanceGroup,
+ defaultControlPlane,
+ defaultExecution,
+}) {
const { setFieldValue, setFieldTouched } = useFormikContext();
const [credentialField, credentialMeta, credentialHelpers] =
useField('credential');
- const [nameField] = useField('name');
+ const [, { initialValue }] = useField('name');
+
+ const isProtected =
+ initialValue === `${defaultControlPlane}` ||
+ initialValue === `${defaultExecution}`;
const [overrideField] = useField('override');
@@ -42,11 +50,21 @@ function ContainerGroupFormFields({ instanceGroup }) {
<>
- {isDisabled ? (
-
-
-
- ) : (
-
- )}
+
', () => {
afterEach(() => {
jest.clearAllMocks();
+ wrapper.unmount();
});
test('Initially renders successfully', () => {
diff --git a/awx/ui/src/util/validators.js b/awx/ui/src/util/validators.js
index 51a68126ac..c8ef9d7563 100644
--- a/awx/ui/src/util/validators.js
+++ b/awx/ui/src/util/validators.js
@@ -186,3 +186,8 @@ export function regExp() {
return undefined;
};
}
+
+export function protectedResourceName(message, names = []) {
+ return (value) =>
+ names.some((name) => value.trim() === `${name}`) ? message : undefined;
+}
diff --git a/awx/ui/src/util/validators.test.js b/awx/ui/src/util/validators.test.js
index 0bbd4d1f19..a8631893c6 100644
--- a/awx/ui/src/util/validators.test.js
+++ b/awx/ui/src/util/validators.test.js
@@ -12,6 +12,7 @@ import {
regExp,
requiredEmail,
validateTime,
+ protectedResourceName,
} from './validators';
describe('validators', () => {
@@ -187,4 +188,21 @@ describe('validators', () => {
expect(validateTime()('12.15 PM')).toEqual('Invalid time format');
expect(validateTime()('12;15 PM')).toEqual('Invalid time format');
});
+ test('protectedResourceName should validate properly', () => {
+ expect(
+ protectedResourceName('failed validation', ['Alex'])('Apollo')
+ ).toBeUndefined();
+ expect(
+ protectedResourceName('failed validation', ['Alex', 'Athena'])('alex')
+ ).toBeUndefined();
+ expect(
+ protectedResourceName('failed validation', ['Alex', 'Athena'])('Alex')
+ ).toEqual('failed validation');
+ expect(
+ protectedResourceName('failed validation', ['Alex'])('Alex')
+ ).toEqual('failed validation');
+ expect(
+ protectedResourceName('failed validation', ['Alex'])('Alex ')
+ ).toEqual('failed validation');
+ });
});