Skip to content

Commit

Permalink
Read params via environment instead of cli flags
Browse files Browse the repository at this point in the history
Instead of reading the parameters to the docker-quobyte-plugin service
via cli flags they are now read directly from the environment. This
prevents credential leakage for the API password.
A tenant_id is now provided via the configuration (not via cli param).
  • Loading branch information
casusbelli committed Dec 15, 2017
1 parent 7a29f50 commit 862ce88
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 61 deletions.
55 changes: 30 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,33 +47,36 @@ $ systemctl enable docker-quobyte-plugin
$ systemctl status docker-quobyte-plugin
```

### Configuration

Configuration is done mainly through the systemd environment file:

```
# Maximum number of filesystem checks when a Volume is created before returning an error
MAX_FS_CHECKS=5
# Maximum wait time for filesystem checks to complete when a Volume is created before returning an error
MAX_WAIT_TIME=30
# Group to create the unix socket
SOCKET_GROUP=root
QUOBYTE_API_URL=http://localhost:7860
QUOBYTE_API_PASSWORD=quobyte
QUOBYTE_API_USER=admin
QUOBYTE_MOUNT_PATH=/run/docker/quobyte/mnt
QUOBYTE_MOUNT_OPTIONS=-o user_xattr
QUOBYTE_REGISTRY=localhost:7861
# ID of the Quobyte tenant in whose domain volumes are managed by this plugin
QUOBYTE_TENANT_ID=replace_me
# Default volume config for new volumes, can be overridden via --opt flag 'configuration_name'
QUOBYTE_VOLUME_CONFIG_NAME=BASE
```

### Usage

The cli is faily simple:

```
$ bin/docker-quobyte-plugin -h
Usage of bin/docker-quobyte-plugin:
-api string
URL to the API server(s) in the form http(s)://host[:port][,host:port] or SRV record name (default "http://localhost:7860")
-configuration_name string
Name of the volume configuration of new volumes (default "BASE")
-group string
Group to create the unix socket (default "root")
-max-fs-checks int
Maximimum number of filesystem checks when a Volume is created before returning an error (default 5)
-max-wait-time float
Maximimum wait time for filesystem checks to complete when a Volume is created before returning an error (default 30)
-options string
Fuse options to be used when Quobyte is mounted (default "-o user_xattr")
-password string
Password for the user to connect to the Quobyte API server (default "quobyte")
-path string
Path where Quobyte is mounted on the host (default "/run/docker/quobyte/mnt")
-registry string
URL to the registry server(s) in the form of host[:port][,host:port] or SRV record name (default "localhost:7861")
-tenant_id string
Id of the Quobyte tenant in whose domain the operation takes place (default "no default")
-user string
User to connect to the Quobyte API server (default "root")
-version
Shows version string
```
Expand All @@ -83,13 +86,15 @@ Usage of bin/docker-quobyte-plugin:
### Create a volume

```
$ docker volume create --driver quobyte --name <volumename> --opt tenant_id=<your Quobyte tenant_id>
# Set user and group of the volume
$ docker volume create --driver quobyte --name <volumename> --opt user=docker --opt group=docker --opt tenant_id=<your Quobyte tenant_id>
$ docker volume create --driver quobyte --name <volumename>
# Set user, group and specific volume configuration for the new volume
$ docker volume create --driver quobyte --name <volumename> --opt user=docker --opt group=docker --opt configuration_name=SSD_ONLY
```

### Delete a volume

__Important__: Be careful when using this. The volume removal allows removing any volume accessible in the configured tenant!

```
$ docker volume rm <volumename>
```
Expand Down
57 changes: 35 additions & 22 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,67 @@ import (
"flag"
"log"
"os"
"strconv"

"github.com/docker/go-plugins-helpers/volume"
)

const quobyteID string = "quobyte"
const (
quobyteID string = "quobyte"
)

var (
version string
revision string
)

func main() {
quobyteMountPath := flag.String("path", "/run/docker/quobyte/mnt", "Path where Quobyte is mounted on the host")
quobyteMountOptions := flag.String("options", "-o user_xattr", "Fuse options to be used when Quobyte is mounted")

quobyteUser := flag.String("user", "root", "User to connect to the Quobyte API server")
quobytePassword := flag.String("password", "quobyte", "Password for the user to connect to the Quobyte API server")
quobyteConfigName := flag.String("configuration_name", "BASE", "Name of the volume configuration of new volumes")
quobyteAPIURL := flag.String("api", "http://localhost:7860", "URL to the API server(s) in the form http(s)://host[:port][,host:port] or SRV record name")
quobyteRegistry := flag.String("registry", "localhost:7861", "URL to the registry server(s) in the form of host[:port][,host:port] or SRV record name")
quobyteTenantId := flag.String("tenant_id", "no default", "Id of the Quobyte tenant in whose domain the operation takes place")

group := flag.String("group", "root", "Group to create the unix socket")
maxWaitTime := flag.Float64("max-wait-time", 30, "Maximimum wait time for filesystem checks to complete when a Volume is created before returning an error")
maxFSChecks := flag.Int("max-fs-checks", 5, "Maximimum number of filesystem checks when a Volume is created before returning an error")
showVersion := flag.Bool("version", false, "Shows version string")

flag.Parse()

maxFSChecks, _ := strconv.Atoi(os.Getenv("MAX_FS_CHECKS"))
maxWaitTime, _ := strconv.ParseFloat(os.Getenv("MAX_WAIT_TIME"), 64)
socketGroup := os.Getenv("SOCKET_GROUP")

quobyteAPIURL := os.Getenv("QUOBYTE_API_URL")
quobyteAPIPassword := os.Getenv("QUOBYTE_API_PASSWORD")
quobyteAPIUser := os.Getenv("QUOBYTE_API_USER")
quobyteMountPath := os.Getenv("QUOBYTE_MOUNT_PATH")
quobyteMountOptions := os.Getenv("QUOBYTE_MOUNT_OPTIONS")
quobyteRegistry := os.Getenv("QUOBYTE_REGISTRY")
quobyteTenantID := os.Getenv("QUOBYTE_TENANT_ID")
quobyteVolConfigName := os.Getenv("QUOBYTE_VOLUME_CONFIG_NAME")
log.Printf("\nVariables read from environment:\n"+
"MAX_FS_CHECKS: %v\nMAX_WAIT_TIME: %v\nSOCKET_GROUP: %s\n"+
"QUOBYTE_API_URL: %s\nQUOBYTE_API_USER: %s\nQUOBYTE_MOUNT_PATH:"+
" %s\nQUOBYTE_MOUNT_OPTIONS: %s\nQUOBYTE_REGISTRY: %s\nQUOBYTE_TENANT_ID: "+
" %s\nQUOBYTE_VOLUME_CONFIG_NAME: %s\n", maxFSChecks, maxWaitTime,
socketGroup, quobyteAPIURL, quobyteAPIUser,
quobyteMountPath, quobyteMountOptions, quobyteRegistry, quobyteTenantID,
quobyteVolConfigName)

if *showVersion {
log.Printf("Version: %s - Revision: %s\n", version, revision)
log.Printf("\nVersion: %s - Revision: %s\n", version, revision)
return
}

if err := validateAPIURL(*quobyteAPIURL); err != nil {
if err := validateAPIURL(quobyteAPIURL); err != nil {
log.Fatalln(err)
}

if err := os.MkdirAll(*quobyteMountPath, 0555); err != nil {
if err := os.MkdirAll(quobyteMountPath, 0555); err != nil {
log.Println(err.Error())
}

if !isMounted(*quobyteMountPath) {
log.Printf("Mounting Quobyte namespace in %s", *quobyteMountPath)
mountAll(*quobyteMountOptions, *quobyteRegistry, *quobyteMountPath)
if !isMounted(quobyteMountPath) {
log.Printf("Mounting Quobyte namespace in %s", quobyteMountPath)
mountAll(quobyteMountOptions, quobyteRegistry, quobyteMountPath)
}

qDriver := newQuobyteDriver(*quobyteAPIURL, *quobyteUser, *quobytePassword, *quobyteMountPath, *maxFSChecks, *maxWaitTime, *quobyteConfigName, *quobyteTenantId)
qDriver := newQuobyteDriver(quobyteAPIURL, quobyteAPIUser, quobyteAPIPassword,
quobyteMountPath, maxFSChecks, maxWaitTime, quobyteVolConfigName, quobyteTenantID)
handler := volume.NewHandler(qDriver)

log.Println(handler.ServeUnix(*group, quobyteID))
log.Println(handler.ServeUnix(socketGroup, quobyteID))
}
14 changes: 3 additions & 11 deletions quobyte_driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,28 +44,20 @@ func (driver quobyteDriver) Create(request volume.Request) volume.Response {
defer driver.m.Unlock()

user, group := "root", "root"
configurationName := "BASE"
configurationName := driver.configName
retryPolicy := "INTERACTIVE"
tenantID := "default"
tenantID := driver.tenantID

if usr, ok := request.Options["user"]; ok {
user = usr
}

if grp, ok := request.Options["group"]; ok {
group = grp
}

if conf, ok := request.Options["configuration_name"]; ok {
configurationName = conf
}

if tenant, ok := request.Options["tenant_id"]; ok {
tenantID = tenant
} else {
return volume.Response{Err: "No tenant_id given, cannot create a new volume."}
}

if _, err := driver.client.CreateVolume(&quobyte_api.CreateVolumeRequest{
Name: request.Name,
RootUserID: user,
Expand Down Expand Up @@ -122,7 +114,7 @@ func (driver quobyteDriver) Remove(request volume.Request) volume.Response {
driver.m.Lock()
defer driver.m.Unlock()

if err := driver.client.DeleteVolumeByName(request.Name, ""); err != nil {
if err := driver.client.DeleteVolumeByName(request.Name, driver.tenantID); err != nil {
log.Println(err)
return volume.Response{Err: err.Error()}
}
Expand Down
2 changes: 1 addition & 1 deletion systemd/docker-quobyte-plugin.service
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Requires=docker.service

[Service]
EnvironmentFile=/etc/quobyte/docker-quobyte.env
ExecStart=/usr/local/bin/docker-quobyte-plugin --user ${QUOBYTE_API_USER} --password ${QUOBYTE_API_PASSWORD} --api ${QUOBYTE_API_URL} --registry ${QUOBYTE_REGISTRY} --configuration_name ${QUOBYTE_CONFIGURATION_NAME}
ExecStart=/usr/local/bin/docker-quobyte-plugin

[Install]
WantedBy=multi-user.target
16 changes: 14 additions & 2 deletions systemd/docker-quobyte.env.sample
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
QUOBYTE_API_USER=admin
QUOBYTE_API_PASSWORD=quobyte
# Maximum number of filesystem checks when a Volume is created before returning an error
MAX_FS_CHECKS=5
# Maximum wait time for filesystem checks to complete when a Volume is created before returning an error
MAX_WAIT_TIME=30
# Group to create the unix socket
SOCKET_GROUP=root
QUOBYTE_API_URL=http://localhost:7860
QUOBYTE_API_PASSWORD=quobyte
QUOBYTE_API_USER=admin
QUOBYTE_MOUNT_PATH=/run/docker/quobyte/mnt
QUOBYTE_MOUNT_OPTIONS=-o user_xattr
QUOBYTE_REGISTRY=localhost:7861
# ID of the Quobyte tenant in whose domain volumes are managed by this plugin
QUOBYTE_TENANT_ID=replace_me
# Default volume config for new volumes, can be overridden via --opt flag 'configuration_name'
QUOBYTE_VOLUME_CONFIG_NAME=BASE

0 comments on commit 862ce88

Please sign in to comment.