-
Notifications
You must be signed in to change notification settings - Fork 18
/
fixtures.go
185 lines (159 loc) · 6.5 KB
/
fixtures.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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
package ospreytest
import (
"fmt"
"io/ioutil"
"net/http"
"github.com/SermoDigital/jose/jws"
"github.com/SermoDigital/jose/jwt"
"github.com/sky-uk/osprey/common/web"
"github.com/sky-uk/osprey/server/osprey"
"k8s.io/client-go/tools/clientcmd"
clientgo "k8s.io/client-go/tools/clientcmd/api"
)
const targetNamePrefix = "kubectl."
const targetAliasPrefix = "alias."
//AddCustomNamespaceToContexts adds a namespace to each context in the kubeconfig file
// the name of the namespace will be
func AddCustomNamespaceToContexts(namespaceSuffix, kubeconfig string, targetedOspreys []*TestOsprey) error {
existingConfig, err := clientcmd.LoadFromFile(kubeconfig)
if err != nil {
return fmt.Errorf("unable to load kubeconfig file %s: %v", kubeconfig, err)
}
for _, target := range targetedOspreys {
targetName := target.OspreyconfigTargetName()
existingConfig.Contexts[targetName].Namespace = target.CustomTargetNamespace(namespaceSuffix)
aliasTargetName := target.OspreyconfigAliasName()
existingConfig.Contexts[aliasTargetName].Namespace = target.CustomAliasNamespace(namespaceSuffix)
}
err = clientcmd.WriteToFile(*existingConfig, kubeconfig)
if err != nil {
return fmt.Errorf("unable to write kubeconfig file %s: %v", kubeconfig, err)
}
return nil
}
// ToKubeconfigCluster returns a *Cluster representation of the TestOsprey instance.
func (o *TestOsprey) ToKubeconfigCluster(locationOfOrigin string) *clientgo.Cluster {
apiServer := fmt.Sprintf("https://apiserver.%s.cluster", o.Environment)
caData, _ := ioutil.ReadFile(o.APIServerCA)
expectedCluster := clientgo.NewCluster()
expectedCluster.LocationOfOrigin = locationOfOrigin
expectedCluster.Server = apiServer
expectedCluster.CertificateAuthorityData = caData
return expectedCluster
}
// ToKubeconfigUserWithoutToken returns an *AuthInfo representation, with an empty id-token, of the TestOsprey instance.
func (o *TestOsprey) ToKubeconfigUserWithoutToken(locationOfOrigin string) *clientgo.AuthInfo {
caData, _ := osprey.ReadAndEncodeFile(o.IssuerCA)
authInfo := clientgo.NewAuthInfo()
authProviderConfig := make(map[string]string)
authProviderConfig["client-id"] = o.Environment
authProviderConfig["client-secret"] = o.Secret
authProviderConfig["id-token"] = ""
authProviderConfig["idp-certificate-authority-data"] = caData
authProviderConfig["idp-issuer-url"] = o.IssuerURL
authInfo.ImpersonateUserExtra = nil
authInfo.LocationOfOrigin = locationOfOrigin
authInfo.AuthProvider = &clientgo.AuthProviderConfig{
Name: "oidc",
Config: authProviderConfig,
}
return authInfo
}
// WithoutToken creates a DeepCopy() of authInfo without an id-token.
func WithoutToken(authInfo *clientgo.AuthInfo) *clientgo.AuthInfo {
clone := authInfo.DeepCopy()
clone.AuthProvider.Config["id-token"] = ""
return clone
}
// OspreyTargetOutput returns the name and aliases output format for the environment.
func OspreyTargetOutput(environment string) string {
return fmt.Sprintf("%s | %s", OspreyconfigTargetName(environment), OspreyconfigAliasName(environment))
}
// OspreyconfigTargetName returns the ospreyconfig target's name for the TestOsprey instance.
func (o *TestOsprey) OspreyconfigTargetName() string {
return OspreyconfigTargetName(o.Environment)
}
// OspreyconfigTargetName returns the ospreyconfig target's name for the environment.
func OspreyconfigTargetName(environment string) string {
return fmt.Sprintf("%s%s", targetNamePrefix, environment)
}
// OspreyconfigAliasName returns the ospreyconfig target's alias for the environment.
func OspreyconfigAliasName(environment string) string {
return fmt.Sprintf("%s%s", targetAliasPrefix, OspreyconfigTargetName(environment))
}
// OspreyconfigAliasName returns the ospreyconfig target's alias for the TestOsprey instance.
func (o *TestOsprey) OspreyconfigAliasName() string {
return OspreyconfigAliasName(o.Environment)
}
// ToKubeconfigContext returns a *Context representation of the TestOsprey instance.
func (o *TestOsprey) ToKubeconfigContext(locationOfOrigin string) *clientgo.Context {
targetName := o.OspreyconfigTargetName()
kubeconfigCtx := clientgo.NewContext()
kubeconfigCtx.Cluster = targetName
kubeconfigCtx.AuthInfo = targetName
kubeconfigCtx.LocationOfOrigin = locationOfOrigin
return kubeconfigCtx
}
// CustomTargetNamespace returns the name for a namespace appending the suffix to the osprey's target name.
func (o *TestOsprey) CustomTargetNamespace(suffix string) string {
return o.OspreyconfigTargetName() + suffix
}
// CustomAliasNamespace returns the name for a namespace appending the suffix to the osprey's alias name.
func (o *TestOsprey) CustomAliasNamespace(suffix string) string {
return o.OspreyconfigAliasName() + suffix
}
// ToGroupClaims returns the groups contained in the groups claim of the id-token for the authInfo.
// If no tokens exists it returns an empty slice.
func (o *TestOsprey) ToGroupClaims(authInfo *clientgo.AuthInfo) ([]string, error) {
var groups []string
tokenString := authInfo.AuthProvider.Config["id-token"]
token, err := jws.ParseJWT([]byte(tokenString))
if err != nil {
return groups, err
}
return extractClaims(token)
}
// CallHealthcheck returns the current status of osprey's healthcheck as an http response and error
func (o *TestOsprey) CallHealthcheck() (*http.Response, error) {
certData, _ := web.LoadTLSCert(o.CertFile)
httpClient, err := web.NewTLSClient(certData)
if err != nil {
return nil, err
}
ospreyHealthCheckURL := fmt.Sprintf("%s/healthz", o.URL)
req, err := http.NewRequest(http.MethodGet, ospreyHealthCheckURL, nil)
if err != nil {
return nil, err
}
return httpClient.Do(req)
}
// CreateCustom
// GetOspreysByGroup returns the ospreys matching by group or default group given the environmentGroups definition.
func GetOspreysByGroup(group, defaultGroup string, environmentGroups map[string][]string, ospreys []*TestOsprey) []*TestOsprey {
var targetedOspreys []*TestOsprey
actualGroup := group
if actualGroup == "" {
actualGroup = defaultGroup
}
for _, target := range ospreys {
if groups, ok := environmentGroups[target.Environment]; ok {
if len(groups) == 0 && actualGroup == "" {
targetedOspreys = append(targetedOspreys, target)
}
for _, ospreyGroup := range groups {
if actualGroup == ospreyGroup {
targetedOspreys = append(targetedOspreys, target)
break
}
}
}
}
return targetedOspreys
}
func extractClaims(token jwt.JWT) (groups []string, err error) {
claimedGroups := token.Claims().Get("groups")
for _, group := range claimedGroups.([]interface{}) {
groups = append(groups, group.(string))
}
return groups, err
}