Add CSI Volume Sentinel Policy scaffolding (#26438)

* Add ent policy enforcement stubs to CSI Volume create/register

* Wire policy override/warnings through CSI volume register/create

* Add new scope to sentinel apply

* Sanitize CSISecrets & CSIMountOptions

* Add sentinel policy scope to ui

* Update docs for new sentinel scope/policy

* Create new api funcs for CSI endpoints

* fix sentinel csi ui test

* Update sentinel-policy docs

* Add changelog

* Update docs from feedback
This commit is contained in:
Allison Larson
2025-08-07 12:03:18 -07:00
committed by GitHub
parent 79bf619833
commit e16a3339ad
24 changed files with 396 additions and 48 deletions

View File

@@ -76,13 +76,27 @@ func (v *CSIVolumes) Info(id string, q *QueryOptions) (*CSIVolume, *QueryMeta, e
// Register registers a single CSIVolume with Nomad. The volume must already
// exist in the external storage provider.
func (v *CSIVolumes) Register(vol *CSIVolume, w *WriteOptions) (*WriteMeta, error) {
req := CSIVolumeRegisterRequest{
req := &CSIVolumeRegisterRequest{
Volumes: []*CSIVolume{vol},
}
meta, err := v.client.put("/v1/volume/csi/"+vol.ID, req, nil, w)
_, meta, err := v.RegisterOpts(req, w)
return meta, err
}
// RegisterOpts registers a single CSIVolume with Nomad. The volume must already
// exist in the external storage provider. It expects a single volume in the
// request.
func (v *CSIVolumes) RegisterOpts(req *CSIVolumeRegisterRequest, w *WriteOptions) (*CSIVolumeRegisterResponse, *WriteMeta, error) {
if w == nil {
w = &WriteOptions{}
}
vol := req.Volumes[0]
resp := &CSIVolumeRegisterResponse{}
meta, err := v.client.put("/v1/volume/csi/"+vol.ID, req, resp, w)
return resp, meta, err
}
// Deregister deregisters a single CSIVolume from Nomad. The volume will not be deleted from the external storage provider.
func (v *CSIVolumes) Deregister(id string, force bool, w *WriteOptions) error {
_, err := v.client.delete(fmt.Sprintf("/v1/volume/csi/%v?force=%t", url.PathEscape(id), force), nil, nil, w)
@@ -97,9 +111,21 @@ func (v *CSIVolumes) Create(vol *CSIVolume, w *WriteOptions) ([]*CSIVolume, *Wri
Volumes: []*CSIVolume{vol},
}
resp, meta, err := v.CreateOpts(&req, w)
return resp.Volumes, meta, err
}
// CreateOpts creates a single CSIVolume in an external storage provider and
// registers it with Nomad. You do not need to call Register if this call is
// successful. It expects a single volume in the request.
func (v *CSIVolumes) CreateOpts(req *CSIVolumeCreateRequest, w *WriteOptions) (*CSIVolumeCreateResponse, *WriteMeta, error) {
if w == nil {
w = &WriteOptions{}
}
vol := req.Volumes[0]
resp := &CSIVolumeCreateResponse{}
meta, err := v.client.put(fmt.Sprintf("/v1/volume/csi/%v/create", vol.ID), req, resp, w)
return resp.Volumes, meta, err
return resp, meta, err
}
// Delete deletes a CSI volume from an external storage provider. The ID
@@ -452,19 +478,33 @@ func (v CSIVolumeExternalStubSort) Swap(i, j int) {
type CSIVolumeCreateRequest struct {
Volumes []*CSIVolume
// PolicyOverride overrides Sentinel soft-mandatory policy enforcement
PolicyOverride bool
WriteRequest
}
type CSIVolumeCreateResponse struct {
Volumes []*CSIVolume
Volumes []*CSIVolume
Warnings string
QueryMeta
}
type CSIVolumeRegisterRequest struct {
Volumes []*CSIVolume
// PolicyOverride overrides Sentinel soft-mandatory policy enforcement
PolicyOverride bool
WriteRequest
}
type CSIVolumeRegisterResponse struct {
Volumes []*CSIVolume
Warnings string
}
type CSIVolumeDeregisterRequest struct {
VolumeIDs []string
WriteRequest

View File

@@ -87,4 +87,5 @@ type SentinelPolicyListStub struct {
const (
SentinelScopeSubmitJob = "submit-job"
SentinelScopeSubmitHostVolume = "submit-host-volume"
SentinelScopeSubmitCSIVolume = "submit-csi-volume"
)