package configs import ( "fmt" "sync" "github.com/docker/swarmkit/agent/exec" "github.com/docker/swarmkit/api" ) // configs is a map that keeps all the currently available configs to the agent // mapped by config ID. type configs struct { mu sync.RWMutex m map[string]*api.Config } // NewManager returns a place to store configs. func NewManager() exec.ConfigsManager { return &configs{ m: make(map[string]*api.Config), } } // Get returns a config by ID. If the config doesn't exist, returns nil. func (r *configs) Get(configID string) (*api.Config, error) { r.mu.RLock() defer r.mu.RUnlock() if r, ok := r.m[configID]; ok { return r, nil } return nil, fmt.Errorf("config %s not found", configID) } // Add adds one or more configs to the config map. func (r *configs) Add(configs ...api.Config) { r.mu.Lock() defer r.mu.Unlock() for _, config := range configs { r.m[config.ID] = config.Copy() } } // Remove removes one or more configs by ID from the config map. Succeeds // whether or not the given IDs are in the map. func (r *configs) Remove(configs []string) { r.mu.Lock() defer r.mu.Unlock() for _, config := range configs { delete(r.m, config) } } // Reset removes all the configs. func (r *configs) Reset() { r.mu.Lock() defer r.mu.Unlock() r.m = make(map[string]*api.Config) } // taskRestrictedConfigsProvider restricts the ids to the task. type taskRestrictedConfigsProvider struct { configs exec.ConfigGetter configIDs map[string]struct{} // allow list of config ids } func (sp *taskRestrictedConfigsProvider) Get(configID string) (*api.Config, error) { if _, ok := sp.configIDs[configID]; !ok { return nil, fmt.Errorf("task not authorized to access config %s", configID) } return sp.configs.Get(configID) } // Restrict provides a getter that only allows access to the configs // referenced by the task. func Restrict(configs exec.ConfigGetter, t *api.Task) exec.ConfigGetter { cids := map[string]struct{}{} container := t.Spec.GetContainer() if container != nil { for _, configRef := range container.Configs { cids[configRef.ConfigID] = struct{}{} } } return &taskRestrictedConfigsProvider{configs: configs, configIDs: cids} }