-
Notifications
You must be signed in to change notification settings - Fork 0
/
naming.go
117 lines (98 loc) · 2.87 KB
/
naming.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
package validation
import (
"crypto/x509"
"encoding/pem"
"fmt"
"net"
"net/mail"
"strings"
"github.com/cloudogu/k8s-ces-setup/app/context"
)
type namingValidator struct{}
// NewNamingValidator creates a new validator for the naming section of the setup configuration
func NewNamingValidator() *namingValidator {
return &namingValidator{}
}
// ValidateNaming validates all properties of the naming section from a setup json
// see: https://docs.cloudogu.com/docs/system-components/ces-setup/operations/setup-json_de/
func (nv *namingValidator) ValidateNaming(naming context.Naming) error {
if naming.Fqdn == "" {
return getPropertyNotSetError("fqdn")
}
if naming.Domain == "" {
return getPropertyNotSetError("domain")
}
certificateType := naming.CertificateType
if certificateType != "selfsigned" && certificateType != "external" {
return getInvalidOptionError("certificateType", "selfsigned", "external")
}
if certificateType == "external" {
err := validateCertificates(naming)
if err != nil {
return err
}
}
if naming.RelayHost == "" {
return getPropertyNotSetError("relayHost")
}
address := naming.MailAddress
if address != "" {
_, err := mail.ParseAddress(address)
if err != nil {
return fmt.Errorf("failed to validate mail address: %w", err)
}
}
if naming.UseInternalIp {
internalIP := naming.InternalIp
ip := net.ParseIP(internalIP)
if ip == nil {
return fmt.Errorf("failed to parse internal ip: %s", internalIP)
}
}
return nil
}
func validateCertificates(naming context.Naming) error {
cert := naming.Certificate
if cert == "" {
return getPropertyNotSetError("certificate")
}
certs := SplitPemCertificates(cert)
for i, cert := range certs {
block, _ := pem.Decode([]byte(cert))
if block == nil {
return fmt.Errorf("failed to decode %d-th certificate in [certificate] property", i)
}
_, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return fmt.Errorf("failed to parse %d-th certificate in [certificate] property: %w", i, err)
}
}
key := naming.CertificateKey
if key == "" {
return getPropertyNotSetError("certificate key")
}
keyBlock, _ := pem.Decode([]byte(key))
if keyBlock == nil {
return fmt.Errorf("failed to parse certificate key")
}
return nil
}
// SplitPemCertificates splits a certificate chain in pem format and returns all certificates of the chain as []string
func SplitPemCertificates(chain string) []string {
sep := "-----BEGIN CERTIFICATE-----\n"
result := []string{}
split := strings.Split(chain, sep)
for _, s := range split {
if s == "" {
continue
}
result = append(result, fmt.Sprintf("%s%s", sep, s))
}
return result
}
func getInvalidOptionError(property string, validOptions ...string) error {
return fmt.Errorf("invalid %s valid options are %s", property, validOptions)
}
func getPropertyNotSetError(property string) error {
return fmt.Errorf("no %s set", property)
}