Skip to content

Commit 0238e58

Browse files
lndinit: add ability to write to k8s configmap
We'll use this to write connection relateed information for consumption by payment service proxy.
1 parent 97404fa commit 0238e58

File tree

9 files changed

+367
-50
lines changed

9 files changed

+367
-50
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ initialization, including seed and password generation.
1010
- [`gen-seed`](#gen-seed)
1111
- [`load-secret`](#load-secret)
1212
- [`store-secret`](#store-secret)
13+
- [`store-configmap`](#store-configmap)
1314
- [`init-wallet`](#init-wallet)
1415
- [`wait-ready`](#wait-ready)
1516
- [Example usage](#example-usage)
@@ -48,6 +49,9 @@ No `lnd` needed, but seed will be in `lnd`-specific [`aezeed` format](https://gi
4849
### store-secret
4950
`store-secret` interacts with kubernetes to write to secrets (no `lnd` needed)
5051

52+
### store-configmap
53+
`store-configmap` interacts with kubernetes to write to configmaps (no `lnd` needed)
54+
5155
### init-wallet
5256
`init-wallet` has two modes:
5357
- `--init-type=file` creates an `lnd` specific `wallet.db` file

cmd_gen_seed.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,15 @@ func (x *genSeedCommand) Execute(_ []string) error {
6868

6969
// Read passphrase from Kubernetes secret.
7070
case x.PassphraseK8s.AnySet():
71-
passPhrase, _, err = readK8s(x.PassphraseK8s)
71+
k8sSecret := &k8sObjectOptions{
72+
Namespace: x.PassphraseK8s.Namespace,
73+
Name: x.PassphraseK8s.SecretName,
74+
KeyName: x.PassphraseK8s.SecretKeyName,
75+
Base64: x.PassphraseK8s.Base64,
76+
ObjectType: ObjectTypeSecret,
77+
}
78+
79+
passPhrase, _, err = readK8s(k8sSecret)
7280

7381
}
7482
if err != nil {

cmd_init_wallet.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -239,12 +239,13 @@ func (x *initWalletCommand) readInput(requireSeed bool) (string, string, string,
239239

240240
// Read passphrase from Kubernetes secret.
241241
case storageK8s:
242-
k8sSecret := &k8sSecretOptions{
242+
k8sSecret := &k8sObjectOptions{
243243
Namespace: x.K8s.Namespace,
244-
SecretName: x.K8s.SecretName,
244+
Name: x.K8s.SecretName,
245+
KeyName: x.K8s.SeedKeyName,
245246
Base64: x.K8s.Base64,
247+
ObjectType: ObjectTypeSecret,
246248
}
247-
k8sSecret.SecretKeyName = x.K8s.SeedKeyName
248249

249250
if requireSeed {
250251
log("Reading seed from k8s secret %s (namespace %s)",
@@ -260,7 +261,7 @@ func (x *initWalletCommand) readInput(requireSeed bool) (string, string, string,
260261
log("Reading seed passphrase from k8s secret %s "+
261262
"(namespace %s)", x.K8s.SecretName,
262263
x.K8s.Namespace)
263-
k8sSecret.SecretKeyName = x.K8s.SeedPassphraseKeyName
264+
k8sSecret.KeyName = x.K8s.SeedPassphraseKeyName
264265
seedPassPhrase, _, err = readK8s(k8sSecret)
265266
if err != nil {
266267
return "", "", "", err
@@ -269,7 +270,7 @@ func (x *initWalletCommand) readInput(requireSeed bool) (string, string, string,
269270

270271
log("Reading wallet password from k8s secret %s (namespace %s)",
271272
x.K8s.SecretName, x.K8s.Namespace)
272-
k8sSecret.SecretKeyName = x.K8s.WalletPasswordKeyName
273+
k8sSecret.KeyName = x.K8s.WalletPasswordKeyName
273274
walletPassword, _, err = readK8s(k8sSecret)
274275
if err != nil {
275276
return "", "", "", err

cmd_load_secret.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,15 @@ func (x *loadSecretCommand) Register(parser *flags.Parser) error {
3737
func (x *loadSecretCommand) Execute(_ []string) error {
3838
switch x.Source {
3939
case storageK8s:
40-
content, secret, err := readK8s(x.K8s)
40+
objectOpts := &k8sObjectOptions{
41+
Namespace: x.K8s.Namespace,
42+
Name: x.K8s.SecretName,
43+
KeyName: x.K8s.SecretKeyName,
44+
Base64: x.K8s.Base64,
45+
ObjectType: ObjectTypeSecret,
46+
}
47+
48+
content, secret, err := readK8s(objectOpts)
4149
if err != nil {
4250
return fmt.Errorf("error reading secret %s in "+
4351
"namespace %s: %v", x.K8s.SecretName,

cmd_store_configmap.go

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"io"
6+
"os"
7+
"path/filepath"
8+
9+
"github.com/jessevdk/go-flags"
10+
)
11+
12+
type targetK8sConfigmap struct {
13+
k8sConfigmapOptions
14+
15+
Helm *helmOptions `group:"Flags for configuring the Helm annotations (use when --target=k8s)" namespace:"helm"`
16+
}
17+
18+
type storeConfigmapCommand struct {
19+
Batch bool `long:"batch" description:"Instead of reading one configmap from stdin, read all files of the argument list and store them as entries in the configmap"`
20+
Overwrite bool `long:"overwrite" description:"Overwrite existing configmap entries instead of aborting"`
21+
Target string `long:"target" short:"t" description:"Configmap storage target" choice:"k8s"`
22+
K8s *targetK8sConfigmap `group:"Flags for storing the key/value pair inside a Kubernetes Configmap (use when --target=k8s)" namespace:"k8s"`
23+
}
24+
25+
func newStoreConfigmapCommand() *storeConfigmapCommand {
26+
return &storeConfigmapCommand{
27+
Target: storageK8s,
28+
K8s: &targetK8sConfigmap{
29+
k8sConfigmapOptions: k8sConfigmapOptions{
30+
Namespace: defaultK8sNamespace,
31+
},
32+
},
33+
}
34+
}
35+
36+
func (x *storeConfigmapCommand) Register(parser *flags.Parser) error {
37+
_, err := parser.AddCommand(
38+
"store-configmap",
39+
"Write key/value pairs to a Kubernetes configmap",
40+
"Read a configmap from stdin and store it to the "+
41+
"external configmaps storage indicated by the --target "+
42+
"flag; if the --batch flag is used, instead of "+
43+
"reading a single configmap entry from stdin, each command "+
44+
"line argument is treated as a file and each file's "+
45+
"content is added to the configmap with the file's name "+
46+
"as the key name for the configmap entry",
47+
x,
48+
)
49+
return err
50+
}
51+
52+
func (x *storeConfigmapCommand) Execute(args []string) error {
53+
var entries []*entry
54+
55+
switch {
56+
case x.Batch && len(args) == 0:
57+
return fmt.Errorf("at least one command line argument is " +
58+
"required when using --batch flag")
59+
60+
case x.Batch:
61+
for _, file := range args {
62+
log("Reading value/entry from file %s", file)
63+
content, err := readFile(file)
64+
if err != nil {
65+
return fmt.Errorf("cannot read file %s: %v",
66+
file, err)
67+
}
68+
69+
entries = append(entries, &entry{
70+
key: filepath.Base(file),
71+
value: content,
72+
})
73+
}
74+
75+
default:
76+
log("Reading value/entry from stdin")
77+
value, err := io.ReadAll(os.Stdin)
78+
if err != nil {
79+
return fmt.Errorf("error reading entry from stdin: %v", err)
80+
}
81+
entries = append(entries, &entry{value: string(value)})
82+
}
83+
84+
switch x.Target {
85+
case storageK8s:
86+
// Take the actual entry key from the options if we aren't in
87+
// batch mode.
88+
if len(entries) == 1 && entries[0].key == "" {
89+
entries[0].key = x.K8s.KeyName
90+
}
91+
92+
return storeConfigmapsK8s(entries, x.K8s, x.Overwrite)
93+
94+
default:
95+
return fmt.Errorf("invalid configmap storage target %s", x.Target)
96+
}
97+
}
98+
99+
func storeConfigmapsK8s(entries []*entry, opts *targetK8sConfigmap,
100+
overwrite bool) error {
101+
102+
if opts.Name == "" {
103+
return fmt.Errorf("configmap name is required")
104+
}
105+
106+
for _, entry := range entries {
107+
if entry.key == "" {
108+
return fmt.Errorf("configmap entry key name is required")
109+
}
110+
111+
entryOpts := &k8sObjectOptions{
112+
Namespace: opts.Namespace,
113+
Name: opts.Name,
114+
KeyName: entry.key,
115+
ObjectType: ObjectTypeConfigMap,
116+
}
117+
118+
log("Storing key with name %s to configmap %s in namespace %s",
119+
entryOpts.KeyName, entryOpts.Name,
120+
entryOpts.Namespace)
121+
122+
err := saveK8s(entry.value, entryOpts, overwrite, opts.Helm)
123+
if err != nil {
124+
return fmt.Errorf("error storing key %s in configmap %s: "+
125+
"%v", entry.key, opts.Name, err)
126+
}
127+
}
128+
129+
return nil
130+
}

cmd_store_secret.go

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,28 @@ import (
1010
"github.com/jessevdk/go-flags"
1111
)
1212

13-
type targetK8s struct {
13+
type targetK8sSecret struct {
1414
k8sSecretOptions
1515

1616
Helm *helmOptions `group:"Flags for configuring the Helm annotations (use when --target=k8s)" namespace:"helm"`
1717
}
1818

19-
type secretEntry struct {
19+
type entry struct {
2020
key string
2121
value string
2222
}
2323

2424
type storeSecretCommand struct {
25-
Batch bool `long:"batch" description:"Instead of reading one secret from stdin, read all files of the argument list and store them as entries in the secret"`
26-
Overwrite bool `long:"overwrite" description:"Overwrite existing secret entries instead of aborting"`
27-
Target string `long:"target" short:"t" description:"Secret storage target" choice:"k8s"`
28-
K8s *targetK8s `group:"Flags for storing the secret as a value inside a Kubernetes Secret (use when --target=k8s)" namespace:"k8s"`
25+
Batch bool `long:"batch" description:"Instead of reading one secret from stdin, read all files of the argument list and store them as entries in the secret"`
26+
Overwrite bool `long:"overwrite" description:"Overwrite existing secret entries instead of aborting"`
27+
Target string `long:"target" short:"t" description:"Secret storage target" choice:"k8s"`
28+
K8s *targetK8sSecret `group:"Flags for storing the secret as a value inside a Kubernetes Secret (use when --target=k8s)" namespace:"k8s"`
2929
}
3030

3131
func newStoreSecretCommand() *storeSecretCommand {
3232
return &storeSecretCommand{
3333
Target: storageK8s,
34-
K8s: &targetK8s{
34+
K8s: &targetK8sSecret{
3535
k8sSecretOptions: k8sSecretOptions{
3636
Namespace: defaultK8sNamespace,
3737
},
@@ -59,7 +59,7 @@ func (x *storeSecretCommand) Register(parser *flags.Parser) error {
5959
}
6060

6161
func (x *storeSecretCommand) Execute(args []string) error {
62-
var entries []*secretEntry
62+
var entries []*entry
6363

6464
switch {
6565
case x.Batch && len(args) == 0:
@@ -75,7 +75,7 @@ func (x *storeSecretCommand) Execute(args []string) error {
7575
file, err)
7676
}
7777

78-
entries = append(entries, &secretEntry{
78+
entries = append(entries, &entry{
7979
key: filepath.Base(file),
8080
value: content,
8181
})
@@ -88,7 +88,7 @@ func (x *storeSecretCommand) Execute(args []string) error {
8888
return fmt.Errorf("error reading secret from stdin: %v",
8989
err)
9090
}
91-
entries = append(entries, &secretEntry{value: secret})
91+
entries = append(entries, &entry{value: secret})
9292
}
9393

9494
switch x.Target {
@@ -106,7 +106,7 @@ func (x *storeSecretCommand) Execute(args []string) error {
106106
}
107107
}
108108

109-
func storeSecretsK8s(entries []*secretEntry, opts *targetK8s,
109+
func storeSecretsK8s(entries []*entry, opts *targetK8sSecret,
110110
overwrite bool) error {
111111

112112
if opts.SecretName == "" {
@@ -118,15 +118,16 @@ func storeSecretsK8s(entries []*secretEntry, opts *targetK8s,
118118
return fmt.Errorf("secret key name is required")
119119
}
120120

121-
entryOpts := &k8sSecretOptions{
122-
Namespace: opts.Namespace,
123-
SecretName: opts.SecretName,
124-
SecretKeyName: entry.key,
125-
Base64: opts.Base64,
121+
entryOpts := &k8sObjectOptions{
122+
Namespace: opts.Namespace,
123+
Name: opts.SecretName,
124+
KeyName: entry.key,
125+
Base64: opts.Base64,
126+
ObjectType: ObjectTypeSecret,
126127
}
127128

128129
log("Storing key with name %s to secret %s in namespace %s",
129-
entryOpts.SecretKeyName, entryOpts.SecretName,
130+
entryOpts.KeyName, entryOpts.Name,
130131
entryOpts.Namespace)
131132
err := saveK8s(entry.value, entryOpts, overwrite, opts.Helm)
132133
if err != nil {

0 commit comments

Comments
 (0)