Jordan Reimer 44a8e1bb2b
Kubernetes Secrets Engine (#17893)
* Ember Engine for Kubernetes Secrets Engine (#17881)

* adds in-repo ember engine for kubernetes secrets engine

* updates kubernetes engine class name

* Kubernetes route plumbing (#17895)

* kubernetes route plumbing

* adds kubernetes role index route with redirect to details

* adds kubernetes as mountable and supported secrets engine (#17891)

* adds models, adapters and serializers for kubernetes secrets engine (#18010)

* adds mirage factories and handlers for kubernetes (#17943)

* Kubernetes Secrets Engine Configuration (#18093)

* moves RadioCard component to core addon

* adds kubernetes configuration view

* fixes tests using RadioCard after label for and input id changes

* adds confirm modal when editing kubernetes config

* addresses review comments

* Kubernetes Configuration View (#18147)

* removes configuration edit and index routes

* adds kubernetes configuration view

* Kubernetes Roles List (#18211)

* removes configuration edit and index routes

* adds kubernetes configuration view

* adds kubernetes secrets engine roles list view

* updates role details disabled state to explicitly check for false

* VAULT-9863 Kubernetes Overview Page (#18232)

* Add overview page view

* Add overview page tests

* Address feedback to update tests and minor changes

* Use template built in helper for conditionally showing num roles

* Set up roleOptions in constructor

* Set up models in tests and fix minor bug

* Kubernetes Secrets Engine Create/Edit Views (#18271)

* moves kv-object-editor to core addon

* moves json-editor to core addon

* adds kubernetes secrets engine create/edit views

* updates kubernetes/role adapter test

* addresses feedback

* fixes issue with overview route showing 404 page (#18303)

* Kubernetes Role Details View (#18294)

* moves format-duration helper to core addon

* adds kubernetes secrets engine role details view

* adds tests for role details page component

* adds capabilities checks for toolbar actions

* fixes list link for secrets in an ember engine (#18313)

* Manual Testing: Bug Fixes and Improvements (#18333)

* updates overview, configuration and roles components to pass args for individual model properties

* bug fixes and improvements

* adds top level index route to redirect to overview

* VAULT-9877 Kubernetes Credential Generate/View Pages (#18270)

* Add credentials route with create and view components

* Update mirage response for creds and add ajax post call for creds in adapter

* Move credentials create and view into one component

* Add test classes

* Remove files and update backend property name

* Code cleanup and add tests

* Put test helper in helper function

* Add one more test!

* Add code optimizations

* Fix model in route and add form

* Add onSubmit to form and preventDefault

* Fix tests

* Update mock data for test to be strong rather than record

* adds acceptance tests for kubernetes secrets engine roles (#18360)

* VAULT-11862 Kubernetes acceptance tests (#18431)

* VAULT-12185 overview acceptance tests

* VAULT-12298 credentials acceptance tests

* VAULT-12186 configuration acceptance tests

* VAULT-12127 Refactor breadcrumbs to use breadcrumb component (#18489)

* VAULT-12127 Refactor breadcrumbs to use Page::Breadcrumbs component

* Fix failing tests by adding breadcrumbs properties

* VAULT-12166 add jsdocs to kubernetes secrets engine pages (#18509)

* fixes incorrect merge conflict resolution

* updates kubernetes check env vars endpoint (#18588)

* hides kubernetes ca cert field if not defined in configuration view

* fixes loading substate handling issue (#18592)

* adds changelog entry

Co-authored-by: Kianna <30884335+kiannaquach@users.noreply.github.com>
2023-01-18 15:02:41 -06:00

164 lines
5.0 KiB
JavaScript

import Component from '@glimmer/component';
import { inject as service } from '@ember/service';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
import { task } from 'ember-concurrency';
import { waitFor } from '@ember/test-waiters';
import { getRules } from '../../../utils/generated-role-rules';
import { htmlSafe } from '@ember/template';
import errorMessage from 'vault/utils/error-message';
/**
* @module CreateAndEditRolePage
* CreateAndEditRolePage component is a child component for create and edit role pages.
*
* @param {object} model - role model that contains role record and backend
*/
export default class CreateAndEditRolePageComponent extends Component {
@service router;
@service flashMessages;
@tracked roleRulesTemplates;
@tracked selectedTemplateId;
@tracked modelValidations;
constructor() {
super(...arguments);
this.initRoleRules();
// if editing and annotations or labels exist expand the section
const { extraAnnotations, extraLabels } = this.args.model;
if (extraAnnotations || extraLabels) {
this.showAnnotations = true;
}
}
get generationPreferences() {
return [
{
title: 'Generate token only using existing service account',
description:
'Enter a service account that already exists in Kubernetes and Vault will dynamically generate a token.',
value: 'basic',
},
{
title: 'Generate token, service account, and role binding objects',
description:
'Enter a pre-existing role (or ClusterRole) to use. Vault will generate a token, a service account and role binding objects.',
value: 'expanded',
},
{
title: 'Generate entire Kubernetes object chain',
description:
'Vault will generate the entire chain— a role, a token, a service account, and role binding objects— based on rules you supply.',
value: 'full',
},
];
}
get extraFields() {
return [
{
type: 'annotations',
key: 'extraAnnotations',
description: 'Attach arbitrary non-identifying metadata to objects.',
},
{
type: 'labels',
key: 'extraLabels',
description:
'Labels specify identifying attributes of objects that are meaningful and relevant to users.',
},
];
}
get roleRulesHelpText() {
const message =
'This specifies the Role or ClusterRole rules to use when generating a role. Kubernetes documentation is';
const link =
'<a href="https://kubernetes.io/docs/reference/access-authn-authz/rbac/" target="_blank" rel="noopener noreferrer">available here</>';
return htmlSafe(`${message} ${link}.`);
}
@action
initRoleRules() {
// first check if generatedRoleRules matches one of the templates, the user may have chosen a template and not made changes
// in this case we need to select the corresponding template in the dropdown
// if there is no match then replace the example rules with the user defined value for no template option
const { generatedRoleRules } = this.args.model;
const rulesTemplates = getRules();
this.selectedTemplateId = '1';
if (generatedRoleRules) {
const template = rulesTemplates.findBy('rules', generatedRoleRules);
if (template) {
this.selectedTemplateId = template.id;
} else {
rulesTemplates.findBy('id', '1').rules = generatedRoleRules;
}
}
this.roleRulesTemplates = rulesTemplates;
}
@action
resetRoleRules() {
this.roleRulesTemplates = getRules();
}
@action
selectTemplate(event) {
this.selectedTemplateId = event.target.value;
}
@action
changePreference(pref) {
if (pref === 'full') {
this.initRoleRules();
} else {
this.selectedTemplateId = null;
}
this.args.model.generationPreference = pref;
}
@task
@waitFor
*save() {
try {
// set generatedRoleRoles to value of selected template
const selectedTemplate = this.roleRulesTemplates.findBy('id', this.selectedTemplateId);
if (selectedTemplate) {
this.args.model.generatedRoleRules = selectedTemplate.rules;
}
yield this.args.model.save();
this.router.transitionTo(
'vault.cluster.secrets.backend.kubernetes.roles.role.details',
this.args.model.name
);
} catch (error) {
const message = errorMessage(error, 'Error saving role. Please try again or contact support');
this.flashMessages.danger(message);
}
}
@action
async onSave(event) {
event.preventDefault();
const { isValid, state } = await this.args.model.validate();
if (isValid) {
this.modelValidations = null;
this.save.perform();
} else {
this.flashMessages.info('Save not performed. Check form for errors');
this.modelValidations = state;
}
}
@action
cancel() {
const { model } = this.args;
const method = model.isNew ? 'unloadRecord' : 'rollbackAttributes';
model[method]();
this.router.transitionTo('vault.cluster.secrets.backend.kubernetes.roles');
}
}