2023-04-10 15:36:59 +00:00
/ * *
* Copyright ( c ) HashiCorp , Inc .
* SPDX - License - Identifier : MPL - 2.0
* /
2020-06-09 21:03:28 +00:00
/* eslint-disable ember/avoid-leaking-state-in-ember-objects */
2020-01-20 20:57:01 +00:00
import { module , test } from 'qunit' ;
import { setupTest } from 'ember-qunit' ;
import Service from '@ember/service' ;
2020-01-28 01:32:29 +00:00
import setupAbility from 'nomad-ui/tests/helpers/setup-ability' ;
2020-01-20 20:57:01 +00:00
2021-12-28 14:45:20 +00:00
module ( 'Unit | Ability | job' , function ( hooks ) {
2020-01-20 20:57:01 +00:00
setupTest ( hooks ) ;
2020-01-28 01:32:29 +00:00
setupAbility ( 'job' ) ( hooks ) ;
2020-01-20 20:57:01 +00:00
2021-12-28 14:45:20 +00:00
test ( 'it permits job run when ACLs are disabled' , function ( assert ) {
2020-01-31 00:34:35 +00:00
const mockToken = Service . extend ( {
aclEnabled : false ,
} ) ;
this . owner . register ( 'service:token' , mockToken ) ;
assert . ok ( this . ability . canRun ) ;
} ) ;
2021-12-28 14:45:20 +00:00
test ( 'it permits job run for management tokens' , function ( assert ) {
2020-01-20 20:57:01 +00:00
const mockToken = Service . extend ( {
2020-01-31 00:34:35 +00:00
aclEnabled : true ,
2020-01-20 20:57:01 +00:00
selfToken : { type : 'management' } ,
} ) ;
this . owner . register ( 'service:token' , mockToken ) ;
2020-01-28 01:32:29 +00:00
assert . ok ( this . ability . canRun ) ;
2020-01-20 20:57:01 +00:00
} ) ;
2021-12-28 14:45:20 +00:00
test ( 'it permits job run for client tokens with a policy that has namespace submit-job' , function ( assert ) {
2020-01-20 20:57:01 +00:00
const mockSystem = Service . extend ( {
2020-01-31 00:34:35 +00:00
aclEnabled : true ,
2020-01-20 20:57:01 +00:00
} ) ;
const mockToken = Service . extend ( {
2020-01-31 00:34:35 +00:00
aclEnabled : true ,
2020-01-20 20:57:01 +00:00
selfToken : { type : 'client' } ,
selfTokenPolicies : [
{
rulesJSON : {
Namespaces : [
{
Name : 'aNamespace' ,
Capabilities : [ 'submit-job' ] ,
} ,
] ,
} ,
} ,
] ,
} ) ;
this . owner . register ( 'service:system' , mockSystem ) ;
this . owner . register ( 'service:token' , mockToken ) ;
2021-04-29 20:00:59 +00:00
assert . ok ( this . can . can ( 'run job' , null , { namespace : 'aNamespace' } ) ) ;
2020-01-20 20:57:01 +00:00
} ) ;
2021-12-28 14:45:20 +00:00
test ( 'it permits job run for client tokens with a policy that has default namespace submit-job and no capabilities for active namespace' , function ( assert ) {
2020-01-20 20:57:01 +00:00
const mockSystem = Service . extend ( {
2020-01-31 00:34:35 +00:00
aclEnabled : true ,
2020-01-20 20:57:01 +00:00
} ) ;
const mockToken = Service . extend ( {
2020-01-31 00:34:35 +00:00
aclEnabled : true ,
2020-01-20 20:57:01 +00:00
selfToken : { type : 'client' } ,
selfTokenPolicies : [
{
rulesJSON : {
Namespaces : [
{
Name : 'aNamespace' ,
Capabilities : [ ] ,
} ,
{
Name : 'default' ,
Capabilities : [ 'submit-job' ] ,
} ,
] ,
} ,
} ,
] ,
} ) ;
this . owner . register ( 'service:system' , mockSystem ) ;
this . owner . register ( 'service:token' , mockToken ) ;
2021-04-29 20:00:59 +00:00
assert . ok ( this . can . can ( 'run job' , null , { namespace : 'anotherNamespace' } ) ) ;
2020-01-20 20:57:01 +00:00
} ) ;
2021-12-28 14:45:20 +00:00
test ( 'it blocks job run for client tokens with a policy that has no submit-job capability' , function ( assert ) {
2020-01-20 20:57:01 +00:00
const mockSystem = Service . extend ( {
2020-01-31 00:34:35 +00:00
aclEnabled : true ,
2020-01-20 20:57:01 +00:00
} ) ;
const mockToken = Service . extend ( {
2020-01-31 00:34:35 +00:00
aclEnabled : true ,
2020-01-20 20:57:01 +00:00
selfToken : { type : 'client' } ,
selfTokenPolicies : [
{
rulesJSON : {
Namespaces : [
{
Name : 'aNamespace' ,
Capabilities : [ 'list-jobs' ] ,
} ,
] ,
} ,
} ,
] ,
} ) ;
this . owner . register ( 'service:system' , mockSystem ) ;
this . owner . register ( 'service:token' , mockToken ) ;
2021-04-29 20:00:59 +00:00
assert . ok ( this . can . cannot ( 'run job' , null , { namespace : 'aNamespace' } ) ) ;
2020-01-20 20:57:01 +00:00
} ) ;
2021-12-28 14:45:20 +00:00
test ( 'job scale requires a client token with the submit-job or scale-job capability' , function ( assert ) {
2020-06-18 05:44:35 +00:00
const makePolicies = ( namespace , ... capabilities ) => [
{
rulesJSON : {
Namespaces : [
{
Name : namespace ,
Capabilities : capabilities ,
} ,
] ,
} ,
} ,
] ;
const mockSystem = Service . extend ( {
aclEnabled : true ,
} ) ;
const mockToken = Service . extend ( {
aclEnabled : true ,
selfToken : { type : 'client' } ,
selfTokenPolicies : makePolicies ( 'aNamespace' ) ,
} ) ;
this . owner . register ( 'service:system' , mockSystem ) ;
this . owner . register ( 'service:token' , mockToken ) ;
const tokenService = this . owner . lookup ( 'service:token' ) ;
2021-04-29 20:00:59 +00:00
assert . ok ( this . can . cannot ( 'scale job' , null , { namespace : 'aNamespace' } ) ) ;
2020-06-18 05:44:35 +00:00
2021-12-28 16:08:12 +00:00
tokenService . set (
'selfTokenPolicies' ,
makePolicies ( 'aNamespace' , 'scale-job' )
) ;
2021-04-29 20:00:59 +00:00
assert . ok ( this . can . can ( 'scale job' , null , { namespace : 'aNamespace' } ) ) ;
2020-06-18 05:44:35 +00:00
2021-12-28 16:08:12 +00:00
tokenService . set (
'selfTokenPolicies' ,
makePolicies ( 'aNamespace' , 'submit-job' )
) ;
2021-04-29 20:00:59 +00:00
assert . ok ( this . can . can ( 'scale job' , null , { namespace : 'aNamespace' } ) ) ;
2020-06-18 05:44:35 +00:00
2021-12-28 16:08:12 +00:00
tokenService . set (
'selfTokenPolicies' ,
makePolicies ( 'bNamespace' , 'scale-job' )
) ;
2021-04-29 20:00:59 +00:00
assert . ok ( this . can . cannot ( 'scale job' , null , { namespace : 'aNamespace' } ) ) ;
2020-06-18 05:44:35 +00:00
} ) ;
2021-12-28 14:45:20 +00:00
test ( 'job dispatch requires a client token with the dispatch-job capability' , function ( assert ) {
2021-07-20 22:27:41 +00:00
const makePolicies = ( namespace , ... capabilities ) => [
{
rulesJSON : {
Namespaces : [
{
Name : namespace ,
Capabilities : capabilities ,
} ,
] ,
} ,
} ,
] ;
const mockSystem = Service . extend ( {
aclEnabled : true ,
} ) ;
const mockToken = Service . extend ( {
aclEnabled : true ,
selfToken : { type : 'client' } ,
selfTokenPolicies : makePolicies ( 'aNamespace' ) ,
} ) ;
this . owner . register ( 'service:system' , mockSystem ) ;
this . owner . register ( 'service:token' , mockToken ) ;
const tokenService = this . owner . lookup ( 'service:token' ) ;
2021-12-28 16:08:12 +00:00
assert . ok (
this . can . cannot ( 'dispatch job' , null , { namespace : 'aNamespace' } )
) ;
2021-07-20 22:27:41 +00:00
2021-12-28 16:08:12 +00:00
tokenService . set (
'selfTokenPolicies' ,
makePolicies ( 'aNamespace' , 'dispatch-job' )
) ;
2021-07-20 22:27:41 +00:00
assert . ok ( this . can . can ( 'dispatch job' , null , { namespace : 'aNamespace' } ) ) ;
} ) ;
2021-12-28 14:45:20 +00:00
test ( 'it handles globs in namespace names' , function ( assert ) {
2020-01-20 20:57:01 +00:00
const mockSystem = Service . extend ( {
2020-01-31 00:34:35 +00:00
aclEnabled : true ,
2020-01-20 20:57:01 +00:00
} ) ;
const mockToken = Service . extend ( {
2020-01-31 00:34:35 +00:00
aclEnabled : true ,
2020-01-20 20:57:01 +00:00
selfToken : { type : 'client' } ,
selfTokenPolicies : [
{
rulesJSON : {
Namespaces : [
{
Name : 'production-*' ,
Capabilities : [ 'submit-job' ] ,
} ,
{
Name : 'production-api' ,
Capabilities : [ 'submit-job' ] ,
} ,
{
Name : 'production-web' ,
Capabilities : [ ] ,
} ,
{
Name : '*-suffixed' ,
Capabilities : [ 'submit-job' ] ,
} ,
{
Name : '*-more-suffixed' ,
Capabilities : [ ] ,
} ,
{
Name : '*-abc-*' ,
Capabilities : [ 'submit-job' ] ,
} ,
] ,
} ,
} ,
] ,
} ) ;
this . owner . register ( 'service:system' , mockSystem ) ;
this . owner . register ( 'service:token' , mockToken ) ;
2021-12-28 16:08:12 +00:00
assert . ok (
2022-07-11 16:33:17 +00:00
this . can . can (
'run job' ,
null ,
{ namespace : 'production-web' } ,
'The existence of a single namespace where a job can be run means that can run is enabled'
)
2021-12-28 16:08:12 +00:00
) ;
2021-04-29 20:00:59 +00:00
assert . ok ( this . can . can ( 'run job' , null , { namespace : 'production-api' } ) ) ;
assert . ok ( this . can . can ( 'run job' , null , { namespace : 'production-other' } ) ) ;
assert . ok (
2021-12-28 16:08:12 +00:00
this . can . can ( 'run job' , null , { namespace : 'something-suffixed' } )
) ;
2021-04-29 20:00:59 +00:00
assert . ok (
this . can . can ( 'run job' , null , { namespace : '000-abc-999' } ) ,
'expected to be able to match against more than one wildcard'
) ;
2020-01-20 20:57:01 +00:00
} ) ;
} ) ;