forked from sensu/sensu-go
/
asset.go
130 lines (105 loc) · 3.07 KB
/
asset.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
package v2
import (
"crypto/rand"
"encoding/hex"
"errors"
"net/url"
"path"
"regexp"
"strings"
"github.com/sensu/sensu-go/js"
)
const (
// AssetsResource is the name of this resource type
AssetsResource = "assets"
)
var (
// AssetNameRegexStr used to validate name of asset
AssetNameRegexStr = `[a-z0-9\/\_\.\-]+`
// AssetNameRegex used to validate name of asset
AssetNameRegex = regexp.MustCompile("^" + AssetNameRegexStr + "$")
)
// StorePrefix returns the path prefix to this resource in the store
func (a *Asset) StorePrefix() string {
return AssetsResource
}
// URIPath returns the path component of an asset URI.
func (a *Asset) URIPath() string {
return path.Join(URLPrefix, "namespaces", url.PathEscape(a.Namespace), AssetsResource, url.PathEscape(a.Name))
}
// Validate returns an error if the asset contains invalid values.
func (a *Asset) Validate() error {
if err := ValidateAssetName(a.Name); err != nil {
return err
}
if a.Namespace == "" {
return errors.New("namespace cannot be empty")
}
if a.Sha512 == "" {
return errors.New("SHA-512 checksum cannot be empty")
}
if len(a.Sha512) < 128 {
return errors.New("SHA-512 checksum must be at least 128 characters")
}
if a.URL == "" {
return errors.New("URL cannot be empty")
}
u, err := url.Parse(a.URL)
if err != nil {
return errors.New("invalid URL provided")
}
if u.Scheme != "https" && u.Scheme != "http" {
return errors.New("URL must be HTTP or HTTPS")
}
return js.ParseExpressions(a.Filters)
}
// ValidateAssetName validates that asset's name is valid
func ValidateAssetName(name string) error {
if name == "" {
return errors.New("name cannot be empty")
}
if !AssetNameRegex.MatchString(name) {
return errors.New(
"name must be lowercase and may only contain forward slashes, underscores, dashes and numbers",
)
}
return nil
}
// Filename returns the filename of the underlying asset; pulled from the URL
func (a *Asset) Filename() string {
u, err := url.Parse(a.URL)
if err != nil {
return ""
}
_, file := path.Split(u.EscapedPath())
return file
}
// FixtureAsset given a name returns a valid asset for use in tests
func FixtureAsset(name string) *Asset {
bytes := make([]byte, 10)
_, _ = rand.Read(bytes)
hash := hex.EncodeToString(bytes)
asset := &Asset{
ObjectMeta: NewObjectMeta(name, "default"),
Sha512: "25e01b962045f4f5b624c3e47e782bef65c6c82602524dc569a8431b76cc1f57639d267380a7ec49f70876339ae261704fc51ed2fc520513cf94bc45ed7f6e17",
URL: "https://localhost/" + hash + ".zip",
}
return asset
}
// NewAsset creates a new Asset.
func NewAsset(meta ObjectMeta) *Asset {
return &Asset{ObjectMeta: meta}
}
// AssetFields returns a set of fields that represent that resource
func AssetFields(r Resource) map[string]string {
resource := r.(*Asset)
return map[string]string{
"asset.name": resource.ObjectMeta.Name,
"asset.namespace": resource.ObjectMeta.Namespace,
"asset.filters": strings.Join(resource.Filters, ","),
}
}
// SetNamespace sets the namespace of the resource.
func (a *Asset) SetNamespace(namespace string) {
a.Namespace = namespace
}