-
Notifications
You must be signed in to change notification settings - Fork 9
/
phase0.go
117 lines (94 loc) · 3.63 KB
/
phase0.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// Copyright 2022 Namespace Labs Inc; All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
package cuefrontendopaque
import (
"context"
"cuelang.org/go/cue"
"namespacelabs.dev/foundation/internal/fnerrors"
"namespacelabs.dev/foundation/internal/frontend/cuefrontend"
"namespacelabs.dev/foundation/internal/frontend/cuefrontend/binary"
integrationparsing "namespacelabs.dev/foundation/internal/frontend/cuefrontend/integration/api"
"namespacelabs.dev/foundation/internal/frontend/fncue"
"namespacelabs.dev/foundation/internal/parsing"
integrationapplying "namespacelabs.dev/foundation/internal/parsing/integration/api"
"namespacelabs.dev/foundation/internal/protos"
"namespacelabs.dev/foundation/schema"
"namespacelabs.dev/foundation/std/pkggraph"
)
var packageFields = []string{
"server", "sidecars", "volumes", "secrets", "tests", "binary",
"resources", "resourceClasses", "providers", "extension",
}
var sidecarFields = []string{
"args", "env", "mounts", "image", "imageFrom", "init",
}
type Frontend struct {
loader parsing.EarlyPackageLoader
env *schema.Environment
}
func NewFrontend(env *schema.Environment, pl parsing.EarlyPackageLoader) *Frontend {
return &Frontend{pl, env}
}
func (ft Frontend) ParsePackage(ctx context.Context, partial *fncue.Partial, loc pkggraph.Location) (*pkggraph.Package, error) {
v := &partial.CueV
// Ensure all fields are bound.
if err := v.Val.Validate(cue.Concrete(true)); err != nil {
return nil, err
}
allowedFields := packageFields
if loc.Module.ModuleName() == string(loc.PackageName) {
allowedFields = append(allowedFields, cuefrontend.ModuleFields...)
}
// Is this too strict? What if there is non-Namespace CUE in a package?
if err := cuefrontend.ValidateNoExtraFields(loc, "top level" /* messagePrefix */, v, allowedFields); err != nil {
return nil, err
}
parsedPkg, err := cuefrontend.ParsePackage(ctx, ft.env, ft.loader, v, loc)
if err != nil {
return nil, err
}
if server := v.LookupPath("server"); server.Exists() {
parsedSrv, err := parseCueServer(ctx, ft.env, ft.loader, parsedPkg, server)
if err != nil {
return nil, fnerrors.NewWithLocation(loc, "parsing server failed: %w", err)
}
parsedPkg.Server = parsedSrv
if i := server.LookupPath("integration"); i.Exists() {
integration, err := integrationparsing.IntegrationParser.ParseEntity(ctx, ft.env, ft.loader, loc, i)
if err != nil {
return nil, err
}
parsedPkg.Integration = &schema.Integration{
Data: protos.WrapAnyOrDie(integration.Data),
}
}
binRef, err := binary.ParseImage(ctx, ft.env, ft.loader, parsedPkg, "server" /* binaryName */, server, binary.ParseImageOpts{})
if err != nil {
return nil, err
} else if binRef != nil {
if err := integrationapplying.SetServerBinaryRef(parsedPkg, binRef); err != nil {
return nil, err
}
}
if naming := server.LookupPath("unstable_naming"); naming.Exists() {
parsedPkg.Server.ServerNaming, err = cuefrontend.ParseNaming(naming)
if err != nil {
return nil, err
}
}
}
if extension := v.LookupPath("extension"); extension.Exists() {
parsed, err := parseCueServerExtension(ctx, ft.env, ft.loader, parsedPkg, extension)
if err != nil {
return nil, fnerrors.NewWithLocation(loc, "parsing server failed: %w", err)
}
if parsedPkg.Server != nil {
return nil, fnerrors.NewWithLocation(loc, "it is not yet possible to declare a server and an extension in the same package")
}
parsedPkg.ServerFragment = parsed
}
parsedPkg.NewFrontend = true
parsedPkg.PackageSources = partial.Package.Snapshot
return parsedPkg, nil
}