Skip to content

Commit 1468792

Browse files
author
Oleg Sucharevich
authored
add test cluster cmd (#142)
1 parent dd11b74 commit 1468792

File tree

14 files changed

+462
-79
lines changed

14 files changed

+462
-79
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,5 @@ venonactl/dist/*
1717
venonactl-linux
1818
venonalog.json
1919
.venonaconf
20+
.cover
21+
configdir

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "venona",
3-
"version": "1.2.17",
3+
"version": "1.3.0",
44
"description": "Codefresh agent to run on Codefresh's runtime environment and execute pipeline",
55
"main": "index.js",
66
"scripts": {

venonactl/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.2.17
1+
1.3.0

venonactl/cmd/install-agent.go

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,10 @@ var installAgentCmdOptions struct {
3737
venona struct {
3838
version string
3939
}
40-
agentToken string
41-
agentID string
42-
kubernetesRunnerType bool
43-
tolerations string
44-
skipClusterAcceptanceTest bool
40+
agentToken string
41+
agentID string
42+
kubernetesRunnerType bool
43+
tolerations string
4544
}
4645

4746
var installAgentCmd = &cobra.Command{
@@ -59,8 +58,7 @@ var installAgentCmd = &cobra.Command{
5958
cfAPIHost = "https://g.codefresh.io"
6059
}
6160
builderInstallOpt := &plugins.InstallOptions{
62-
CodefreshHost: cfAPIHost,
63-
SkipAcceptanceTest: installAgentCmdOptions.skipClusterAcceptanceTest,
61+
CodefreshHost: cfAPIHost,
6462
}
6563

6664
if installAgentCmdOptions.agentToken == "" {
@@ -133,7 +131,6 @@ func init() {
133131
installAgentCmd.Flags().BoolVar(&installAgentCmdOptions.kube.inCluster, "in-cluster", false, "Set flag if venona is been installed from inside a cluster")
134132
installAgentCmd.Flags().BoolVar(&installAgentCmdOptions.dryRun, "dry-run", false, "Set to true to simulate installation")
135133
installAgentCmd.Flags().BoolVar(&installAgentCmdOptions.kubernetesRunnerType, "kubernetes-runner-type", false, "Set the runner type to kubernetes (alpha feature)")
136-
installAgentCmd.Flags().BoolVar(&installAgentCmdOptions.skipClusterAcceptanceTest, "skip-cluster-test", false, "Do not run cluster acceptance test")
137134
}
138135

139136
func fillCodefreshAPI(logger logger.Logger) {

venonactl/cmd/install-runtime.go

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,12 @@ var installRuntimeCmdOptions struct {
3434
context string
3535
nodeSelector string
3636
}
37-
storageClass string
38-
runtimeEnvironmentName string
39-
kubernetesRunnerType bool
40-
tolerations string
41-
templateValues []string
42-
templateFileValues []string
43-
skipClusterAcceptanceTest bool
37+
storageClass string
38+
runtimeEnvironmentName string
39+
kubernetesRunnerType bool
40+
tolerations string
41+
templateValues []string
42+
templateFileValues []string
4443
}
4544

4645
var installRuntimeCmd = &cobra.Command{
@@ -96,7 +95,6 @@ var installRuntimeCmd = &cobra.Command{
9695
CodefreshToken: installRuntimeCmdOptions.codefreshToken,
9796
RuntimeEnvironment: installRuntimeCmdOptions.runtimeEnvironmentName,
9897
ClusterNamespace: installRuntimeCmdOptions.kube.namespace,
99-
SkipAcceptanceTest: installRuntimeCmdOptions.skipClusterAcceptanceTest,
10098
}
10199

102100
if installRuntimeCmdOptions.kubernetesRunnerType {
@@ -175,6 +173,4 @@ func init() {
175173

176174
installRuntimeCmd.Flags().StringArrayVar(&installRuntimeCmdOptions.templateValues, "set-value", []string{}, "Set values for templates, example: --set-value LocalVolumesDir=/mnt/disks/ssd0/codefresh-volumes")
177175
installRuntimeCmd.Flags().StringArrayVar(&installRuntimeCmdOptions.templateFileValues, "set-file", []string{}, "Set values for templates from file, example: --set-file Storage.GoogleServiceAccount=/path/to/service-account.json")
178-
installRuntimeCmd.Flags().BoolVar(&installRuntimeCmdOptions.skipClusterAcceptanceTest, "skip-cluster-test", false, "Do not run cluster acceptance test")
179-
180176
}

venonactl/cmd/test.go

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package cmd
2+
3+
/*
4+
Copyright 2019 The Codefresh Authors.
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
*/
17+
18+
import (
19+
"fmt"
20+
21+
"github.com/codefresh-io/venona/venonactl/pkg/plugins"
22+
"github.com/codefresh-io/venona/venonactl/pkg/store"
23+
"github.com/spf13/cobra"
24+
"github.com/spf13/viper"
25+
)
26+
27+
var allTestPluginTypes = []string{
28+
plugins.RuntimeEnvironmentPluginType,
29+
plugins.VenonaPluginType,
30+
plugins.MonitorAgentPluginType,
31+
plugins.VolumeProvisionerPluginType,
32+
plugins.EnginePluginType,
33+
plugins.RuntimeAttachType,
34+
}
35+
36+
var testCommandOptions struct {
37+
kube struct {
38+
namespace string
39+
context string
40+
}
41+
plugin []string
42+
}
43+
44+
var testCommand = &cobra.Command{
45+
Use: "test",
46+
Short: "Run test on the target cluster prior installation",
47+
Run: func(cmd *cobra.Command, args []string) {
48+
lgr := createLogger("test", verbose)
49+
s := store.GetStore()
50+
extendStoreWithKubeClient(lgr)
51+
fillKubernetesAPI(lgr, testCommandOptions.kube.context, testCommandOptions.kube.namespace, false)
52+
53+
builder := plugins.NewBuilder(lgr)
54+
for _, p := range testCommandOptions.plugin {
55+
if p == plugins.RuntimeEnvironmentPluginType {
56+
builder.Add(plugins.RuntimeEnvironmentPluginType)
57+
}
58+
if p == plugins.VenonaPluginType {
59+
builder.Add(plugins.VenonaPluginType)
60+
}
61+
if p == plugins.MonitorAgentPluginType {
62+
builder.Add(plugins.MonitorAgentPluginType)
63+
}
64+
if p == plugins.VolumeProvisionerPluginType {
65+
builder.Add(plugins.VolumeProvisionerPluginType)
66+
}
67+
if p == plugins.EnginePluginType {
68+
builder.Add(plugins.EnginePluginType)
69+
}
70+
if p == plugins.RuntimeAttachType {
71+
builder.Add(plugins.RuntimeAttachType)
72+
}
73+
}
74+
var finalerr error
75+
for _, p := range builder.Get() {
76+
lgr.Info("Testing requirements", "installer", p.Name())
77+
err := p.Test(plugins.TestOptions{
78+
KubeBuilder: getKubeClientBuilder(s.KubernetesAPI.ContextName, s.KubernetesAPI.Namespace, s.KubernetesAPI.ConfigPath, false),
79+
ClusterNamespace: s.KubernetesAPI.Namespace,
80+
})
81+
if err != nil {
82+
if finalerr != nil {
83+
finalerr = fmt.Errorf("%s - %s", finalerr.Error(), err.Error())
84+
} else {
85+
finalerr = fmt.Errorf("%s", err.Error())
86+
87+
}
88+
}
89+
}
90+
dieOnError(finalerr)
91+
92+
lgr.Info("Cluster passed acceptance test")
93+
},
94+
}
95+
96+
func init() {
97+
viper.BindEnv("kube-namespace", "KUBE_NAMESPACE")
98+
viper.BindEnv("kube-context", "KUBE_CONTEXT")
99+
100+
testCommand.Flags().StringVar(&testCommandOptions.kube.namespace, "kube-namespace", viper.GetString("kube-namespace"), "Name of the namespace on which monitor should be installed [$KUBE_NAMESPACE]")
101+
testCommand.Flags().StringVar(&testCommandOptions.kube.context, "kube-context-name", viper.GetString("kube-context"), "Name of the kubernetes context on which monitor should be installed (default is current-context) [$KUBE_CONTEXT]")
102+
testCommand.Flags().StringArrayVar(&testCommandOptions.plugin, "installer", allTestPluginTypes, "Which test to run, based on the installer type")
103+
104+
rootCmd.AddCommand(testCommand)
105+
}

venonactl/pkg/plugins/engine.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,11 @@ func (u *enginePlugin) Upgrade(opt *UpgradeOptions, v Values) (Values, error) {
145145
func (u *enginePlugin) Migrate(*MigrateOptions, Values) error {
146146
return fmt.Errorf("not supported")
147147
}
148+
149+
func (u *enginePlugin) Test(opt TestOptions) error {
150+
return nil
151+
}
152+
153+
func (u *enginePlugin) Name() string {
154+
return EnginePluginType
155+
}

venonactl/pkg/plugins/helper.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"strings"
2626

2727
// import all cloud providers auth clients
28+
authv1 "k8s.io/api/authorization/v1"
2829
v1 "k8s.io/api/core/v1"
2930
"k8s.io/client-go/kubernetes"
3031
_ "k8s.io/client-go/plugin/pkg/client/auth"
@@ -51,6 +52,14 @@ type (
5152
cpu string
5253
localDiskMinimumSize string
5354
momorySize string
55+
rbac []rbacValidation
56+
}
57+
58+
rbacValidation struct {
59+
Namespace string
60+
Resource string
61+
Verbs []string
62+
Group string
5463
}
5564
)
5665

@@ -155,6 +164,32 @@ func getKubeObjectsFromTempalte(values map[string]interface{}, pattern string, l
155164

156165
func ensureClusterRequirements(client *kubernetes.Clientset, req validationRequest, logger logger.Logger) (validationResult, error) {
157166
result := validationResult{true, nil}
167+
specs := []*authv1.SelfSubjectAccessReview{}
168+
for _, rbac := range req.rbac {
169+
for _, verb := range rbac.Verbs {
170+
attr := &authv1.ResourceAttributes{
171+
Resource: rbac.Resource,
172+
Verb: verb,
173+
Group: rbac.Group,
174+
}
175+
if rbac.Namespace != "" {
176+
attr.Namespace = rbac.Namespace
177+
}
178+
specs = append(specs, &authv1.SelfSubjectAccessReview{
179+
Spec: authv1.SelfSubjectAccessReviewSpec{
180+
ResourceAttributes: attr,
181+
},
182+
})
183+
}
184+
}
185+
rbacres := testRBAC(client, specs)
186+
if len(rbacres) > 0 {
187+
result.isValid = false
188+
for _, res := range rbacres {
189+
result.message = append(result.message, res)
190+
}
191+
return result, nil
192+
}
158193

159194
v, err := client.ServerVersion()
160195
if err != nil {
@@ -198,6 +233,20 @@ func ensureClusterRequirements(client *kubernetes.Clientset, req validationReque
198233
return result, nil
199234
}
200235

236+
func handleValidationResult(res validationResult, logger logger.Logger) error {
237+
if !res.isValid {
238+
for _, m := range res.message {
239+
logger.Error(m)
240+
}
241+
return errors.New("Failed to run acceptance test on cluster")
242+
}
243+
244+
for _, m := range res.message {
245+
logger.Warn(m)
246+
}
247+
return nil
248+
}
249+
201250
func testKubernetesVersion(version *version.Info) (bool, error) {
202251
v, err := semver.NewVersion(version.String())
203252
if err != nil {
@@ -244,3 +293,27 @@ func testNode(n v1.Node, req validationRequest) []string {
244293

245294
return result
246295
}
296+
297+
func testRBAC(client *kubernetes.Clientset, specs []*authv1.SelfSubjectAccessReview) []string {
298+
res := []string{}
299+
for _, sar := range specs {
300+
resp, err := client.AuthorizationV1().SelfSubjectAccessReviews().Create(sar)
301+
if err != nil {
302+
res = append(res, err.Error())
303+
continue
304+
}
305+
if !resp.Status.Allowed {
306+
verb := sar.Spec.ResourceAttributes.Verb
307+
namespace := sar.Spec.ResourceAttributes.Namespace
308+
resource := sar.Spec.ResourceAttributes.Resource
309+
group := sar.Spec.ResourceAttributes.Group
310+
msg := strings.Builder{}
311+
msg.WriteString(fmt.Sprintf("Insufficient permission, %s %s/%s is not allowed", verb, group, resource))
312+
if namespace != "" {
313+
msg.WriteString(fmt.Sprintf(" on namespace %s", namespace))
314+
}
315+
res = append(res, msg.String())
316+
}
317+
}
318+
return res
319+
}

venonactl/pkg/plugins/monitor.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package plugins
1818

1919
import (
2020
"fmt"
21+
2122
"github.com/codefresh-io/venona/venonactl/pkg/logger"
2223
templates "github.com/codefresh-io/venona/venonactl/pkg/templates/kubernetes"
2324
)
@@ -84,3 +85,42 @@ func (u *monitorAgentPlugin) Upgrade(opt *UpgradeOptions, v Values) (Values, err
8485
func (u *monitorAgentPlugin) Migrate(*MigrateOptions, Values) error {
8586
return fmt.Errorf("not supported")
8687
}
88+
89+
func (u *monitorAgentPlugin) Test(opt TestOptions) error {
90+
validationRequest := validationRequest{
91+
rbac: []rbacValidation{
92+
{
93+
Group: "apps",
94+
Resource: "*",
95+
Verbs: []string{"get", "list", "watch"},
96+
Namespace: opt.ClusterNamespace,
97+
},
98+
{
99+
Resource: "*",
100+
Verbs: []string{"get", "list", "watch", "create", "delete"},
101+
Namespace: opt.ClusterNamespace,
102+
},
103+
{
104+
Group: "extensions",
105+
Resource: "*",
106+
Verbs: []string{"get", "list", "watch"},
107+
Namespace: opt.ClusterNamespace,
108+
},
109+
{
110+
Resource: "pods",
111+
Verbs: []string{"deletecollection"},
112+
Namespace: opt.ClusterNamespace,
113+
},
114+
},
115+
}
116+
return test(testOptions{
117+
logger: u.logger,
118+
kubeBuilder: opt.KubeBuilder,
119+
namespace: opt.ClusterNamespace,
120+
validationRequest: validationRequest,
121+
})
122+
}
123+
124+
func (u *monitorAgentPlugin) Name() string {
125+
return MonitorAgentPluginType
126+
}

0 commit comments

Comments
 (0)