This repository has been archived by the owner on Mar 24, 2022. It is now read-only.
forked from cppforlife/bosh-provisioner
/
manifest.go
144 lines (107 loc) · 3.46 KB
/
manifest.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// Package manifest represents structure
// of a user entered YAML deployment manifest.
package manifest
import (
gonet "net"
"github.com/cloudfoundry-incubator/candiedyaml"
bosherr "github.com/cloudfoundry/bosh-utils/errors"
boshsys "github.com/cloudfoundry/bosh-utils/system"
)
type Manifest struct {
Deployment Deployment
}
type Deployment struct {
Name string `yaml:"name"`
Releases []Release `yaml:"releases"`
Networks []Network `yaml:"networks"`
Compilation Compilation `yaml:"compilation"`
// Deployment-wide update config can be
// overwritten by job-specific update config
Update Update `yaml:"update"`
Jobs []Job `yaml:"jobs"`
// Global properties.
// Non-raw field is populated by the validator.
PropertiesRaw map[interface{}]interface{} `yaml:"properties"`
Properties Properties
}
type Release struct {
Name string `yaml:"name"`
Version string `yaml:"version"`
// Not offical BOSH manifest construct
URL string `yaml:"url"`
}
const (
NetworkTypeManual = "manual"
NetworkTypeLocal = "local"
NetworkTypeDynamic = "dynamic"
NetworkTypeVip = "vip"
)
var NetworkTypes = []string{NetworkTypeManual, NetworkTypeLocal, NetworkTypeDynamic, NetworkTypeVip}
type Network struct {
Name string `yaml:"name"`
// e.g. manual, dynamic, vip
Type string `yaml:"type"`
}
type Compilation struct {
NetworkName string `yaml:"network"`
}
type Job struct {
Name string `yaml:"name"`
Instances int `yaml:"instances"`
Update Update `yaml:"update"`
// Deprecated in favor of Templates
Template interface{} `yaml:"template"`
Templates []Template `yaml:"templates"`
// Job specific properties that override global properties.
// Non-raw field is populated by the validator.
PropertiesRaw map[interface{}]interface{} `yaml:"properties"`
Properties Properties
NetworkAssociations []NetworkAssociation `yaml:"networks"`
}
type Template struct {
Name string `yaml:"name"`
ReleaseName string `yaml:"release"`
}
type Properties map[string]interface{}
type Update struct {
// Integer pointers to determine absence
Canaries *int `yaml:"canaries"`
MaxInFlight *int `yaml:"max_in_flight"`
// String pointers to determine absence
CanaryWatchTimeRaw *string `yaml:"canary_watch_time"`
UpdateWatchTimeRaw *string `yaml:"update_watch_time"`
// Populated by the validator
CanaryWatchTime *WatchTime
UpdateWatchTime *WatchTime
}
type NetworkAssociation struct {
NetworkName string `yaml:"name"`
// Non-raw field populated by the validator.
StaticIPsRaw []string `yaml:"static_ips"`
StaticIPs []gonet.IP
}
// NewManifestFromPath returns manifest read from the file system.
// Before returning manifest is syntactically validated.
func NewManifestFromPath(path string, fs boshsys.FileSystem) (Manifest, error) {
bytes, err := fs.ReadFile(path)
if err != nil {
return Manifest{}, bosherr.WrapErrorf(err, "Reading manifest %s", path)
}
return NewManifestFromBytes(bytes)
}
// NewManifestFromBytes returns manifest built from given bytes.
// Before returning manifest is syntactically validated.
func NewManifestFromBytes(bytes []byte) (Manifest, error) {
var manifest Manifest
var deployment Deployment
err := candiedyaml.Unmarshal(bytes, &deployment)
if err != nil {
return manifest, bosherr.WrapError(err, "Parsing deployment")
}
manifest.Deployment = deployment
err = NewSyntaxValidator(&manifest).Validate()
if err != nil {
return manifest, bosherr.WrapError(err, "Validating manifest syntactically")
}
return manifest, nil
}