2018-09-25 16:28:26 +00:00
import { assign } from '@ember/polyfills' ;
2018-04-03 14:16:57 +00:00
import ApplicationAdapter from './application' ;
2019-03-01 16:08:30 +00:00
import { encodePath } from 'vault/utils/path-encoding-helpers' ;
2021-08-31 15:41:41 +00:00
import { splitObject } from 'vault/helpers/split-object' ;
2018-04-03 14:16:57 +00:00
export default ApplicationAdapter . extend ( {
url ( path ) {
const url = ` ${ this . buildURL ( ) } /mounts ` ;
2019-03-01 16:08:30 +00:00
return path ? url + '/' + encodePath ( path ) : url ;
2018-04-03 14:16:57 +00:00
} ,
2021-08-31 15:41:41 +00:00
urlForConfig ( path ) {
return ` /v1/ ${ path } /config ` ;
} ,
2019-02-14 18:52:34 +00:00
internalURL ( path ) {
let url = ` / ${ this . urlPrefix ( ) } /internal/ui/mounts ` ;
if ( path ) {
2019-03-01 16:08:30 +00:00
url = ` ${ url } / ${ encodePath ( path ) } ` ;
2019-02-14 18:52:34 +00:00
}
return url ;
} ,
2018-04-24 21:30:44 +00:00
pathForType ( ) {
return 'mounts' ;
2018-04-03 14:16:57 +00:00
} ,
2021-09-15 18:14:18 +00:00
async query ( store , type , query ) {
let mountModel , configModel ;
try {
mountModel = await this . ajax ( this . internalURL ( query . path ) , 'GET' ) ;
// if kv2 then add the config data to the mountModel
// version comes in as a string
2021-11-09 20:42:46 +00:00
if ( mountModel ? . data ? . type === 'kv' && mountModel ? . data ? . options ? . version === '2' ) {
2021-09-15 18:14:18 +00:00
configModel = await this . ajax ( this . urlForConfig ( query . path ) , 'GET' ) ;
mountModel . data = { ... mountModel . data , ... configModel . data } ;
}
} catch ( error ) {
2021-11-09 20:42:46 +00:00
// no path means this was an error on listing
if ( ! query . path ) {
throw error ;
}
2021-09-15 18:14:18 +00:00
// control groups will throw a 403 permission denied error. If this happens return the mountModel
// error is handled on routing
}
return mountModel ;
2018-04-03 14:16:57 +00:00
} ,
2021-09-15 18:14:18 +00:00
async createRecord ( store , type , snapshot ) {
2018-04-03 14:16:57 +00:00
const serializer = store . serializerFor ( type . modelName ) ;
2021-08-31 15:41:41 +00:00
let data = serializer . serialize ( snapshot ) ;
2018-04-03 14:16:57 +00:00
const path = snapshot . attr ( 'path' ) ;
2021-08-31 15:41:41 +00:00
// for kv2 we make two network requests
2021-09-15 18:14:18 +00:00
if ( data . type === 'kv' && data . options . version === 2 ) {
2021-08-31 15:41:41 +00:00
// data has both data for sys mount and the config, we need to separate them
let splitObjects = splitObject ( data , [ 'max_versions' , 'delete_version_after' , 'cas_required' ] ) ;
let configData ;
[ configData , data ] = splitObjects ;
2021-09-15 18:14:18 +00:00
if ( ! data . id ) {
data . id = path ;
}
2021-08-31 15:41:41 +00:00
// first create the engine
2022-03-18 23:47:42 +00:00
await this . ajax ( this . url ( path ) , 'POST' , { data } ) ;
2021-09-15 18:14:18 +00:00
// second post to config
try {
await this . ajax ( this . urlForConfig ( path ) , 'POST' , { data : configData } ) ;
} catch ( e ) {
// error here means you do not have update capabilities to config endpoint. If that's the case we show a flash message in the component and continue with the transition.
// the error is handled by mount-backend-form component which checks capabilities before hitting the save to the adapter.
// we do not handle the error here because we want the secret-engine to mount successfully and to continue the flow.
}
return {
data : assign ( { } , data , { path : path + '/' , id : path } ) ,
} ;
2021-08-31 15:41:41 +00:00
} else {
return this . ajax ( this . url ( path ) , 'POST' , { data } ) . then ( ( ) => {
// ember data doesn't like 204s if it's not a DELETE
return {
data : assign ( { } , data , { path : path + '/' , id : path } ) ,
} ;
} ) ;
}
2018-04-03 14:16:57 +00:00
} ,
findRecord ( store , type , path , snapshot ) {
if ( snapshot . attr ( 'type' ) === 'ssh' ) {
2019-03-01 16:08:30 +00:00
return this . ajax ( ` /v1/ ${ encodePath ( path ) } /config/ca ` , 'GET' ) ;
2018-04-03 14:16:57 +00:00
}
return ;
} ,
queryRecord ( store , type , query ) {
if ( query . type === 'aws' ) {
2021-12-17 03:44:29 +00:00
return this . ajax ( ` /v1/ ${ encodePath ( query . backend ) } /config/lease ` , 'GET' ) . then ( ( resp ) => {
2018-04-03 14:16:57 +00:00
resp . path = query . backend + '/' ;
return resp ;
} ) ;
}
return ;
} ,
updateRecord ( store , type , snapshot ) {
const { apiPath , options , adapterMethod } = snapshot . adapterOptions ;
if ( adapterMethod ) {
return this [ adapterMethod ] ( ... arguments ) ;
}
if ( apiPath ) {
const serializer = store . serializerFor ( type . modelName ) ;
const data = serializer . serialize ( snapshot ) ;
2019-03-01 16:08:30 +00:00
const path = encodePath ( snapshot . id ) ;
2018-04-03 14:16:57 +00:00
return this . ajax ( ` /v1/ ${ path } / ${ apiPath } ` , options . isDelete ? 'DELETE' : 'POST' , { data } ) ;
}
} ,
saveAWSRoot ( store , type , snapshot ) {
let { data } = snapshot . adapterOptions ;
2019-03-01 16:08:30 +00:00
const path = encodePath ( snapshot . id ) ;
2018-04-03 14:16:57 +00:00
return this . ajax ( ` /v1/ ${ path } /config/root ` , 'POST' , { data } ) ;
} ,
saveAWSLease ( store , type , snapshot ) {
let { data } = snapshot . adapterOptions ;
2019-03-01 16:08:30 +00:00
const path = encodePath ( snapshot . id ) ;
2018-04-03 14:16:57 +00:00
return this . ajax ( ` /v1/ ${ path } /config/lease ` , 'POST' , { data } ) ;
} ,
saveZeroAddressConfig ( store , type , snapshot ) {
2019-03-01 16:08:30 +00:00
const path = encodePath ( snapshot . id ) ;
2021-12-17 03:44:29 +00:00
const roles = store . peekAll ( 'role-ssh' ) . filterBy ( 'zeroAddress' ) . mapBy ( 'id' ) . join ( ',' ) ;
2018-04-03 14:16:57 +00:00
const url = ` /v1/ ${ path } /config/zeroaddress ` ;
const data = { roles } ;
if ( roles === '' ) {
return this . ajax ( url , 'DELETE' ) ;
}
return this . ajax ( url , 'POST' , { data } ) ;
} ,
} ) ;