Updated code and docs to reflect correct terminology

- Updated instances of fsid with clusterid
- Updated instances of credentials/subject with user/key

Signed-off-by: ShyamsundarR <srangana@redhat.com>
This commit is contained in:
ShyamsundarR 2019-03-12 11:57:36 -04:00 committed by mergify[bot]
parent e1c685ef39
commit fc0cf957be
13 changed files with 151 additions and 122 deletions

View File

@ -53,7 +53,7 @@ Parameter | Required | Description
--------- | -------- | -----------
`monitors` | one of `monitors`, `clusterID` or `monValueFromSecret` must be set | Comma separated list of Ceph monitors (e.g. `192.168.100.1:6789,192.168.100.2:6789,192.168.100.3:6789`)
`monValueFromSecret` | one of `monitors`, `clusterID` or and `monValueFromSecret` must be set | a string pointing the key in the credential secret, whose value is the mon. This is used for the case when the monitors' IP or hostnames are changed, the secret can be updated to pick up the new monitors.
`clusterID` | one of `monitors`, `clusterID` or `monValueFromSecret` must be set | Value of `ceph fsid`, into which RBD images shall be created (e.g. `4ae5ae3d-ebfb-4150-bfc8-798970f4e3d9`)
`clusterID` | one of `monitors`, `clusterID` or `monValueFromSecret` must be set | String representing a Ceph cluster, must be unique across all Ceph clusters in use for provisioning, cannot be greater than 36 bytes in length, and should remain immutable for the lifetime of the Ceph cluster in use
`pool` | yes | Ceph pool into which the RBD image shall be created
`imageFormat` | no | RBD image format. Defaults to `2`. See [man pages](http://docs.ceph.com/docs/mimic/man/8/rbd/#cmdoption-rbd-image-format)
`imageFeatures` | no | RBD image features. Available for `imageFormat=2`. CSI RBD currently supports only `layering` feature. See [man pages](http://docs.ceph.com/docs/mimic/man/8/rbd/#cmdoption-rbd-image-feature)
@ -64,7 +64,8 @@ Parameter | Required | Description
NOTE: If `clusterID` parameter is used, then an accompanying Ceph cluster
configuration secret or config files needs to be provided to the running pods.
Refer to `examples/README.md` section titled "Cluster ID based configuration"
for more information.
for more information. A suggested way to populate the clusterID is to use the
output of `ceph fsid` of the Ceph cluster to be used for provisioning.
**Required secrets:**
@ -72,10 +73,10 @@ Admin credentials are required for provisioning new RBD images `ADMIN_NAME`:
`ADMIN_PASSWORD` - note that the key of the key-value pair is the name of the
client with admin privileges, and the value is its password
If clusterID is specified, then a pair of secrets are required, with keys named
`subjectid` and `credentials`. Where, `subjectid` is the name of the client
with admin privileges and `credentials` contain its password. The pair required
are provisioner and publish secrets, and should contain the same value.
If clusterID is specified, then a secret with various keys and values as
specified in `examples/rbd/template-ceph-cluster-ID-secret.yaml` needs to be
created, with the secret name matching the string value provided as the
`clusterID`.
## Deployment with Kubernetes

View File

@ -226,9 +226,6 @@ Ceph cluster, the following actions need to be completed.
Get the following information from the Ceph cluster,
* Ceph Cluster fsid
* Output of `ceph fsid`
* Used to substitute `<cluster-fsid>` references in the files below
* Admin ID and key, that has privileges to perform CRUD operations on the Ceph
cluster and pools of choice
* Key is typically the output of, `ceph auth get-key client.admin` where
@ -237,13 +234,18 @@ Get the following information from the Ceph cluster,
* Ceph monitor list
* Typically in the output of `ceph mon dump`
* Used to prepare comma separated MON list where required in the files below
* Ceph Cluster fsid
* If choosing to use the Ceph cluster fsid as the unique value of clusterID,
* Output of `ceph fsid`
* Used to substitute `<cluster-id>` references in the files below
Update the template `rbd/template-ceph-cluster-ID-secret.yaml` with values from
a Ceph cluster and create the following secret,
a Ceph cluster and replace `<cluster-id>` with the chosen clusterID to create
the following secret,
* `kubectl create -f rbd/template-ceph-cluster-ID-secret.yaml`
Storage class and snapshot class, using `<cluster-fsid>` as the value for the
Storage class and snapshot class, using `<cluster-id>` as the value for the
option `clusterID`, can now be created on the cluster.
Remaining steps to test functionality remains the same as mentioned in the

View File

@ -10,8 +10,14 @@ parameters:
# if using FQDN, make sure csi plugin's dns policy is appropriate.
monitors: mon1:port,mon2:port,...
# OR,
# Ceph cluster fsid, of the cluster to provision storage from
# clusterID: <ceph-fsid>
# String representing a Ceph cluster to provision storage from.
# Should be unique unique across all Ceph clusters in use for provisioning,
# cannot be greater than 36 bytes in length, and should remain immutable for
# the lifetime of the StorageClass in use.
# If using clusterID, ensure to create a secret, as in
# template-ceph-cluster-ID-secret.yaml, to accompany the string chosen to
# represent the Ceph cluster in clusterID
# clusterID: <cluster-id>
csi.storage.k8s.io/snapshotter-secret-name: csi-rbd-secret
csi.storage.k8s.io/snapshotter-secret-namespace: default

View File

@ -9,11 +9,14 @@ parameters:
# if using FQDN, make sure csi plugin's dns policy is appropriate.
monitors: mon1:port,mon2:port,...
# OR,
# Ceph cluster fsid, of the cluster to provision storage from
# clusterID: <ceph-fsid>
# If using clusterID based configuration, CSI pods need to be passed in a
# secret named ceph-cluster-<cluster-fsid> that contains the cluster
# information. (as in the provided template-ceph-cluster-ID-secret.yaml)
# String representing a Ceph cluster to provision storage from.
# Should be unique unique across all Ceph clusters in use for provisioning,
# cannot be greater than 36 bytes in length, and should remain immutable for
# the lifetime of the StorageClass in use.
# If using clusterID, ensure to create a secret, as in
# template-ceph-cluster-ID-secret.yaml, to accompany the string chosen to
# represent the Ceph cluster in clusterID
# clusterID: <cluster-id>
# OR,
# if "monitors" parameter is not set, driver to get monitors from same
# secret as admin/user credentials. "monValueFromSecret" provides the
@ -32,7 +35,7 @@ parameters:
# The secrets have to contain Ceph admin credentials.
# NOTE: If using "clusterID" instead of "monitors" above, the following
# secrets MAY be added to the ceph-cluster-<cluster-fsid> secret and skipped
# secrets MAY be added to the ceph-cluster-<cluster-id> secret and skipped
# here
csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
csi.storage.k8s.io/provisioner-secret-namespace: default
@ -41,7 +44,7 @@ parameters:
# Ceph users for operating RBD
# NOTE: If using "clusterID" instead of "monitors" above, the following
# IDs MAY be added to the ceph-cluster-<cluster-fsid> secret and skipped
# IDs MAY be added to the ceph-cluster-<cluster-id> secret and skipped
# here
adminid: admin
userid: kubernetes

View File

@ -6,11 +6,10 @@
apiVersion: v1
kind: Secret
metadata:
# The <cluster-fsid> is used by the CSI plugin to uniquely identify and use a
# Ceph cluster, hence the value MUST match the output of the following
# command.
# - Output of: `ceph fsid`
name: ceph-cluster-<cluster-fsid>
# The <cluster-id> is used by the CSI plugin to uniquely identify and use a
# Ceph cluster, the value MUST match the value provided as `clusterID` in the
# StorageClass
name: ceph-cluster-<cluster-id>
namespace: default
data:
# Base64 encoded and comma separated Ceph cluster monitor list
@ -24,7 +23,7 @@ data:
# Substitute the entire string including angle braces, with the base64 value
adminid: <BASE64-ENCODED-ID>
# Base64 encoded key of the provisioner admin ID
# - Output of: `ceph auth get-key client.admin | base64`
# - Output of: `ceph auth get-key client.<admin-id> | base64`
# Substitute the entire string including angle braces, with the base64 value
adminkey: <BASE64-ENCODED-PASSWORD>
# Base64 encoded user ID to use for publishing
@ -32,6 +31,6 @@ data:
# Substitute the entire string including angle braces, with the base64 value
userid: <BASE64-ENCODED-ID>
# Base64 encoded key of the publisher user ID
# - Output of: `ceph auth get-key client.admin | base64`
# - Output of: `ceph auth get-key client.<admin-id> | base64`
# Substitute the entire string including angle braces, with the base64 value
userkey: <BASE64-ENCODED-PASSWORD>

View File

@ -1,8 +1,17 @@
---
# This is a patch to the existing daemonset deployment of CSI rbdplugin.
# This is to be used when adding a new Ceph cluster to the CSI plugin.
#
# This is to be used when using `clusterID` instead of monitors or
# monValueFromSecret in the StorageClass to specify the Ceph cluster to
# provision storage from, AND when the value of `--configroot` option to the
# CSI pods is NOT "k8s_objects".
#
# This patch file, patches in the specified secret for the 'clusterID' as a
# volume, instead of the Ceph CSI plugin actively fetching and using kubernetes
# secrets.
#
# NOTE: Update csi-rbdplugin-provisioner StatefulSet as well with similar patch
# Post substituting the <cluster-fsid> in all places execute,
# Post substituting the <cluster-id> in all places execute,
# `kubectl patch daemonset csi-rbdplugin --patch\
# "$(cat template-csi-rbdplugin-patch.yaml)"`
# to patch the statefulset deployment.
@ -12,10 +21,10 @@ spec:
containers:
- name: csi-rbdplugin
volumeMounts:
- name: ceph-cluster-<cluster-fsid>
mountPath: "/etc/csi-config/ceph-cluster-<cluster-fsid>"
- name: ceph-cluster-<cluster-id>
mountPath: "/etc/csi-config/ceph-cluster-<cluster-id>"
readOnly: true
volumes:
- name: ceph-cluster-<cluster-fsid>
- name: ceph-cluster-<cluster-id>
secret:
secretName: ceph-cluster-<cluster-fsid>
secretName: ceph-cluster-<cluster-id>

View File

@ -1,8 +1,17 @@
---
# This is a patch to the existing statefulset deployment of CSI rbdplugin.
# This is to be used when adding a new Ceph cluster to the CSI plugin.
#
# This is to be used when using `clusterID` instead of monitors or
# monValueFromSecret in the StorageClass to specify the Ceph cluster to
# provision storage from, AND when the value of `--configroot` option to the
# CSI pods is NOT "k8s_objects".
#
# This patch file, patches in the specified secret for the 'clusterID' as a
# volume, instead of the Ceph CSI plugin actively fetching and using kubernetes
# secrets.
#
# NOTE: Update csi-rbdplugin DaemonSet as well with similar patch
# Post substituting the <cluster-fsid> in all places execute,
# Post substituting the <cluster-id> in all places execute,
# `kubectl patch statefulset csi-rbdplugin-provisioner --patch\
# "$(cat template-csi-rbdplugin-provisioner-patch.yaml)"`
# to patch the statefulset deployment.
@ -12,10 +21,10 @@ spec:
containers:
- name: csi-rbdplugin
volumeMounts:
- name: ceph-cluster-<cluster-fsid>
mountPath: "/etc/csi-config/ceph-cluster-<cluster-fsid>"
- name: ceph-cluster-<cluster-id>
mountPath: "/etc/csi-config/ceph-cluster-<cluster-id>"
readOnly: true
volumes:
- name: ceph-cluster-<cluster-fsid>
- name: ceph-cluster-<cluster-id>
secret:
secretName: ceph-cluster-<cluster-fsid>
secretName: ceph-cluster-<cluster-id>

View File

@ -280,7 +280,7 @@ func createPath(volOpt *rbdVolume, userID string, creds map[string]string) (stri
}
klog.V(5).Infof("rbd: map mon %s", mon)
key, err := getRBDKey(volOpt.FsID, userID, creds)
key, err := getRBDKey(volOpt.ClusterID, userID, creds)
if err != nil {
return "", err
}

View File

@ -52,7 +52,7 @@ type rbdVolume struct {
UserID string `json:"userId"`
Mounter string `json:"mounter"`
DisableInUseChecks bool `json:"disableInUseChecks"`
FsID string `json:"fsid"`
ClusterID string `json:"clusterId"`
}
type rbdSnapshot struct {
@ -67,7 +67,7 @@ type rbdSnapshot struct {
SizeBytes int64 `json:"sizeBytes"`
AdminID string `json:"adminId"`
UserID string `json:"userId"`
FsID string `json:"fsid"`
ClusterID string `json:"clusterId"`
}
var (
@ -87,17 +87,16 @@ var (
supportedFeatures = sets.NewString("layering")
)
func getRBDKey(fsid string, id string, credentials map[string]string) (string, error) {
func getRBDKey(clusterid string, id string, credentials map[string]string) (string, error) {
var ok bool
var err error
var key string
if key, ok = credentials[id]; !ok {
if fsid != "" {
key, err = confStore.CredentialForUser(fsid, id)
if clusterid != "" {
key, err = confStore.KeyForUser(clusterid, id)
if err != nil {
klog.Errorf("failed getting credentials (%s)", err)
return "", fmt.Errorf("RBD key for ID: %s not found in config store", id)
return "", fmt.Errorf("RBD key for ID: %s not found in config store of clusterID (%s)", id, clusterid)
}
} else {
return "", fmt.Errorf("RBD key for ID: %s not found", id)
@ -137,7 +136,7 @@ func createRBDImage(pOpts *rbdVolume, volSz int, adminID string, credentials map
image := pOpts.VolName
volSzMiB := fmt.Sprintf("%dM", volSz)
key, err := getRBDKey(pOpts.FsID, adminID, credentials)
key, err := getRBDKey(pOpts.ClusterID, adminID, credentials)
if err != nil {
return err
}
@ -168,7 +167,7 @@ func rbdStatus(pOpts *rbdVolume, userID string, credentials map[string]string) (
image := pOpts.VolName
// If we don't have admin id/secret (e.g. attaching), fallback to user id/secret.
key, err := getRBDKey(pOpts.FsID, userID, credentials)
key, err := getRBDKey(pOpts.ClusterID, userID, credentials)
if err != nil {
return false, "", err
}
@ -216,7 +215,7 @@ func deleteRBDImage(pOpts *rbdVolume, adminID string, credentials map[string]str
klog.Info("rbd is still being used ", image)
return fmt.Errorf("rbd %s is still being used", image)
}
key, err := getRBDKey(pOpts.FsID, adminID, credentials)
key, err := getRBDKey(pOpts.ClusterID, adminID, credentials)
if err != nil {
return err
}
@ -241,22 +240,22 @@ func execCommand(command string, args []string) ([]byte, error) {
return cmd.CombinedOutput()
}
func getMonsAndFsID(options map[string]string) (monitors, fsID, monInSecret string, err error) {
func getMonsAndClusterID(options map[string]string) (monitors, clusterID, monInSecret string, err error) {
var ok bool
monitors, ok = options["monitors"]
if !ok {
// if mons are not set in options, check if they are set in secret
if monInSecret, ok = options["monValueFromSecret"]; !ok {
// if mons are not in secret, check if we have a cluster-fsid
if fsID, ok = options["clusterID"]; !ok {
// if mons are not in secret, check if we have a cluster-id
if clusterID, ok = options["clusterID"]; !ok {
err = errors.New("either monitors or monValueFromSecret or clusterID must be set")
return
}
if monitors, err = confStore.Mons(fsID); err != nil {
if monitors, err = confStore.Mons(clusterID); err != nil {
klog.Errorf("failed getting mons (%s)", err)
err = fmt.Errorf("failed to fetch monitor list using clusterID (%s)", fsID)
err = fmt.Errorf("failed to fetch monitor list using clusterID (%s)", clusterID)
return
}
}
@ -265,16 +264,16 @@ func getMonsAndFsID(options map[string]string) (monitors, fsID, monInSecret stri
return
}
func getIDs(options map[string]string, fsID string) (adminID, userID string, err error) {
func getIDs(options map[string]string, clusterID string) (adminID, userID string, err error) {
var ok bool
adminID, ok = options["adminid"]
switch {
case ok:
case fsID != "":
if adminID, err = confStore.AdminID(fsID); err != nil {
case clusterID != "":
if adminID, err = confStore.AdminID(clusterID); err != nil {
klog.Errorf("failed getting subject (%s)", err)
return "", "", fmt.Errorf("failed to fetch provisioner ID using clusterID (%s)", fsID)
return "", "", fmt.Errorf("failed to fetch admin ID for clusterID (%s)", clusterID)
}
default:
adminID = rbdDefaultAdminID
@ -283,10 +282,10 @@ func getIDs(options map[string]string, fsID string) (adminID, userID string, err
userID, ok = options["userid"]
switch {
case ok:
case fsID != "":
if userID, err = confStore.UserID(fsID); err != nil {
case clusterID != "":
if userID, err = confStore.UserID(clusterID); err != nil {
klog.Errorf("failed getting subject (%s)", err)
return "", "", fmt.Errorf("failed to fetch publisher ID using clusterID (%s)", fsID)
return "", "", fmt.Errorf("failed to fetch user ID using clusterID (%s)", clusterID)
}
default:
userID = rbdDefaultUserID
@ -305,7 +304,7 @@ func getRBDVolumeOptions(volOptions map[string]string, disableInUseChecks bool)
return nil, errors.New("missing required parameter pool")
}
rbdVol.Monitors, rbdVol.FsID, rbdVol.MonValueFromSecret, err = getMonsAndFsID(volOptions)
rbdVol.Monitors, rbdVol.ClusterID, rbdVol.MonValueFromSecret, err = getMonsAndClusterID(volOptions)
if err != nil {
return nil, err
}
@ -346,7 +345,7 @@ func getCredsFromVol(rbdVol *rbdVolume, volOptions map[string]string) error {
var ok bool
var err error
rbdVol.AdminID, rbdVol.UserID, err = getIDs(volOptions, rbdVol.FsID)
rbdVol.AdminID, rbdVol.UserID, err = getIDs(volOptions, rbdVol.ClusterID)
if err != nil {
return err
}
@ -369,12 +368,12 @@ func getRBDSnapshotOptions(snapOptions map[string]string) (*rbdSnapshot, error)
return nil, errors.New("missing required parameter pool")
}
rbdSnap.Monitors, rbdSnap.FsID, rbdSnap.MonValueFromSecret, err = getMonsAndFsID(snapOptions)
rbdSnap.Monitors, rbdSnap.ClusterID, rbdSnap.MonValueFromSecret, err = getMonsAndClusterID(snapOptions)
if err != nil {
return nil, err
}
rbdSnap.AdminID, rbdSnap.UserID, err = getIDs(snapOptions, rbdSnap.FsID)
rbdSnap.AdminID, rbdSnap.UserID, err = getIDs(snapOptions, rbdSnap.ClusterID)
if err != nil {
return nil, err
}
@ -439,7 +438,7 @@ func protectSnapshot(pOpts *rbdSnapshot, adminID string, credentials map[string]
image := pOpts.VolName
snapID := pOpts.SnapID
key, err := getRBDKey(pOpts.FsID, adminID, credentials)
key, err := getRBDKey(pOpts.ClusterID, adminID, credentials)
if err != nil {
return err
}
@ -502,7 +501,7 @@ func createSnapshot(pOpts *rbdSnapshot, adminID string, credentials map[string]s
image := pOpts.VolName
snapID := pOpts.SnapID
key, err := getRBDKey(pOpts.FsID, adminID, credentials)
key, err := getRBDKey(pOpts.ClusterID, adminID, credentials)
if err != nil {
return err
}
@ -529,7 +528,7 @@ func unprotectSnapshot(pOpts *rbdSnapshot, adminID string, credentials map[strin
image := pOpts.VolName
snapID := pOpts.SnapID
key, err := getRBDKey(pOpts.FsID, adminID, credentials)
key, err := getRBDKey(pOpts.ClusterID, adminID, credentials)
if err != nil {
return err
}
@ -556,7 +555,7 @@ func deleteSnapshot(pOpts *rbdSnapshot, adminID string, credentials map[string]s
image := pOpts.VolName
snapID := pOpts.SnapID
key, err := getRBDKey(pOpts.FsID, adminID, credentials)
key, err := getRBDKey(pOpts.ClusterID, adminID, credentials)
if err != nil {
return err
}
@ -583,7 +582,7 @@ func restoreSnapshot(pVolOpts *rbdVolume, pSnapOpts *rbdSnapshot, adminID string
image := pVolOpts.VolName
snapID := pSnapOpts.SnapID
key, err := getRBDKey(pVolOpts.FsID, adminID, credentials)
key, err := getRBDKey(pVolOpts.ClusterID, adminID, credentials)
if err != nil {
return err
}

View File

@ -27,7 +27,7 @@ import (
// StoreReader interface enables plugging different stores, that contain the
// keys and data. (e.g k8s secrets or local files)
type StoreReader interface {
DataForKey(fsid string, key string) (string, error)
DataForKey(clusterID string, key string) (string, error)
}
/* ConfigKeys contents and format,
@ -55,23 +55,23 @@ type ConfigStore struct {
}
// dataForKey returns data from the config store for the provided key
func (dc *ConfigStore) dataForKey(fsid string, key string) (string, error) {
func (dc *ConfigStore) dataForKey(clusterID string, key string) (string, error) {
if dc.StoreReader != nil {
return dc.StoreReader.DataForKey(fsid, key)
return dc.StoreReader.DataForKey(clusterID, key)
}
err := errors.New("config store location uninitialized")
return "", err
}
// Mons returns a comma separated MON list from the cluster config represented by fsid
func (dc *ConfigStore) Mons(fsid string) (string, error) {
return dc.dataForKey(fsid, csMonitors)
// Mons returns a comma separated MON list from the cluster config represented by clusterID
func (dc *ConfigStore) Mons(clusterID string) (string, error) {
return dc.dataForKey(clusterID, csMonitors)
}
// Pools returns a list of pool names from the cluster config represented by fsid
func (dc *ConfigStore) Pools(fsid string) ([]string, error) {
content, err := dc.dataForKey(fsid, csPools)
// Pools returns a list of pool names from the cluster config represented by clusterID
func (dc *ConfigStore) Pools(clusterID string) ([]string, error) {
content, err := dc.dataForKey(clusterID, csPools)
if err != nil {
return nil, err
}
@ -79,42 +79,42 @@ func (dc *ConfigStore) Pools(fsid string) ([]string, error) {
return strings.Split(content, ","), nil
}
// AdminID returns the admin ID from the cluster config represented by fsid
func (dc *ConfigStore) AdminID(fsid string) (string, error) {
return dc.dataForKey(fsid, csAdminID)
// AdminID returns the admin ID from the cluster config represented by clusterID
func (dc *ConfigStore) AdminID(clusterID string) (string, error) {
return dc.dataForKey(clusterID, csAdminID)
}
// UserID returns the user ID from the cluster config represented by fsid
func (dc *ConfigStore) UserID(fsid string) (string, error) {
return dc.dataForKey(fsid, csUserID)
// UserID returns the user ID from the cluster config represented by clusterID
func (dc *ConfigStore) UserID(clusterID string) (string, error) {
return dc.dataForKey(clusterID, csUserID)
}
// CredentialForUser returns the credentials for the requested user ID
// from the cluster config represented by fsid
func (dc *ConfigStore) CredentialForUser(fsid, userID string) (data string, err error) {
var credkey string
user, err := dc.AdminID(fsid)
// KeyForUser returns the key for the requested user ID from the cluster config
// represented by clusterID
func (dc *ConfigStore) KeyForUser(clusterID, userID string) (data string, err error) {
var fetchKey string
user, err := dc.AdminID(clusterID)
if err != nil {
return
}
if user == userID {
credkey = csAdminKey
fetchKey = csAdminKey
} else {
user, err = dc.UserID(fsid)
user, err = dc.UserID(clusterID)
if err != nil {
return
}
if user != userID {
err = fmt.Errorf("requested user (%s) not found in cluster configuration of (%s)", userID, fsid)
err = fmt.Errorf("requested user (%s) not found in cluster configuration of (%s)", userID, clusterID)
return
}
credkey = csUserKey
fetchKey = csUserKey
}
return dc.dataForKey(fsid, credkey)
return dc.dataForKey(clusterID, fetchKey)
}
// NewConfigStore returns a config store based on value of configRoot. If

View File

@ -14,8 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// nolint: gocyclo
package util
import (
@ -26,6 +24,7 @@ import (
)
var basePath = "./test_artifacts"
var clusterID = "testclusterid"
var cs *ConfigStore
func cleanupTestData() {
@ -51,20 +50,20 @@ func TestConfigStore(t *testing.T) {
t.Errorf("Test setup error %s", err)
}
// TEST: Should fail as fsid directory is missing
_, err = cs.Mons("testfsid")
// TEST: Should fail as clusterid directory is missing
_, err = cs.Mons(clusterID)
if err == nil {
t.Errorf("Failed: expected error due to missing parent directory")
}
testDir = basePath + "/" + "ceph-cluster-testfsid"
testDir = basePath + "/" + "ceph-cluster-" + clusterID
err = os.MkdirAll(testDir, 0700)
if err != nil {
t.Errorf("Test setup error %s", err)
}
// TEST: Should fail as mons file is missing
_, err = cs.Mons("testfsid")
_, err = cs.Mons(clusterID)
if err == nil {
t.Errorf("Failed: expected error due to missing mons file")
}
@ -76,7 +75,7 @@ func TestConfigStore(t *testing.T) {
}
// TEST: Should fail as MONs is an empty string
content, err = cs.Mons("testfsid")
content, err = cs.Mons(clusterID)
if err == nil {
t.Errorf("Failed: want (%s), got (%s)", data, content)
}
@ -88,7 +87,7 @@ func TestConfigStore(t *testing.T) {
}
// TEST: Fetching MONs should succeed
content, err = cs.Mons("testfsid")
content, err = cs.Mons(clusterID)
if err != nil || content != data {
t.Errorf("Failed: want (%s), got (%s), err (%s)", data, content, err)
}
@ -100,7 +99,7 @@ func TestConfigStore(t *testing.T) {
}
// TEST: Fetching MONs should succeed
listContent, err := cs.Pools("testfsid")
listContent, err := cs.Pools(clusterID)
if err != nil || strings.Join(listContent, ",") != data {
t.Errorf("Failed: want (%s), got (%s), err (%s)", data, content, err)
}
@ -112,7 +111,7 @@ func TestConfigStore(t *testing.T) {
}
// TEST: Fetching provuser should succeed
content, err = cs.AdminID("testfsid")
content, err = cs.AdminID(clusterID)
if err != nil || content != data {
t.Errorf("Failed: want (%s), got (%s), err (%s)", data, content, err)
}
@ -124,7 +123,7 @@ func TestConfigStore(t *testing.T) {
}
// TEST: Fetching pubuser should succeed
content, err = cs.UserID("testfsid")
content, err = cs.UserID(clusterID)
if err != nil || content != data {
t.Errorf("Failed: want (%s), got (%s), err (%s)", data, content, err)
}
@ -136,7 +135,7 @@ func TestConfigStore(t *testing.T) {
}
// TEST: Fetching provkey should succeed
content, err = cs.CredentialForUser("testfsid", "provuser")
content, err = cs.KeyForUser(clusterID, "provuser")
if err != nil || content != data {
t.Errorf("Failed: want (%s), got (%s), err (%s)", data, content, err)
}
@ -148,13 +147,13 @@ func TestConfigStore(t *testing.T) {
}
// TEST: Fetching pubkey should succeed
content, err = cs.CredentialForUser("testfsid", "pubuser")
content, err = cs.KeyForUser(clusterID, "pubuser")
if err != nil || content != data {
t.Errorf("Failed: want (%s), got (%s), err (%s)", data, content, err)
}
// TEST: Fetching random user key should fail
_, err = cs.CredentialForUser("testfsid", "random")
_, err = cs.KeyForUser(clusterID, "random")
if err == nil {
t.Errorf("Failed: Expected to fail fetching random user key")
}

View File

@ -30,7 +30,8 @@ BasePath defines the directory under which FileConfig will attempt to open and
read contents of various Ceph cluster configurations.
Each Ceph cluster configuration is stored under a directory named,
BasePath/ceph-cluster-<fsid>, where <fsid> is the Ceph cluster fsid.
BasePath/ceph-cluster-<clusterid>, where <clusterid> uniquely identifies and
separates the each Ceph cluster configuration.
Under each Ceph cluster configuration directory, individual files named as per
the ConfigKeys constants in the ConfigStore interface, store the required
@ -42,12 +43,12 @@ type FileConfig struct {
// DataForKey reads the appropriate config file, named using key, and returns
// the contents of the file to the caller
func (fc *FileConfig) DataForKey(fsid string, key string) (data string, err error) {
pathToKey := path.Join(fc.BasePath, "ceph-cluster-"+fsid, key)
func (fc *FileConfig) DataForKey(clusterid string, key string) (data string, err error) {
pathToKey := path.Join(fc.BasePath, "ceph-cluster-"+clusterid, key)
// #nosec
content, err := ioutil.ReadFile(pathToKey)
if err != nil || string(content) == "" {
err = fmt.Errorf("error fetching configuration for cluster ID (%s). (%s)", fsid, err)
err = fmt.Errorf("error fetching configuration for cluster ID (%s). (%s)", clusterid, err)
return
}

View File

@ -27,7 +27,8 @@ K8sConfig is a ConfigStore interface implementation that reads configuration
information from k8s secrets.
Each Ceph cluster configuration secret is expected to be named,
ceph-cluster-<fsid>, where <fsid> is the Ceph cluster fsid.
ceph-cluster-<clusterid>, where <clusterid> uniquely identifies and
separates the each Ceph cluster configuration.
The secret is expected to contain keys, as defined by the ConfigKeys constants
in the ConfigStore interface.
@ -37,18 +38,18 @@ type K8sConfig struct {
Namespace string
}
// DataForKey reads the appropriate k8s secret, named using fsid, and returns
// the contents of key within the secret
func (kc *K8sConfig) DataForKey(fsid string, key string) (data string, err error) {
secret, err := kc.Client.CoreV1().Secrets(kc.Namespace).Get("ceph-cluster-"+fsid, metav1.GetOptions{})
// DataForKey reads the appropriate k8s secret, named using clusterid, and
// returns the contents of key within the secret
func (kc *K8sConfig) DataForKey(clusterid string, key string) (data string, err error) {
secret, err := kc.Client.CoreV1().Secrets(kc.Namespace).Get("ceph-cluster-"+clusterid, metav1.GetOptions{})
if err != nil {
err = fmt.Errorf("error fetching configuration for cluster ID (%s). (%s)", fsid, err)
err = fmt.Errorf("error fetching configuration for cluster ID (%s). (%s)", clusterid, err)
return
}
content, ok := secret.Data[key]
if !ok {
err = fmt.Errorf("missing data for key (%s) in cluster configuration of (%s)", key, fsid)
err = fmt.Errorf("missing data for key (%s) in cluster configuration of (%s)", key, clusterid)
return
}