-
Notifications
You must be signed in to change notification settings - Fork 320
/
secrets.go
94 lines (81 loc) · 2.79 KB
/
secrets.go
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
package secrets
import (
"fmt"
"go/ast"
"go/token"
"encr.dev/pkg/errors"
"encr.dev/v2/internals/pkginfo"
"encr.dev/v2/internals/schema"
"encr.dev/v2/internals/schema/schemautil"
"encr.dev/v2/parser/infra/internal/literals"
"encr.dev/v2/parser/infra/internal/parseutil"
"encr.dev/v2/parser/resource"
"encr.dev/v2/parser/resource/resourceparser"
)
// Secrets represents a secrets struct.
type Secrets struct {
AST *ast.StructType
File *pkginfo.File // Where the secrets struct is declared
Ident *ast.Ident // The identifier of the secrets struct
Keys []string // Secret keys to load
// Spec is the value spec that defines the 'secrets' variable.
Spec *ast.ValueSpec
}
type SecretKey struct {
Name string
}
func (*Secrets) Kind() resource.Kind { return resource.Secrets }
func (s *Secrets) Package() *pkginfo.Package { return s.File.Pkg }
func (s *Secrets) ASTExpr() ast.Expr { return s.AST }
func (s *Secrets) Pos() token.Pos { return s.AST.Pos() }
func (s *Secrets) End() token.Pos { return s.AST.End() }
func (s *Secrets) SortKey() string {
return fmt.Sprintf("%s:%s:%d", s.File.Pkg.ImportPath, s.File.Name, s.AST.Pos())
}
var SecretsParser = &resourceparser.Parser{
Name: "Secrets",
InterestingImports: resourceparser.RunAlways,
Run: func(p *resourceparser.Pass) {
secrets := p.Pkg.Names().PkgDecls["secrets"]
if secrets == nil || secrets.Type != token.VAR {
return // nothing to do
}
// Note: we can't use schema.ParseTypeDecl since this is not a type declaration.
// Resolve the type expression manually instead.
spec := secrets.Spec.(*ast.ValueSpec)
if spec.Type == nil {
p.Errs.Add(errSecretsMustBeStruct.AtGoNode(spec, errors.AsError(fmt.Sprintf("got %s", parseutil.NodeType(spec)))))
return
} else if len(spec.Names) != 1 {
p.Errs.Add(errSecretsDefinedSeperately.AtGoNode(spec))
return
} else if len(spec.Values) != 0 {
p.Errs.Add(errSecretsGivenValue.AtGoNode(spec.Values[0]))
return
}
st, ok := p.SchemaParser.ParseType(secrets.File, spec.Type).(schema.StructType)
if !ok {
p.Errs.Add(errSecretsMustBeStruct.AtGoNode(spec, errors.AsError(fmt.Sprintf("got %s", parseutil.NodeType(spec)))))
return
}
res := &Secrets{
AST: spec.Type.(*ast.StructType),
File: secrets.File,
Spec: spec,
Ident: spec.Names[0],
}
for _, f := range st.Fields {
if f.IsAnonymous() {
p.Errs.Add(errAnonymousFields.AtGoNode(f.AST))
continue
}
if !schemautil.IsBuiltinKind(f.Type, schema.String) {
p.Errs.Add(errSecretsMustBeString.AtGoNode(f.AST.Type, errors.AsError(fmt.Sprintf("got %s", literals.PrettyPrint(f.Type.ASTExpr())))))
continue
}
res.Keys = append(res.Keys, f.Name.MustGet())
}
p.RegisterResource(res)
p.AddNamedBind(res.File, res.Ident, res)
},
}