Files
nomad/ui/app/components/sentinel-policy-editor.js
Phil Renaud 88ff5a7cae [ui] Scope selection for Sentinel Policies (#25390)
* An option to select, and column etc. to view, sentinel policy scope

* Flake potential: Seed(1) had a couple jobs with the same ModifyIndex

* More de-flaking
2025-03-14 12:37:39 -04:00

97 lines
2.7 KiB
JavaScript

/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
// @ts-check
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { inject as service } from '@ember/service';
import { alias } from '@ember/object/computed';
import messageFromAdapterError from 'nomad-ui/utils/message-from-adapter-error';
export default class SentinelPolicyEditorComponent extends Component {
@service notifications;
@service router;
@service store;
@alias('args.policy') policy;
@action updatePolicy(value) {
this.policy.set('policy', value);
}
@action updatePolicyName({ target: { value } }) {
this.policy.set('name', value);
}
@action updatePolicyEnforcementLevel({ target: { id } }) {
this.policy.set('enforcementLevel', id);
}
@action updatePolicyScope({ target: { id } }) {
this.policy.set('scope', id);
}
@action async save(e) {
if (e instanceof Event) {
e.preventDefault(); // code-mirror "command+enter" submits the form, but doesnt have a preventDefault()
}
try {
const nameRegex = '^[a-zA-Z0-9-]{1,128}$';
if (!this.policy.name?.match(nameRegex)) {
throw new Error(
`Policy name must be 1-128 characters long and can only contain letters, numbers, and dashes.`
);
}
if (this.policy.description?.length > 256) {
throw new Error(
`Policy description must be under 256 characters long.`
);
}
const shouldRedirectAfterSave = this.policy.isNew;
// Because we set the ID for adapter/serialization reasons just before save here,
// that becomes a barrier to our Unique Name validation. So we explicltly exclude
// the current policy when checking for uniqueness.
if (
this.policy.isNew &&
this.store
.peekAll('sentinel-policy')
.filter((policy) => policy !== this.policy)
.findBy('name', this.policy.name)
) {
throw new Error(
`A sentinel policy with name ${this.policy.name} already exists.`
);
}
this.policy.set('id', this.policy.name);
await this.policy.save();
this.notifications.add({
title: 'Sentinel Policy Saved',
color: 'success',
});
if (shouldRedirectAfterSave) {
this.router.transitionTo(
'administration.sentinel-policies.policy',
this.policy.name
);
}
} catch (err) {
let message = err.errors?.length
? messageFromAdapterError(err)
: err.message || 'Unknown Error';
this.notifications.add({
title: `Error creating Sentinel Policy ${this.policy.name}`,
message,
color: 'critical',
sticky: true,
});
}
}
}