github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/creds/conjur/manager.go (about)

     1  package conjur
     2  
     3  import (
     4  	"errors"
     5  
     6  	"code.cloudfoundry.org/lager"
     7  
     8  	"github.com/pf-qiu/concourse/v6/atc/creds"
     9  	"github.com/cyberark/conjur-api-go/conjurapi"
    10  	"github.com/cyberark/conjur-api-go/conjurapi/authn"
    11  )
    12  
    13  // Do not know if these constants are doing anything
    14  // Defaults are grabbed from the 'default:' path in the Manager struct for PipelineSecretTemplate and TeamSecretTemplate
    15  
    16  const DefaultPipelineSecretTemplate = "concourse/{{.Team}}/{{.Pipeline}}/{{.Secret}}"
    17  const DefaultTeamSecretTemplate = "concourse/{{.Team}}/{{.Secret}}"
    18  
    19  type Manager struct {
    20  	ConjurApplianceUrl     string `long:"appliance-url" description:"URL of the conjur instance"`
    21  	ConjurAccount          string `long:"account" description:"Conjur Account"`
    22  	ConjurCertFile         string `long:"cert-file" description:"Cert file used if conjur instance is using a self signed cert. E.g. /path/to/conjur.pem"`
    23  	ConjurAuthnLogin       string `long:"authn-login" description:"Host username. E.g host/concourse"`
    24  	ConjurAuthnApiKey      string `long:"authn-api-key" description:"Api key related to the host"`
    25  	ConjurAuthnTokenFile   string `long:"authn-token-file" description:"Token file used if conjur instance is running in k8s or iam. E.g. /path/to/token_file"`
    26  	PipelineSecretTemplate string `long:"pipeline-secret-template" description:"Conjur secret identifier template used for pipeline specific parameter" default:"concourse/{{.Team}}/{{.Pipeline}}/{{.Secret}}"`
    27  	TeamSecretTemplate     string `long:"team-secret-template" description:"Conjur secret identifier template used for team specific parameter" default:"concourse/{{.Team}}/{{.Secret}}"`
    28  	SecretTemplate         string `long:"secret-template" description:"Conjur secret identifier template used for full path conjur secrets" default:"vaultName/{{.Secret}}"`
    29  	Conjur                 *Conjur
    30  }
    31  
    32  func newConjurClient(manager *Manager) (*conjurapi.Client, error) {
    33  	config := conjurapi.Config{
    34  		Account:      manager.ConjurAccount,
    35  		ApplianceURL: manager.ConjurApplianceUrl,
    36  		SSLCertPath:  manager.ConjurCertFile,
    37  	}
    38  
    39  	if manager.ConjurAuthnTokenFile != "" {
    40  		return conjurapi.NewClientFromTokenFile(
    41  			config,
    42  			manager.ConjurAuthnTokenFile,
    43  		)
    44  	}
    45  
    46  	return conjurapi.NewClientFromKey(config,
    47  		authn.LoginPair{
    48  			Login:  manager.ConjurAuthnLogin,
    49  			APIKey: manager.ConjurAuthnApiKey,
    50  		},
    51  	)
    52  }
    53  
    54  func (manager *Manager) Init(log lager.Logger) error {
    55  	conjur, err := newConjurClient(manager)
    56  	if err != nil {
    57  		log.Error("create-conjur-api-instance", err)
    58  		return err
    59  	}
    60  
    61  	manager.Conjur = &Conjur{
    62  		log:    log,
    63  		client: conjur,
    64  	}
    65  
    66  	return nil
    67  }
    68  
    69  func (manager *Manager) Health() (*creds.HealthResponse, error) {
    70  	health := &creds.HealthResponse{
    71  		Method: "GetSecretValue",
    72  	}
    73  
    74  	health.Response = map[string]string{
    75  		"status": "UP",
    76  	}
    77  
    78  	return health, nil
    79  }
    80  
    81  func (manager *Manager) IsConfigured() bool {
    82  	return manager.ConjurApplianceUrl != ""
    83  }
    84  
    85  func (manager *Manager) Validate() error {
    86  	if _, err := creds.BuildSecretTemplate("pipeline-secret-template", manager.PipelineSecretTemplate); err != nil {
    87  		return err
    88  	}
    89  
    90  	if _, err := creds.BuildSecretTemplate("team-secret-template", manager.TeamSecretTemplate); err != nil {
    91  		return err
    92  	}
    93  
    94  	if _, err := creds.BuildSecretTemplate("secret-template", manager.SecretTemplate); err != nil {
    95  		return err
    96  	}
    97  
    98  	if manager.ConjurApplianceUrl == "" {
    99  		return errors.New("must provide conjur appliance url")
   100  	}
   101  
   102  	if manager.ConjurAccount == "" {
   103  		return errors.New("must provide conjur account")
   104  	}
   105  
   106  	if manager.ConjurAuthnLogin == "" {
   107  		return errors.New("must provide conjur login")
   108  	}
   109  
   110  	if manager.ConjurAuthnApiKey == "" && manager.ConjurAuthnTokenFile == "" {
   111  		return errors.New("must provide conjur authn key or conjur authn token file")
   112  	}
   113  
   114  	if manager.ConjurAuthnApiKey != "" && manager.ConjurAuthnTokenFile != "" {
   115  		return errors.New("must provide conjur authn key or conjur authn token file")
   116  	}
   117  
   118  	return nil
   119  }
   120  
   121  func (manager *Manager) NewSecretsFactory(log lager.Logger) (creds.SecretsFactory, error) {
   122  	client, err := newConjurClient(manager)
   123  
   124  	if err != nil {
   125  		log.Error("create-conjur-api-instance", err)
   126  		return nil, err
   127  	}
   128  
   129  	pipelineSecretTemplate, err := creds.BuildSecretTemplate("pipeline-secret-template", manager.PipelineSecretTemplate)
   130  	if err != nil {
   131  		return nil, err
   132  	}
   133  
   134  	teamSecretTemplate, err := creds.BuildSecretTemplate("team-secret-template", manager.TeamSecretTemplate)
   135  	if err != nil {
   136  		return nil, err
   137  	}
   138  
   139  	secretTemplate, err := creds.BuildSecretTemplate("secret-template", manager.SecretTemplate)
   140  	if err != nil {
   141  		return nil, err
   142  	}
   143  
   144  	return NewConjurFactory(log, client, []*creds.SecretTemplate{pipelineSecretTemplate, teamSecretTemplate, secretTemplate}), nil
   145  }
   146  
   147  func (manager Manager) Close(logger lager.Logger) {
   148  	// TODO - to implement
   149  }