mirror of
https://github.com/containers/podman.git
synced 2025-11-14 01:57:58 +08:00
Implement Secrets
Implement podman secret create, inspect, ls, rm Implement podman run/create --secret Secrets are blobs of data that are sensitive. Currently, the only secret driver supported is filedriver, which means creating a secret stores it in base64 unencrypted in a file. After creating a secret, a user can use the --secret flag to expose the secret inside the container at /run/secrets/[secretname] This secret will not be commited to an image on a podman commit Signed-off-by: Ashley Cui <acui@redhat.com>
This commit is contained in:
158
vendor/github.com/containers/common/pkg/secrets/filedriver/filedriver.go
generated
vendored
Normal file
158
vendor/github.com/containers/common/pkg/secrets/filedriver/filedriver.go
generated
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
package filedriver
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
|
||||
"github.com/containers/storage/pkg/lockfile"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// secretsDataFile is the file where secrets data/payload will be stored
|
||||
var secretsDataFile = "secretsdata.json"
|
||||
|
||||
// errNoSecretData indicates that there is not data associated with an id
|
||||
var errNoSecretData = errors.New("no secret data with ID")
|
||||
|
||||
// errNoSecretData indicates that there is secret data already associated with an id
|
||||
var errSecretIDExists = errors.New("secret data with ID already exists")
|
||||
|
||||
// Driver is the filedriver object
|
||||
type Driver struct {
|
||||
// secretsDataFilePath is the path to the secretsfile
|
||||
secretsDataFilePath string
|
||||
// lockfile is the filedriver lockfile
|
||||
lockfile lockfile.Locker
|
||||
}
|
||||
|
||||
// NewDriver creates a new file driver.
|
||||
// rootPath is the directory where the secrets data file resides.
|
||||
func NewDriver(rootPath string) (*Driver, error) {
|
||||
fileDriver := new(Driver)
|
||||
fileDriver.secretsDataFilePath = filepath.Join(rootPath, secretsDataFile)
|
||||
// the lockfile functions requre that the rootPath dir is executable
|
||||
if err := os.MkdirAll(rootPath, 0700); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
lock, err := lockfile.GetLockfile(filepath.Join(rootPath, "secretsdata.lock"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fileDriver.lockfile = lock
|
||||
|
||||
return fileDriver, nil
|
||||
}
|
||||
|
||||
// List returns all secret IDs
|
||||
func (d *Driver) List() ([]string, error) {
|
||||
d.lockfile.Lock()
|
||||
defer d.lockfile.Unlock()
|
||||
secretData, err := d.getAllData()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var allID []string
|
||||
for k := range secretData {
|
||||
allID = append(allID, k)
|
||||
}
|
||||
sort.Strings(allID)
|
||||
return allID, err
|
||||
}
|
||||
|
||||
// Lookup returns the bytes associated with a secret ID
|
||||
func (d *Driver) Lookup(id string) ([]byte, error) {
|
||||
d.lockfile.Lock()
|
||||
defer d.lockfile.Unlock()
|
||||
|
||||
secretData, err := d.getAllData()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if data, ok := secretData[id]; ok {
|
||||
return data, nil
|
||||
}
|
||||
return nil, errors.Wrapf(errNoSecretData, "%s", id)
|
||||
}
|
||||
|
||||
// Store stores the bytes associated with an ID. An error is returned if the ID arleady exists
|
||||
func (d *Driver) Store(id string, data []byte) error {
|
||||
d.lockfile.Lock()
|
||||
defer d.lockfile.Unlock()
|
||||
|
||||
secretData, err := d.getAllData()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, ok := secretData[id]; ok {
|
||||
return errors.Wrapf(errSecretIDExists, "%s", id)
|
||||
}
|
||||
secretData[id] = data
|
||||
marshalled, err := json.MarshalIndent(secretData, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(d.secretsDataFilePath, marshalled, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete deletes the secret associated with the specified ID. An error is returned if no matching secret is found.
|
||||
func (d *Driver) Delete(id string) error {
|
||||
d.lockfile.Lock()
|
||||
defer d.lockfile.Unlock()
|
||||
secretData, err := d.getAllData()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, ok := secretData[id]; ok {
|
||||
delete(secretData, id)
|
||||
} else {
|
||||
return errors.Wrap(errNoSecretData, id)
|
||||
}
|
||||
marshalled, err := json.MarshalIndent(secretData, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(d.secretsDataFilePath, marshalled, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// getAllData reads the data file and returns all data
|
||||
func (d *Driver) getAllData() (map[string][]byte, error) {
|
||||
// check if the db file exists
|
||||
_, err := os.Stat(d.secretsDataFilePath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
// the file will be created later on a store()
|
||||
return make(map[string][]byte), nil
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
file, err := os.Open(d.secretsDataFilePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
byteValue, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
secretData := new(map[string][]byte)
|
||||
err = json.Unmarshal([]byte(byteValue), secretData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return *secretData, nil
|
||||
}
|
||||
Reference in New Issue
Block a user