1package context
2
3import (
4	"io/ioutil"
5
6	"github.com/docker/cli/cli/context/store"
7	"github.com/pkg/errors"
8	"github.com/sirupsen/logrus"
9)
10
11const (
12	caKey   = "ca.pem"
13	certKey = "cert.pem"
14	keyKey  = "key.pem"
15)
16
17// TLSData holds ca/cert/key raw data
18type TLSData struct {
19	CA   []byte
20	Key  []byte
21	Cert []byte
22}
23
24// ToStoreTLSData converts TLSData to the store representation
25func (data *TLSData) ToStoreTLSData() *store.EndpointTLSData {
26	if data == nil {
27		return nil
28	}
29	result := store.EndpointTLSData{
30		Files: make(map[string][]byte),
31	}
32	if data.CA != nil {
33		result.Files[caKey] = data.CA
34	}
35	if data.Cert != nil {
36		result.Files[certKey] = data.Cert
37	}
38	if data.Key != nil {
39		result.Files[keyKey] = data.Key
40	}
41	return &result
42}
43
44// LoadTLSData loads TLS data from the store
45func LoadTLSData(s store.Reader, contextName, endpointName string) (*TLSData, error) {
46	tlsFiles, err := s.ListTLSFiles(contextName)
47	if err != nil {
48		return nil, errors.Wrapf(err, "failed to retrieve context tls files for context %q", contextName)
49	}
50	if epTLSFiles, ok := tlsFiles[endpointName]; ok {
51		var tlsData TLSData
52		for _, f := range epTLSFiles {
53			data, err := s.GetTLSData(contextName, endpointName, f)
54			if err != nil {
55				return nil, errors.Wrapf(err, "failed to retrieve context tls data for file %q of context %q", f, contextName)
56			}
57			switch f {
58			case caKey:
59				tlsData.CA = data
60			case certKey:
61				tlsData.Cert = data
62			case keyKey:
63				tlsData.Key = data
64			default:
65				logrus.Warnf("unknown file %s in context %s tls bundle", f, contextName)
66			}
67		}
68		return &tlsData, nil
69	}
70	return nil, nil
71}
72
73// TLSDataFromFiles reads files into a TLSData struct (or returns nil if all paths are empty)
74func TLSDataFromFiles(caPath, certPath, keyPath string) (*TLSData, error) {
75	var (
76		ca, cert, key []byte
77		err           error
78	)
79	if caPath != "" {
80		if ca, err = ioutil.ReadFile(caPath); err != nil {
81			return nil, err
82		}
83	}
84	if certPath != "" {
85		if cert, err = ioutil.ReadFile(certPath); err != nil {
86			return nil, err
87		}
88	}
89	if keyPath != "" {
90		if key, err = ioutil.ReadFile(keyPath); err != nil {
91			return nil, err
92		}
93	}
94	if ca == nil && cert == nil && key == nil {
95		return nil, nil
96	}
97	return &TLSData{CA: ca, Cert: cert, Key: key}, nil
98}
99