github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/manager/drivers/secrets.go (about)

     1  package drivers
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/docker/docker/pkg/plugingetter"
     7  	"github.com/docker/swarmkit/api"
     8  	"github.com/docker/swarmkit/api/naming"
     9  )
    10  
    11  const (
    12  	// SecretsProviderAPI is the endpoint for fetching secrets from plugins
    13  	SecretsProviderAPI = "/SecretProvider.GetSecret"
    14  
    15  	// SecretsProviderCapability is the secrets provider plugin capability identification
    16  	SecretsProviderCapability = "secretprovider"
    17  )
    18  
    19  // SecretDriver provides secrets from different stores
    20  type SecretDriver struct {
    21  	plugin plugingetter.CompatPlugin
    22  }
    23  
    24  // NewSecretDriver creates a new driver that provides third party secrets
    25  func NewSecretDriver(plugin plugingetter.CompatPlugin) *SecretDriver {
    26  	return &SecretDriver{plugin: plugin}
    27  }
    28  
    29  // Get gets a secret from the secret provider. The function returns: the secret value;
    30  // a bool indicating whether the value should be reused across different tasks (defaults to false);
    31  // and an error if either the spec or task are nil, if calling the driver returns an error, or if
    32  // the driver returns an error in the payload.
    33  func (d *SecretDriver) Get(spec *api.SecretSpec, task *api.Task) ([]byte, bool, error) {
    34  	if spec == nil {
    35  		return nil, false, fmt.Errorf("secret spec is nil")
    36  	}
    37  	if task == nil {
    38  		return nil, false, fmt.Errorf("task is nil")
    39  	}
    40  
    41  	var secretResp SecretsProviderResponse
    42  	secretReq := &SecretsProviderRequest{
    43  		SecretName:    spec.Annotations.Name,
    44  		SecretLabels:  spec.Annotations.Labels,
    45  		ServiceID:     task.ServiceID,
    46  		ServiceName:   task.ServiceAnnotations.Name,
    47  		ServiceLabels: task.ServiceAnnotations.Labels,
    48  		TaskID:        task.ID,
    49  		TaskName:      naming.Task(task),
    50  		TaskImage:     task.Spec.GetContainer().Image,
    51  		NodeID:        task.NodeID,
    52  	}
    53  	container := task.Spec.GetContainer()
    54  	if container != nil {
    55  		secretReq.ServiceHostname = container.Hostname
    56  	}
    57  
    58  	if task.Endpoint != nil && task.Endpoint.Spec != nil {
    59  		secretReq.ServiceEndpointSpec = &EndpointSpec{
    60  			Mode: int32(task.Endpoint.Spec.Mode),
    61  		}
    62  		for _, p := range task.Endpoint.Spec.Ports {
    63  			if p == nil {
    64  				continue
    65  			}
    66  			secretReq.ServiceEndpointSpec.Ports =
    67  				append(secretReq.ServiceEndpointSpec.Ports,
    68  					PortConfig{
    69  						Name:          p.Name,
    70  						Protocol:      int32(p.Protocol),
    71  						PublishedPort: p.PublishedPort,
    72  						TargetPort:    p.TargetPort,
    73  						PublishMode:   int32(p.PublishMode),
    74  					})
    75  		}
    76  	}
    77  
    78  	err := d.plugin.Client().Call(SecretsProviderAPI, secretReq, &secretResp)
    79  	if err != nil {
    80  		return nil, false, err
    81  	}
    82  	if secretResp.Err != "" {
    83  		return nil, secretResp.DoNotReuse, fmt.Errorf(secretResp.Err)
    84  	}
    85  	// Assign the secret value
    86  	return secretResp.Value, secretResp.DoNotReuse, nil
    87  }
    88  
    89  // SecretsProviderRequest is the secrets provider request.
    90  type SecretsProviderRequest struct {
    91  	SecretName          string            `json:",omitempty"` // SecretName is the name of the secret to request from the plugin
    92  	SecretLabels        map[string]string `json:",omitempty"` // SecretLabels capture environment names and other metadata pertaining to the secret
    93  	ServiceHostname     string            `json:",omitempty"` // ServiceHostname is the hostname of the service, can be used for x509 certificate
    94  	ServiceID           string            `json:",omitempty"` // ServiceID is the name of the service that requested the secret
    95  	ServiceName         string            `json:",omitempty"` // ServiceName is the name of the service that requested the secret
    96  	ServiceLabels       map[string]string `json:",omitempty"` // ServiceLabels capture environment names and other metadata pertaining to the service
    97  	TaskID              string            `json:",omitempty"` // TaskID is the ID of the task that the secret will be assigned to
    98  	TaskName            string            `json:",omitempty"` // TaskName is the name of the task that the secret will be assigned to
    99  	TaskImage           string            `json:",omitempty"` // TaskName is the image of the task that the secret will be assigned to
   100  	NodeID              string            `json:",omitempty"` // NodeID is the ID of the node that the task will be executed on
   101  	ServiceEndpointSpec *EndpointSpec     `json:",omitempty"` // ServiceEndpointSpec holds the specification for endpoints
   102  }
   103  
   104  // SecretsProviderResponse is the secrets provider response.
   105  type SecretsProviderResponse struct {
   106  	Value []byte `json:",omitempty"` // Value is the value of the secret
   107  	Err   string `json:",omitempty"` // Err is the error response of the plugin
   108  
   109  	// DoNotReuse indicates that the secret returned from this request should
   110  	// only be used for one task, and any further tasks should call the secret
   111  	// driver again.
   112  	DoNotReuse bool `json:",omitempty"`
   113  }
   114  
   115  // EndpointSpec represents the spec of an endpoint.
   116  type EndpointSpec struct {
   117  	Mode  int32        `json:",omitempty"`
   118  	Ports []PortConfig `json:",omitempty"`
   119  }
   120  
   121  // PortConfig represents the config of a port.
   122  type PortConfig struct {
   123  	Name     string `json:",omitempty"`
   124  	Protocol int32  `json:",omitempty"`
   125  	// TargetPort is the port inside the container
   126  	TargetPort uint32 `json:",omitempty"`
   127  	// PublishedPort is the port on the swarm hosts
   128  	PublishedPort uint32 `json:",omitempty"`
   129  	// PublishMode is the mode in which port is published
   130  	PublishMode int32 `json:",omitempty"`
   131  }