Skip to content

Commit

Permalink
csi: support Secrets parameter in CSI RPCs
Browse files Browse the repository at this point in the history
CSI plugins can require credentials for some publishing and
unpublishing workflow RPCs. Secrets are configured at the time of
volume registration, stored in the volume struct, and then passed
around as an opaque map by Nomad to the plugins.
  • Loading branch information
tgross committed May 11, 2020
1 parent 3d6c088 commit a0a7ba7
Show file tree
Hide file tree
Showing 26 changed files with 1,659 additions and 1,553 deletions.
3 changes: 3 additions & 0 deletions api/csi.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ type CSIMountOptions struct {
ExtraKeysHCL []string `hcl:",unusedKeys" json:"-"` // report unexpected keys
}

type CSISecrets map[string]string

// CSIVolume is used for serialization, see also nomad/structs/csi.go
type CSIVolume struct {
ID string
Expand All @@ -97,6 +99,7 @@ type CSIVolume struct {
AccessMode CSIVolumeAccessMode `hcl:"access_mode"`
AttachmentMode CSIVolumeAttachmentMode `hcl:"attachment_mode"`
MountOptions *CSIMountOptions `hcl:"mount_options"`
Secrets CSISecrets `hcl:"secrets"`

// Allocations, tracking claim status
ReadAllocs map[string]*Allocation
Expand Down
1 change: 1 addition & 0 deletions client/csi_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ func (c *CSI) ControllerValidateVolume(req *structs.ClientCSIControllerValidateV
// CSI ValidateVolumeCapabilities errors for timeout, codes.Unavailable and
// codes.ResourceExhausted are retried; all other errors are fatal.
return plugin.ControllerValidateCapabilities(ctx, req.VolumeID, caps,
req.Secrets,
grpc_retry.WithPerRetryTimeout(CSIPluginRequestTimeout),
grpc_retry.WithMax(3),
grpc_retry.WithBackoff(grpc_retry.BackoffExponential(100*time.Millisecond)))
Expand Down
116 changes: 50 additions & 66 deletions client/logmon/proto/logmon.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions client/pluginmanager/csimanager/volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ func (v *volumeManager) stageVolume(ctx context.Context, vol *structs.CSIVolume,
publishContext,
pluginStagingPath,
capability,
vol.Secrets,
grpc_retry.WithPerRetryTimeout(DefaultMountActionTimeout),
grpc_retry.WithMax(3),
grpc_retry.WithBackoff(grpc_retry.BackoffExponential(100*time.Millisecond)),
Expand Down Expand Up @@ -208,6 +209,7 @@ func (v *volumeManager) publishVolume(ctx context.Context, vol *structs.CSIVolum
TargetPath: pluginTargetPath,
VolumeCapability: capabilities,
Readonly: usage.ReadOnly,
Secrets: vol.Secrets,
},
grpc_retry.WithPerRetryTimeout(DefaultMountActionTimeout),
grpc_retry.WithMax(3),
Expand Down
19 changes: 18 additions & 1 deletion client/structs/csi.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ type ClientCSIControllerValidateVolumeRequest struct {

AttachmentMode structs.CSIVolumeAttachmentMode
AccessMode structs.CSIVolumeAccessMode
Secrets structs.CSISecrets
// Parameters map[string]string // TODO: https://github.com/hashicorp/nomad/issues/7670

CSIControllerQuery
}
Expand Down Expand Up @@ -66,6 +68,15 @@ type ClientCSIControllerAttachVolumeRequest struct {
// only works when the Controller has the PublishReadonly capability.
ReadOnly bool

// Secrets required by plugin to complete the controller publish
// volume request. This field is OPTIONAL.
Secrets structs.CSISecrets

// TODO https://github.com/hashicorp/nomad/issues/7771
// Volume context as returned by storage provider in CreateVolumeResponse.
// This field is optional.
// VolumeContext map[string]string

CSIControllerQuery
}

Expand All @@ -82,8 +93,10 @@ func (c *ClientCSIControllerAttachVolumeRequest) ToCSIRequest() (*csi.Controller
return &csi.ControllerPublishVolumeRequest{
VolumeID: c.VolumeID,
NodeID: c.ClientCSINodeID,
ReadOnly: c.ReadOnly,
VolumeCapability: caps,
ReadOnly: c.ReadOnly,
Secrets: c.Secrets,
// VolumeContext: c.VolumeContext, TODO: https://github.com/hashicorp/nomad/issues/7771
}, nil
}

Expand Down Expand Up @@ -117,6 +130,10 @@ type ClientCSIControllerDetachVolumeRequest struct {
// by the target node for this plugin name.
ClientCSINodeID string

// Secrets required by plugin to complete the controller unpublish
// volume request. This field is OPTIONAL.
Secrets structs.CSISecrets

CSIControllerQuery
}

Expand Down
4 changes: 4 additions & 0 deletions command/agent/csi_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ func (s *HTTPServer) csiVolumeGet(id string, resp http.ResponseWriter, req *http
return nil, CodedError(404, "volume not found")
}

// remove sensitive fields, as our redaction mechanism doesn't
// help serializing here
out.Volume.Secrets = nil
out.Volume.MountOptions = nil
return out.Volume, nil
}

Expand Down
4 changes: 4 additions & 0 deletions command/volume_register_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,17 @@ namespace = "n"
access_mode = "single-node-writer"
attachment_mode = "file-system"
plugin_id = "p"
secrets {
mysecret = "secretvalue"
}
`,
q: &api.CSIVolume{
ID: "foo",
Namespace: "n",
AccessMode: "single-node-writer",
AttachmentMode: "file-system",
PluginID: "p",
Secrets: api.CSISecrets{"mysecret": "secretvalue"},
},
err: "",
}, {
Expand Down
Loading

0 comments on commit a0a7ba7

Please sign in to comment.