Browse code

Revert "Added support for project node selector"

Clayton Coleman authored on 2015/05/05 22:42:51
Showing 25 changed files
... ...
@@ -20,10 +20,9 @@ import (
20 20
 const NewProjectRecommendedName = "new-project"
21 21
 
22 22
 type NewProjectOptions struct {
23
-	ProjectName  string
24
-	DisplayName  string
25
-	Description  string
26
-	NodeSelector string
23
+	ProjectName string
24
+	DisplayName string
25
+	Description string
27 26
 
28 27
 	Client client.Interface
29 28
 
... ...
@@ -60,7 +59,6 @@ func NewCmdNewProject(name, fullName string, f *clientcmd.Factory, out io.Writer
60 60
 	cmd.Flags().StringVar(&options.AdminUser, "admin", "", "project admin username")
61 61
 	cmd.Flags().StringVar(&options.DisplayName, "display-name", "", "project display name")
62 62
 	cmd.Flags().StringVar(&options.Description, "description", "", "project description")
63
-	cmd.Flags().StringVar(&options.NodeSelector, "node-selector", "", "Restrict pods onto nodes matching given label selector")
64 63
 
65 64
 	return cmd
66 65
 }
... ...
@@ -88,7 +86,6 @@ func (o *NewProjectOptions) Run() error {
88 88
 	project.Annotations = make(map[string]string)
89 89
 	project.Annotations["description"] = o.Description
90 90
 	project.Annotations["displayName"] = o.DisplayName
91
-	project.Annotations["nodeSelector"] = o.NodeSelector
92 91
 	project, err := o.Client.Projects().Create(project)
93 92
 	if err != nil {
94 93
 		return err
... ...
@@ -18,10 +18,9 @@ import (
18 18
 )
19 19
 
20 20
 type NewProjectOptions struct {
21
-	ProjectName  string
22
-	DisplayName  string
23
-	Description  string
24
-	NodeSelector string
21
+	ProjectName string
22
+	DisplayName string
23
+	Description string
25 24
 
26 25
 	Client client.Interface
27 26
 
... ...
@@ -41,8 +40,8 @@ After your project is created you can switch to it using %[2]s <project name>.`
41 41
 	requestProject_example = `  // Create a new project with minimal information
42 42
   $ %[1]s web-team-dev
43 43
 
44
-  // Create a new project with a description and node selector
45
-  $ %[1]s web-team-dev --display-name="Web Team Development" --description="Development project for the web team." --node-selector="env=dev"`
44
+  // Create a new project with a description
45
+  $ %[1]s web-team-dev --display-name="Web Team Development" --description="Development project for the web team."`
46 46
 )
47 47
 
48 48
 func NewCmdRequestProject(name, fullName, oscLoginName, oscProjectName string, f *clientcmd.Factory, out io.Writer) *cobra.Command {
... ...
@@ -50,7 +49,7 @@ func NewCmdRequestProject(name, fullName, oscLoginName, oscProjectName string, f
50 50
 	options.Out = out
51 51
 
52 52
 	cmd := &cobra.Command{
53
-		Use:     fmt.Sprintf("%s NAME [--display-name=DISPLAYNAME] [--description=DESCRIPTION] [--node-selector=<label selector>]", name),
53
+		Use:     fmt.Sprintf("%s NAME [--display-name=DISPLAYNAME] [--description=DESCRIPTION]", name),
54 54
 		Short:   "Request a new project",
55 55
 		Long:    fmt.Sprintf(requestProject_long, oscLoginName, oscProjectName),
56 56
 		Example: fmt.Sprintf(requestProject_example, fullName),
... ...
@@ -72,7 +71,6 @@ func NewCmdRequestProject(name, fullName, oscLoginName, oscProjectName string, f
72 72
 
73 73
 	cmd.Flags().StringVar(&options.DisplayName, "display-name", "", "project display name")
74 74
 	cmd.Flags().StringVar(&options.Description, "description", "", "project description")
75
-	cmd.Flags().StringVar(&options.NodeSelector, "node-selector", "", "Restrict pods onto nodes matching given label selector")
76 75
 
77 76
 	return cmd
78 77
 }
... ...
@@ -107,7 +105,6 @@ func (o *NewProjectOptions) Run() error {
107 107
 	projectRequest.DisplayName = o.DisplayName
108 108
 	projectRequest.Annotations = make(map[string]string)
109 109
 	projectRequest.Annotations["description"] = o.Description
110
-	projectRequest.Annotations["nodeSelector"] = o.NodeSelector
111 110
 
112 111
 	project, err := o.Client.ProjectRequests().Create(projectRequest)
113 112
 	if err != nil {
... ...
@@ -451,18 +451,11 @@ func (d *ProjectDescriber) Describe(namespace, name string) (string, error) {
451 451
 	if err != nil {
452 452
 		return "", err
453 453
 	}
454
-	nodeSelector := ""
455
-	if len(project.ObjectMeta.Annotations) > 0 {
456
-		if ns, ok := project.ObjectMeta.Annotations["nodeSelector"]; ok {
457
-			nodeSelector = ns
458
-		}
459
-	}
460 454
 
461 455
 	return tabbedString(func(out *tabwriter.Writer) error {
462 456
 		formatMeta(out, project.ObjectMeta)
463 457
 		formatString(out, "Display Name", project.Annotations["displayName"])
464 458
 		formatString(out, "Status", project.Status.Phase)
465
-		formatString(out, "Node Selector", nodeSelector)
466 459
 		return nil
467 460
 	})
468 461
 }
... ...
@@ -89,8 +89,6 @@ func GetMasterFileReferences(config *MasterConfig) []*string {
89 89
 
90 90
 	refs = append(refs, &config.PolicyConfig.BootstrapPolicyFile)
91 91
 
92
-	refs = append(refs, &config.ProjectNodeSelector)
93
-
94 92
 	return refs
95 93
 }
96 94
 
... ...
@@ -85,8 +85,6 @@ type MasterConfig struct {
85 85
 	// PolicyConfig holds information about where to locate critical pieces of bootstrapping policy
86 86
 	PolicyConfig PolicyConfig
87 87
 
88
-	// ProjectNodeSelector holds default project node label selector
89
-	ProjectNodeSelector string `json:"projectNodeSelector,omitempty"`
90 88
 	// ProjectRequestConfig holds information about how to handle new project requests
91 89
 	ProjectRequestConfig ProjectRequestConfig
92 90
 }
... ...
@@ -81,8 +81,6 @@ type MasterConfig struct {
81 81
 
82 82
 	PolicyConfig PolicyConfig `json:"policyConfig"`
83 83
 
84
-	// ProjectNodeSelector holds default project node label selector
85
-	ProjectNodeSelector string `json:"projectNodeSelector,omitempty"`
86 84
 	// ProjectRequestConfig holds information about how to handle new project requests
87 85
 	ProjectRequestConfig ProjectRequestConfig `json:"projectRequestConfig"`
88 86
 }
... ...
@@ -6,7 +6,6 @@ import (
6 6
 	"net/url"
7 7
 	"strings"
8 8
 
9
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
10 9
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/util/fielderrors"
11 10
 
12 11
 	"github.com/openshift/origin/pkg/cmd/server/api"
... ...
@@ -89,8 +88,6 @@ func ValidateMasterConfig(config *api.MasterConfig) fielderrors.ValidationErrorL
89 89
 		allErrs = append(allErrs, ValidateOAuthConfig(config.OAuthConfig).Prefix("oauthConfig")...)
90 90
 	}
91 91
 
92
-	allErrs = append(allErrs, ValidateProjectNodeSelector(config.ProjectNodeSelector)...)
93
-
94 92
 	allErrs = append(allErrs, ValidateServingInfo(config.ServingInfo).Prefix("servingInfo")...)
95 93
 
96 94
 	allErrs = append(allErrs, ValidateProjectRequestConfig(config.ProjectRequestConfig).Prefix("projectRequestConfig")...)
... ...
@@ -111,19 +108,6 @@ func ValidateEtcdStorageConfig(config api.EtcdStorageConfig) fielderrors.Validat
111 111
 	return allErrs
112 112
 }
113 113
 
114
-func ValidateProjectNodeSelector(nodeSelector string) fielderrors.ValidationErrorList {
115
-	allErrs := fielderrors.ValidationErrorList{}
116
-
117
-	if len(nodeSelector) > 0 {
118
-		_, err := labels.Parse(nodeSelector)
119
-		if err != nil {
120
-			allErrs = append(allErrs, fielderrors.NewFieldInvalid("projectNodeSelector", nodeSelector, "must be a valid label selector"))
121
-		}
122
-	}
123
-
124
-	return allErrs
125
-}
126
-
127 114
 func ValidateAssetConfig(config *api.AssetConfig) fielderrors.ValidationErrorList {
128 115
 	allErrs := fielderrors.ValidationErrorList{}
129 116
 
... ...
@@ -26,7 +26,6 @@ import (
26 26
 	"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/factory"
27 27
 
28 28
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/namespace"
29
-	originscheduler "github.com/openshift/origin/pkg/scheduler"
30 29
 )
31 30
 
32 31
 const (
... ...
@@ -172,5 +171,5 @@ func (c *MasterConfig) createSchedulerConfig() (*scheduler.Config, error) {
172 172
 	}
173 173
 
174 174
 	// if the config file isn't provided, use the default provider
175
-	return configFactory.CreateFromProvider(originscheduler.DefaultProvider)
175
+	return configFactory.CreateFromProvider(factory.DefaultProvider)
176 176
 }
... ...
@@ -74,7 +74,6 @@ import (
74 74
 	clientetcd "github.com/openshift/origin/pkg/oauth/registry/oauthclient/etcd"
75 75
 	clientauthetcd "github.com/openshift/origin/pkg/oauth/registry/oauthclientauthorization/etcd"
76 76
 	projectapi "github.com/openshift/origin/pkg/project/api"
77
-	projectcache "github.com/openshift/origin/pkg/project/cache"
78 77
 	projectcontroller "github.com/openshift/origin/pkg/project/controller"
79 78
 	projectproxy "github.com/openshift/origin/pkg/project/registry/project/proxy"
80 79
 	projectrequeststorage "github.com/openshift/origin/pkg/project/registry/projectrequest/delegated"
... ...
@@ -756,12 +755,6 @@ func (c *MasterConfig) RunDNSServer() {
756 756
 	glog.Infof("OpenShift DNS listening at %s", c.Options.DNSConfig.BindAddress)
757 757
 }
758 758
 
759
-// RunProjectCache populates project cache, used by scheduler and project admission controller.
760
-func (c *MasterConfig) RunProjectCache() {
761
-	glog.Infof("Using default project node label selector: %s", c.Options.ProjectNodeSelector)
762
-	projectcache.RunProjectCache(c.PrivilegedLoopbackKubernetesClient, c.Options.ProjectNodeSelector)
763
-}
764
-
765 759
 // RunBuildController starts the build sync loop for builds and buildConfig processing.
766 760
 func (c *MasterConfig) RunBuildController() {
767 761
 	// initialize build controller
... ...
@@ -47,7 +47,6 @@ type MasterArgs struct {
47 47
 	KubeConnectionArgs *KubeConnectionArgs
48 48
 
49 49
 	SchedulerConfigFile string
50
-	ProjectNodeSelector string
51 50
 }
52 51
 
53 52
 // BindMasterArgs binds the options to the flags with prefix + default flag names
... ...
@@ -61,7 +60,6 @@ func BindMasterArgs(args *MasterArgs, flags *pflag.FlagSet, prefix string) {
61 61
 
62 62
 	flags.Var(&args.NodeList, prefix+"nodes", "The hostnames of each node. This currently must be specified up front. Comma delimited list")
63 63
 	flags.Var(&args.CORSAllowedOrigins, prefix+"cors-allowed-origins", "List of allowed origins for CORS, comma separated.  An allowed origin can be a regular expression to support subdomain matching.  CORS is enabled for localhost, 127.0.0.1, and the asset server by default.")
64
-	flags.StringVar(&args.ProjectNodeSelector, prefix+"project-node-selector", "", "Default node label selector for the project if not explicitly specified.")
65 64
 }
66 65
 
67 66
 // NewDefaultMasterArgs creates MasterArgs with sub-objects created and default values set.
... ...
@@ -200,10 +198,6 @@ func (args MasterArgs) BuildSerializeableMasterConfig() (*configapi.MasterConfig
200 200
 		},
201 201
 	}
202 202
 
203
-	if len(args.ProjectNodeSelector) > 0 {
204
-		config.ProjectNodeSelector = args.ProjectNodeSelector
205
-	}
206
-
207 203
 	if args.ListenArg.UseTLS() {
208 204
 		config.ServingInfo.ServerCert = admin.DefaultMasterServingCertInfo(args.ConfigDir.Value())
209 205
 		config.ServingInfo.ClientCA = admin.DefaultAPIClientCAFile(args.ConfigDir.Value())
... ...
@@ -8,8 +8,5 @@ import (
8 8
 	_ "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/namespace/exists"
9 9
 	_ "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/namespace/lifecycle"
10 10
 	_ "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/resourcequota"
11
-	_ "github.com/openshift/origin/pkg/project/admission/lifecycle"
12
-
13
-	// Scheduler plugins used by OpenShift
14
-	_ "github.com/openshift/origin/pkg/scheduler/algorithmprovider/defaults"
11
+	_ "github.com/openshift/origin/pkg/project/admission"
15 12
 )
... ...
@@ -308,9 +308,8 @@ func StartMaster(openshiftMasterConfig *configapi.MasterConfig) error {
308 308
 	if err != nil {
309 309
 		return err
310 310
 	}
311
-	// Must start policy caching immediately
311
+	//	 must start policy caching immediately
312 312
 	openshiftConfig.RunPolicyCache()
313
-	openshiftConfig.RunProjectCache()
314 313
 
315 314
 	unprotectedInstallers := []origin.APIInstaller{}
316 315
 
317 316
new file mode 100644
... ...
@@ -0,0 +1,131 @@
0
+/*
1
+Copyright 2014 Google Inc. All rights reserved.
2
+
3
+Licensed under the Apache License, Version 2.0 (the "License");
4
+you may not use this file except in compliance with the License.
5
+You may obtain a copy of the License at
6
+
7
+    http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+Unless required by applicable law or agreed to in writing, software
10
+distributed under the License is distributed on an "AS IS" BASIS,
11
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+See the License for the specific language governing permissions and
13
+limitations under the License.
14
+*/
15
+
16
+package admission
17
+
18
+import (
19
+	"fmt"
20
+	"io"
21
+
22
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/admission"
23
+	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
24
+	apierrors "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
25
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
26
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
27
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache"
28
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
29
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
30
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
31
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
32
+	"github.com/openshift/origin/pkg/api/latest"
33
+)
34
+
35
+// TODO: modify the upstream plug-in so this can be collapsed
36
+// need ability to specify a RESTMapper on upstream version
37
+func init() {
38
+	admission.RegisterPlugin("OriginNamespaceLifecycle", func(client client.Interface, config io.Reader) (admission.Interface, error) {
39
+		return NewLifecycle(client), nil
40
+	})
41
+}
42
+
43
+type lifecycle struct {
44
+	client client.Interface
45
+	store  cache.Store
46
+}
47
+
48
+// Admit enforces that a namespace must exist in order to associate content with it.
49
+// Admit enforces that a namespace that is terminating cannot accept new content being associated with it.
50
+func (e *lifecycle) Admit(a admission.Attributes) (err error) {
51
+	defaultVersion, kind, err := latest.RESTMapper.VersionAndKindForResource(a.GetResource())
52
+	if err != nil {
53
+		return err
54
+	}
55
+	mapping, err := latest.RESTMapper.RESTMapping(kind, defaultVersion)
56
+	if err != nil {
57
+		return err
58
+	}
59
+	if mapping.Scope.Name() != meta.RESTScopeNameNamespace {
60
+		return nil
61
+	}
62
+
63
+	// we want to allow someone to delete something in case it was phantom created somehow
64
+	if a.GetOperation() == "DELETE" {
65
+		return nil
66
+	}
67
+
68
+	// check for namespace in the cache
69
+	namespaceObj, exists, err := e.store.Get(&kapi.Namespace{
70
+		ObjectMeta: kapi.ObjectMeta{
71
+			Name:      a.GetNamespace(),
72
+			Namespace: "",
73
+		},
74
+		Status: kapi.NamespaceStatus{},
75
+	})
76
+
77
+	if err != nil {
78
+		return err
79
+	}
80
+
81
+	name := "Unknown"
82
+	obj := a.GetObject()
83
+	if obj != nil {
84
+		name, _ = meta.NewAccessor().Name(obj)
85
+	}
86
+
87
+	var namespace *kapi.Namespace
88
+	if exists {
89
+		namespace = namespaceObj.(*kapi.Namespace)
90
+	} else {
91
+		// Our watch maybe latent, so we make a best effort to get the object, and only fail if not found
92
+		namespace, err = e.client.Namespaces().Get(a.GetNamespace())
93
+		// the namespace does not exist, so prevent create and update in that namespace
94
+		if err != nil {
95
+			return apierrors.NewForbidden(kind, name, fmt.Errorf("Namespace %s does not exist", a.GetNamespace()))
96
+		}
97
+	}
98
+
99
+	if a.GetOperation() != "CREATE" {
100
+		return nil
101
+	}
102
+
103
+	if namespace.Status.Phase != kapi.NamespaceTerminating {
104
+		return nil
105
+	}
106
+
107
+	return apierrors.NewForbidden(kind, name, fmt.Errorf("Namespace %s is terminating", a.GetNamespace()))
108
+}
109
+
110
+func NewLifecycle(c client.Interface) admission.Interface {
111
+	store := cache.NewStore(cache.MetaNamespaceKeyFunc)
112
+	reflector := cache.NewReflector(
113
+		&cache.ListWatch{
114
+			ListFunc: func() (runtime.Object, error) {
115
+				return c.Namespaces().List(labels.Everything(), fields.Everything())
116
+			},
117
+			WatchFunc: func(resourceVersion string) (watch.Interface, error) {
118
+				return c.Namespaces().Watch(labels.Everything(), fields.Everything(), resourceVersion)
119
+			},
120
+		},
121
+		&kapi.Namespace{},
122
+		store,
123
+		0,
124
+	)
125
+	reflector.Run()
126
+	return &lifecycle{
127
+		client: c,
128
+		store:  store,
129
+	}
130
+}
0 131
new file mode 100644
... ...
@@ -0,0 +1,116 @@
0
+package admission
1
+
2
+import (
3
+	"fmt"
4
+	"testing"
5
+
6
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/admission"
7
+	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
8
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache"
9
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/client/testclient"
10
+
11
+	buildapi "github.com/openshift/origin/pkg/build/api"
12
+)
13
+
14
+// TestAdmissionExists verifies you cannot create Origin content if namespace is not known
15
+func TestAdmissionExists(t *testing.T) {
16
+	store := cache.NewStore(cache.MetaNamespaceKeyFunc)
17
+	mockClient := &testclient.Fake{
18
+		Err: fmt.Errorf("DOES NOT EXIST"),
19
+	}
20
+	handler := &lifecycle{
21
+		client: mockClient,
22
+		store:  store,
23
+	}
24
+	build := &buildapi.Build{
25
+		ObjectMeta: kapi.ObjectMeta{Name: "buildid"},
26
+		Parameters: buildapi.BuildParameters{
27
+			Source: buildapi.BuildSource{
28
+				Type: buildapi.BuildSourceGit,
29
+				Git: &buildapi.GitBuildSource{
30
+					URI: "http://github.com/my/repository",
31
+				},
32
+				ContextDir: "context",
33
+			},
34
+			Strategy: buildapi.BuildStrategy{
35
+				Type:           buildapi.DockerBuildStrategyType,
36
+				DockerStrategy: &buildapi.DockerBuildStrategy{},
37
+			},
38
+			Output: buildapi.BuildOutput{
39
+				DockerImageReference: "repository/data",
40
+			},
41
+		},
42
+		Status: buildapi.BuildStatusNew,
43
+	}
44
+	err := handler.Admit(admission.NewAttributesRecord(build, "bogus-ns", "builds", "CREATE"))
45
+	if err == nil {
46
+		t.Errorf("Expected an error because namespace does not exist")
47
+	}
48
+}
49
+
50
+// TestAdmissionLifecycle verifies you cannot create Origin content if namespace is terminating
51
+func TestAdmissionLifecycle(t *testing.T) {
52
+	namespaceObj := &kapi.Namespace{
53
+		ObjectMeta: kapi.ObjectMeta{
54
+			Name:      "test",
55
+			Namespace: "",
56
+		},
57
+		Status: kapi.NamespaceStatus{
58
+			Phase: kapi.NamespaceActive,
59
+		},
60
+	}
61
+	store := cache.NewStore(cache.MetaNamespaceIndexFunc)
62
+	store.Add(namespaceObj)
63
+	mockClient := &testclient.Fake{}
64
+	handler := &lifecycle{
65
+		client: mockClient,
66
+		store:  store,
67
+	}
68
+	build := &buildapi.Build{
69
+		ObjectMeta: kapi.ObjectMeta{Name: "buildid"},
70
+		Parameters: buildapi.BuildParameters{
71
+			Source: buildapi.BuildSource{
72
+				Type: buildapi.BuildSourceGit,
73
+				Git: &buildapi.GitBuildSource{
74
+					URI: "http://github.com/my/repository",
75
+				},
76
+				ContextDir: "context",
77
+			},
78
+			Strategy: buildapi.BuildStrategy{
79
+				Type:           buildapi.DockerBuildStrategyType,
80
+				DockerStrategy: &buildapi.DockerBuildStrategy{},
81
+			},
82
+			Output: buildapi.BuildOutput{
83
+				DockerImageReference: "repository/data",
84
+			},
85
+		},
86
+		Status: buildapi.BuildStatusNew,
87
+	}
88
+	err := handler.Admit(admission.NewAttributesRecord(build, namespaceObj.Namespace, "builds", "CREATE"))
89
+	if err != nil {
90
+		t.Errorf("Unexpected error returned from admission handler: %v", err)
91
+	}
92
+
93
+	// change namespace state to terminating
94
+	namespaceObj.Status.Phase = kapi.NamespaceTerminating
95
+	store.Add(namespaceObj)
96
+
97
+	// verify create operations in the namespace cause an error
98
+	err = handler.Admit(admission.NewAttributesRecord(build, namespaceObj.Namespace, "builds", "CREATE"))
99
+	if err == nil {
100
+		t.Errorf("Expected error rejecting creates in a namespace when it is terminating")
101
+	}
102
+
103
+	// verify update operations in the namespace can proceed
104
+	err = handler.Admit(admission.NewAttributesRecord(build, namespaceObj.Namespace, "builds", "UPDATE"))
105
+	if err != nil {
106
+		t.Errorf("Unexpected error returned from admission handler: %v", err)
107
+	}
108
+
109
+	// verify delete operations in the namespace can proceed
110
+	err = handler.Admit(admission.NewAttributesRecord(nil, namespaceObj.Namespace, "builds", "DELETE"))
111
+	if err != nil {
112
+		t.Errorf("Unexpected error returned from admission handler: %v", err)
113
+	}
114
+
115
+}
0 116
deleted file mode 100644
... ...
@@ -1,92 +0,0 @@
1
-/*
2
-Copyright 2014 Google Inc. All rights reserved.
3
-
4
-Licensed under the Apache License, Version 2.0 (the "License");
5
-you may not use this file except in compliance with the License.
6
-You may obtain a copy of the License at
7
-
8
-    http://www.apache.org/licenses/LICENSE-2.0
9
-
10
-Unless required by applicable law or agreed to in writing, software
11
-distributed under the License is distributed on an "AS IS" BASIS,
12
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
-See the License for the specific language governing permissions and
14
-limitations under the License.
15
-*/
16
-
17
-package admission
18
-
19
-import (
20
-	"fmt"
21
-	"io"
22
-
23
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/admission"
24
-	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
25
-	apierrors "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
26
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
27
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
28
-
29
-	"github.com/openshift/origin/pkg/api/latest"
30
-	"github.com/openshift/origin/pkg/project/cache"
31
-)
32
-
33
-// TODO: modify the upstream plug-in so this can be collapsed
34
-// need ability to specify a RESTMapper on upstream version
35
-func init() {
36
-	admission.RegisterPlugin("OriginNamespaceLifecycle", func(client client.Interface, config io.Reader) (admission.Interface, error) {
37
-		return NewLifecycle()
38
-	})
39
-}
40
-
41
-type lifecycle struct {
42
-}
43
-
44
-// Admit enforces that a namespace must exist in order to associate content with it.
45
-// Admit enforces that a namespace that is terminating cannot accept new content being associated with it.
46
-func (e *lifecycle) Admit(a admission.Attributes) (err error) {
47
-	defaultVersion, kind, err := latest.RESTMapper.VersionAndKindForResource(a.GetResource())
48
-	if err != nil {
49
-		return err
50
-	}
51
-	mapping, err := latest.RESTMapper.RESTMapping(kind, defaultVersion)
52
-	if err != nil {
53
-		return err
54
-	}
55
-	if mapping.Scope.Name() != meta.RESTScopeNameNamespace {
56
-		return nil
57
-	}
58
-
59
-	// we want to allow someone to delete something in case it was phantom created somehow
60
-	if a.GetOperation() == "DELETE" {
61
-		return nil
62
-	}
63
-
64
-	name := "Unknown"
65
-	obj := a.GetObject()
66
-	if obj != nil {
67
-		name, _ = meta.NewAccessor().Name(obj)
68
-	}
69
-
70
-	projects, err := cache.GetProjectCache()
71
-	if err != nil {
72
-		return err
73
-	}
74
-	namespace, err := projects.GetNamespaceObject(a.GetNamespace())
75
-	if err != nil {
76
-		return apierrors.NewForbidden(kind, name, err)
77
-	}
78
-
79
-	if a.GetOperation() != "CREATE" {
80
-		return nil
81
-	}
82
-
83
-	if namespace.Status.Phase != kapi.NamespaceTerminating {
84
-		return nil
85
-	}
86
-
87
-	return apierrors.NewForbidden(kind, name, fmt.Errorf("Namespace %s is terminating", a.GetNamespace()))
88
-}
89
-
90
-func NewLifecycle() (admission.Interface, error) {
91
-	return &lifecycle{}, nil
92
-}
93 1
deleted file mode 100644
... ...
@@ -1,112 +0,0 @@
1
-package admission
2
-
3
-import (
4
-	"fmt"
5
-	"testing"
6
-
7
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/admission"
8
-	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
9
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache"
10
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/client/testclient"
11
-
12
-	buildapi "github.com/openshift/origin/pkg/build/api"
13
-	projectcache "github.com/openshift/origin/pkg/project/cache"
14
-)
15
-
16
-// TestAdmissionExists verifies you cannot create Origin content if namespace is not known
17
-func TestAdmissionExists(t *testing.T) {
18
-	mockClient := &testclient.Fake{
19
-		Err: fmt.Errorf("DOES NOT EXIST"),
20
-	}
21
-	projectcache.FakeProjectCache(mockClient, cache.NewStore(cache.MetaNamespaceKeyFunc), "")
22
-	handler := &lifecycle{}
23
-	build := &buildapi.Build{
24
-		ObjectMeta: kapi.ObjectMeta{Name: "buildid"},
25
-		Parameters: buildapi.BuildParameters{
26
-			Source: buildapi.BuildSource{
27
-				Type: buildapi.BuildSourceGit,
28
-				Git: &buildapi.GitBuildSource{
29
-					URI: "http://github.com/my/repository",
30
-				},
31
-				ContextDir: "context",
32
-			},
33
-			Strategy: buildapi.BuildStrategy{
34
-				Type:           buildapi.DockerBuildStrategyType,
35
-				DockerStrategy: &buildapi.DockerBuildStrategy{},
36
-			},
37
-			Output: buildapi.BuildOutput{
38
-				DockerImageReference: "repository/data",
39
-			},
40
-		},
41
-		Status: buildapi.BuildStatusNew,
42
-	}
43
-	err := handler.Admit(admission.NewAttributesRecord(build, "bogus-ns", "builds", "CREATE"))
44
-	if err == nil {
45
-		t.Errorf("Expected an error because namespace does not exist")
46
-	}
47
-}
48
-
49
-// TestAdmissionLifecycle verifies you cannot create Origin content if namespace is terminating
50
-func TestAdmissionLifecycle(t *testing.T) {
51
-	namespaceObj := &kapi.Namespace{
52
-		ObjectMeta: kapi.ObjectMeta{
53
-			Name:      "test",
54
-			Namespace: "",
55
-		},
56
-		Status: kapi.NamespaceStatus{
57
-			Phase: kapi.NamespaceActive,
58
-		},
59
-	}
60
-	store := cache.NewStore(cache.MetaNamespaceIndexFunc)
61
-	store.Add(namespaceObj)
62
-	mockClient := &testclient.Fake{}
63
-	projectcache.FakeProjectCache(mockClient, store, "")
64
-	handler := &lifecycle{}
65
-	build := &buildapi.Build{
66
-		ObjectMeta: kapi.ObjectMeta{Name: "buildid"},
67
-		Parameters: buildapi.BuildParameters{
68
-			Source: buildapi.BuildSource{
69
-				Type: buildapi.BuildSourceGit,
70
-				Git: &buildapi.GitBuildSource{
71
-					URI: "http://github.com/my/repository",
72
-				},
73
-				ContextDir: "context",
74
-			},
75
-			Strategy: buildapi.BuildStrategy{
76
-				Type:           buildapi.DockerBuildStrategyType,
77
-				DockerStrategy: &buildapi.DockerBuildStrategy{},
78
-			},
79
-			Output: buildapi.BuildOutput{
80
-				DockerImageReference: "repository/data",
81
-			},
82
-		},
83
-		Status: buildapi.BuildStatusNew,
84
-	}
85
-	err := handler.Admit(admission.NewAttributesRecord(build, namespaceObj.Namespace, "builds", "CREATE"))
86
-	if err != nil {
87
-		t.Errorf("Unexpected error returned from admission handler: %v", err)
88
-	}
89
-
90
-	// change namespace state to terminating
91
-	namespaceObj.Status.Phase = kapi.NamespaceTerminating
92
-	store.Add(namespaceObj)
93
-
94
-	// verify create operations in the namespace cause an error
95
-	err = handler.Admit(admission.NewAttributesRecord(build, namespaceObj.Namespace, "builds", "CREATE"))
96
-	if err == nil {
97
-		t.Errorf("Expected error rejecting creates in a namespace when it is terminating")
98
-	}
99
-
100
-	// verify update operations in the namespace can proceed
101
-	err = handler.Admit(admission.NewAttributesRecord(build, namespaceObj.Namespace, "builds", "UPDATE"))
102
-	if err != nil {
103
-		t.Errorf("Unexpected error returned from admission handler: %v", err)
104
-	}
105
-
106
-	// verify delete operations in the namespace can proceed
107
-	err = handler.Admit(admission.NewAttributesRecord(nil, namespaceObj.Namespace, "builds", "DELETE"))
108
-	if err != nil {
109
-		t.Errorf("Unexpected error returned from admission handler: %v", err)
110
-	}
111
-
112
-}
... ...
@@ -4,7 +4,6 @@ import (
4 4
 	"strings"
5 5
 
6 6
 	kvalidation "github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation"
7
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
8 7
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
9 8
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/util/fielderrors"
10 9
 	"github.com/openshift/origin/pkg/project/api"
... ...
@@ -24,7 +23,6 @@ func ValidateProject(project *api.Project) fielderrors.ValidationErrorList {
24 24
 	if !validateNoNewLineOrTab(project.Annotations["displayName"]) {
25 25
 		result = append(result, fielderrors.NewFieldInvalid("displayName", project.Annotations["displayName"], "may not contain a new line or tab"))
26 26
 	}
27
-	result = append(result, validateNodeSelector(project)...)
28 27
 	return result
29 28
 }
30 29
 
... ...
@@ -37,7 +35,6 @@ func validateNoNewLineOrTab(s string) bool {
37 37
 func ValidateProjectUpdate(newProject *api.Project, oldProject *api.Project) fielderrors.ValidationErrorList {
38 38
 	allErrs := fielderrors.ValidationErrorList{}
39 39
 	allErrs = append(allErrs, kvalidation.ValidateObjectMetaUpdate(&oldProject.ObjectMeta, &newProject.ObjectMeta).Prefix("metadata")...)
40
-	allErrs = append(allErrs, validateNodeSelector(newProject)...)
41 40
 	newProject.Spec.Finalizers = oldProject.Spec.Finalizers
42 41
 	newProject.Status = oldProject.Status
43 42
 	return allErrs
... ...
@@ -49,16 +46,3 @@ func ValidateProjectRequest(request *api.ProjectRequest) fielderrors.ValidationE
49 49
 
50 50
 	return ValidateProject(project)
51 51
 }
52
-
53
-func validateNodeSelector(p *api.Project) fielderrors.ValidationErrorList {
54
-	allErrs := fielderrors.ValidationErrorList{}
55
-
56
-	if len(p.Annotations) > 0 {
57
-		if selector, ok := p.Annotations["nodeSelector"]; ok {
58
-			if _, err := labels.Parse(selector); err != nil {
59
-				allErrs = append(allErrs, fielderrors.NewFieldInvalid("nodeSelector", p.Annotations["nodeSelector"], "must be a valid label selector"))
60
-			}
61
-		}
62
-	}
63
-	return allErrs
64
-}
... ...
@@ -97,33 +97,6 @@ func TestValidateProject(t *testing.T) {
97 97
 			// Should fail because the display name has \t \n
98 98
 			numErrs: 1,
99 99
 		},
100
-		{
101
-			name: "valid node selector",
102
-			project: api.Project{
103
-				ObjectMeta: kapi.ObjectMeta{
104
-					Name:      "foo",
105
-					Namespace: "",
106
-					Annotations: map[string]string{
107
-						"nodeSelector": "infra=true, env in (prod, qa)",
108
-					},
109
-				},
110
-			},
111
-			numErrs: 0,
112
-		},
113
-		{
114
-			name: "invalid node selector",
115
-			project: api.Project{
116
-				ObjectMeta: kapi.ObjectMeta{
117
-					Name:      "foo",
118
-					Namespace: "",
119
-					Annotations: map[string]string{
120
-						"nodeSelector": "infra:true,env",
121
-					},
122
-				},
123
-			},
124
-			// Should fail because infra:true is invalid format
125
-			numErrs: 1,
126
-		},
127 100
 	}
128 101
 
129 102
 	for _, tc := range testCases {
130 103
deleted file mode 100644
... ...
@@ -1,117 +0,0 @@
1
-package cache
2
-
3
-import (
4
-	"fmt"
5
-
6
-	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
7
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
8
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache"
9
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
10
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
11
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
12
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
13
-)
14
-
15
-type ProjectCache struct {
16
-	Client              client.Interface
17
-	Store               cache.Store
18
-	DefaultNodeSelector string
19
-}
20
-
21
-var pcache *ProjectCache
22
-
23
-func (p *ProjectCache) GetNamespaceObject(name string) (*kapi.Namespace, error) {
24
-	// check for namespace in the cache
25
-	namespaceObj, exists, err := p.Store.Get(&kapi.Namespace{
26
-		ObjectMeta: kapi.ObjectMeta{
27
-			Name:      name,
28
-			Namespace: "",
29
-		},
30
-		Status: kapi.NamespaceStatus{},
31
-	})
32
-	if err != nil {
33
-		return nil, err
34
-	}
35
-
36
-	var namespace *kapi.Namespace
37
-	if exists {
38
-		namespace = namespaceObj.(*kapi.Namespace)
39
-	} else {
40
-		// Our watch maybe latent, so we make a best effort to get the object, and only fail if not found
41
-		namespace, err = p.Client.Namespaces().Get(name)
42
-		// the namespace does not exist, so prevent create and update in that namespace
43
-		if err != nil {
44
-			return nil, fmt.Errorf("Namespace %s does not exist", name)
45
-		}
46
-	}
47
-	return namespace, nil
48
-}
49
-
50
-func (p *ProjectCache) GetNodeSelector(namespace *kapi.Namespace) string {
51
-	selector := ""
52
-	if len(namespace.ObjectMeta.Annotations) > 0 {
53
-		if ns, ok := namespace.ObjectMeta.Annotations["nodeSelector"]; ok {
54
-			selector = ns
55
-		}
56
-	}
57
-	if len(selector) == 0 {
58
-		selector = p.DefaultNodeSelector
59
-	}
60
-	return selector
61
-}
62
-
63
-func (p *ProjectCache) GetNodeSelectorObject(namespace *kapi.Namespace) (labels.Selector, error) {
64
-	selector := p.GetNodeSelector(namespace)
65
-	if len(selector) == 0 {
66
-		return labels.Everything(), nil
67
-	} else {
68
-		selectorObj, err := labels.Parse(selector)
69
-		if err != nil {
70
-			return nil, err
71
-		}
72
-		return selectorObj, nil
73
-	}
74
-}
75
-
76
-func GetProjectCache() (*ProjectCache, error) {
77
-	if pcache == nil {
78
-		return nil, fmt.Errorf("project cache not initialized")
79
-	}
80
-	return pcache, nil
81
-}
82
-
83
-func RunProjectCache(c client.Interface, defaultNodeSelector string) {
84
-	if pcache != nil {
85
-		return
86
-	}
87
-
88
-	store := cache.NewStore(cache.MetaNamespaceKeyFunc)
89
-	reflector := cache.NewReflector(
90
-		&cache.ListWatch{
91
-			ListFunc: func() (runtime.Object, error) {
92
-				return c.Namespaces().List(labels.Everything(), fields.Everything())
93
-			},
94
-			WatchFunc: func(resourceVersion string) (watch.Interface, error) {
95
-				return c.Namespaces().Watch(labels.Everything(), fields.Everything(), resourceVersion)
96
-			},
97
-		},
98
-		&kapi.Namespace{},
99
-		store,
100
-		0,
101
-	)
102
-	reflector.Run()
103
-	pcache = &ProjectCache{
104
-		Client:              c,
105
-		Store:               store,
106
-		DefaultNodeSelector: defaultNodeSelector,
107
-	}
108
-}
109
-
110
-// Used for testing purpose only
111
-func FakeProjectCache(c client.Interface, store cache.Store, defaultNodeSelector string) {
112
-	pcache = &ProjectCache{
113
-		Client:              c,
114
-		Store:               store,
115
-		DefaultNodeSelector: defaultNodeSelector,
116
-	}
117
-}
118 1
deleted file mode 100644
... ...
@@ -1,68 +0,0 @@
1
-// This is the default algorithm provider for the Origin scheduler.
2
-package defaults
3
-
4
-import (
5
-	kscheduler "github.com/GoogleCloudPlatform/kubernetes/pkg/scheduler"
6
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
7
-	_ "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/algorithmprovider/defaults"
8
-	"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/factory"
9
-
10
-	"github.com/openshift/origin/pkg/scheduler"
11
-)
12
-
13
-func init() {
14
-	defaultPredicates, err := defaultPredicates()
15
-	if err != nil {
16
-		panic(err)
17
-	}
18
-	defaultPriorities, err := defaultPriorities()
19
-	if err != nil {
20
-		panic(err)
21
-	}
22
-	factory.RegisterAlgorithmProvider(scheduler.DefaultProvider, defaultPredicates, defaultPriorities)
23
-
24
-	// Register non-default origin predicates/priorities here
25
-	// factory.RegisterFitPredicateFactory(...)
26
-	// factory.RegisterPriorityConfigFactory(...)
27
-}
28
-
29
-func defaultPredicates() (util.StringSet, error) {
30
-	// Fit is determined by project node label selector query.
31
-	matchProjectNodeSelector := "MatchProjectNodeSelector"
32
-	factory.RegisterFitPredicateFactory(
33
-		matchProjectNodeSelector,
34
-		func(args factory.PluginFactoryArgs) kscheduler.FitPredicate {
35
-			return scheduler.NewProjectSelectorMatchPredicate(args.NodeInfo)
36
-		},
37
-	)
38
-
39
-	// Get predicates from k8s default provider.
40
-	// If we decide not to use all the predicates from k8s default provider,
41
-	// chery-pick individual predicates from <k8s>/plugin/pkg/scheduler/algorithmprovider/defaults/defaults.go
42
-	kprovider, err := factory.GetAlgorithmProvider(factory.DefaultProvider)
43
-	if err != nil {
44
-		return nil, err
45
-	}
46
-
47
-	originDefaultPredicates := kprovider.FitPredicateKeys
48
-	// Add default origin predicates
49
-	originDefaultPredicates.Insert(matchProjectNodeSelector)
50
-
51
-	return originDefaultPredicates, nil
52
-}
53
-
54
-func defaultPriorities() (util.StringSet, error) {
55
-	// Get priority functions from k8s default provider.
56
-	// If we decide not to use all the priority functions from k8s default provider,
57
-	// chery-pick individual priority function from <k8s>/plugin/pkg/scheduler/algorithmprovider/defaults/defaults.go
58
-	kprovider, err := factory.GetAlgorithmProvider(factory.DefaultProvider)
59
-	if err != nil {
60
-		return nil, err
61
-	}
62
-
63
-	OriginDefaultPriorities := kprovider.PriorityFunctionKeys
64
-	// Add default origin priority function keys
65
-	// OriginDefaultPriorities.Insert(...)
66
-
67
-	return OriginDefaultPriorities, nil
68
-}
69 1
deleted file mode 100644
... ...
@@ -1,6 +0,0 @@
1
-// This package is used to register algorithm provider plugins.
2
-package algorithmprovider
3
-
4
-import (
5
-	_ "github.com/openshift/origin/pkg/scheduler/algorithmprovider/defaults"
6
-)
7 1
deleted file mode 100644
... ...
@@ -1,51 +0,0 @@
1
-package algorithmprovider
2
-
3
-import (
4
-	"testing"
5
-
6
-	"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/factory"
7
-
8
-	"github.com/openshift/origin/pkg/scheduler"
9
-)
10
-
11
-var (
12
-	algorithmProviderNames = []string{
13
-		scheduler.DefaultProvider,
14
-	}
15
-)
16
-
17
-func TestDefaultConfigExists(t *testing.T) {
18
-	p, err := factory.GetAlgorithmProvider(scheduler.DefaultProvider)
19
-	if err != nil {
20
-		t.Errorf("error retrieving default provider: %v", err)
21
-	}
22
-	if p == nil {
23
-		t.Error("algorithm provider config should not be nil")
24
-	}
25
-	if len(p.FitPredicateKeys) == 0 {
26
-		t.Error("default algorithm provider shouldn't have 0 fit predicates")
27
-	}
28
-}
29
-
30
-func TestAlgorithmProviders(t *testing.T) {
31
-	for _, pn := range algorithmProviderNames {
32
-		p, err := factory.GetAlgorithmProvider(pn)
33
-		if err != nil {
34
-			t.Errorf("error retrieving '%s' provider: %v", pn, err)
35
-			break
36
-		}
37
-		if len(p.PriorityFunctionKeys) == 0 {
38
-			t.Errorf("%s algorithm provider shouldn't have 0 priority functions", pn)
39
-		}
40
-		for _, pf := range p.PriorityFunctionKeys.List() {
41
-			if !factory.IsPriorityFunctionRegistered(pf) {
42
-				t.Errorf("priority function %s is not registered but is used in the %s algorithm provider", pf, pn)
43
-			}
44
-		}
45
-		for _, fp := range p.FitPredicateKeys.List() {
46
-			if !factory.IsFitPredicateRegistered(fp) {
47
-				t.Errorf("fit predicate %s is not registered but is used in the %s algorithm provider", fp, pn)
48
-			}
49
-		}
50
-	}
51
-}
52 1
deleted file mode 100644
... ...
@@ -1,48 +0,0 @@
1
-package scheduler
2
-
3
-import (
4
-	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
5
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
6
-	kscheduler "github.com/GoogleCloudPlatform/kubernetes/pkg/scheduler"
7
-
8
-	"github.com/openshift/origin/pkg/project/cache"
9
-)
10
-
11
-const (
12
-	DefaultProvider = "OriginDefaultProvider"
13
-)
14
-
15
-func NewProjectSelectorMatchPredicate(info kscheduler.NodeInfo) kscheduler.FitPredicate {
16
-	selector := &projectNodeSelector{
17
-		info: info,
18
-	}
19
-	return selector.ProjectSelectorMatches
20
-}
21
-
22
-type projectNodeSelector struct {
23
-	info kscheduler.NodeInfo
24
-}
25
-
26
-func (p *projectNodeSelector) ProjectSelectorMatches(pod kapi.Pod, existingPods []kapi.Pod, node string) (bool, error) {
27
-	minion, err := p.info.GetNodeInfo(node)
28
-	if err != nil {
29
-		return false, err
30
-	}
31
-	return ProjectMatchesNodeLabels(&pod, minion)
32
-}
33
-
34
-func ProjectMatchesNodeLabels(pod *kapi.Pod, node *kapi.Node) (bool, error) {
35
-	projects, err := cache.GetProjectCache()
36
-	if err != nil {
37
-		return false, err
38
-	}
39
-	namespace, err := projects.GetNamespaceObject(pod.ObjectMeta.Namespace)
40
-	if err != nil {
41
-		return false, err
42
-	}
43
-	selector, err := projects.GetNodeSelectorObject(namespace)
44
-	if err != nil {
45
-		return false, err
46
-	}
47
-	return selector.Matches(labels.Set(node.Labels)), nil
48
-}
49 1
deleted file mode 100644
... ...
@@ -1,90 +0,0 @@
1
-package scheduler
2
-
3
-import (
4
-	"testing"
5
-
6
-	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
7
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache"
8
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/client/testclient"
9
-
10
-	projectcache "github.com/openshift/origin/pkg/project/cache"
11
-)
12
-
13
-type FakeNodeInfo kapi.Node
14
-
15
-func (n FakeNodeInfo) GetNodeInfo(nodeName string) (*kapi.Node, error) {
16
-	node := kapi.Node(n)
17
-	return &node, nil
18
-}
19
-
20
-func TestPodFitsProjectSelector(t *testing.T) {
21
-	mockClient := &testclient.Fake{}
22
-	project := &kapi.Namespace{
23
-		ObjectMeta: kapi.ObjectMeta{
24
-			Name:      "testProject",
25
-			Namespace: "",
26
-		},
27
-	}
28
-	projectStore := cache.NewStore(cache.MetaNamespaceIndexFunc)
29
-	projectStore.Add(project)
30
-
31
-	pod := kapi.Pod{ObjectMeta: kapi.ObjectMeta{Name: "testPod"}}
32
-	node := kapi.Node{ObjectMeta: kapi.ObjectMeta{Name: "testNode"}}
33
-
34
-	tests := []struct {
35
-		defaultNodeSelector string
36
-		projectNodeSelector string
37
-		nodeLabels          map[string]string
38
-		fits                bool
39
-		testName            string
40
-	}{
41
-		{
42
-			defaultNodeSelector: "",
43
-			projectNodeSelector: "",
44
-			nodeLabels:          map[string]string{"infra": "false"},
45
-			fits:                true,
46
-			testName:            "No node selectors",
47
-		},
48
-		{
49
-			defaultNodeSelector: "infra=false",
50
-			projectNodeSelector: "",
51
-			nodeLabels:          map[string]string{"infra": "false"},
52
-			fits:                true,
53
-			testName:            "Matches default node selector",
54
-		},
55
-		{
56
-			defaultNodeSelector: "env=test",
57
-			projectNodeSelector: "",
58
-			nodeLabels:          map[string]string{"infra": "false"},
59
-			fits:                false,
60
-			testName:            "Doesn't match default node selector",
61
-		},
62
-		{
63
-			defaultNodeSelector: "",
64
-			projectNodeSelector: "infra=false",
65
-			nodeLabels:          map[string]string{"infra": "false"},
66
-			fits:                true,
67
-			testName:            "Matches project node selector",
68
-		},
69
-		{
70
-			defaultNodeSelector: "infra=false",
71
-			projectNodeSelector: "env=test",
72
-			nodeLabels:          map[string]string{"infra": "false"},
73
-			fits:                false,
74
-			testName:            "Doesn't match project node selector",
75
-		},
76
-	}
77
-	for _, test := range tests {
78
-		node.ObjectMeta.Labels = test.nodeLabels
79
-		projectcache.FakeProjectCache(mockClient, projectStore, test.defaultNodeSelector)
80
-		project.ObjectMeta.Annotations = map[string]string{"nodeSelector": test.projectNodeSelector}
81
-		predicate := projectNodeSelector{FakeNodeInfo(node)}
82
-		fits, err := predicate.ProjectSelectorMatches(pod, []kapi.Pod{}, "machine")
83
-		if err != nil {
84
-			t.Errorf("unexpected error: %v", err)
85
-		}
86
-		if fits != test.fits {
87
-			t.Errorf("%s: expected: %v got %v", test.testName, test.fits, fits)
88
-		}
89
-	}
90
-}
... ...
@@ -131,8 +131,7 @@ func TestProjectIsNamespace(t *testing.T) {
131 131
 		ObjectMeta: kapi.ObjectMeta{
132 132
 			Name: "new-project",
133 133
 			Annotations: map[string]string{
134
-				"displayName":  "Hello World",
135
-				"nodeSelector": "env=test",
134
+				"displayName": "Hello World",
136 135
 			},
137 136
 		},
138 137
 	}
... ...
@@ -152,9 +151,7 @@ func TestProjectIsNamespace(t *testing.T) {
152 152
 	if project.Annotations["displayName"] != namespace.Annotations["displayName"] {
153 153
 		t.Fatalf("Project display name did not match namespace annotation, project %v, namespace %v", project.Annotations["displayName"], namespace.Annotations["displayName"])
154 154
 	}
155
-	if project.Annotations["nodeSelector"] != namespace.Annotations["nodeSelector"] {
156
-		t.Fatalf("Project node selector did not match namespace node selector, project %v, namespace %v", project.Annotations["nodeSelector"], namespace.Annotations["displayname"])
157
-	}
155
+
158 156
 }
159 157
 
160 158
 // TestProjectMustExist verifies that content cannot be added in a project that does not exist
... ...
@@ -213,4 +210,5 @@ func TestProjectMustExist(t *testing.T) {
213 213
 	if err == nil {
214 214
 		t.Errorf("Expected an error on creation of a Origin resource because namespace does not exist")
215 215
 	}
216
+
216 217
 }