File: client.go

package info (click to toggle)
gitlab-ci-multi-runner 14.10.1-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 31,248 kB
  • sloc: sh: 1,694; makefile: 384; asm: 79; ruby: 68
file content (126 lines) | stat: -rw-r--r-- 2,642 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package vault

import (
	"errors"
	"fmt"

	"github.com/hashicorp/vault/api"
)

type Client interface {
	Authenticate(auth AuthMethod) error
	Write(path string, data map[string]interface{}) (Result, error)
	Read(path string) (Result, error)
	Delete(path string) error
}

type defaultClient struct {
	internal apiClient
}

type apiClient interface {
	Sys() apiClientSys
	Logical() apiClientLogical
	SetToken(v string)
	SetNamespace(ns string)
}

type apiClientSys interface {
	Health() (*api.HealthResponse, error)
}

type apiClientLogical interface {
	Write(path string, data map[string]interface{}) (*api.Secret, error)
	Read(path string) (*api.Secret, error)
	Delete(path string) (*api.Secret, error)
}

type apiClientAdapter struct {
	c *api.Client
}

func (c *apiClientAdapter) Sys() apiClientSys {
	return c.c.Sys()
}

func (c *apiClientAdapter) Logical() apiClientLogical {
	return c.c.Logical()
}

func (c *apiClientAdapter) SetToken(v string) {
	c.c.SetToken(v)
}

func (c *apiClientAdapter) SetNamespace(ns string) {
	c.c.SetNamespace(ns)
}

var (
	ErrVaultServerNotReady = errors.New("not initialized or sealed Vault server")

	newAPIClient = func(config *api.Config) (apiClient, error) {
		c, err := api.NewClient(config)
		if err != nil {
			return nil, err
		}

		return &apiClientAdapter{c: c}, nil
	}
)

func NewClient(URL string, namespace string) (Client, error) {
	config := &api.Config{
		Address: URL,
	}

	client, err := newAPIClient(config)
	if err != nil {
		return nil, fmt.Errorf("creating new Vault client: %w", unwrapAPIResponseError(err))
	}

	healthResp, err := client.Sys().Health()
	if err != nil {
		return nil, fmt.Errorf("checking Vault server health: %w", unwrapAPIResponseError(err))
	}

	if !healthResp.Initialized || healthResp.Sealed {
		return nil, ErrVaultServerNotReady
	}

	client.SetNamespace(namespace)

	c := &defaultClient{
		internal: client,
	}

	return c, nil
}

func (c *defaultClient) Authenticate(auth AuthMethod) error {
	err := auth.Authenticate(c)
	if err != nil {
		return fmt.Errorf("authenticating Vault client: %w", err)
	}

	c.internal.SetToken(auth.Token())

	return nil
}

func (c *defaultClient) Write(path string, data map[string]interface{}) (Result, error) {
	secret, err := c.internal.Logical().Write(path, data)

	return newResult(secret), unwrapAPIResponseError(err)
}

func (c *defaultClient) Read(path string) (Result, error) {
	secret, err := c.internal.Logical().Read(path)

	return newResult(secret), unwrapAPIResponseError(err)
}

func (c *defaultClient) Delete(path string) error {
	_, err := c.internal.Logical().Delete(path)

	return unwrapAPIResponseError(err)
}