* Change signature of storage.Update in rest to accept
rest.DefaultObjectUpdatedInfo
* Validation now returns []string instead of (bool, string)
* Internal HPA group is now autoscaling, not extensions
* genericapiserver constants moved into genericapiserver/options
* api/errors now returns *StatusError instead of error
* All code accepts unversioned.GroupVersion now
* EncodeToStream became Encode
* Temporarily disable encoding round trippers
... | ... |
@@ -7,7 +7,7 @@ import ( |
7 | 7 |
|
8 | 8 |
kapi "k8s.io/kubernetes/pkg/api" |
9 | 9 |
"k8s.io/kubernetes/pkg/api/meta" |
10 |
- "k8s.io/kubernetes/pkg/apis/extensions" |
|
10 |
+ "k8s.io/kubernetes/pkg/apis/autoscaling" |
|
11 | 11 |
"k8s.io/kubernetes/pkg/kubectl/resource" |
12 | 12 |
"k8s.io/kubernetes/pkg/runtime" |
13 | 13 |
|
... | ... |
@@ -58,7 +58,7 @@ func init() { |
58 | 58 |
if err := RegisterEnsureNode(&kapi.ReplicationController{}, kubegraph.EnsureReplicationControllerNode); err != nil { |
59 | 59 |
panic(err) |
60 | 60 |
} |
61 |
- if err := RegisterEnsureNode(&extensions.HorizontalPodAutoscaler{}, kubegraph.EnsureHorizontalPodAutoscalerNode); err != nil { |
|
61 |
+ if err := RegisterEnsureNode(&autoscaling.HorizontalPodAutoscaler{}, kubegraph.EnsureHorizontalPodAutoscalerNode); err != nil { |
|
62 | 62 |
panic(err) |
63 | 63 |
} |
64 | 64 |
if err := RegisterEnsureNode(&routeapi.Route{}, routegraph.EnsureRouteNode); err != nil { |
... | ... |
@@ -10,27 +10,27 @@ import ( |
10 | 10 |
var NameMayNotBe = []string{".", ".."} |
11 | 11 |
var NameMayNotContain = []string{"/", "%"} |
12 | 12 |
|
13 |
-func MinimalNameRequirements(name string, prefix bool) (bool, string) { |
|
13 |
+func MinimalNameRequirements(name string, prefix bool) []string { |
|
14 | 14 |
for _, illegalName := range NameMayNotBe { |
15 | 15 |
if name == illegalName { |
16 |
- return false, fmt.Sprintf(`name may not be %q`, illegalName) |
|
16 |
+ return []string{fmt.Sprintf(`name may not be %q`, illegalName)} |
|
17 | 17 |
} |
18 | 18 |
} |
19 | 19 |
|
20 | 20 |
for _, illegalContent := range NameMayNotContain { |
21 | 21 |
if strings.Contains(name, illegalContent) { |
22 |
- return false, fmt.Sprintf(`name may not contain %q`, illegalContent) |
|
22 |
+ return []string{fmt.Sprintf(`name may not contain %q`, illegalContent)} |
|
23 | 23 |
} |
24 | 24 |
} |
25 | 25 |
|
26 |
- return true, "" |
|
26 |
+ return nil |
|
27 | 27 |
} |
28 | 28 |
|
29 | 29 |
// GetNameValidationFunc returns a name validation function that includes the standard restrictions we want for all types |
30 | 30 |
func GetNameValidationFunc(nameFunc validation.ValidateNameFunc) validation.ValidateNameFunc { |
31 |
- return func(name string, prefix bool) (bool, string) { |
|
32 |
- if ok, reason := MinimalNameRequirements(name, prefix); !ok { |
|
33 |
- return ok, reason |
|
31 |
+ return func(name string, prefix bool) []string { |
|
32 |
+ if reasons := MinimalNameRequirements(name, prefix); len(reasons) != 0 { |
|
33 |
+ return reasons |
|
34 | 34 |
} |
35 | 35 |
|
36 | 36 |
return nameFunc(name, prefix) |
... | ... |
@@ -35,13 +35,13 @@ func FindHPASpecsMissingCPUTargets(graph osgraph.Graph, namer osgraph.Namer) []o |
35 | 35 |
for _, uncastNode := range graph.NodesByKind(kubenodes.HorizontalPodAutoscalerNodeKind) { |
36 | 36 |
node := uncastNode.(*kubenodes.HorizontalPodAutoscalerNode) |
37 | 37 |
|
38 |
- if node.HorizontalPodAutoscaler.Spec.CPUUtilization == nil { |
|
38 |
+ if node.HorizontalPodAutoscaler.Spec.TargetCPUUtilizationPercentage == nil { |
|
39 | 39 |
markers = append(markers, osgraph.Marker{ |
40 | 40 |
Node: node, |
41 | 41 |
Severity: osgraph.ErrorSeverity, |
42 | 42 |
Key: HPAMissingCPUTargetError, |
43 | 43 |
Message: fmt.Sprintf("%s is missing a CPU utilization target", namer.ResourceName(node)), |
44 |
- Suggestion: osgraph.Suggestion(fmt.Sprintf(`oc patch %s -p '{"spec":{"cpuUtilization":{"targetPercentage": 80}}}'`, namer.ResourceName(node))), |
|
44 |
+ Suggestion: osgraph.Suggestion(fmt.Sprintf(`oc patch %s -p '{"spec":{"targetCPUUtilizationPercentage": 80}}'`, namer.ResourceName(node))), |
|
45 | 45 |
}) |
46 | 46 |
} |
47 | 47 |
} |
... | ... |
@@ -86,8 +86,8 @@ func createMissingScaleRefMarker(hpaNode *kubenodes.HorizontalPodAutoscalerNode, |
86 | 86 |
Key: HPAMissingScaleRefError, |
87 | 87 |
Message: fmt.Sprintf("%s is attempting to scale %s/%s, which doesn't exist", |
88 | 88 |
namer.ResourceName(hpaNode), |
89 |
- hpaNode.HorizontalPodAutoscaler.Spec.ScaleRef.Kind, |
|
90 |
- hpaNode.HorizontalPodAutoscaler.Spec.ScaleRef.Name, |
|
89 |
+ hpaNode.HorizontalPodAutoscaler.Spec.ScaleTargetRef.Kind, |
|
90 |
+ hpaNode.HorizontalPodAutoscaler.Spec.ScaleTargetRef.Name, |
|
91 | 91 |
), |
92 | 92 |
} |
93 | 93 |
} |
... | ... |
@@ -29,7 +29,7 @@ func TestHPAMissingCPUTargetError(t *testing.T) { |
29 | 29 |
t.Errorf("expected marker type %v, got %v", expected, actual) |
30 | 30 |
} |
31 | 31 |
|
32 |
- patchString := `-p '{"spec":{"cpuUtilization":{"targetPercentage": 80}}}'` |
|
32 |
+ patchString := `-p '{"spec":{"targetCPUUtilizationPercentage": 80}}'` |
|
33 | 33 |
if !strings.HasSuffix(string(markers[0].Suggestion), patchString) { |
34 | 34 |
t.Errorf("expected suggestion to end with patch JSON path, got %q", markers[0].Suggestion) |
35 | 35 |
} |
... | ... |
@@ -8,7 +8,7 @@ import ( |
8 | 8 |
|
9 | 9 |
kapi "k8s.io/kubernetes/pkg/api" |
10 | 10 |
_ "k8s.io/kubernetes/pkg/api/install" |
11 |
- "k8s.io/kubernetes/pkg/apis/extensions" |
|
11 |
+ "k8s.io/kubernetes/pkg/apis/autoscaling" |
|
12 | 12 |
"k8s.io/kubernetes/pkg/runtime" |
13 | 13 |
|
14 | 14 |
osgraph "github.com/openshift/origin/pkg/api/graph" |
... | ... |
@@ -130,11 +130,11 @@ func TestSecretEdges(t *testing.T) { |
130 | 130 |
} |
131 | 131 |
|
132 | 132 |
func TestHPARCEdges(t *testing.T) { |
133 |
- hpa := &extensions.HorizontalPodAutoscaler{} |
|
133 |
+ hpa := &autoscaling.HorizontalPodAutoscaler{} |
|
134 | 134 |
hpa.Namespace = "test-ns" |
135 | 135 |
hpa.Name = "test-hpa" |
136 |
- hpa.Spec = extensions.HorizontalPodAutoscalerSpec{ |
|
137 |
- ScaleRef: extensions.SubresourceReference{ |
|
136 |
+ hpa.Spec = autoscaling.HorizontalPodAutoscalerSpec{ |
|
137 |
+ ScaleTargetRef: autoscaling.CrossVersionObjectReference{ |
|
138 | 138 |
Name: "test-rc", |
139 | 139 |
Kind: "ReplicationController", |
140 | 140 |
}, |
... | ... |
@@ -160,11 +160,11 @@ func TestHPARCEdges(t *testing.T) { |
160 | 160 |
} |
161 | 161 |
|
162 | 162 |
func TestHPADCEdges(t *testing.T) { |
163 |
- hpa := &extensions.HorizontalPodAutoscaler{} |
|
163 |
+ hpa := &autoscaling.HorizontalPodAutoscaler{} |
|
164 | 164 |
hpa.Namespace = "test-ns" |
165 | 165 |
hpa.Name = "test-hpa" |
166 |
- hpa.Spec = extensions.HorizontalPodAutoscalerSpec{ |
|
167 |
- ScaleRef: extensions.SubresourceReference{ |
|
166 |
+ hpa.Spec = autoscaling.HorizontalPodAutoscalerSpec{ |
|
167 |
+ ScaleTargetRef: autoscaling.CrossVersionObjectReference{ |
|
168 | 168 |
Name: "test-dc", |
169 | 169 |
Kind: "DeploymentConfig", |
170 | 170 |
}, |
... | ... |
@@ -211,13 +211,13 @@ func AddHPAScaleRefEdges(g osgraph.Graph) { |
211 | 211 |
hpaNode := node.(*kubegraph.HorizontalPodAutoscalerNode) |
212 | 212 |
|
213 | 213 |
syntheticMeta := kapi.ObjectMeta{ |
214 |
- Name: hpaNode.HorizontalPodAutoscaler.Spec.ScaleRef.Name, |
|
214 |
+ Name: hpaNode.HorizontalPodAutoscaler.Spec.ScaleTargetRef.Name, |
|
215 | 215 |
Namespace: hpaNode.HorizontalPodAutoscaler.Namespace, |
216 | 216 |
} |
217 | 217 |
|
218 | 218 |
var groupVersionResource unversioned.GroupVersionResource |
219 |
- resource := strings.ToLower(hpaNode.HorizontalPodAutoscaler.Spec.ScaleRef.Kind) |
|
220 |
- if groupVersion, err := unversioned.ParseGroupVersion(hpaNode.HorizontalPodAutoscaler.Spec.ScaleRef.APIVersion); err == nil { |
|
219 |
+ resource := strings.ToLower(hpaNode.HorizontalPodAutoscaler.Spec.ScaleTargetRef.Kind) |
|
220 |
+ if groupVersion, err := unversioned.ParseGroupVersion(hpaNode.HorizontalPodAutoscaler.Spec.ScaleTargetRef.APIVersion); err == nil { |
|
221 | 221 |
groupVersionResource = groupVersion.WithResource(resource) |
222 | 222 |
} else { |
223 | 223 |
groupVersionResource = unversioned.GroupVersionResource{Resource: resource} |
... | ... |
@@ -4,7 +4,7 @@ import ( |
4 | 4 |
"github.com/gonum/graph" |
5 | 5 |
|
6 | 6 |
kapi "k8s.io/kubernetes/pkg/api" |
7 |
- "k8s.io/kubernetes/pkg/apis/extensions" |
|
7 |
+ "k8s.io/kubernetes/pkg/apis/autoscaling" |
|
8 | 8 |
|
9 | 9 |
osgraph "github.com/openshift/origin/pkg/api/graph" |
10 | 10 |
) |
... | ... |
@@ -146,7 +146,7 @@ func EnsurePodTemplateSpecNode(g osgraph.MutableUniqueGraph, ptSpec *kapi.PodTem |
146 | 146 |
return ptSpecNode |
147 | 147 |
} |
148 | 148 |
|
149 |
-func EnsureHorizontalPodAutoscalerNode(g osgraph.MutableUniqueGraph, hpa *extensions.HorizontalPodAutoscaler) *HorizontalPodAutoscalerNode { |
|
149 |
+func EnsureHorizontalPodAutoscalerNode(g osgraph.MutableUniqueGraph, hpa *autoscaling.HorizontalPodAutoscaler) *HorizontalPodAutoscalerNode { |
|
150 | 150 |
return osgraph.EnsureUnique(g, |
151 | 151 |
HorizontalPodAutoscalerNodeName(hpa), |
152 | 152 |
func(node osgraph.Node) graph.Node { |
... | ... |
@@ -5,7 +5,7 @@ import ( |
5 | 5 |
"reflect" |
6 | 6 |
|
7 | 7 |
kapi "k8s.io/kubernetes/pkg/api" |
8 |
- "k8s.io/kubernetes/pkg/apis/extensions" |
|
8 |
+ "k8s.io/kubernetes/pkg/apis/autoscaling" |
|
9 | 9 |
|
10 | 10 |
osgraph "github.com/openshift/origin/pkg/api/graph" |
11 | 11 |
) |
... | ... |
@@ -19,7 +19,7 @@ var ( |
19 | 19 |
ReplicationControllerSpecNodeKind = reflect.TypeOf(kapi.ReplicationControllerSpec{}).Name() |
20 | 20 |
ServiceAccountNodeKind = reflect.TypeOf(kapi.ServiceAccount{}).Name() |
21 | 21 |
SecretNodeKind = reflect.TypeOf(kapi.Secret{}).Name() |
22 |
- HorizontalPodAutoscalerNodeKind = reflect.TypeOf(extensions.HorizontalPodAutoscaler{}).Name() |
|
22 |
+ HorizontalPodAutoscalerNodeKind = reflect.TypeOf(autoscaling.HorizontalPodAutoscaler{}).Name() |
|
23 | 23 |
) |
24 | 24 |
|
25 | 25 |
func ServiceNodeName(o *kapi.Service) osgraph.UniqueName { |
... | ... |
@@ -243,13 +243,13 @@ func (*SecretNode) Kind() string { |
243 | 243 |
return SecretNodeKind |
244 | 244 |
} |
245 | 245 |
|
246 |
-func HorizontalPodAutoscalerNodeName(o *extensions.HorizontalPodAutoscaler) osgraph.UniqueName { |
|
246 |
+func HorizontalPodAutoscalerNodeName(o *autoscaling.HorizontalPodAutoscaler) osgraph.UniqueName { |
|
247 | 247 |
return osgraph.GetUniqueRuntimeObjectNodeName(HorizontalPodAutoscalerNodeKind, o) |
248 | 248 |
} |
249 | 249 |
|
250 | 250 |
type HorizontalPodAutoscalerNode struct { |
251 | 251 |
osgraph.Node |
252 |
- HorizontalPodAutoscaler *extensions.HorizontalPodAutoscaler |
|
252 |
+ HorizontalPodAutoscaler *autoscaling.HorizontalPodAutoscaler |
|
253 | 253 |
} |
254 | 254 |
|
255 | 255 |
func (n HorizontalPodAutoscalerNode) Object() interface{} { |
... | ... |
@@ -151,6 +151,14 @@ func (d *discoveryRESTMapper) RESTMapping(gk unversioned.GroupKind, versions ... |
151 | 151 |
return delegate.RESTMapping(gk, versions...) |
152 | 152 |
} |
153 | 153 |
|
154 |
+func (d *discoveryRESTMapper) RESTMappings(gk unversioned.GroupKind) ([]*meta.RESTMapping, error) { |
|
155 |
+ delegate, err := d.getDelegate() |
|
156 |
+ if err != nil { |
|
157 |
+ return nil, err |
|
158 |
+ } |
|
159 |
+ return delegate.RESTMappings(gk) |
|
160 |
+} |
|
161 |
+ |
|
154 | 162 |
func (d *discoveryRESTMapper) AliasesForResource(resource string) ([]string, bool) { |
155 | 163 |
delegate, err := d.getDelegate() |
156 | 164 |
if err != nil { |
... | ... |
@@ -32,6 +32,7 @@ import ( |
32 | 32 |
quotaapi "github.com/openshift/origin/pkg/quota/api" |
33 | 33 |
quotaapiv1 "github.com/openshift/origin/pkg/quota/api/v1" |
34 | 34 |
route "github.com/openshift/origin/pkg/route/api" |
35 |
+ securityapi "github.com/openshift/origin/pkg/security/api" |
|
35 | 36 |
template "github.com/openshift/origin/pkg/template/api" |
36 | 37 |
uservalidation "github.com/openshift/origin/pkg/user/api/validation" |
37 | 38 |
|
... | ... |
@@ -65,21 +66,21 @@ func fuzzInternalObject(t *testing.T, forVersion unversioned.GroupVersion, item |
65 | 65 |
switch j.Subjects[i].Kind { |
66 | 66 |
case authorizationapi.UserKind: |
67 | 67 |
j.Subjects[i].Namespace = "" |
68 |
- if valid, _ := uservalidation.ValidateUserName(j.Subjects[i].Name, false); !valid { |
|
68 |
+ if len(uservalidation.ValidateUserName(j.Subjects[i].Name, false)) != 0 { |
|
69 | 69 |
j.Subjects[i].Name = fmt.Sprintf("validusername%d", i) |
70 | 70 |
} |
71 | 71 |
|
72 | 72 |
case authorizationapi.GroupKind: |
73 | 73 |
j.Subjects[i].Namespace = "" |
74 |
- if valid, _ := uservalidation.ValidateGroupName(j.Subjects[i].Name, false); !valid { |
|
74 |
+ if len(uservalidation.ValidateGroupName(j.Subjects[i].Name, false)) != 0 { |
|
75 | 75 |
j.Subjects[i].Name = fmt.Sprintf("validgroupname%d", i) |
76 | 76 |
} |
77 | 77 |
|
78 | 78 |
case authorizationapi.ServiceAccountKind: |
79 |
- if valid, _ := validation.ValidateNamespaceName(j.Subjects[i].Namespace, false); !valid { |
|
79 |
+ if len(validation.ValidateNamespaceName(j.Subjects[i].Namespace, false)) != 0 { |
|
80 | 80 |
j.Subjects[i].Namespace = fmt.Sprintf("sanamespacehere%d", i) |
81 | 81 |
} |
82 |
- if valid, _ := validation.ValidateServiceAccountName(j.Subjects[i].Name, false); !valid { |
|
82 |
+ if len(validation.ValidateServiceAccountName(j.Subjects[i].Name, false)) != 0 { |
|
83 | 83 |
j.Subjects[i].Name = fmt.Sprintf("sanamehere%d", i) |
84 | 84 |
} |
85 | 85 |
|
... | ... |
@@ -110,21 +111,21 @@ func fuzzInternalObject(t *testing.T, forVersion unversioned.GroupVersion, item |
110 | 110 |
switch j.Subjects[i].Kind { |
111 | 111 |
case authorizationapi.UserKind: |
112 | 112 |
j.Subjects[i].Namespace = "" |
113 |
- if valid, _ := uservalidation.ValidateUserName(j.Subjects[i].Name, false); !valid { |
|
113 |
+ if len(uservalidation.ValidateUserName(j.Subjects[i].Name, false)) != 0 { |
|
114 | 114 |
j.Subjects[i].Name = fmt.Sprintf("validusername%d", i) |
115 | 115 |
} |
116 | 116 |
|
117 | 117 |
case authorizationapi.GroupKind: |
118 | 118 |
j.Subjects[i].Namespace = "" |
119 |
- if valid, _ := uservalidation.ValidateGroupName(j.Subjects[i].Name, false); !valid { |
|
119 |
+ if len(uservalidation.ValidateGroupName(j.Subjects[i].Name, false)) != 0 { |
|
120 | 120 |
j.Subjects[i].Name = fmt.Sprintf("validgroupname%d", i) |
121 | 121 |
} |
122 | 122 |
|
123 | 123 |
case authorizationapi.ServiceAccountKind: |
124 |
- if valid, _ := validation.ValidateNamespaceName(j.Subjects[i].Namespace, false); !valid { |
|
124 |
+ if len(validation.ValidateNamespaceName(j.Subjects[i].Namespace, false)) != 0 { |
|
125 | 125 |
j.Subjects[i].Namespace = fmt.Sprintf("sanamespacehere%d", i) |
126 | 126 |
} |
127 |
- if valid, _ := validation.ValidateServiceAccountName(j.Subjects[i].Name, false); !valid { |
|
127 |
+ if len(validation.ValidateServiceAccountName(j.Subjects[i].Name, false)) != 0 { |
|
128 | 128 |
j.Subjects[i].Name = fmt.Sprintf("sanamehere%d", i) |
129 | 129 |
} |
130 | 130 |
|
... | ... |
@@ -340,6 +341,27 @@ func fuzzInternalObject(t *testing.T, forVersion unversioned.GroupVersion, item |
340 | 340 |
j.From.Kind = "DockerImage" |
341 | 341 |
j.From.Name = specs[c.Intn(len(specs))] |
342 | 342 |
}, |
343 |
+ |
|
344 |
+ // TODO: uncomment when round tripping for init containers is available (the annotation is |
|
345 |
+ // not supported on security context review for now) |
|
346 |
+ func(j *securityapi.PodSecurityPolicyReview, c fuzz.Continue) { |
|
347 |
+ c.FuzzNoCustom(j) |
|
348 |
+ j.Spec.PodSpec.InitContainers = nil |
|
349 |
+ for i := range j.Status.AllowedServiceAccounts { |
|
350 |
+ j.Status.AllowedServiceAccounts[i].PodSpec.InitContainers = nil |
|
351 |
+ } |
|
352 |
+ }, |
|
353 |
+ func(j *securityapi.PodSecurityPolicySelfSubjectReview, c fuzz.Continue) { |
|
354 |
+ c.FuzzNoCustom(j) |
|
355 |
+ j.Spec.PodSpec.InitContainers = nil |
|
356 |
+ j.Status.PodSpec.InitContainers = nil |
|
357 |
+ }, |
|
358 |
+ func(j *securityapi.PodSecurityPolicySubjectReview, c fuzz.Continue) { |
|
359 |
+ c.FuzzNoCustom(j) |
|
360 |
+ j.Spec.PodSpec.InitContainers = nil |
|
361 |
+ j.Status.PodSpec.InitContainers = nil |
|
362 |
+ }, |
|
363 |
+ |
|
343 | 364 |
func(j *runtime.Object, c fuzz.Continue) { |
344 | 365 |
// runtime.EmbeddedObject causes a panic inside of fuzz because runtime.Object isn't handled. |
345 | 366 |
}, |
... | ... |
@@ -420,7 +442,7 @@ func roundTrip(t *testing.T, codec runtime.Codec, originalItem runtime.Object) { |
420 | 420 |
} |
421 | 421 |
|
422 | 422 |
if !kapi.Semantic.DeepEqual(originalItem, obj2) { |
423 |
- t.Errorf("1: %v: diff: %v\nCodec: %v\nData: %s\nSource: %s", name, diff.ObjectDiff(originalItem, obj2), codec, string(data), diff.ObjectGoPrintSideBySide(originalItem, obj2)) |
|
423 |
+ t.Errorf("1: %v: diff: %v\nCodec: %v\nData: %s", name, diff.ObjectReflectDiff(originalItem, obj2), codec, string(data)) |
|
424 | 424 |
return |
425 | 425 |
} |
426 | 426 |
|
... | ... |
@@ -430,7 +452,7 @@ func roundTrip(t *testing.T, codec runtime.Codec, originalItem runtime.Object) { |
430 | 430 |
return |
431 | 431 |
} |
432 | 432 |
if !kapi.Semantic.DeepEqual(originalItem, obj3) { |
433 |
- t.Errorf("3: %v: diff: %v\nCodec: %v", name, diff.ObjectDiff(originalItem, obj3), codec) |
|
433 |
+ t.Errorf("3: %v: diff: %v\nCodec: %v", name, diff.ObjectReflectDiff(originalItem, obj3), codec) |
|
434 | 434 |
return |
435 | 435 |
} |
436 | 436 |
} |
... | ... |
@@ -457,14 +479,14 @@ func TestSpecificKind(t *testing.T) { |
457 | 457 |
} |
458 | 458 |
seed := int64(2703387474910584091) //rand.Int63() |
459 | 459 |
for i := 0; i < fuzzIters; i++ { |
460 |
- t.Logf(`About to test %v with "v1"`, kind) |
|
460 |
+ //t.Logf(`About to test %v with "v1"`, kind) |
|
461 | 461 |
fuzzInternalObject(t, v1.SchemeGroupVersion, item, seed) |
462 | 462 |
roundTrip(t, kapi.Codecs.LegacyCodec(v1.SchemeGroupVersion), item) |
463 | 463 |
} |
464 | 464 |
} |
465 | 465 |
|
466 | 466 |
// Keep this in sync with the respective upstream set |
467 |
-var nonInternalRoundTrippableTypes = sets.NewString("List", "ListOptions") |
|
467 |
+var nonInternalRoundTrippableTypes = sets.NewString("List", "ListOptions", "WatchEvent") |
|
468 | 468 |
|
469 | 469 |
// TestTypes will try to roundtrip all OpenShift and Kubernetes stable api types |
470 | 470 |
func TestTypes(t *testing.T) { |
... | ... |
@@ -497,13 +519,13 @@ func TestTypes(t *testing.T) { |
497 | 497 |
|
498 | 498 |
if versions, ok := skipStandardVersions[kind]; ok { |
499 | 499 |
for _, v := range versions { |
500 |
- t.Logf("About to test %v with %q", kind, v) |
|
500 |
+ //t.Logf("About to test %v with %q", kind, v) |
|
501 | 501 |
fuzzInternalObject(t, v, item, seed) |
502 | 502 |
roundTrip(t, kapi.Codecs.LegacyCodec(v), item) |
503 | 503 |
} |
504 | 504 |
continue |
505 | 505 |
} |
506 |
- t.Logf(`About to test %v with "v1"`, kind) |
|
506 |
+ //t.Logf(`About to test %v with "v1"`, kind) |
|
507 | 507 |
fuzzInternalObject(t, externalVersion, item, seed) |
508 | 508 |
roundTrip(t, kapi.Codecs.LegacyCodec(externalVersion), item) |
509 | 509 |
} |
... | ... |
@@ -122,12 +122,12 @@ func (v *RuntimeObjectsValidator) getSpecificValidationInfo(obj runtime.Object) |
122 | 122 |
} |
123 | 123 |
|
124 | 124 |
func GetRequiresNamespace(obj runtime.Object) (bool, error) { |
125 |
- groupVersionKind, err := kapi.Scheme.ObjectKind(obj) |
|
125 |
+ groupVersionKinds, _, err := kapi.Scheme.ObjectKinds(obj) |
|
126 | 126 |
if err != nil { |
127 | 127 |
return false, err |
128 | 128 |
} |
129 | 129 |
|
130 |
- restMapping, err := kapi.RESTMapper.RESTMapping(groupVersionKind.GroupKind()) |
|
130 |
+ restMapping, err := kapi.RESTMapper.RESTMapping(groupVersionKinds[0].GroupKind()) |
|
131 | 131 |
if err != nil { |
132 | 132 |
return false, err |
133 | 133 |
} |
... | ... |
@@ -3,6 +3,7 @@ package validation |
3 | 3 |
import ( |
4 | 4 |
"fmt" |
5 | 5 |
"reflect" |
6 |
+ "strings" |
|
6 | 7 |
"testing" |
7 | 8 |
|
8 | 9 |
kapi "k8s.io/kubernetes/pkg/api" |
... | ... |
@@ -39,6 +40,8 @@ func TestNilPath(t *testing.T) { |
39 | 39 |
} |
40 | 40 |
|
41 | 41 |
func TestNameFunc(t *testing.T) { |
42 |
+ const nameRulesMessage = `must match the regex [a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)* (e.g. 'example.com')` |
|
43 |
+ |
|
42 | 44 |
for apiType, validationInfo := range Validator.typeToValidator { |
43 | 45 |
if !validationInfo.HasObjectMeta { |
44 | 46 |
continue |
... | ... |
@@ -52,7 +55,8 @@ func TestNameFunc(t *testing.T) { |
52 | 52 |
apiObjectMeta.Set(reflect.ValueOf(kapi.ObjectMeta{Name: illegalName})) |
53 | 53 |
|
54 | 54 |
errList := validationInfo.Validator.Validate(apiValue.Interface().(runtime.Object)) |
55 |
- _, requiredMessage := api.MinimalNameRequirements(illegalName, false) |
|
55 |
+ reasons := api.MinimalNameRequirements(illegalName, false) |
|
56 |
+ requiredMessage := strings.Join(reasons, ", ") |
|
56 | 57 |
|
57 | 58 |
if len(errList) == 0 { |
58 | 59 |
t.Errorf("expected error for %v in %v not found amongst %v. You probably need to add api.MinimalNameRequirements to your name validator..", illegalName, apiType.Elem(), errList) |
... | ... |
@@ -65,13 +69,12 @@ func TestNameFunc(t *testing.T) { |
65 | 65 |
if validationError.Type != field.ErrorTypeInvalid || validationError.Field != "metadata.name" { |
66 | 66 |
continue |
67 | 67 |
} |
68 |
- |
|
69 | 68 |
if validationError.Detail == requiredMessage { |
70 | 69 |
foundExpectedError = true |
71 | 70 |
break |
72 | 71 |
} |
73 | 72 |
// this message is from a stock name validation method in kube that covers our requirements in MinimalNameRequirements |
74 |
- if validationError.Detail == validation.DNSSubdomainErrorMsg { |
|
73 |
+ if validationError.Detail == nameRulesMessage { |
|
75 | 74 |
foundExpectedError = true |
76 | 75 |
break |
77 | 76 |
} |
... | ... |
@@ -89,7 +92,8 @@ func TestNameFunc(t *testing.T) { |
89 | 89 |
apiObjectMeta.Set(reflect.ValueOf(kapi.ObjectMeta{Name: illegalName})) |
90 | 90 |
|
91 | 91 |
errList := validationInfo.Validator.Validate(apiValue.Interface().(runtime.Object)) |
92 |
- _, requiredMessage := api.MinimalNameRequirements(illegalName, false) |
|
92 |
+ reasons := api.MinimalNameRequirements(illegalName, false) |
|
93 |
+ requiredMessage := strings.Join(reasons, ", ") |
|
93 | 94 |
|
94 | 95 |
if len(errList) == 0 { |
95 | 96 |
t.Errorf("expected error for %v in %v not found amongst %v. You probably need to add api.MinimalNameRequirements to your name validator.", illegalName, apiType.Elem(), errList) |
... | ... |
@@ -107,7 +111,8 @@ func TestNameFunc(t *testing.T) { |
107 | 107 |
foundExpectedError = true |
108 | 108 |
break |
109 | 109 |
} |
110 |
- if validationError.Detail == validation.DNSSubdomainErrorMsg { |
|
110 |
+ // this message is from a stock name validation method in kube that covers our requirements in MinimalNameRequirements |
|
111 |
+ if validationError.Detail == nameRulesMessage { |
|
111 | 112 |
foundExpectedError = true |
112 | 113 |
break |
113 | 114 |
} |
... | ... |
@@ -165,7 +165,7 @@ func BuildSubjects(users, groups []string, userNameValidator, groupNameValidator |
165 | 165 |
} |
166 | 166 |
|
167 | 167 |
kind := UserKind |
168 |
- if valid, _ := userNameValidator(user, false); !valid { |
|
168 |
+ if len(userNameValidator(user, false)) != 0 { |
|
169 | 169 |
kind = SystemUserKind |
170 | 170 |
} |
171 | 171 |
|
... | ... |
@@ -174,7 +174,7 @@ func BuildSubjects(users, groups []string, userNameValidator, groupNameValidator |
174 | 174 |
|
175 | 175 |
for _, group := range groups { |
176 | 176 |
kind := GroupKind |
177 |
- if valid, _ := groupNameValidator(group, false); !valid { |
|
177 |
+ if len(groupNameValidator(group, false)) != 0 { |
|
178 | 178 |
kind = SystemGroupKind |
179 | 179 |
} |
180 | 180 |
|
... | ... |
@@ -2,6 +2,7 @@ package validation |
2 | 2 |
|
3 | 3 |
import ( |
4 | 4 |
"fmt" |
5 |
+ "strings" |
|
5 | 6 |
|
6 | 7 |
kapi "k8s.io/kubernetes/pkg/api" |
7 | 8 |
"k8s.io/kubernetes/pkg/api/validation" |
... | ... |
@@ -69,16 +70,16 @@ func ValidateLocalResourceAccessReview(review *authorizationapi.LocalResourceAcc |
69 | 69 |
return allErrs |
70 | 70 |
} |
71 | 71 |
|
72 |
-func ValidatePolicyName(name string, prefix bool) (bool, string) { |
|
73 |
- if ok, reason := oapi.MinimalNameRequirements(name, prefix); !ok { |
|
74 |
- return ok, reason |
|
72 |
+func ValidatePolicyName(name string, prefix bool) []string { |
|
73 |
+ if reasons := oapi.MinimalNameRequirements(name, prefix); len(reasons) != 0 { |
|
74 |
+ return reasons |
|
75 | 75 |
} |
76 | 76 |
|
77 | 77 |
if name != authorizationapi.PolicyName { |
78 |
- return false, "name must be " + authorizationapi.PolicyName |
|
78 |
+ return []string{"name must be " + authorizationapi.PolicyName} |
|
79 | 79 |
} |
80 | 80 |
|
81 |
- return true, "" |
|
81 |
+ return nil |
|
82 | 82 |
} |
83 | 83 |
|
84 | 84 |
func ValidateLocalPolicy(policy *authorizationapi.Policy) field.ErrorList { |
... | ... |
@@ -125,16 +126,16 @@ func ValidatePolicyUpdate(policy *authorizationapi.Policy, oldPolicy *authorizat |
125 | 125 |
} |
126 | 126 |
|
127 | 127 |
func PolicyBindingNameValidator(policyRefNamespace string) validation.ValidateNameFunc { |
128 |
- return func(name string, prefix bool) (bool, string) { |
|
129 |
- if ok, reason := oapi.MinimalNameRequirements(name, prefix); !ok { |
|
130 |
- return ok, reason |
|
128 |
+ return func(name string, prefix bool) []string { |
|
129 |
+ if reasons := oapi.MinimalNameRequirements(name, prefix); len(reasons) != 0 { |
|
130 |
+ return reasons |
|
131 | 131 |
} |
132 | 132 |
|
133 | 133 |
if name != authorizationapi.GetPolicyBindingName(policyRefNamespace) { |
134 |
- return false, "name must be " + authorizationapi.GetPolicyBindingName(policyRefNamespace) |
|
134 |
+ return []string{"name must be " + authorizationapi.GetPolicyBindingName(policyRefNamespace)} |
|
135 | 135 |
} |
136 | 136 |
|
137 |
- return true, "" |
|
137 |
+ return nil |
|
138 | 138 |
} |
139 | 139 |
} |
140 | 140 |
|
... | ... |
@@ -251,15 +252,15 @@ func validateRoleBinding(roleBinding *authorizationapi.RoleBinding, isNamespaced |
251 | 251 |
allErrs = append(allErrs, validation.ValidateObjectMeta(&roleBinding.ObjectMeta, isNamespaced, oapi.MinimalNameRequirements, fldPath.Child("metadata"))...) |
252 | 252 |
|
253 | 253 |
// roleRef namespace is empty when referring to global policy. |
254 |
- if (len(roleBinding.RoleRef.Namespace) > 0) && !kvalidation.IsDNS1123Subdomain(roleBinding.RoleRef.Namespace) { |
|
254 |
+ if (len(roleBinding.RoleRef.Namespace) > 0) && len(kvalidation.IsDNS1123Subdomain(roleBinding.RoleRef.Namespace)) != 0 { |
|
255 | 255 |
allErrs = append(allErrs, field.Invalid(fldPath.Child("roleRef", "namespace"), roleBinding.RoleRef.Namespace, "roleRef.namespace must be a valid subdomain")) |
256 | 256 |
} |
257 | 257 |
|
258 | 258 |
if len(roleBinding.RoleRef.Name) == 0 { |
259 | 259 |
allErrs = append(allErrs, field.Required(fldPath.Child("roleRef", "name"), "")) |
260 | 260 |
} else { |
261 |
- if valid, err := oapi.MinimalNameRequirements(roleBinding.RoleRef.Name, false); !valid { |
|
262 |
- allErrs = append(allErrs, field.Invalid(fldPath.Child("roleRef", "name"), roleBinding.RoleRef.Name, err)) |
|
261 |
+ if reasons := oapi.MinimalNameRequirements(roleBinding.RoleRef.Name, false); len(reasons) != 0 { |
|
262 |
+ allErrs = append(allErrs, field.Invalid(fldPath.Child("roleRef", "name"), roleBinding.RoleRef.Name, strings.Join(reasons, ", "))) |
|
263 | 263 |
} |
264 | 264 |
} |
265 | 265 |
|
... | ... |
@@ -292,32 +293,32 @@ func validateRoleBindingSubject(subject kapi.ObjectReference, isNamespaced bool, |
292 | 292 |
|
293 | 293 |
switch subject.Kind { |
294 | 294 |
case authorizationapi.ServiceAccountKind: |
295 |
- if valid, reason := validation.ValidateServiceAccountName(subject.Name, false); len(subject.Name) > 0 && !valid { |
|
296 |
- allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), subject.Name, reason)) |
|
295 |
+ if reasons := validation.ValidateServiceAccountName(subject.Name, false); len(subject.Name) > 0 && len(reasons) != 0 { |
|
296 |
+ allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), subject.Name, strings.Join(reasons, ", "))) |
|
297 | 297 |
} |
298 | 298 |
if !isNamespaced && len(subject.Namespace) == 0 { |
299 | 299 |
allErrs = append(allErrs, field.Required(fldPath.Child("namespace"), "")) |
300 | 300 |
} |
301 | 301 |
|
302 | 302 |
case authorizationapi.UserKind: |
303 |
- if valid, reason := uservalidation.ValidateUserName(subject.Name, false); len(subject.Name) > 0 && !valid { |
|
304 |
- allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), subject.Name, reason)) |
|
303 |
+ if reasons := uservalidation.ValidateUserName(subject.Name, false); len(subject.Name) > 0 && len(reasons) != 0 { |
|
304 |
+ allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), subject.Name, strings.Join(reasons, ", "))) |
|
305 | 305 |
} |
306 | 306 |
|
307 | 307 |
case authorizationapi.GroupKind: |
308 |
- if valid, reason := uservalidation.ValidateGroupName(subject.Name, false); len(subject.Name) > 0 && !valid { |
|
309 |
- allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), subject.Name, reason)) |
|
308 |
+ if reasons := uservalidation.ValidateGroupName(subject.Name, false); len(subject.Name) > 0 && len(reasons) != 0 { |
|
309 |
+ allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), subject.Name, strings.Join(reasons, ", "))) |
|
310 | 310 |
} |
311 | 311 |
|
312 | 312 |
case authorizationapi.SystemUserKind: |
313 |
- isValidSAName, _ := validation.ValidateServiceAccountName(subject.Name, false) |
|
314 |
- isValidUserName, _ := uservalidation.ValidateUserName(subject.Name, false) |
|
313 |
+ isValidSAName := len(validation.ValidateServiceAccountName(subject.Name, false)) == 0 |
|
314 |
+ isValidUserName := len(uservalidation.ValidateUserName(subject.Name, false)) == 0 |
|
315 | 315 |
if isValidSAName || isValidUserName { |
316 | 316 |
allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), subject.Name, "conforms to User.name or ServiceAccount.name restrictions")) |
317 | 317 |
} |
318 | 318 |
|
319 | 319 |
case authorizationapi.SystemGroupKind: |
320 |
- if valid, _ := uservalidation.ValidateGroupName(subject.Name, false); len(subject.Name) > 0 && valid { |
|
320 |
+ if reasons := uservalidation.ValidateGroupName(subject.Name, false); len(subject.Name) > 0 && len(reasons) == 0 { |
|
321 | 321 |
allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), subject.Name, "conforms to Group.name restrictions")) |
322 | 322 |
} |
323 | 323 |
|
... | ... |
@@ -243,6 +243,9 @@ func (e clusterRoleEvaluator) ResolveRules(scope, namespace string, clusterPolic |
243 | 243 |
return rules, nil |
244 | 244 |
} |
245 | 245 |
|
246 |
+// TODO: direct deep copy needing a cloner is something that should be fixed upstream |
|
247 |
+var localCloner = conversion.NewCloner() |
|
248 |
+ |
|
246 | 249 |
// removeEscalatingResources inspects a PolicyRule and removes any references to escalating resources. |
247 | 250 |
// It has coarse logic for now. It is possible to rewrite one rule into many for the finest grain control |
248 | 251 |
// but removing the entire matching resource regardless of verb or secondary group is cheaper, easier, and errs on the side removing |
... | ... |
@@ -260,7 +263,7 @@ func removeEscalatingResources(in authorizationapi.PolicyRule) authorizationapi. |
260 | 260 |
// we're using a cache of cache of an object that uses pointers to data. I'm pretty sure we need to do a copy to avoid |
261 | 261 |
// muddying the cache |
262 | 262 |
ruleCopy = &authorizationapi.PolicyRule{} |
263 |
- authorizationapi.DeepCopy_api_PolicyRule(in, ruleCopy, nil) |
|
263 |
+ authorizationapi.DeepCopy_api_PolicyRule(in, ruleCopy, localCloner) |
|
264 | 264 |
} |
265 | 265 |
|
266 | 266 |
ruleCopy.Resources.Delete(resource.Resource) |
... | ... |
@@ -59,13 +59,13 @@ func (s *storage) ListClusterPolicies(ctx kapi.Context, options *kapi.ListOption |
59 | 59 |
return obj.(*authorizationapi.ClusterPolicyList), nil |
60 | 60 |
} |
61 | 61 |
|
62 |
-func (s *storage) CreateClusterPolicy(ctx kapi.Context, node *authorizationapi.ClusterPolicy) error { |
|
63 |
- _, err := s.Create(ctx, node) |
|
62 |
+func (s *storage) CreateClusterPolicy(ctx kapi.Context, policy *authorizationapi.ClusterPolicy) error { |
|
63 |
+ _, err := s.Create(ctx, policy) |
|
64 | 64 |
return err |
65 | 65 |
} |
66 | 66 |
|
67 |
-func (s *storage) UpdateClusterPolicy(ctx kapi.Context, node *authorizationapi.ClusterPolicy) error { |
|
68 |
- _, _, err := s.Update(ctx, node) |
|
67 |
+func (s *storage) UpdateClusterPolicy(ctx kapi.Context, policy *authorizationapi.ClusterPolicy) error { |
|
68 |
+ _, _, err := s.Update(ctx, policy.Name, rest.DefaultUpdatedObjectInfo(policy, kapi.Scheme)) |
|
69 | 69 |
return err |
70 | 70 |
} |
71 | 71 |
|
... | ... |
@@ -65,7 +65,7 @@ func (s *storage) CreateClusterPolicyBinding(ctx kapi.Context, policyBinding *au |
65 | 65 |
} |
66 | 66 |
|
67 | 67 |
func (s *storage) UpdateClusterPolicyBinding(ctx kapi.Context, policyBinding *authorizationapi.ClusterPolicyBinding) error { |
68 |
- _, _, err := s.Update(ctx, policyBinding) |
|
68 |
+ _, _, err := s.Update(ctx, policyBinding.Name, rest.DefaultUpdatedObjectInfo(policyBinding, kapi.Scheme)) |
|
69 | 69 |
return err |
70 | 70 |
} |
71 | 71 |
|
... | ... |
@@ -2,6 +2,7 @@ package proxy |
2 | 2 |
|
3 | 3 |
import ( |
4 | 4 |
kapi "k8s.io/kubernetes/pkg/api" |
5 |
+ "k8s.io/kubernetes/pkg/api/rest" |
|
5 | 6 |
"k8s.io/kubernetes/pkg/api/unversioned" |
6 | 7 |
"k8s.io/kubernetes/pkg/runtime" |
7 | 8 |
|
... | ... |
@@ -81,11 +82,24 @@ func (s *ClusterRoleStorage) Create(ctx kapi.Context, obj runtime.Object) (runti |
81 | 81 |
return authorizationapi.ToClusterRole(ret.(*authorizationapi.Role)), err |
82 | 82 |
} |
83 | 83 |
|
84 |
-func (s *ClusterRoleStorage) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, bool, error) { |
|
84 |
+type convertingObjectInfo struct { |
|
85 |
+ rest.UpdatedObjectInfo |
|
86 |
+} |
|
87 |
+ |
|
88 |
+func (i convertingObjectInfo) UpdatedObject(ctx kapi.Context, old runtime.Object) (runtime.Object, error) { |
|
89 |
+ oldObj := old.(*authorizationapi.Role) |
|
90 |
+ convertedOldObj := authorizationapi.ToClusterRole(oldObj) |
|
91 |
+ obj, err := i.UpdatedObjectInfo.UpdatedObject(ctx, convertedOldObj) |
|
92 |
+ if err != nil { |
|
93 |
+ return nil, err |
|
94 |
+ } |
|
85 | 95 |
clusterObj := obj.(*authorizationapi.ClusterRole) |
86 | 96 |
convertedObj := authorizationapi.ToRole(clusterObj) |
97 |
+ return convertedObj, nil |
|
98 |
+} |
|
87 | 99 |
|
88 |
- ret, created, err := s.roleStorage.Update(ctx, convertedObj) |
|
100 |
+func (s *ClusterRoleStorage) Update(ctx kapi.Context, name string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) { |
|
101 |
+ ret, created, err := s.roleStorage.Update(ctx, name, convertingObjectInfo{objInfo}) |
|
89 | 102 |
if ret == nil { |
90 | 103 |
return nil, created, err |
91 | 104 |
} |
... | ... |
@@ -64,7 +64,7 @@ func (s *storage) CreateClusterRole(ctx kapi.Context, node *authorizationapi.Clu |
64 | 64 |
} |
65 | 65 |
|
66 | 66 |
func (s *storage) UpdateClusterRole(ctx kapi.Context, node *authorizationapi.ClusterRole) (*authorizationapi.ClusterRole, bool, error) { |
67 |
- obj, created, err := s.Update(ctx, node) |
|
67 |
+ obj, created, err := s.Update(ctx, node.Name, rest.DefaultUpdatedObjectInfo(node, kapi.Scheme)) |
|
68 | 68 |
if err != nil { |
69 | 69 |
return nil, created, err |
70 | 70 |
} |
... | ... |
@@ -2,6 +2,7 @@ package proxy |
2 | 2 |
|
3 | 3 |
import ( |
4 | 4 |
kapi "k8s.io/kubernetes/pkg/api" |
5 |
+ "k8s.io/kubernetes/pkg/api/rest" |
|
5 | 6 |
"k8s.io/kubernetes/pkg/api/unversioned" |
6 | 7 |
"k8s.io/kubernetes/pkg/runtime" |
7 | 8 |
|
... | ... |
@@ -82,11 +83,24 @@ func (s *ClusterRoleBindingStorage) Create(ctx kapi.Context, obj runtime.Object) |
82 | 82 |
return authorizationapi.ToClusterRoleBinding(ret.(*authorizationapi.RoleBinding)), err |
83 | 83 |
} |
84 | 84 |
|
85 |
-func (s *ClusterRoleBindingStorage) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, bool, error) { |
|
85 |
+type convertingObjectInfo struct { |
|
86 |
+ rest.UpdatedObjectInfo |
|
87 |
+} |
|
88 |
+ |
|
89 |
+func (i convertingObjectInfo) UpdatedObject(ctx kapi.Context, old runtime.Object) (runtime.Object, error) { |
|
90 |
+ oldObj := old.(*authorizationapi.RoleBinding) |
|
91 |
+ convertedOldObj := authorizationapi.ToClusterRoleBinding(oldObj) |
|
92 |
+ obj, err := i.UpdatedObjectInfo.UpdatedObject(ctx, convertedOldObj) |
|
93 |
+ if err != nil { |
|
94 |
+ return nil, err |
|
95 |
+ } |
|
86 | 96 |
clusterObj := obj.(*authorizationapi.ClusterRoleBinding) |
87 | 97 |
convertedObj := authorizationapi.ToRoleBinding(clusterObj) |
98 |
+ return convertedObj, nil |
|
99 |
+} |
|
88 | 100 |
|
89 |
- ret, created, err := s.roleBindingStorage.Update(ctx, convertedObj) |
|
101 |
+func (s *ClusterRoleBindingStorage) Update(ctx kapi.Context, name string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) { |
|
102 |
+ ret, created, err := s.roleBindingStorage.Update(ctx, name, convertingObjectInfo{objInfo}) |
|
90 | 103 |
if ret == nil { |
91 | 104 |
return nil, created, err |
92 | 105 |
} |
... | ... |
@@ -54,16 +54,16 @@ func (s *storage) ListRoleBindings(ctx kapi.Context, options *kapi.ListOptions) |
54 | 54 |
return obj.(*authorizationapi.RoleBindingList), nil |
55 | 55 |
} |
56 | 56 |
|
57 |
-func (s *storage) CreateRoleBinding(ctx kapi.Context, node *authorizationapi.RoleBinding) (*authorizationapi.RoleBinding, error) { |
|
58 |
- obj, err := s.Create(ctx, node) |
|
57 |
+func (s *storage) CreateRoleBinding(ctx kapi.Context, binding *authorizationapi.RoleBinding) (*authorizationapi.RoleBinding, error) { |
|
58 |
+ obj, err := s.Create(ctx, binding) |
|
59 | 59 |
if err != nil { |
60 | 60 |
return nil, err |
61 | 61 |
} |
62 | 62 |
return obj.(*authorizationapi.RoleBinding), err |
63 | 63 |
} |
64 | 64 |
|
65 |
-func (s *storage) UpdateRoleBinding(ctx kapi.Context, node *authorizationapi.RoleBinding) (*authorizationapi.RoleBinding, bool, error) { |
|
66 |
- obj, created, err := s.Update(ctx, node) |
|
65 |
+func (s *storage) UpdateRoleBinding(ctx kapi.Context, binding *authorizationapi.RoleBinding) (*authorizationapi.RoleBinding, bool, error) { |
|
66 |
+ obj, created, err := s.Update(ctx, binding.Name, rest.DefaultUpdatedObjectInfo(binding, kapi.Scheme)) |
|
67 | 67 |
if err != nil { |
68 | 68 |
return nil, created, err |
69 | 69 |
} |
... | ... |
@@ -59,7 +59,7 @@ func (s *storage) CreatePolicy(ctx kapi.Context, node *authorizationapi.Policy) |
59 | 59 |
} |
60 | 60 |
|
61 | 61 |
func (s *storage) UpdatePolicy(ctx kapi.Context, node *authorizationapi.Policy) error { |
62 |
- _, _, err := s.Update(ctx, node) |
|
62 |
+ _, _, err := s.Update(ctx, node.Name, rest.DefaultUpdatedObjectInfo(node, kapi.Scheme)) |
|
63 | 63 |
return err |
64 | 64 |
} |
65 | 65 |
|
... | ... |
@@ -59,7 +59,7 @@ func (s *storage) CreatePolicyBinding(ctx kapi.Context, policyBinding *authoriza |
59 | 59 |
} |
60 | 60 |
|
61 | 61 |
func (s *storage) UpdatePolicyBinding(ctx kapi.Context, policyBinding *authorizationapi.PolicyBinding) error { |
62 |
- _, _, err := s.Update(ctx, policyBinding) |
|
62 |
+ _, _, err := s.Update(ctx, policyBinding.Name, rest.DefaultUpdatedObjectInfo(policyBinding, kapi.Scheme)) |
|
63 | 63 |
return err |
64 | 64 |
} |
65 | 65 |
|
... | ... |
@@ -74,7 +74,7 @@ func (r *REST) isAllowed(ctx kapi.Context, rar *authorizationapi.ResourceAccessR |
74 | 74 |
return kapierrors.NewForbidden(authorizationapi.Resource(localRARAttributes.GetResource()), localRARAttributes.GetResourceName(), err) |
75 | 75 |
} |
76 | 76 |
if !allowed { |
77 |
- forbiddenError, _ := kapierrors.NewForbidden(authorizationapi.Resource(localRARAttributes.GetResource()), localRARAttributes.GetResourceName(), errors.New("") /*discarded*/).(*kapierrors.StatusError) |
|
77 |
+ forbiddenError := kapierrors.NewForbidden(authorizationapi.Resource(localRARAttributes.GetResource()), localRARAttributes.GetResourceName(), errors.New("") /*discarded*/) |
|
78 | 78 |
forbiddenError.ErrStatus.Message = reason |
79 | 79 |
return forbiddenError |
80 | 80 |
} |
... | ... |
@@ -140,24 +140,29 @@ func (m *VirtualStorage) createRole(ctx kapi.Context, obj runtime.Object, allowE |
140 | 140 |
return role, nil |
141 | 141 |
} |
142 | 142 |
|
143 |
-func (m *VirtualStorage) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, bool, error) { |
|
144 |
- return m.updateRole(ctx, obj, false) |
|
143 |
+func (m *VirtualStorage) Update(ctx kapi.Context, name string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) { |
|
144 |
+ return m.updateRole(ctx, name, objInfo, false) |
|
145 | 145 |
} |
146 | 146 |
func (m *VirtualStorage) UpdateRoleWithEscalation(ctx kapi.Context, obj *authorizationapi.Role) (*authorizationapi.Role, bool, error) { |
147 |
- return m.updateRole(ctx, obj, true) |
|
147 |
+ return m.updateRole(ctx, obj.Name, rest.DefaultUpdatedObjectInfo(obj, kapi.Scheme), true) |
|
148 | 148 |
} |
149 | 149 |
|
150 |
-func (m *VirtualStorage) updateRole(ctx kapi.Context, obj runtime.Object, allowEscalation bool) (*authorizationapi.Role, bool, error) { |
|
151 |
- role, ok := obj.(*authorizationapi.Role) |
|
152 |
- if !ok { |
|
153 |
- return nil, false, kapierrors.NewBadRequest(fmt.Sprintf("obj is not a role: %#v", obj)) |
|
150 |
+func (m *VirtualStorage) updateRole(ctx kapi.Context, name string, objInfo rest.UpdatedObjectInfo, allowEscalation bool) (*authorizationapi.Role, bool, error) { |
|
151 |
+ old, err := m.Get(ctx, name) |
|
152 |
+ if err != nil { |
|
153 |
+ return nil, false, err |
|
154 | 154 |
} |
155 | 155 |
|
156 |
- old, err := m.Get(ctx, role.Name) |
|
156 |
+ obj, err := objInfo.UpdatedObject(ctx, old) |
|
157 | 157 |
if err != nil { |
158 | 158 |
return nil, false, err |
159 | 159 |
} |
160 | 160 |
|
161 |
+ role, ok := obj.(*authorizationapi.Role) |
|
162 |
+ if !ok { |
|
163 |
+ return nil, false, kapierrors.NewBadRequest(fmt.Sprintf("obj is not a role: %#v", obj)) |
|
164 |
+ } |
|
165 |
+ |
|
161 | 166 |
if err := rest.BeforeUpdate(m.UpdateStrategy, ctx, obj, old); err != nil { |
162 | 167 |
return nil, false, err |
163 | 168 |
} |
... | ... |
@@ -6,8 +6,10 @@ import ( |
6 | 6 |
|
7 | 7 |
kapi "k8s.io/kubernetes/pkg/api" |
8 | 8 |
kapierrors "k8s.io/kubernetes/pkg/api/errors" |
9 |
+ "k8s.io/kubernetes/pkg/api/rest" |
|
9 | 10 |
"k8s.io/kubernetes/pkg/api/unversioned" |
10 | 11 |
"k8s.io/kubernetes/pkg/auth/user" |
12 |
+ "k8s.io/kubernetes/pkg/util/diff" |
|
11 | 13 |
"k8s.io/kubernetes/pkg/util/sets" |
12 | 14 |
|
13 | 15 |
authorizationapi "github.com/openshift/origin/pkg/authorization/api" |
... | ... |
@@ -108,25 +110,28 @@ func TestUpdate(t *testing.T) { |
108 | 108 |
realizedRole := realizedRoleObj.(*authorizationapi.Role) |
109 | 109 |
|
110 | 110 |
role := &authorizationapi.Role{ |
111 |
- ObjectMeta: kapi.ObjectMeta{Name: "my-role", ResourceVersion: realizedRole.ResourceVersion}, |
|
111 |
+ ObjectMeta: realizedRole.ObjectMeta, |
|
112 | 112 |
Rules: []authorizationapi.PolicyRule{ |
113 | 113 |
{Verbs: sets.NewString("list", "update")}, |
114 | 114 |
}, |
115 | 115 |
} |
116 | 116 |
|
117 |
- obj, created, err := storage.Update(ctx, role) |
|
117 |
+ obj, created, err := storage.Update(ctx, role.Name, rest.DefaultUpdatedObjectInfo(role, kapi.Scheme)) |
|
118 | 118 |
if err != nil || created { |
119 | 119 |
t.Errorf("Unexpected error %v", err) |
120 | 120 |
} |
121 | 121 |
|
122 |
- switch obj.(type) { |
|
122 |
+ switch actual := obj.(type) { |
|
123 | 123 |
case *unversioned.Status: |
124 | 124 |
t.Errorf("Unexpected operation error: %v", obj) |
125 | 125 |
|
126 | 126 |
case *authorizationapi.Role: |
127 |
+ if realizedRole.ResourceVersion == actual.ResourceVersion { |
|
128 |
+ t.Errorf("Expected change to role binding. Expected: %s, Got: %s", realizedRole.ResourceVersion, actual.ResourceVersion) |
|
129 |
+ } |
|
130 |
+ role.ResourceVersion = actual.ResourceVersion |
|
127 | 131 |
if !reflect.DeepEqual(role, obj) { |
128 |
- t.Errorf("Updated role does not match input role."+ |
|
129 |
- " Expected: %v, Got: %v", role, obj) |
|
132 |
+ t.Errorf("Updated role does not match input role. %s", diff.ObjectReflectDiff(role, obj)) |
|
130 | 133 |
} |
131 | 134 |
default: |
132 | 135 |
t.Errorf("Unexpected result type: %v", obj) |
... | ... |
@@ -149,13 +154,13 @@ func TestUpdateNoOp(t *testing.T) { |
149 | 149 |
realizedRole := realizedRoleObj.(*authorizationapi.Role) |
150 | 150 |
|
151 | 151 |
role := &authorizationapi.Role{ |
152 |
- ObjectMeta: kapi.ObjectMeta{Name: "my-role", ResourceVersion: realizedRole.ResourceVersion}, |
|
152 |
+ ObjectMeta: realizedRole.ObjectMeta, |
|
153 | 153 |
Rules: []authorizationapi.PolicyRule{ |
154 | 154 |
{Verbs: sets.NewString(authorizationapi.VerbAll)}, |
155 | 155 |
}, |
156 | 156 |
} |
157 | 157 |
|
158 |
- obj, created, err := storage.Update(ctx, role) |
|
158 |
+ obj, created, err := storage.Update(ctx, role.Name, rest.DefaultUpdatedObjectInfo(role, kapi.Scheme)) |
|
159 | 159 |
if err != nil || created { |
160 | 160 |
t.Errorf("Unexpected error %v", err) |
161 | 161 |
} |
... | ... |
@@ -169,8 +174,7 @@ func TestUpdateNoOp(t *testing.T) { |
169 | 169 |
t.Errorf("Expected no change to role binding. Expected: %s, Got: %s", realizedRole.ResourceVersion, o.ResourceVersion) |
170 | 170 |
} |
171 | 171 |
if !reflect.DeepEqual(role, obj) { |
172 |
- t.Errorf("Updated role does not match input role."+ |
|
173 |
- " Expected: %v, Got: %v", role, obj) |
|
172 |
+ t.Errorf("Updated role does not match input role. %s", diff.ObjectReflectDiff(role, obj)) |
|
174 | 173 |
} |
175 | 174 |
default: |
176 | 175 |
t.Errorf("Unexpected result type: %v", obj) |
... | ... |
@@ -185,7 +189,7 @@ func TestUpdateError(t *testing.T) { |
185 | 185 |
} |
186 | 186 |
|
187 | 187 |
ctx := kapi.WithNamespace(kapi.NewContext(), "unittest") |
188 |
- _, _, err := storage.Update(ctx, role) |
|
188 |
+ _, _, err := storage.Update(ctx, role.Name, rest.DefaultUpdatedObjectInfo(role, kapi.Scheme)) |
|
189 | 189 |
if err == nil { |
190 | 190 |
t.Errorf("Missing expected error") |
191 | 191 |
return |
... | ... |
@@ -54,13 +54,13 @@ func (s *storage) ListRoles(ctx kapi.Context, options *kapi.ListOptions) (*autho |
54 | 54 |
return obj.(*authorizationapi.RoleList), nil |
55 | 55 |
} |
56 | 56 |
|
57 |
-func (s *storage) CreateRole(ctx kapi.Context, node *authorizationapi.Role) (*authorizationapi.Role, error) { |
|
58 |
- obj, err := s.Create(ctx, node) |
|
57 |
+func (s *storage) CreateRole(ctx kapi.Context, role *authorizationapi.Role) (*authorizationapi.Role, error) { |
|
58 |
+ obj, err := s.Create(ctx, role) |
|
59 | 59 |
return obj.(*authorizationapi.Role), err |
60 | 60 |
} |
61 | 61 |
|
62 |
-func (s *storage) UpdateRole(ctx kapi.Context, node *authorizationapi.Role) (*authorizationapi.Role, bool, error) { |
|
63 |
- obj, created, err := s.Update(ctx, node) |
|
62 |
+func (s *storage) UpdateRole(ctx kapi.Context, role *authorizationapi.Role) (*authorizationapi.Role, bool, error) { |
|
63 |
+ obj, created, err := s.Update(ctx, role.Name, rest.DefaultUpdatedObjectInfo(role, kapi.Scheme)) |
|
64 | 64 |
return obj.(*authorizationapi.Role), created, err |
65 | 65 |
} |
66 | 66 |
|
... | ... |
@@ -150,24 +150,29 @@ func (m *VirtualStorage) createRoleBinding(ctx kapi.Context, obj runtime.Object, |
150 | 150 |
return roleBinding, nil |
151 | 151 |
} |
152 | 152 |
|
153 |
-func (m *VirtualStorage) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, bool, error) { |
|
154 |
- return m.updateRoleBinding(ctx, obj, false) |
|
153 |
+func (m *VirtualStorage) Update(ctx kapi.Context, name string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) { |
|
154 |
+ return m.updateRoleBinding(ctx, name, objInfo, false) |
|
155 | 155 |
} |
156 | 156 |
func (m *VirtualStorage) UpdateRoleBindingWithEscalation(ctx kapi.Context, obj *authorizationapi.RoleBinding) (*authorizationapi.RoleBinding, bool, error) { |
157 |
- return m.updateRoleBinding(ctx, obj, true) |
|
157 |
+ return m.updateRoleBinding(ctx, obj.Name, rest.DefaultUpdatedObjectInfo(obj, kapi.Scheme), true) |
|
158 | 158 |
} |
159 | 159 |
|
160 |
-func (m *VirtualStorage) updateRoleBinding(ctx kapi.Context, obj runtime.Object, allowEscalation bool) (*authorizationapi.RoleBinding, bool, error) { |
|
161 |
- roleBinding, ok := obj.(*authorizationapi.RoleBinding) |
|
162 |
- if !ok { |
|
163 |
- return nil, false, kapierrors.NewBadRequest(fmt.Sprintf("obj is not a role: %#v", obj)) |
|
160 |
+func (m *VirtualStorage) updateRoleBinding(ctx kapi.Context, name string, objInfo rest.UpdatedObjectInfo, allowEscalation bool) (*authorizationapi.RoleBinding, bool, error) { |
|
161 |
+ old, err := m.Get(ctx, name) |
|
162 |
+ if err != nil { |
|
163 |
+ return nil, false, err |
|
164 | 164 |
} |
165 | 165 |
|
166 |
- old, err := m.Get(ctx, roleBinding.Name) |
|
166 |
+ obj, err := objInfo.UpdatedObject(ctx, old) |
|
167 | 167 |
if err != nil { |
168 | 168 |
return nil, false, err |
169 | 169 |
} |
170 | 170 |
|
171 |
+ roleBinding, ok := obj.(*authorizationapi.RoleBinding) |
|
172 |
+ if !ok { |
|
173 |
+ return nil, false, kapierrors.NewBadRequest(fmt.Sprintf("obj is not a role: %#v", obj)) |
|
174 |
+ } |
|
175 |
+ |
|
171 | 176 |
if err := rest.BeforeUpdate(m.UpdateStrategy, ctx, obj, old); err != nil { |
172 | 177 |
return nil, false, err |
173 | 178 |
} |
... | ... |
@@ -8,8 +8,10 @@ import ( |
8 | 8 |
|
9 | 9 |
kapi "k8s.io/kubernetes/pkg/api" |
10 | 10 |
kapierrors "k8s.io/kubernetes/pkg/api/errors" |
11 |
+ "k8s.io/kubernetes/pkg/api/rest" |
|
11 | 12 |
"k8s.io/kubernetes/pkg/api/unversioned" |
12 | 13 |
"k8s.io/kubernetes/pkg/auth/user" |
14 |
+ "k8s.io/kubernetes/pkg/util/diff" |
|
13 | 15 |
"k8s.io/kubernetes/pkg/util/sets" |
14 | 16 |
|
15 | 17 |
authorizationapi "github.com/openshift/origin/pkg/authorization/api" |
... | ... |
@@ -152,24 +154,27 @@ func TestUpdate(t *testing.T) { |
152 | 152 |
original := obj.(*authorizationapi.RoleBinding) |
153 | 153 |
|
154 | 154 |
roleBinding := &authorizationapi.RoleBinding{ |
155 |
- ObjectMeta: kapi.ObjectMeta{Name: "my-roleBinding", ResourceVersion: original.ResourceVersion}, |
|
155 |
+ ObjectMeta: original.ObjectMeta, |
|
156 | 156 |
RoleRef: kapi.ObjectReference{Name: "admin"}, |
157 | 157 |
Subjects: []kapi.ObjectReference{{Name: "bob", Kind: "User"}}, |
158 | 158 |
} |
159 | 159 |
|
160 |
- obj, created, err := storage.Update(ctx, roleBinding) |
|
160 |
+ obj, created, err := storage.Update(ctx, roleBinding.Name, rest.DefaultUpdatedObjectInfo(roleBinding, kapi.Scheme)) |
|
161 | 161 |
if err != nil || created { |
162 | 162 |
t.Errorf("Unexpected error %v", err) |
163 | 163 |
} |
164 | 164 |
|
165 |
- switch obj.(type) { |
|
165 |
+ switch actual := obj.(type) { |
|
166 | 166 |
case *unversioned.Status: |
167 | 167 |
t.Errorf("Unexpected operation error: %v", obj) |
168 | 168 |
|
169 | 169 |
case *authorizationapi.RoleBinding: |
170 |
+ if original.ResourceVersion == actual.ResourceVersion { |
|
171 |
+ t.Errorf("Expected change to role binding. Expected: %s, Got: %s", original.ResourceVersion, actual.ResourceVersion) |
|
172 |
+ } |
|
173 |
+ roleBinding.ResourceVersion = actual.ResourceVersion |
|
170 | 174 |
if !reflect.DeepEqual(roleBinding, obj) { |
171 |
- t.Errorf("Updated roleBinding does not match input roleBinding."+ |
|
172 |
- " Expected: %v, Got: %v", roleBinding, obj) |
|
175 |
+ t.Errorf("Updated roleBinding does not match input roleBinding. %s", diff.ObjectReflectDiff(roleBinding, obj)) |
|
173 | 176 |
} |
174 | 177 |
default: |
175 | 178 |
t.Errorf("Unexpected result type: %v", obj) |
... | ... |
@@ -191,11 +196,11 @@ func TestUpdateNoOp(t *testing.T) { |
191 | 191 |
original := obj.(*authorizationapi.RoleBinding) |
192 | 192 |
|
193 | 193 |
roleBinding := &authorizationapi.RoleBinding{ |
194 |
- ObjectMeta: kapi.ObjectMeta{Name: "my-roleBinding", ResourceVersion: original.ResourceVersion}, |
|
194 |
+ ObjectMeta: original.ObjectMeta, |
|
195 | 195 |
RoleRef: kapi.ObjectReference{Name: "admin"}, |
196 | 196 |
} |
197 | 197 |
|
198 |
- obj, created, err := storage.Update(ctx, roleBinding) |
|
198 |
+ obj, created, err := storage.Update(ctx, roleBinding.Name, rest.DefaultUpdatedObjectInfo(roleBinding, kapi.Scheme)) |
|
199 | 199 |
if err != nil || created { |
200 | 200 |
t.Errorf("Unexpected error %v", err) |
201 | 201 |
} |
... | ... |
@@ -209,8 +214,7 @@ func TestUpdateNoOp(t *testing.T) { |
209 | 209 |
t.Errorf("Expected no change to role binding. Expected: %s, Got: %s", original.ResourceVersion, o.ResourceVersion) |
210 | 210 |
} |
211 | 211 |
if !reflect.DeepEqual(roleBinding, obj) { |
212 |
- t.Errorf("Updated roleBinding does not match input roleBinding."+ |
|
213 |
- " Expected: %v, Got: %v", roleBinding, obj) |
|
212 |
+ t.Errorf("Updated roleBinding does not match input roleBinding. %s", diff.ObjectReflectDiff(roleBinding, obj)) |
|
214 | 213 |
} |
215 | 214 |
default: |
216 | 215 |
t.Errorf("Unexpected result type: %v", obj) |
... | ... |
@@ -236,7 +240,7 @@ func TestUpdateError(t *testing.T) { |
236 | 236 |
RoleRef: kapi.ObjectReference{Name: "admin"}, |
237 | 237 |
} |
238 | 238 |
|
239 |
- _, _, err = storage.Update(ctx, roleBinding) |
|
239 |
+ _, _, err = storage.Update(ctx, roleBinding.Name, rest.DefaultUpdatedObjectInfo(roleBinding, kapi.Scheme)) |
|
240 | 240 |
if err == nil { |
241 | 241 |
t.Errorf("Missing expected error") |
242 | 242 |
return |
... | ... |
@@ -265,7 +269,7 @@ func TestUpdateCannotChangeRoleRefError(t *testing.T) { |
265 | 265 |
RoleRef: kapi.ObjectReference{Name: "cluster-admin"}, |
266 | 266 |
} |
267 | 267 |
|
268 |
- _, _, err = storage.Update(ctx, roleBinding) |
|
268 |
+ _, _, err = storage.Update(ctx, roleBinding.Name, rest.DefaultUpdatedObjectInfo(roleBinding, kapi.Scheme)) |
|
269 | 269 |
if err == nil { |
270 | 270 |
t.Errorf("Missing expected error") |
271 | 271 |
return |
... | ... |
@@ -54,13 +54,13 @@ func (s *storage) ListRoleBindings(ctx kapi.Context, options *kapi.ListOptions) |
54 | 54 |
return obj.(*authorizationapi.RoleBindingList), nil |
55 | 55 |
} |
56 | 56 |
|
57 |
-func (s *storage) CreateRoleBinding(ctx kapi.Context, node *authorizationapi.RoleBinding) (*authorizationapi.RoleBinding, error) { |
|
58 |
- obj, err := s.Create(ctx, node) |
|
57 |
+func (s *storage) CreateRoleBinding(ctx kapi.Context, rolebinding *authorizationapi.RoleBinding) (*authorizationapi.RoleBinding, error) { |
|
58 |
+ obj, err := s.Create(ctx, rolebinding) |
|
59 | 59 |
return obj.(*authorizationapi.RoleBinding), err |
60 | 60 |
} |
61 | 61 |
|
62 |
-func (s *storage) UpdateRoleBinding(ctx kapi.Context, node *authorizationapi.RoleBinding) (*authorizationapi.RoleBinding, bool, error) { |
|
63 |
- obj, created, err := s.Update(ctx, node) |
|
62 |
+func (s *storage) UpdateRoleBinding(ctx kapi.Context, rolebinding *authorizationapi.RoleBinding) (*authorizationapi.RoleBinding, bool, error) { |
|
63 |
+ obj, created, err := s.Update(ctx, rolebinding.Name, rest.DefaultUpdatedObjectInfo(rolebinding, kapi.Scheme)) |
|
64 | 64 |
return obj.(*authorizationapi.RoleBinding), created, err |
65 | 65 |
} |
66 | 66 |
|
... | ... |
@@ -125,7 +125,7 @@ func (r *REST) isAllowed(ctx kapi.Context, sar *authorizationapi.SubjectAccessRe |
125 | 125 |
return kapierrors.NewForbidden(authorizationapi.Resource(localSARAttributes.GetResource()), localSARAttributes.GetResourceName(), err) |
126 | 126 |
} |
127 | 127 |
if !allowed { |
128 |
- forbiddenError, _ := kapierrors.NewForbidden(authorizationapi.Resource(localSARAttributes.GetResource()), localSARAttributes.GetResourceName(), errors.New("") /*discarded*/).(*kapierrors.StatusError) |
|
128 |
+ forbiddenError := kapierrors.NewForbidden(authorizationapi.Resource(localSARAttributes.GetResource()), localSARAttributes.GetResourceName(), errors.New("") /*discarded*/) |
|
129 | 129 |
forbiddenError.ErrStatus.Message = reason |
130 | 130 |
return forbiddenError |
131 | 131 |
} |
... | ... |
@@ -31,33 +31,33 @@ func TestAdmission(t *testing.T) { |
31 | 31 |
}{ |
32 | 32 |
{ |
33 | 33 |
name: "disabled", |
34 |
- attributes: admission.NewAttributesRecord(enableBuild, unversioned.GroupVersionKind{}, "namespace", "name", buildapi.SchemeGroupVersion.WithResource("builds"), "", admission.Create, &user.DefaultInfo{}), |
|
34 |
+ attributes: admission.NewAttributesRecord(enableBuild, nil, unversioned.GroupVersionKind{}, "namespace", "name", buildapi.SchemeGroupVersion.WithResource("builds"), "", admission.Create, &user.DefaultInfo{}), |
|
35 | 35 |
jenkinsEnabled: boolptr(false), |
36 | 36 |
validateClients: noAction, |
37 | 37 |
}, |
38 | 38 |
{ |
39 | 39 |
name: "not a jenkins build", |
40 |
- attributes: admission.NewAttributesRecord(&buildapi.Build{Spec: buildapi.BuildSpec{CommonSpec: buildapi.CommonSpec{Strategy: buildapi.BuildStrategy{}}}}, unversioned.GroupVersionKind{}, "namespace", "name", buildapi.SchemeGroupVersion.WithResource("builds"), "", admission.Create, &user.DefaultInfo{}), |
|
40 |
+ attributes: admission.NewAttributesRecord(&buildapi.Build{Spec: buildapi.BuildSpec{CommonSpec: buildapi.CommonSpec{Strategy: buildapi.BuildStrategy{}}}}, nil, unversioned.GroupVersionKind{}, "namespace", "name", buildapi.SchemeGroupVersion.WithResource("builds"), "", admission.Create, &user.DefaultInfo{}), |
|
41 | 41 |
validateClients: noAction, |
42 | 42 |
}, |
43 | 43 |
{ |
44 | 44 |
name: "not a build kind", |
45 |
- attributes: admission.NewAttributesRecord(&kapi.Service{}, unversioned.GroupVersionKind{}, "namespace", "name", buildapi.SchemeGroupVersion.WithResource("builds"), "", admission.Create, &user.DefaultInfo{}), |
|
45 |
+ attributes: admission.NewAttributesRecord(&kapi.Service{}, nil, unversioned.GroupVersionKind{}, "namespace", "name", buildapi.SchemeGroupVersion.WithResource("builds"), "", admission.Create, &user.DefaultInfo{}), |
|
46 | 46 |
validateClients: noAction, |
47 | 47 |
}, |
48 | 48 |
{ |
49 | 49 |
name: "not a build resource", |
50 |
- attributes: admission.NewAttributesRecord(enableBuild, unversioned.GroupVersionKind{}, "namespace", "name", buildapi.SchemeGroupVersion.WithResource("notbuilds"), "", admission.Create, &user.DefaultInfo{}), |
|
50 |
+ attributes: admission.NewAttributesRecord(enableBuild, nil, unversioned.GroupVersionKind{}, "namespace", "name", buildapi.SchemeGroupVersion.WithResource("notbuilds"), "", admission.Create, &user.DefaultInfo{}), |
|
51 | 51 |
validateClients: noAction, |
52 | 52 |
}, |
53 | 53 |
{ |
54 | 54 |
name: "subresource", |
55 |
- attributes: admission.NewAttributesRecord(enableBuild, unversioned.GroupVersionKind{}, "namespace", "name", buildapi.SchemeGroupVersion.WithResource("builds"), "subresource", admission.Create, &user.DefaultInfo{}), |
|
55 |
+ attributes: admission.NewAttributesRecord(enableBuild, nil, unversioned.GroupVersionKind{}, "namespace", "name", buildapi.SchemeGroupVersion.WithResource("builds"), "subresource", admission.Create, &user.DefaultInfo{}), |
|
56 | 56 |
validateClients: noAction, |
57 | 57 |
}, |
58 | 58 |
{ |
59 | 59 |
name: "service present", |
60 |
- attributes: admission.NewAttributesRecord(enableBuild, unversioned.GroupVersionKind{}, "namespace", "name", buildapi.SchemeGroupVersion.WithResource("builds"), "", admission.Create, &user.DefaultInfo{}), |
|
60 |
+ attributes: admission.NewAttributesRecord(enableBuild, nil, unversioned.GroupVersionKind{}, "namespace", "name", buildapi.SchemeGroupVersion.WithResource("builds"), "", admission.Create, &user.DefaultInfo{}), |
|
61 | 61 |
objects: []runtime.Object{ |
62 | 62 |
&kapi.Service{ObjectMeta: kapi.ObjectMeta{Namespace: "namespace", Name: "jenkins"}}, |
63 | 63 |
}, |
... | ... |
@@ -70,7 +70,7 @@ func TestAdmission(t *testing.T) { |
70 | 70 |
}, |
71 | 71 |
{ |
72 | 72 |
name: "works on true", |
73 |
- attributes: admission.NewAttributesRecord(enableBuild, unversioned.GroupVersionKind{}, "namespace", "name", buildapi.SchemeGroupVersion.WithResource("builds"), "", admission.Create, &user.DefaultInfo{}), |
|
73 |
+ attributes: admission.NewAttributesRecord(enableBuild, nil, unversioned.GroupVersionKind{}, "namespace", "name", buildapi.SchemeGroupVersion.WithResource("builds"), "", admission.Create, &user.DefaultInfo{}), |
|
74 | 74 |
objects: []runtime.Object{ |
75 | 75 |
&kapi.Service{ObjectMeta: kapi.ObjectMeta{Namespace: "namespace", Name: "jenkins"}}, |
76 | 76 |
}, |
... | ... |
@@ -84,7 +84,7 @@ func TestAdmission(t *testing.T) { |
84 | 84 |
}, |
85 | 85 |
{ |
86 | 86 |
name: "service missing", |
87 |
- attributes: admission.NewAttributesRecord(enableBuild, unversioned.GroupVersionKind{}, "namespace", "name", buildapi.SchemeGroupVersion.WithResource("builds"), "", admission.Create, &user.DefaultInfo{}), |
|
87 |
+ attributes: admission.NewAttributesRecord(enableBuild, nil, unversioned.GroupVersionKind{}, "namespace", "name", buildapi.SchemeGroupVersion.WithResource("builds"), "", admission.Create, &user.DefaultInfo{}), |
|
88 | 88 |
objects: []runtime.Object{}, |
89 | 89 |
validateClients: func(kubeClient *fake.Clientset, originClient *testclient.Fake) string { |
90 | 90 |
if len(kubeClient.Actions()) == 0 { |
... | ... |
@@ -26,6 +26,7 @@ func TestBuildAdmission(t *testing.T) { |
26 | 26 |
resource unversioned.GroupResource |
27 | 27 |
subResource string |
28 | 28 |
object runtime.Object |
29 |
+ oldObject runtime.Object |
|
29 | 30 |
responseObject runtime.Object |
30 | 31 |
reviewResponse *authorizationapi.SubjectAccessReviewResponse |
31 | 32 |
expectedResource string |
... | ... |
@@ -167,7 +168,7 @@ func TestBuildAdmission(t *testing.T) { |
167 | 167 |
client := fakeClient(test.expectedResource, test.reviewResponse, test.responseObject) |
168 | 168 |
c := NewBuildByStrategy() |
169 | 169 |
c.(oadmission.WantsOpenshiftClient).SetOpenshiftClient(client) |
170 |
- attrs := admission.NewAttributesRecord(test.object, test.kind.WithVersion("version"), "default", "name", test.resource.WithVersion("version"), test.subResource, op, fakeUser()) |
|
170 |
+ attrs := admission.NewAttributesRecord(test.object, test.oldObject, test.kind.WithVersion("version"), "default", "name", test.resource.WithVersion("version"), test.subResource, op, fakeUser()) |
|
171 | 171 |
err := c.Admit(attrs) |
172 | 172 |
if err != nil && test.expectAccept { |
173 | 173 |
t.Errorf("%s: unexpected error: %v", test.name, err) |
... | ... |
@@ -72,6 +72,7 @@ func (p *TestPod) GetBuild(t *testing.T) *buildapi.Build { |
72 | 72 |
|
73 | 73 |
func (p *TestPod) ToAttributes() admission.Attributes { |
74 | 74 |
return admission.NewAttributesRecord((*kapi.Pod)(p), |
75 |
+ nil, |
|
75 | 76 |
kapi.Kind("Pod").WithVersion("version"), |
76 | 77 |
"default", |
77 | 78 |
"TestPod", |
... | ... |
@@ -38,7 +38,7 @@ func TestBinaryBuildRequestOptions(t *testing.T) { |
38 | 38 |
AsFile: "Dockerfile", |
39 | 39 |
Commit: "abcdef", |
40 | 40 |
} |
41 |
- versioned, err := knewer.Scheme.ConvertToVersion(r, "v1") |
|
41 |
+ versioned, err := knewer.Scheme.ConvertToVersion(r, kolder.SchemeGroupVersion) |
|
42 | 42 |
if err != nil { |
43 | 43 |
t.Fatal(err) |
44 | 44 |
} |
... | ... |
@@ -278,7 +278,7 @@ func validateSecrets(secrets []buildapi.SecretBuildSource, isDockerStrategy bool |
278 | 278 |
if len(s.Secret.Name) == 0 { |
279 | 279 |
allErrs = append(allErrs, field.Required(fldPath.Index(i).Child("secret"), "")) |
280 | 280 |
} |
281 |
- if ok, _ := validation.ValidateSecretName(s.Secret.Name, false); !ok { |
|
281 |
+ if reasons := validation.ValidateSecretName(s.Secret.Name, false); len(reasons) != 0 { |
|
282 | 282 |
allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("secret"), s, "must be valid secret name")) |
283 | 283 |
} |
284 | 284 |
if strings.HasPrefix(path.Clean(s.DestinationDir), "..") { |
... | ... |
@@ -349,7 +349,7 @@ func validateToImageReference(reference *kapi.ObjectReference, fldPath *field.Pa |
349 | 349 |
} else if _, _, ok := imageapi.SplitImageStreamTag(name); !ok { |
350 | 350 |
allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), name, "ImageStreamTag object references must be in the form <name>:<tag>")) |
351 | 351 |
} |
352 |
- if len(namespace) != 0 && !kvalidation.IsDNS1123Subdomain(namespace) { |
|
352 |
+ if len(namespace) != 0 && len(kvalidation.IsDNS1123Subdomain(namespace)) != 0 { |
|
353 | 353 |
allErrs = append(allErrs, field.Invalid(fldPath.Child("namespace"), namespace, "namespace must be a valid subdomain")) |
354 | 354 |
} |
355 | 355 |
|
... | ... |
@@ -380,7 +380,7 @@ func validateFromImageReference(reference *kapi.ObjectReference, fldPath *field. |
380 | 380 |
allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), name, "ImageStreamTag object references must be in the form <name>:<tag>")) |
381 | 381 |
} |
382 | 382 |
|
383 |
- if len(namespace) != 0 && !kvalidation.IsDNS1123Subdomain(namespace) { |
|
383 |
+ if len(namespace) != 0 && len(kvalidation.IsDNS1123Subdomain(namespace)) != 0 { |
|
384 | 384 |
allErrs = append(allErrs, field.Invalid(fldPath.Child("namespace"), namespace, "namespace must be a valid subdomain")) |
385 | 385 |
} |
386 | 386 |
|
... | ... |
@@ -397,7 +397,7 @@ func validateFromImageReference(reference *kapi.ObjectReference, fldPath *field. |
397 | 397 |
if len(name) == 0 { |
398 | 398 |
allErrs = append(allErrs, field.Required(fldPath.Child("name"), "")) |
399 | 399 |
} |
400 |
- if len(namespace) != 0 && !kvalidation.IsDNS1123Subdomain(namespace) { |
|
400 |
+ if len(namespace) != 0 && len(kvalidation.IsDNS1123Subdomain(namespace)) != 0 { |
|
401 | 401 |
allErrs = append(allErrs, field.Invalid(fldPath.Child("namespace"), namespace, "namespace must be a valid subdomain")) |
402 | 402 |
} |
403 | 403 |
case "": |
... | ... |
@@ -72,7 +72,7 @@ func (t *PipelineTemplate) Process() (*kapi.List, []error) { |
72 | 72 |
func (t *PipelineTemplate) HasJenkinsService(items *kapi.List) bool { |
73 | 73 |
accessor := meta.NewAccessor() |
74 | 74 |
for _, item := range items.Items { |
75 |
- kind, err := kapi.Scheme.ObjectKind(item) |
|
75 |
+ kind, _, err := kapi.Scheme.ObjectKind(item) |
|
76 | 76 |
if err != nil { |
77 | 77 |
glog.Infof("Error checking Jenkins service kind: %v", err) |
78 | 78 |
return false |
... | ... |
@@ -129,7 +129,7 @@ func (bs *SourceBuildStrategy) canRunAsRoot(build *buildapi.Build) bool { |
129 | 129 |
}, |
130 | 130 |
} |
131 | 131 |
userInfo := serviceaccount.UserInfo(build.Namespace, build.Spec.ServiceAccount, "") |
132 |
- attrs := admission.NewAttributesRecord(pod, kapi.Kind("Pod").WithVersion(""), pod.Namespace, pod.Name, kapi.Resource("pods").WithVersion(""), "", admission.Create, userInfo) |
|
132 |
+ attrs := admission.NewAttributesRecord(pod, pod, kapi.Kind("Pod").WithVersion(""), pod.Namespace, pod.Name, kapi.Resource("pods").WithVersion(""), "", admission.Create, userInfo) |
|
133 | 133 |
err := bs.AdmissionControl.Admit(attrs) |
134 | 134 |
if err != nil { |
135 | 135 |
glog.V(2).Infof("Admit for root user returned error: %v", err) |
... | ... |
@@ -26,6 +26,10 @@ func (s FakeBuildConfigStore) Delete(obj interface{}) error { |
26 | 26 |
return s.Err |
27 | 27 |
} |
28 | 28 |
|
29 |
+func (s FakeBuildConfigStore) Resync() error { |
|
30 |
+ return s.Err |
|
31 |
+} |
|
32 |
+ |
|
29 | 33 |
func (s FakeBuildConfigStore) List() []interface{} { |
30 | 34 |
return []interface{}{s.Build} |
31 | 35 |
} |
... | ... |
@@ -120,7 +120,7 @@ func actionsAreEqual(a, b ktestclient.Action) bool { |
120 | 120 |
|
121 | 121 |
func TestStop(t *testing.T) { |
122 | 122 |
notFound := func() runtime.Object { |
123 |
- return &(kerrors.NewNotFound(buildapi.Resource("BuildConfig"), configName).(*kerrors.StatusError).ErrStatus) |
|
123 |
+ return &(kerrors.NewNotFound(buildapi.Resource("BuildConfig"), configName).ErrStatus) |
|
124 | 124 |
} |
125 | 125 |
|
126 | 126 |
tests := map[string]struct { |
... | ... |
@@ -2,6 +2,7 @@ package etcd |
2 | 2 |
|
3 | 3 |
import ( |
4 | 4 |
kapi "k8s.io/kubernetes/pkg/api" |
5 |
+ "k8s.io/kubernetes/pkg/api/rest" |
|
5 | 6 |
"k8s.io/kubernetes/pkg/fields" |
6 | 7 |
"k8s.io/kubernetes/pkg/labels" |
7 | 8 |
"k8s.io/kubernetes/pkg/registry/generic" |
... | ... |
@@ -64,6 +65,6 @@ func (r *DetailsREST) New() runtime.Object { |
64 | 64 |
} |
65 | 65 |
|
66 | 66 |
// Update finds a resource in the storage and updates it. |
67 |
-func (r *DetailsREST) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, bool, error) { |
|
68 |
- return r.store.Update(ctx, obj) |
|
67 |
+func (r *DetailsREST) Update(ctx kapi.Context, name string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) { |
|
68 |
+ return r.store.Update(ctx, name, objInfo) |
|
69 | 69 |
} |
... | ... |
@@ -61,7 +61,7 @@ func (s *storage) CreateBuild(ctx kapi.Context, build *api.Build) error { |
61 | 61 |
} |
62 | 62 |
|
63 | 63 |
func (s *storage) UpdateBuild(ctx kapi.Context, build *api.Build) error { |
64 |
- _, _, err := s.Update(ctx, build) |
|
64 |
+ _, _, err := s.Update(ctx, build.Name, rest.DefaultUpdatedObjectInfo(build, kapi.Scheme)) |
|
65 | 65 |
return err |
66 | 66 |
} |
67 | 67 |
|
... | ... |
@@ -60,7 +60,7 @@ func (s *storage) CreateBuildConfig(ctx kapi.Context, build *api.BuildConfig) er |
60 | 60 |
} |
61 | 61 |
|
62 | 62 |
func (s *storage) UpdateBuildConfig(ctx kapi.Context, build *api.BuildConfig) error { |
63 |
- _, _, err := s.Update(ctx, build) |
|
63 |
+ _, _, err := s.Update(ctx, build.Name, rest.DefaultUpdatedObjectInfo(build, kapi.Scheme)) |
|
64 | 64 |
return err |
65 | 65 |
} |
66 | 66 |
|
... | ... |
@@ -355,6 +355,30 @@ func (eq *EventQueue) ListConsumed() bool { |
355 | 355 |
return eq.lastReplaceKey == "" |
356 | 356 |
} |
357 | 357 |
|
358 |
+// Resync will touch all objects to put them into the processing queue |
|
359 |
+func (eq *EventQueue) Resync() error { |
|
360 |
+ eq.lock.Lock() |
|
361 |
+ defer eq.lock.Unlock() |
|
362 |
+ |
|
363 |
+ inQueue := sets.NewString() |
|
364 |
+ for _, id := range eq.queue { |
|
365 |
+ inQueue.Insert(id) |
|
366 |
+ } |
|
367 |
+ |
|
368 |
+ for _, id := range eq.store.ListKeys() { |
|
369 |
+ if !inQueue.Has(id) { |
|
370 |
+ eq.queue = append(eq.queue, id) |
|
371 |
+ } |
|
372 |
+ } |
|
373 |
+ |
|
374 |
+ if len(eq.queue) > 0 { |
|
375 |
+ eq.cond.Broadcast() |
|
376 |
+ } else { |
|
377 |
+ eq.lastReplaceKey = "" |
|
378 |
+ } |
|
379 |
+ return nil |
|
380 |
+} |
|
381 |
+ |
|
358 | 382 |
// NewEventQueue returns a new EventQueue. |
359 | 383 |
func NewEventQueue(keyFn kcache.KeyFunc) *EventQueue { |
360 | 384 |
q := &EventQueue{ |
... | ... |
@@ -28,19 +28,19 @@ func TestImageStreamImportUnsupported(t *testing.T) { |
28 | 28 |
errFn func(err error) bool |
29 | 29 |
}{ |
30 | 30 |
{ |
31 |
- status: errors.NewNotFound(api.Resource(""), "").(errors.APIStatus).Status(), |
|
31 |
+ status: errors.NewNotFound(api.Resource(""), "").ErrStatus, |
|
32 | 32 |
errFn: func(err error) bool { return err == ErrImageStreamImportUnsupported }, |
33 | 33 |
}, |
34 | 34 |
{ |
35 |
- status: errors.NewNotFound(api.Resource("ImageStreamImport"), "").(errors.APIStatus).Status(), |
|
35 |
+ status: errors.NewNotFound(api.Resource("ImageStreamImport"), "").ErrStatus, |
|
36 | 36 |
errFn: func(err error) bool { return err != ErrImageStreamImportUnsupported && errors.IsNotFound(err) }, |
37 | 37 |
}, |
38 | 38 |
{ |
39 |
- status: errors.NewConflict(api.Resource("ImageStreamImport"), "", nil).(errors.APIStatus).Status(), |
|
39 |
+ status: errors.NewConflict(api.Resource("ImageStreamImport"), "", nil).ErrStatus, |
|
40 | 40 |
errFn: func(err error) bool { return err != ErrImageStreamImportUnsupported && errors.IsConflict(err) }, |
41 | 41 |
}, |
42 | 42 |
{ |
43 |
- status: errors.NewForbidden(api.Resource("ImageStreamImport"), "", nil).(errors.APIStatus).Status(), |
|
43 |
+ status: errors.NewForbidden(api.Resource("ImageStreamImport"), "", nil).ErrStatus, |
|
44 | 44 |
errFn: func(err error) bool { return err == ErrImageStreamImportUnsupported }, |
45 | 45 |
}, |
46 | 46 |
} |
... | ... |
@@ -41,8 +41,8 @@ func TestErrors(t *testing.T) { |
41 | 41 |
o := testclient.NewObjects(kapi.Scheme, kapi.Codecs.UniversalDecoder()) |
42 | 42 |
o.Add(&kapi.List{ |
43 | 43 |
Items: []runtime.Object{ |
44 |
- &(errors.NewNotFound(deployapi.Resource("DeploymentConfigList"), "").(*errors.StatusError).ErrStatus), |
|
45 |
- &(errors.NewForbidden(deployapi.Resource("DeploymentConfigList"), "", nil).(*errors.StatusError).ErrStatus), |
|
44 |
+ &(errors.NewNotFound(deployapi.Resource("DeploymentConfigList"), "").ErrStatus), |
|
45 |
+ &(errors.NewForbidden(deployapi.Resource("DeploymentConfigList"), "", nil).ErrStatus), |
|
46 | 46 |
}, |
47 | 47 |
}) |
48 | 48 |
oc, _ := NewFixtureClients(o) |
... | ... |
@@ -6,6 +6,8 @@ import ( |
6 | 6 |
|
7 | 7 |
"github.com/spf13/cobra" |
8 | 8 |
|
9 |
+ kubectl "k8s.io/kubernetes/pkg/kubectl/cmd" |
|
10 |
+ |
|
9 | 11 |
"github.com/openshift/origin/pkg/cmd/admin/cert" |
10 | 12 |
diagnostics "github.com/openshift/origin/pkg/cmd/admin/diagnostics" |
11 | 13 |
"github.com/openshift/origin/pkg/cmd/admin/groups" |
... | ... |
@@ -45,54 +47,55 @@ func NewCommandAdmin(name, fullName string, out io.Writer, errout io.Writer) *co |
45 | 45 |
|
46 | 46 |
groups := templates.CommandGroups{ |
47 | 47 |
{ |
48 |
- Message: "Basic Commands:", |
|
48 |
+ Message: "Component Installation:", |
|
49 |
+ Commands: []*cobra.Command{ |
|
50 |
+ router.NewCmdRouter(f, fullName, "router", out), |
|
51 |
+ exipfailover.NewCmdIPFailoverConfig(f, fullName, "ipfailover", out, errout), |
|
52 |
+ registry.NewCmdRegistry(f, fullName, "registry", out), |
|
53 |
+ }, |
|
54 |
+ }, |
|
55 |
+ { |
|
56 |
+ Message: "Security and Policy:", |
|
49 | 57 |
Commands: []*cobra.Command{ |
50 | 58 |
project.NewCmdNewProject(project.NewProjectRecommendedName, fullName+" "+project.NewProjectRecommendedName, f, out), |
51 | 59 |
policy.NewCmdPolicy(policy.PolicyRecommendedName, fullName+" "+policy.PolicyRecommendedName, f, out, errout), |
52 | 60 |
groups.NewCmdGroups(groups.GroupsRecommendedName, fullName+" "+groups.GroupsRecommendedName, f, out), |
61 |
+ cert.NewCmdCert(cert.CertRecommendedName, fullName+" "+cert.CertRecommendedName, out, errout), |
|
62 |
+ admin.NewCommandOverwriteBootstrapPolicy(admin.OverwriteBootstrapPolicyCommandName, fullName+" "+admin.OverwriteBootstrapPolicyCommandName, fullName+" "+admin.CreateBootstrapPolicyFileCommand, out), |
|
53 | 63 |
}, |
54 | 64 |
}, |
55 | 65 |
{ |
56 |
- Message: "Install Commands:", |
|
66 |
+ Message: "Node Management:", |
|
57 | 67 |
Commands: []*cobra.Command{ |
58 |
- router.NewCmdRouter(f, fullName, "router", out), |
|
59 |
- exipfailover.NewCmdIPFailoverConfig(f, fullName, "ipfailover", out, errout), |
|
60 |
- registry.NewCmdRegistry(f, fullName, "registry", out), |
|
68 |
+ admin.NewCommandNodeConfig(admin.NodeConfigCommandName, fullName+" "+admin.NodeConfigCommandName, out), |
|
69 |
+ node.NewCommandManageNode(f, node.ManageNodeCommandName, fullName+" "+node.ManageNodeCommandName, out, errout), |
|
70 |
+ cmdutil.ReplaceCommandName("kubectl", fullName, kubectl.NewCmdCordon(f.Factory, out)), |
|
71 |
+ cmdutil.ReplaceCommandName("kubectl", fullName, kubectl.NewCmdUncordon(f.Factory, out)), |
|
72 |
+ cmdutil.ReplaceCommandName("kubectl", fullName, kubectl.NewCmdDrain(f.Factory, out)), |
|
73 |
+ cmdutil.ReplaceCommandName("kubectl", fullName, kubectl.NewCmdTaint(f.Factory, out)), |
|
74 |
+ network.NewCmdPodNetwork(network.PodNetworkCommandName, fullName+" "+network.PodNetworkCommandName, f, out), |
|
61 | 75 |
}, |
62 | 76 |
}, |
63 | 77 |
{ |
64 |
- Message: "Maintenance Commands:", |
|
78 |
+ Message: "Maintenance:", |
|
65 | 79 |
Commands: []*cobra.Command{ |
66 |
- buildchain.NewCmdBuildChain(name, fullName+" "+buildchain.BuildChainRecommendedCommandName, f, out), |
|
67 | 80 |
diagnostics.NewCmdDiagnostics(diagnostics.DiagnosticsRecommendedName, fullName+" "+diagnostics.DiagnosticsRecommendedName, out), |
68 |
- node.NewCommandManageNode(f, node.ManageNodeCommandName, fullName+" "+node.ManageNodeCommandName, out, errout), |
|
69 | 81 |
prune.NewCommandPrune(prune.PruneRecommendedName, fullName+" "+prune.PruneRecommendedName, f, out), |
82 |
+ buildchain.NewCmdBuildChain(name, fullName+" "+buildchain.BuildChainRecommendedCommandName, f, out), |
|
70 | 83 |
}, |
71 | 84 |
}, |
72 | 85 |
{ |
73 |
- Message: "Settings Commands:", |
|
86 |
+ Message: "Configuration:", |
|
74 | 87 |
Commands: []*cobra.Command{ |
75 |
- cmd.NewCmdConfig(fullName, "config"), |
|
76 |
- |
|
77 |
- // TODO: these probably belong in a sub command |
|
78 | 88 |
admin.NewCommandCreateKubeConfig(admin.CreateKubeConfigCommandName, fullName+" "+admin.CreateKubeConfigCommandName, out), |
79 | 89 |
admin.NewCommandCreateClient(admin.CreateClientCommandName, fullName+" "+admin.CreateClientCommandName, out), |
80 | 90 |
|
81 |
- cmd.NewCmdCompletion(fullName, f, out), |
|
82 |
- }, |
|
83 |
- }, |
|
84 |
- { |
|
85 |
- Message: "Advanced Commands:", |
|
86 |
- Commands: []*cobra.Command{ |
|
87 |
- network.NewCmdPodNetwork(network.PodNetworkCommandName, fullName+" "+network.PodNetworkCommandName, f, out), |
|
88 | 91 |
admin.NewCommandCreateBootstrapProjectTemplate(f, admin.CreateBootstrapProjectTemplateCommand, fullName+" "+admin.CreateBootstrapProjectTemplateCommand, out), |
89 | 92 |
admin.NewCommandCreateBootstrapPolicyFile(admin.CreateBootstrapPolicyFileCommand, fullName+" "+admin.CreateBootstrapPolicyFileCommand, out), |
93 |
+ |
|
90 | 94 |
admin.NewCommandCreateLoginTemplate(f, admin.CreateLoginTemplateCommand, fullName+" "+admin.CreateLoginTemplateCommand, out), |
91 | 95 |
admin.NewCommandCreateProviderSelectionTemplate(f, admin.CreateProviderSelectionTemplateCommand, fullName+" "+admin.CreateProviderSelectionTemplateCommand, out), |
92 | 96 |
admin.NewCommandCreateErrorTemplate(f, admin.CreateErrorTemplateCommand, fullName+" "+admin.CreateErrorTemplateCommand, out), |
93 |
- admin.NewCommandOverwriteBootstrapPolicy(admin.OverwriteBootstrapPolicyCommandName, fullName+" "+admin.OverwriteBootstrapPolicyCommandName, fullName+" "+admin.CreateBootstrapPolicyFileCommand, out), |
|
94 |
- admin.NewCommandNodeConfig(admin.NodeConfigCommandName, fullName+" "+admin.NodeConfigCommandName, out), |
|
95 |
- cert.NewCmdCert(cert.CertRecommendedName, fullName+" "+cert.CertRecommendedName, out, errout), |
|
96 | 97 |
}, |
97 | 98 |
}, |
98 | 99 |
} |
... | ... |
@@ -114,11 +117,18 @@ func NewCommandAdmin(name, fullName string, out io.Writer, errout io.Writer) *co |
114 | 114 |
cmds.AddCommand(cmd) |
115 | 115 |
} |
116 | 116 |
|
117 |
+ cmds.AddCommand( |
|
118 |
+ // part of every root command |
|
119 |
+ cmd.NewCmdConfig(fullName, "config"), |
|
120 |
+ cmd.NewCmdCompletion(fullName, f, out), |
|
121 |
+ |
|
122 |
+ // hidden |
|
123 |
+ cmd.NewCmdOptions(out), |
|
124 |
+ ) |
|
125 |
+ |
|
117 | 126 |
if name == fullName { |
118 | 127 |
cmds.AddCommand(version.NewVersionCommand(fullName, false)) |
119 | 128 |
} |
120 | 129 |
|
121 |
- cmds.AddCommand(cmd.NewCmdOptions(out)) |
|
122 |
- |
|
123 | 130 |
return cmds |
124 | 131 |
} |
... | ... |
@@ -158,11 +158,11 @@ func (n *NodeOptions) GetNodes() ([]*kapi.Node, error) { |
158 | 158 |
} |
159 | 159 |
|
160 | 160 |
func (n *NodeOptions) GetPrintersByObject(obj runtime.Object) (kubectl.ResourcePrinter, kubectl.ResourcePrinter, error) { |
161 |
- gvk, err := kapi.Scheme.ObjectKind(obj) |
|
161 |
+ gvk, _, err := kapi.Scheme.ObjectKinds(obj) |
|
162 | 162 |
if err != nil { |
163 | 163 |
return nil, nil, err |
164 | 164 |
} |
165 |
- return n.GetPrinters(gvk) |
|
165 |
+ return n.GetPrinters(gvk[0]) |
|
166 | 166 |
} |
167 | 167 |
|
168 | 168 |
func (n *NodeOptions) GetPrintersByResource(resource unversioned.GroupVersionResource) (kubectl.ResourcePrinter, kubectl.ResourcePrinter, error) { |
... | ... |
@@ -94,7 +94,7 @@ func (o *CreateClusterQuotaOptions) Complete(cmd *cobra.Command, f *clientcmd.Fa |
94 | 94 |
if err != nil { |
95 | 95 |
return err |
96 | 96 |
} |
97 |
- o.ClusterQuota.Spec.Quota.Hard[kapi.ResourceName(tokens[0])] = *quantity |
|
97 |
+ o.ClusterQuota.Spec.Quota.Hard[kapi.ResourceName(tokens[0])] = quantity |
|
98 | 98 |
} |
99 | 99 |
|
100 | 100 |
o.Client, _, err = f.Clients() |
... | ... |
@@ -138,7 +138,7 @@ func RunExport(f *clientcmd.Factory, exporter Exporter, in io.Reader, out io.Wri |
138 | 138 |
|
139 | 139 |
var result runtime.Object |
140 | 140 |
if len(asTemplate) > 0 { |
141 |
- objects, err := resource.AsVersionedObjects(infos, outputVersion.String(), kapi.Codecs.LegacyCodec(outputVersion)) |
|
141 |
+ objects, err := resource.AsVersionedObjects(infos, outputVersion, kapi.Codecs.LegacyCodec(outputVersion)) |
|
142 | 142 |
if err != nil { |
143 | 143 |
return err |
144 | 144 |
} |
... | ... |
@@ -146,12 +146,12 @@ func RunExport(f *clientcmd.Factory, exporter Exporter, in io.Reader, out io.Wri |
146 | 146 |
Objects: objects, |
147 | 147 |
} |
148 | 148 |
template.Name = asTemplate |
149 |
- result, err = kapi.Scheme.ConvertToVersion(template, outputVersion.String()) |
|
149 |
+ result, err = kapi.Scheme.ConvertToVersion(template, outputVersion) |
|
150 | 150 |
if err != nil { |
151 | 151 |
return err |
152 | 152 |
} |
153 | 153 |
} else { |
154 |
- object, err := resource.AsVersionedObject(infos, !one, outputVersion.String(), kapi.Codecs.LegacyCodec(outputVersion)) |
|
154 |
+ object, err := resource.AsVersionedObject(infos, !one, outputVersion, kapi.Codecs.LegacyCodec(outputVersion)) |
|
155 | 155 |
if err != nil { |
156 | 156 |
return err |
157 | 157 |
} |
... | ... |
@@ -54,9 +54,8 @@ func parsePathSpec(path string) (*pathSpec, error) { |
54 | 54 |
Path: path, |
55 | 55 |
}, nil |
56 | 56 |
} |
57 |
- valid, msg := kvalidation.ValidatePodName(parts[0], false) |
|
58 |
- if !valid { |
|
59 |
- return nil, fmt.Errorf("invalid pod name %s: %s", parts[0], msg) |
|
57 |
+ if reasons := kvalidation.ValidatePodName(parts[0], false); len(reasons) != 0 { |
|
58 |
+ return nil, fmt.Errorf("invalid pod name %s: %s", parts[0], strings.Join(reasons, ", ")) |
|
60 | 59 |
} |
61 | 60 |
return &pathSpec{ |
62 | 61 |
PodName: parts[0], |
... | ... |
@@ -215,7 +215,7 @@ func (o *BuildHookOptions) Run() error { |
215 | 215 |
} |
216 | 216 |
|
217 | 217 |
if o.PrintObject != nil { |
218 |
- object, err := resource.AsVersionedObject(infos, !singular, o.OutputVersion.String(), kapi.Codecs.LegacyCodec(o.OutputVersion)) |
|
218 |
+ object, err := resource.AsVersionedObject(infos, !singular, o.OutputVersion, kapi.Codecs.LegacyCodec(o.OutputVersion)) |
|
219 | 219 |
if err != nil { |
220 | 220 |
return err |
221 | 221 |
} |
... | ... |
@@ -22,15 +22,15 @@ const ( |
22 | 22 |
deploymentHookLong = ` |
23 | 23 |
Set or remove a deployment hook on a deployment config |
24 | 24 |
|
25 |
-Deployment configs allow hooks to execute at different points in the lifecycle of the |
|
26 |
-deployment, depending on the deployment strategy. |
|
25 |
+Deployment configs allow hooks to execute at different points in the lifecycle of the |
|
26 |
+deployment, depending on the deployment strategy. |
|
27 | 27 |
|
28 |
-For deployments with a Recreate strategy, a Pre, Mid, and Post hook can be specified. |
|
29 |
-The Pre hook will execute before the deployment starts. The Mid hook will execute once the |
|
30 |
-previous deployment has been scaled down to 0, but before the new one ramps up. |
|
28 |
+For deployments with a Recreate strategy, a Pre, Mid, and Post hook can be specified. |
|
29 |
+The Pre hook will execute before the deployment starts. The Mid hook will execute once the |
|
30 |
+previous deployment has been scaled down to 0, but before the new one ramps up. |
|
31 | 31 |
The Post hook will execute once the deployment has completed. |
32 | 32 |
|
33 |
-For deployments with a Rolling strategy, a Pre and Post hook can be specified. |
|
33 |
+For deployments with a Rolling strategy, a Pre and Post hook can be specified. |
|
34 | 34 |
The Pre hook will execute before the deployment starts and the Post hook will execute once |
35 | 35 |
the deployment has completed. |
36 | 36 |
|
... | ... |
@@ -253,7 +253,7 @@ func (o *DeploymentHookOptions) Run() error { |
253 | 253 |
} |
254 | 254 |
|
255 | 255 |
if o.PrintObject != nil { |
256 |
- object, err := resource.AsVersionedObject(infos, !singular, o.OutputVersion.String(), kapi.Codecs.LegacyCodec(o.OutputVersion)) |
|
256 |
+ object, err := resource.AsVersionedObject(infos, !singular, o.OutputVersion, kapi.Codecs.LegacyCodec(o.OutputVersion)) |
|
257 | 257 |
if err != nil { |
258 | 258 |
return err |
259 | 259 |
} |
... | ... |
@@ -236,7 +236,8 @@ func RunEnv(f *clientcmd.Factory, in io.Reader, out io.Writer, cmd *cobra.Comman |
236 | 236 |
} |
237 | 237 |
// Keep a copy of the original objects prior to updating their environment. |
238 | 238 |
// Used in constructing the patch(es) that will be applied in the server. |
239 |
- oldObjects, err := resource.AsVersionedObjects(infos, clientConfig.GroupVersion.String(), kapi.Codecs.LegacyCodec(*clientConfig.GroupVersion)) |
|
239 |
+ gv := *clientConfig.GroupVersion |
|
240 |
+ oldObjects, err := resource.AsVersionedObjects(infos, gv, kapi.Codecs.LegacyCodec(gv)) |
|
240 | 241 |
if err != nil { |
241 | 242 |
return err |
242 | 243 |
} |
... | ... |
@@ -332,7 +333,7 @@ func RunEnv(f *clientcmd.Factory, in io.Reader, out io.Writer, cmd *cobra.Comman |
332 | 332 |
if err != nil { |
333 | 333 |
return err |
334 | 334 |
} |
335 |
- objects, err := resource.AsVersionedObjects(infos, outputVersion.String(), kapi.Codecs.LegacyCodec(outputVersion)) |
|
335 |
+ objects, err := resource.AsVersionedObjects(infos, outputVersion, kapi.Codecs.LegacyCodec(outputVersion)) |
|
336 | 336 |
if err != nil { |
337 | 337 |
return err |
338 | 338 |
} |
... | ... |
@@ -351,7 +352,7 @@ func RunEnv(f *clientcmd.Factory, in io.Reader, out io.Writer, cmd *cobra.Comman |
351 | 351 |
return nil |
352 | 352 |
} |
353 | 353 |
|
354 |
- objects, err := resource.AsVersionedObjects(infos, clientConfig.GroupVersion.String(), kapi.Codecs.LegacyCodec(*clientConfig.GroupVersion)) |
|
354 |
+ objects, err := resource.AsVersionedObjects(infos, gv, kapi.Codecs.LegacyCodec(gv)) |
|
355 | 355 |
if err != nil { |
356 | 356 |
return err |
357 | 357 |
} |
... | ... |
@@ -156,7 +156,7 @@ func CalculatePatches(infos []*resource.Info, encoder runtime.Encoder, mutateFn |
156 | 156 |
} |
157 | 157 |
|
158 | 158 |
// TODO: should be via New |
159 |
- versioned, err := info.Mapping.ConvertToVersion(info.Object, info.Mapping.GroupVersionKind.GroupVersion().String()) |
|
159 |
+ versioned, err := info.Mapping.ConvertToVersion(info.Object, info.Mapping.GroupVersionKind.GroupVersion()) |
|
160 | 160 |
if err != nil { |
161 | 161 |
patch.Err = err |
162 | 162 |
continue |
... | ... |
@@ -316,7 +316,7 @@ func (o *ProbeOptions) Run() error { |
316 | 316 |
} |
317 | 317 |
|
318 | 318 |
if o.PrintObject != nil { |
319 |
- object, err := resource.AsVersionedObject(infos, !singular, o.OutputVersion.String(), kapi.Codecs.LegacyCodec(o.OutputVersion)) |
|
319 |
+ object, err := resource.AsVersionedObject(infos, !singular, o.OutputVersion, kapi.Codecs.LegacyCodec(o.OutputVersion)) |
|
320 | 320 |
if err != nil { |
321 | 321 |
return err |
322 | 322 |
} |
... | ... |
@@ -284,7 +284,7 @@ func (o *TriggersOptions) Run() error { |
284 | 284 |
return fmt.Errorf("%s/%s is not a deployment config or build config", infos[0].Mapping.Resource, infos[0].Name) |
285 | 285 |
} |
286 | 286 |
if o.PrintObject != nil { |
287 |
- object, err := resource.AsVersionedObject(infos, !singular, o.OutputVersion.String(), kapi.Codecs.LegacyCodec(o.OutputVersion)) |
|
287 |
+ object, err := resource.AsVersionedObject(infos, !singular, o.OutputVersion, kapi.Codecs.LegacyCodec(o.OutputVersion)) |
|
288 | 288 |
if err != nil { |
289 | 289 |
return err |
290 | 290 |
} |
... | ... |
@@ -447,7 +447,7 @@ func (v *VolumeOptions) RunVolume(args []string) error { |
447 | 447 |
} |
448 | 448 |
|
449 | 449 |
// TODO: replace with a strategic merge patch |
450 |
- objects, err := resource.AsVersionedObject(infos, false, v.OutputVersion.String(), kapi.Codecs.LegacyCodec(v.OutputVersion)) |
|
450 |
+ objects, err := resource.AsVersionedObject(infos, false, v.OutputVersion, kapi.Codecs.LegacyCodec(v.OutputVersion)) |
|
451 | 451 |
if err != nil { |
452 | 452 |
return err |
453 | 453 |
} |
... | ... |
@@ -11,7 +11,7 @@ import ( |
11 | 11 |
kapi "k8s.io/kubernetes/pkg/api" |
12 | 12 |
kerrors "k8s.io/kubernetes/pkg/api/errors" |
13 | 13 |
"k8s.io/kubernetes/pkg/api/unversioned" |
14 |
- "k8s.io/kubernetes/pkg/apis/extensions" |
|
14 |
+ "k8s.io/kubernetes/pkg/apis/autoscaling" |
|
15 | 15 |
kclient "k8s.io/kubernetes/pkg/client/unversioned" |
16 | 16 |
rcutils "k8s.io/kubernetes/pkg/controller/replication" |
17 | 17 |
kctl "k8s.io/kubernetes/pkg/kubectl" |
... | ... |
@@ -264,22 +264,22 @@ func printDeploymentConfigSpec(kc kclient.Interface, dc deployapi.DeploymentConf |
264 | 264 |
|
265 | 265 |
// TODO: Move this upstream |
266 | 266 |
func printAutoscalingInfo(res unversioned.GroupResource, namespace, name string, kclient kclient.Interface, w *tabwriter.Writer) { |
267 |
- hpaList, err := kclient.Extensions().HorizontalPodAutoscalers(namespace).List(kapi.ListOptions{LabelSelector: labels.Everything()}) |
|
267 |
+ hpaList, err := kclient.Autoscaling().HorizontalPodAutoscalers(namespace).List(kapi.ListOptions{LabelSelector: labels.Everything()}) |
|
268 | 268 |
if err != nil { |
269 | 269 |
return |
270 | 270 |
} |
271 | 271 |
|
272 |
- scaledBy := []extensions.HorizontalPodAutoscaler{} |
|
272 |
+ scaledBy := []autoscaling.HorizontalPodAutoscaler{} |
|
273 | 273 |
for _, hpa := range hpaList.Items { |
274 |
- if hpa.Spec.ScaleRef.Name == name && hpa.Spec.ScaleRef.Kind == res.String() { |
|
274 |
+ if hpa.Spec.ScaleTargetRef.Name == name && hpa.Spec.ScaleTargetRef.Kind == res.String() { |
|
275 | 275 |
scaledBy = append(scaledBy, hpa) |
276 | 276 |
} |
277 | 277 |
} |
278 | 278 |
|
279 | 279 |
for _, hpa := range scaledBy { |
280 | 280 |
cpuUtil := "" |
281 |
- if hpa.Spec.CPUUtilization != nil { |
|
282 |
- cpuUtil = fmt.Sprintf(", triggered at %d%% CPU usage", hpa.Spec.CPUUtilization.TargetPercentage) |
|
281 |
+ if hpa.Spec.TargetCPUUtilizationPercentage != nil { |
|
282 |
+ cpuUtil = fmt.Sprintf(", triggered at %d%% CPU usage", *hpa.Spec.TargetCPUUtilizationPercentage) |
|
283 | 283 |
} |
284 | 284 |
fmt.Fprintf(w, "Autoscaling:\tbetween %d and %d replicas%s\n", *hpa.Spec.MinReplicas, hpa.Spec.MaxReplicas, cpuUtil) |
285 | 285 |
// TODO: Print a warning in case of multiple hpas. |
... | ... |
@@ -5,7 +5,7 @@ import ( |
5 | 5 |
"testing" |
6 | 6 |
|
7 | 7 |
kapi "k8s.io/kubernetes/pkg/api" |
8 |
- "k8s.io/kubernetes/pkg/apis/extensions" |
|
8 |
+ "k8s.io/kubernetes/pkg/apis/autoscaling" |
|
9 | 9 |
ktestclient "k8s.io/kubernetes/pkg/client/unversioned/testclient" |
10 | 10 |
"k8s.io/kubernetes/pkg/kubectl" |
11 | 11 |
"k8s.io/kubernetes/pkg/runtime" |
... | ... |
@@ -27,8 +27,8 @@ func TestDeploymentConfigDescriber(t *testing.T) { |
27 | 27 |
}) |
28 | 28 |
kFake := &ktestclient.Fake{} |
29 | 29 |
kFake.PrependReactor("list", "horizontalpodautoscalers", func(action ktestclient.Action) (handled bool, ret runtime.Object, err error) { |
30 |
- return true, &extensions.HorizontalPodAutoscalerList{ |
|
31 |
- Items: []extensions.HorizontalPodAutoscaler{ |
|
30 |
+ return true, &autoscaling.HorizontalPodAutoscalerList{ |
|
31 |
+ Items: []autoscaling.HorizontalPodAutoscaler{ |
|
32 | 32 |
*deployapitest.OkHPAForDeploymentConfig(config, 1, 3), |
33 | 33 |
}}, nil |
34 | 34 |
}) |
... | ... |
@@ -915,10 +915,14 @@ func (d *TemplateDescriber) describeObjects(objects []runtime.Object, out *tabwr |
915 | 915 |
continue |
916 | 916 |
} |
917 | 917 |
|
918 |
- gvk, _ := d.ObjectTyper.ObjectKind(obj) |
|
919 | 918 |
meta := kapi.ObjectMeta{} |
920 | 919 |
meta.Name, _ = d.MetadataAccessor.Name(obj) |
921 |
- fmt.Fprintf(out, fmt.Sprintf("%s%s\t%s\n", indent, gvk.Kind, meta.Name)) |
|
920 |
+ gvk, _, err := d.ObjectTyper.ObjectKinds(obj) |
|
921 |
+ if err != nil { |
|
922 |
+ fmt.Fprintf(out, fmt.Sprintf("%s%s\t%s\n", indent, "<unknown>", meta.Name)) |
|
923 |
+ continue |
|
924 |
+ } |
|
925 |
+ fmt.Fprintf(out, fmt.Sprintf("%s%s\t%s\n", indent, gvk[0].Kind, meta.Name)) |
|
922 | 926 |
//meta.Annotations, _ = d.MetadataAccessor.Annotations(obj) |
923 | 927 |
//meta.Labels, _ = d.MetadataAccessor.Labels(obj) |
924 | 928 |
/*if len(meta.Labels) > 0 { |
... | ... |
@@ -11,7 +11,7 @@ import ( |
11 | 11 |
kapi "k8s.io/kubernetes/pkg/api" |
12 | 12 |
kapierrors "k8s.io/kubernetes/pkg/api/errors" |
13 | 13 |
"k8s.io/kubernetes/pkg/api/unversioned" |
14 |
- "k8s.io/kubernetes/pkg/apis/extensions" |
|
14 |
+ "k8s.io/kubernetes/pkg/apis/autoscaling" |
|
15 | 15 |
kclient "k8s.io/kubernetes/pkg/client/unversioned" |
16 | 16 |
utilerrors "k8s.io/kubernetes/pkg/util/errors" |
17 | 17 |
"k8s.io/kubernetes/pkg/util/sets" |
... | ... |
@@ -66,7 +66,7 @@ func (d *ProjectStatusDescriber) MakeGraph(namespace string) (osgraph.Graph, set |
66 | 66 |
&secretLoader{namespace: namespace, lister: d.K}, |
67 | 67 |
&rcLoader{namespace: namespace, lister: d.K}, |
68 | 68 |
&podLoader{namespace: namespace, lister: d.K}, |
69 |
- &horizontalPodAutoscalerLoader{namespace: namespace, lister: d.K.Extensions()}, |
|
69 |
+ &horizontalPodAutoscalerLoader{namespace: namespace, lister: d.K.Autoscaling()}, |
|
70 | 70 |
// TODO check swagger for feature enablement and selectively add bcLoader and buildLoader |
71 | 71 |
// then remove errors.TolerateNotFoundError method. |
72 | 72 |
&bcLoader{namespace: namespace, lister: d.C}, |
... | ... |
@@ -1188,7 +1188,7 @@ func (l *podLoader) AddToGraph(g osgraph.Graph) error { |
1188 | 1188 |
type horizontalPodAutoscalerLoader struct { |
1189 | 1189 |
namespace string |
1190 | 1190 |
lister kclient.HorizontalPodAutoscalersNamespacer |
1191 |
- items []extensions.HorizontalPodAutoscaler |
|
1191 |
+ items []autoscaling.HorizontalPodAutoscaler |
|
1192 | 1192 |
} |
1193 | 1193 |
|
1194 | 1194 |
func (l *horizontalPodAutoscalerLoader) Load() error { |
... | ... |
@@ -20,9 +20,12 @@ var MissingCommands = sets.NewString( |
20 | 20 |
"namespace", "rolling-update", |
21 | 21 |
"cluster-info", "api-versions", |
22 | 22 |
"stop", |
23 |
+ |
|
24 |
+ // are on admin commands |
|
23 | 25 |
"cordon", |
24 | 26 |
"drain", |
25 | 27 |
"uncordon", |
28 |
+ "taint", |
|
26 | 29 |
) |
27 | 30 |
|
28 | 31 |
// WhitelistedCommands is the list of commands we're never going to have in oc |
... | ... |
@@ -120,7 +120,7 @@ func (o *PatchOptions) RunPatch() error { |
120 | 120 |
} |
121 | 121 |
info := infos[0] |
122 | 122 |
|
123 |
- originalObjJS, err := runtime.Encode(configapi.Codecs.LegacyCodec(), info.VersionedObject.(runtime.Object)) |
|
123 |
+ originalObjJS, err := runtime.Encode(configapi.Codecs.LegacyCodec(info.Mapping.GroupVersionKind.GroupVersion()), info.VersionedObject.(runtime.Object)) |
|
124 | 124 |
if err != nil { |
125 | 125 |
return err |
126 | 126 |
} |
... | ... |
@@ -10,6 +10,7 @@ import ( |
10 | 10 |
|
11 | 11 |
deployapi "github.com/openshift/origin/pkg/deploy/api" |
12 | 12 |
deploytest "github.com/openshift/origin/pkg/deploy/api/test" |
13 |
+ deployv1 "github.com/openshift/origin/pkg/deploy/api/v1" |
|
13 | 14 |
scalertest "github.com/openshift/origin/pkg/deploy/scaler/test" |
14 | 15 |
"github.com/openshift/origin/pkg/deploy/strategy" |
15 | 16 |
deployutil "github.com/openshift/origin/pkg/deploy/util" |
... | ... |
@@ -197,7 +198,7 @@ func TestDeployer_deployScenarios(t *testing.T) { |
197 | 197 |
} |
198 | 198 |
|
199 | 199 |
func mkdeployment(version int64, status deployapi.DeploymentStatus) *kapi.ReplicationController { |
200 |
- deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(version), kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
200 |
+ deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(version), kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
201 | 201 |
deployment.Annotations[deployapi.DeploymentStatusAnnotation] = string(status) |
202 | 202 |
return deployment |
203 | 203 |
} |
... | ... |
@@ -82,7 +82,7 @@ func (o CreateBootstrapPolicyFileOptions) CreateBootstrapPolicyFile() error { |
82 | 82 |
|
83 | 83 |
clusterRoles := bootstrappolicy.GetBootstrapClusterRoles() |
84 | 84 |
for i := range clusterRoles { |
85 |
- versionedObject, err := kapi.Scheme.ConvertToVersion(&clusterRoles[i], latest.Version.String()) |
|
85 |
+ versionedObject, err := kapi.Scheme.ConvertToVersion(&clusterRoles[i], latest.Version) |
|
86 | 86 |
if err != nil { |
87 | 87 |
return err |
88 | 88 |
} |
... | ... |
@@ -91,7 +91,7 @@ func (o CreateBootstrapPolicyFileOptions) CreateBootstrapPolicyFile() error { |
91 | 91 |
|
92 | 92 |
clusterRoleBindings := bootstrappolicy.GetBootstrapClusterRoleBindings() |
93 | 93 |
for i := range clusterRoleBindings { |
94 |
- versionedObject, err := kapi.Scheme.ConvertToVersion(&clusterRoleBindings[i], latest.Version.String()) |
|
94 |
+ versionedObject, err := kapi.Scheme.ConvertToVersion(&clusterRoleBindings[i], latest.Version) |
|
95 | 95 |
if err != nil { |
96 | 96 |
return err |
97 | 97 |
} |
... | ... |
@@ -100,7 +100,7 @@ func (o CreateBootstrapPolicyFileOptions) CreateBootstrapPolicyFile() error { |
100 | 100 |
|
101 | 101 |
openshiftRoles := bootstrappolicy.GetBootstrapOpenshiftRoles(o.OpenShiftSharedResourcesNamespace) |
102 | 102 |
for i := range openshiftRoles { |
103 |
- versionedObject, err := kapi.Scheme.ConvertToVersion(&openshiftRoles[i], latest.Version.String()) |
|
103 |
+ versionedObject, err := kapi.Scheme.ConvertToVersion(&openshiftRoles[i], latest.Version) |
|
104 | 104 |
if err != nil { |
105 | 105 |
return err |
106 | 106 |
} |
... | ... |
@@ -109,14 +109,14 @@ func (o CreateBootstrapPolicyFileOptions) CreateBootstrapPolicyFile() error { |
109 | 109 |
|
110 | 110 |
openshiftRoleBindings := bootstrappolicy.GetBootstrapOpenshiftRoleBindings(o.OpenShiftSharedResourcesNamespace) |
111 | 111 |
for i := range openshiftRoleBindings { |
112 |
- versionedObject, err := kapi.Scheme.ConvertToVersion(&openshiftRoleBindings[i], latest.Version.String()) |
|
112 |
+ versionedObject, err := kapi.Scheme.ConvertToVersion(&openshiftRoleBindings[i], latest.Version) |
|
113 | 113 |
if err != nil { |
114 | 114 |
return err |
115 | 115 |
} |
116 | 116 |
policyTemplate.Objects = append(policyTemplate.Objects, versionedObject) |
117 | 117 |
} |
118 | 118 |
|
119 |
- versionedPolicyTemplate, err := kapi.Scheme.ConvertToVersion(policyTemplate, latest.Version.String()) |
|
119 |
+ versionedPolicyTemplate, err := kapi.Scheme.ConvertToVersion(policyTemplate, latest.Version) |
|
120 | 120 |
if err != nil { |
121 | 121 |
return err |
122 | 122 |
} |
... | ... |
@@ -432,11 +432,11 @@ func (o CreateNodeConfigOptions) MakeNodeConfig(serverCertFile, serverKeyFile, n |
432 | 432 |
} |
433 | 433 |
|
434 | 434 |
// Roundtrip the config to v1 and back to ensure proper defaults are set. |
435 |
- ext, err := configapi.Scheme.ConvertToVersion(config, latestconfigapi.Version.String()) |
|
435 |
+ ext, err := configapi.Scheme.ConvertToVersion(config, latestconfigapi.Version) |
|
436 | 436 |
if err != nil { |
437 | 437 |
return err |
438 | 438 |
} |
439 |
- internal, err := configapi.Scheme.ConvertToVersion(ext, configapi.SchemeGroupVersion.String()) |
|
439 |
+ internal, err := configapi.Scheme.ConvertToVersion(ext, configapi.SchemeGroupVersion) |
|
440 | 440 |
if err != nil { |
441 | 441 |
return err |
442 | 442 |
} |
... | ... |
@@ -293,7 +293,7 @@ func addConversionFuncs(scheme *runtime.Scheme) { |
293 | 293 |
} |
294 | 294 |
if in.Provider.Object != nil { |
295 | 295 |
var err error |
296 |
- out.Provider, err = internal.Scheme.ConvertToVersion(in.Provider.Object, internal.SchemeGroupVersion.String()) |
|
296 |
+ out.Provider, err = internal.Scheme.ConvertToVersion(in.Provider.Object, internal.SchemeGroupVersion) |
|
297 | 297 |
if err != nil { |
298 | 298 |
return err |
299 | 299 |
} |
... | ... |
@@ -317,7 +317,7 @@ func addConversionFuncs(scheme *runtime.Scheme) { |
317 | 317 |
} |
318 | 318 |
if in.Configuration.Object != nil { |
319 | 319 |
var err error |
320 |
- out.Configuration, err = internal.Scheme.ConvertToVersion(in.Configuration.Object, internal.SchemeGroupVersion.String()) |
|
320 |
+ out.Configuration, err = internal.Scheme.ConvertToVersion(in.Configuration.Object, internal.SchemeGroupVersion) |
|
321 | 321 |
if err != nil { |
322 | 322 |
return err |
323 | 323 |
} |
... | ... |
@@ -4,7 +4,6 @@ import ( |
4 | 4 |
"testing" |
5 | 5 |
|
6 | 6 |
"github.com/ghodss/yaml" |
7 |
- "speter.net/go/exp/math/dec/inf" |
|
8 | 7 |
|
9 | 8 |
"k8s.io/kubernetes/pkg/api/unversioned" |
10 | 9 |
"k8s.io/kubernetes/pkg/runtime" |
... | ... |
@@ -532,7 +531,7 @@ volumeConfig: |
532 | 532 |
localQuota: |
533 | 533 |
perFSGroup: 200000 |
534 | 534 |
`, |
535 |
- expected: "200000", |
|
535 |
+ expected: "200k", |
|
536 | 536 |
}, |
537 | 537 |
"Kb quota": { |
538 | 538 |
config: ` |
... | ... |
@@ -541,7 +540,7 @@ volumeConfig: |
541 | 541 |
localQuota: |
542 | 542 |
perFSGroup: 200Ki |
543 | 543 |
`, |
544 |
- expected: "204800", |
|
544 |
+ expected: "200Ki", |
|
545 | 545 |
}, |
546 | 546 |
"Mb quota": { |
547 | 547 |
config: ` |
... | ... |
@@ -550,7 +549,7 @@ volumeConfig: |
550 | 550 |
localQuota: |
551 | 551 |
perFSGroup: 512Mi |
552 | 552 |
`, |
553 |
- expected: "536870912", |
|
553 |
+ expected: "512Mi", |
|
554 | 554 |
}, |
555 | 555 |
"Gb quota": { |
556 | 556 |
config: ` |
... | ... |
@@ -559,7 +558,7 @@ volumeConfig: |
559 | 559 |
localQuota: |
560 | 560 |
perFSGroup: 2Gi |
561 | 561 |
`, |
562 |
- expected: "2147483648", |
|
562 |
+ expected: "2Gi", |
|
563 | 563 |
}, |
564 | 564 |
"Tb quota": { |
565 | 565 |
config: ` |
... | ... |
@@ -568,7 +567,7 @@ volumeConfig: |
568 | 568 |
localQuota: |
569 | 569 |
perFSGroup: 2Ti |
570 | 570 |
`, |
571 |
- expected: "2199023255552", |
|
571 |
+ expected: "2Ti", |
|
572 | 572 |
}, |
573 | 573 |
// This is invalid config, would be caught by validation but just |
574 | 574 |
// testing it parses ok: |
... | ... |
@@ -579,7 +578,7 @@ volumeConfig: |
579 | 579 |
localQuota: |
580 | 580 |
perFSGroup: -512Mi |
581 | 581 |
`, |
582 |
- expected: "-536870912", |
|
582 |
+ expected: "-512Mi", |
|
583 | 583 |
}, |
584 | 584 |
"zero quota": { |
585 | 585 |
config: ` |
... | ... |
@@ -599,19 +598,16 @@ volumeConfig: |
599 | 599 |
t.Errorf("Error reading yaml: %s", err.Error()) |
600 | 600 |
} |
601 | 601 |
if test.expected == "" && nodeConfig.VolumeConfig.LocalQuota.PerFSGroup != nil { |
602 |
- t.Errorf("Expected empty quota but got: %s", *nodeConfig.VolumeConfig.LocalQuota.PerFSGroup) |
|
602 |
+ t.Errorf("Expected empty quota but got: %v", nodeConfig.VolumeConfig.LocalQuota.PerFSGroup) |
|
603 | 603 |
} |
604 | 604 |
if test.expected != "" { |
605 | 605 |
if nodeConfig.VolumeConfig.LocalQuota.PerFSGroup == nil { |
606 | 606 |
t.Errorf("Expected quota: %s, got: nil", test.expected) |
607 | 607 |
} else { |
608 |
- amount := nodeConfig.VolumeConfig.LocalQuota.PerFSGroup.Amount |
|
608 |
+ amount := nodeConfig.VolumeConfig.LocalQuota.PerFSGroup |
|
609 | 609 |
t.Logf("%s", amount.String()) |
610 |
- rounded := new(inf.Dec) |
|
611 |
- rounded.Round(amount, 0, inf.RoundUp) |
|
612 |
- t.Logf("%s", rounded.String()) |
|
613 |
- if test.expected != rounded.String() { |
|
614 |
- t.Errorf("Expected quota: %s, got: %s", test.expected, rounded.String()) |
|
610 |
+ if test.expected != amount.String() { |
|
611 |
+ t.Errorf("Expected quota: %s, got: %s", test.expected, amount.String()) |
|
615 | 612 |
} |
616 | 613 |
} |
617 | 614 |
} |
... | ... |
@@ -276,8 +276,8 @@ func ValidateServiceAccountConfig(config api.ServiceAccountConfig, builtInKubern |
276 | 276 |
} |
277 | 277 |
|
278 | 278 |
for i, name := range config.ManagedNames { |
279 |
- if ok, msg := kvalidation.ValidateServiceAccountName(name, false); !ok { |
|
280 |
- validationResults.AddErrors(field.Invalid(managedNamesPath.Index(i), name, msg)) |
|
279 |
+ if reasons := kvalidation.ValidateServiceAccountName(name, false); len(reasons) != 0 { |
|
280 |
+ validationResults.AddErrors(field.Invalid(managedNamesPath.Index(i), name, strings.Join(reasons, ", "))) |
|
281 | 281 |
} |
282 | 282 |
} |
283 | 283 |
|
... | ... |
@@ -574,7 +574,7 @@ func ValidateRoutingConfig(config api.RoutingConfig, fldPath *field.Path) field. |
574 | 574 |
|
575 | 575 |
if len(config.Subdomain) == 0 { |
576 | 576 |
allErrs = append(allErrs, field.Required(fldPath.Child("subdomain"), "")) |
577 |
- } else if !kuval.IsDNS1123Subdomain(config.Subdomain) { |
|
577 |
+ } else if len(kuval.IsDNS1123Subdomain(config.Subdomain)) != 0 { |
|
578 | 578 |
allErrs = append(allErrs, field.Invalid(fldPath.Child("subdomain"), config.Subdomain, "must be a valid subdomain")) |
579 | 579 |
} |
580 | 580 |
|
... | ... |
@@ -149,8 +149,8 @@ func ValidateIdentityProvider(identityProvider api.IdentityProvider, fldPath *fi |
149 | 149 |
if len(identityProvider.Name) == 0 { |
150 | 150 |
validationResults.AddErrors(field.Required(fldPath.Child("name"), "")) |
151 | 151 |
} |
152 |
- if ok, err := validation.ValidateIdentityProviderName(identityProvider.Name); !ok { |
|
153 |
- validationResults.AddErrors(field.Invalid(fldPath.Child("name"), identityProvider.Name, err)) |
|
152 |
+ if reasons := validation.ValidateIdentityProviderName(identityProvider.Name); len(reasons) != 0 { |
|
153 |
+ validationResults.AddErrors(field.Invalid(fldPath.Child("name"), identityProvider.Name, strings.Join(reasons, ", "))) |
|
154 | 154 |
} |
155 | 155 |
|
156 | 156 |
if len(identityProvider.MappingMethod) == 0 { |
... | ... |
@@ -167,7 +167,7 @@ func ValidateNamedCertificates(fldPath *field.Path, namedCertificates []api.Name |
167 | 167 |
// validate names as domain names or *.*.foo.com domain names |
168 | 168 |
validDNSName := true |
169 | 169 |
for _, s := range strings.Split(name, ".") { |
170 |
- if s != "*" && !utilvalidation.IsDNS1123Label(s) { |
|
170 |
+ if s != "*" && len(utilvalidation.IsDNS1123Label(s)) != 0 { |
|
171 | 171 |
validDNSName = false |
172 | 172 |
} |
173 | 173 |
} |
... | ... |
@@ -313,7 +313,7 @@ func ValidateNamespace(namespace string, fldPath *field.Path) field.ErrorList { |
313 | 313 |
|
314 | 314 |
if len(namespace) == 0 { |
315 | 315 |
allErrs = append(allErrs, field.Required(fldPath, "")) |
316 |
- } else if ok, _ := kvalidation.ValidateNamespaceName(namespace, false); !ok { |
|
316 |
+ } else if reasons := kvalidation.ValidateNamespaceName(namespace, false); len(reasons) != 0 { |
|
317 | 317 |
allErrs = append(allErrs, field.Invalid(fldPath, namespace, "must be a valid namespace")) |
318 | 318 |
} |
319 | 319 |
|
... | ... |
@@ -26,6 +26,7 @@ import ( |
26 | 26 |
clientadapter "k8s.io/kubernetes/pkg/client/unversioned/adapters/internalclientset" |
27 | 27 |
"k8s.io/kubernetes/pkg/cloudprovider" |
28 | 28 |
"k8s.io/kubernetes/pkg/genericapiserver" |
29 |
+ genericapiserveroptions "k8s.io/kubernetes/pkg/genericapiserver/options" |
|
29 | 30 |
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client" |
30 | 31 |
"k8s.io/kubernetes/pkg/master" |
31 | 32 |
"k8s.io/kubernetes/pkg/registry/cachesize" |
... | ... |
@@ -251,7 +252,7 @@ func BuildKubernetesMasterConfig(options configapi.MasterConfig, requestContextM |
251 | 251 |
KeyFile: options.EtcdClientInfo.ClientCert.KeyFile, |
252 | 252 |
CertFile: options.EtcdClientInfo.ClientCert.CertFile, |
253 | 253 |
CAFile: options.EtcdClientInfo.CA, |
254 |
- DeserializationCacheSize: genericapiserver.DefaultDeserializationCacheSize, |
|
254 |
+ DeserializationCacheSize: genericapiserveroptions.DefaultDeserializationCacheSize, |
|
255 | 255 |
} |
256 | 256 |
storageFactory := genericapiserver.NewDefaultStorageFactory(etcdConfig, "", kapi.Codecs, resourceEncodingConfig, master.DefaultAPIResourceConfigSource()) |
257 | 257 |
// the order here is important, it defines which version will be used for storage |
... | ... |
@@ -13,7 +13,7 @@ import ( |
13 | 13 |
"k8s.io/kubernetes/pkg/apimachinery/registered" |
14 | 14 |
"k8s.io/kubernetes/pkg/apis/componentconfig" |
15 | 15 |
extensionsapiv1beta1 "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" |
16 |
- "k8s.io/kubernetes/pkg/genericapiserver" |
|
16 |
+ genericapiserveroptions "k8s.io/kubernetes/pkg/genericapiserver/options" |
|
17 | 17 |
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client" |
18 | 18 |
"k8s.io/kubernetes/pkg/storage/storagebackend" |
19 | 19 |
utilconfig "k8s.io/kubernetes/pkg/util/config" |
... | ... |
@@ -29,7 +29,7 @@ func TestAPIServerDefaults(t *testing.T) { |
29 | 29 |
// If the default changes (new fields are added, or default values change), we want to know |
30 | 30 |
// Once we've reacted to the changes appropriately in BuildKubernetesMasterConfig(), update this expected default to match the new upstream defaults |
31 | 31 |
expectedDefaults := &apiserveroptions.APIServer{ |
32 |
- ServerRunOptions: &genericapiserver.ServerRunOptions{ |
|
32 |
+ ServerRunOptions: &genericapiserveroptions.ServerRunOptions{ |
|
33 | 33 |
BindAddress: net.ParseIP("0.0.0.0"), |
34 | 34 |
CertDirectory: "/var/run/kubernetes", |
35 | 35 |
InsecureBindAddress: net.ParseIP("127.0.0.1"), |
... | ... |
@@ -49,15 +49,15 @@ func TestAPIServerDefaults(t *testing.T) { |
49 | 49 |
DefaultStorageVersions: registered.AllPreferredGroupVersions(), |
50 | 50 |
StorageConfig: storagebackend.Config{ |
51 | 51 |
Prefix: "/registry", |
52 |
- DeserializationCacheSize: genericapiserver.DefaultDeserializationCacheSize, |
|
52 |
+ DeserializationCacheSize: genericapiserveroptions.DefaultDeserializationCacheSize, |
|
53 | 53 |
}, |
54 |
+ DefaultStorageMediaType: "application/json", |
|
55 |
+ AdmissionControl: "AlwaysAdmit", |
|
56 |
+ AuthorizationMode: "AlwaysAllow", |
|
57 |
+ DeleteCollectionWorkers: 1, |
|
58 |
+ MasterServiceNamespace: "default", |
|
54 | 59 |
}, |
55 |
- DefaultStorageMediaType: "application/json", |
|
56 |
- AdmissionControl: "AlwaysAdmit", |
|
57 |
- AuthorizationMode: "AlwaysAllow", |
|
58 |
- DeleteCollectionWorkers: 1, |
|
59 |
- EventTTL: 1 * time.Hour, |
|
60 |
- MasterServiceNamespace: "default", |
|
60 |
+ EventTTL: 1 * time.Hour, |
|
61 | 61 |
KubeletConfig: kubeletclient.KubeletClientConfig{ |
62 | 62 |
Port: 10250, |
63 | 63 |
EnableHttps: true, |
... | ... |
@@ -232,7 +232,7 @@ func (c *NodeConfig) EnsureLocalQuota(nodeConfig configapi.NodeConfig) { |
232 | 232 |
// Can't really do type checking or use a constant here as they are not exported: |
233 | 233 |
if plugin.CanSupport(emptyDirSpec) { |
234 | 234 |
wrapper := emptydir.EmptyDirQuotaPlugin{ |
235 |
- Wrapped: plugin, |
|
235 |
+ VolumePlugin: plugin, |
|
236 | 236 |
Quota: *nodeConfig.VolumeConfig.LocalQuota.PerFSGroup, |
237 | 237 |
QuotaApplicator: quotaApplicator, |
238 | 238 |
} |
... | ... |
@@ -128,7 +128,7 @@ func forbidden(reason string, attributes authorizer.AuthorizationAttributes, w h |
128 | 128 |
// We don't have direct access to kind or name (not that those apply either in the general case) |
129 | 129 |
// We create a NewForbidden to stay close the API, but then we override the message to get a serialization |
130 | 130 |
// that makes sense when a human reads it. |
131 |
- forbiddenError, _ := kapierrors.NewForbidden(unversioned.GroupResource{Group: group, Resource: resource}, name, errors.New("") /*discarded*/).(*kapierrors.StatusError) |
|
131 |
+ forbiddenError := kapierrors.NewForbidden(unversioned.GroupResource{Group: group, Resource: resource}, name, errors.New("") /*discarded*/) |
|
132 | 132 |
forbiddenError.ErrStatus.Message = reason |
133 | 133 |
|
134 | 134 |
formatted := &bytes.Buffer{} |
... | ... |
@@ -22,7 +22,7 @@ import ( |
22 | 22 |
kclient "k8s.io/kubernetes/pkg/client/unversioned" |
23 | 23 |
clientadapter "k8s.io/kubernetes/pkg/client/unversioned/adapters/internalclientset" |
24 | 24 |
sacontroller "k8s.io/kubernetes/pkg/controller/serviceaccount" |
25 |
- "k8s.io/kubernetes/pkg/genericapiserver" |
|
25 |
+ genericapiserveroptions "k8s.io/kubernetes/pkg/genericapiserver/options" |
|
26 | 26 |
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client" |
27 | 27 |
"k8s.io/kubernetes/pkg/runtime" |
28 | 28 |
"k8s.io/kubernetes/pkg/serviceaccount" |
... | ... |
@@ -343,7 +343,7 @@ func newServiceAccountTokenGetter(options configapi.MasterConfig, client newetcd |
343 | 343 |
} else { |
344 | 344 |
// When we're running in-process, go straight to etcd (using the KubernetesStorageVersion/KubernetesStoragePrefix, since service accounts are kubernetes objects) |
345 | 345 |
codec := kapi.Codecs.LegacyCodec(unversioned.GroupVersion{Group: kapi.GroupName, Version: options.EtcdStorageConfig.KubernetesStorageVersion}) |
346 |
- ketcdHelper := etcdstorage.NewEtcdStorage(client, codec, options.EtcdStorageConfig.KubernetesStoragePrefix, false, genericapiserver.DefaultDeserializationCacheSize) |
|
346 |
+ ketcdHelper := etcdstorage.NewEtcdStorage(client, codec, options.EtcdStorageConfig.KubernetesStoragePrefix, false, genericapiserveroptions.DefaultDeserializationCacheSize) |
|
347 | 347 |
tokenGetter = sacontroller.NewGetterFromStorageInterface(ketcdHelper) |
348 | 348 |
} |
349 | 349 |
return tokenGetter, nil |
... | ... |
@@ -734,7 +734,7 @@ func (c *MasterConfig) OriginNamespaceControllerClients() (*osclient.Client, *kc |
734 | 734 |
|
735 | 735 |
// NewEtcdStorage returns a storage interface for the provided storage version. |
736 | 736 |
func NewEtcdStorage(client newetcdclient.Client, version unversioned.GroupVersion, prefix string) (oshelper storage.Interface, err error) { |
737 |
- return etcdstorage.NewEtcdStorage(client, kapi.Codecs.LegacyCodec(version), prefix, false, genericapiserver.DefaultDeserializationCacheSize), nil |
|
737 |
+ return etcdstorage.NewEtcdStorage(client, kapi.Codecs.LegacyCodec(version), prefix, false, genericapiserveroptions.DefaultDeserializationCacheSize), nil |
|
738 | 738 |
} |
739 | 739 |
|
740 | 740 |
// GetServiceAccountClients returns an OpenShift and Kubernetes client with the credentials of the |
... | ... |
@@ -9,7 +9,7 @@ import ( |
9 | 9 |
"k8s.io/kubernetes/pkg/api/rest" |
10 | 10 |
extapi "k8s.io/kubernetes/pkg/apis/extensions" |
11 | 11 |
"k8s.io/kubernetes/pkg/client/unversioned/testclient" |
12 |
- "k8s.io/kubernetes/pkg/genericapiserver" |
|
12 |
+ genericapiserveroptions "k8s.io/kubernetes/pkg/genericapiserver/options" |
|
13 | 13 |
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client" |
14 | 14 |
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd" |
15 | 15 |
|
... | ... |
@@ -72,7 +72,7 @@ func TestValidationRegistration(t *testing.T) { |
72 | 72 |
|
73 | 73 |
// fakeMasterConfig creates a new fake master config with an empty kubelet config and dummy storage. |
74 | 74 |
func fakeMasterConfig() *MasterConfig { |
75 |
- etcdHelper := etcdstorage.NewEtcdStorage(nil, api.Codecs.LegacyCodec(), "", false, genericapiserver.DefaultDeserializationCacheSize) |
|
75 |
+ etcdHelper := etcdstorage.NewEtcdStorage(nil, api.Codecs.LegacyCodec(), "", false, genericapiserveroptions.DefaultDeserializationCacheSize) |
|
76 | 76 |
|
77 | 77 |
informerFactory := shared.NewInformerFactory(testclient.NewSimpleFake(), otestclient.NewSimpleFake(), shared.DefaultListerWatcherOverrides{}, 1*time.Second) |
78 | 78 |
return &MasterConfig{ |
... | ... |
@@ -641,11 +641,11 @@ func getPort(theURL url.URL) int { |
641 | 641 |
|
642 | 642 |
// applyDefaults roundtrips the config to v1 and back to ensure proper defaults are set. |
643 | 643 |
func applyDefaults(config runtime.Object, version unversioned.GroupVersion) (runtime.Object, error) { |
644 |
- ext, err := configapi.Scheme.ConvertToVersion(config, version.String()) |
|
644 |
+ ext, err := configapi.Scheme.ConvertToVersion(config, version) |
|
645 | 645 |
if err != nil { |
646 | 646 |
return nil, err |
647 | 647 |
} |
648 |
- return configapi.Scheme.ConvertToVersion(ext, configapi.SchemeGroupVersion.String()) |
|
648 |
+ return configapi.Scheme.ConvertToVersion(ext, configapi.SchemeGroupVersion) |
|
649 | 649 |
} |
650 | 650 |
|
651 | 651 |
func servingInfoForAddr(addr *flagtypes.Addr) configapi.ServingInfo { |
... | ... |
@@ -38,7 +38,7 @@ func (c *fakeCodec) Decode([]byte, *unversioned.GroupVersionKind, runtime.Object |
38 | 38 |
return nil, nil, nil |
39 | 39 |
} |
40 | 40 |
|
41 |
-func (c *fakeCodec) EncodeToStream(obj runtime.Object, stream io.Writer, overrides ...unversioned.GroupVersion) error { |
|
41 |
+func (c *fakeCodec) Encode(obj runtime.Object, stream io.Writer) error { |
|
42 | 42 |
return nil |
43 | 43 |
} |
44 | 44 |
|
... | ... |
@@ -408,6 +408,16 @@ func NewFactory(clientConfig kclientcmd.ClientConfig) *Factory { |
408 | 408 |
return kAttachablePodForObjectFunc(object) |
409 | 409 |
} |
410 | 410 |
} |
411 |
+ kProtocolsForObject := w.Factory.ProtocolsForObject |
|
412 |
+ w.ProtocolsForObject = func(object runtime.Object) (map[string]string, error) { |
|
413 |
+ switch t := object.(type) { |
|
414 |
+ case *deployapi.DeploymentConfig: |
|
415 |
+ return getProtocols(t.Spec.Template.Spec), nil |
|
416 |
+ default: |
|
417 |
+ return kProtocolsForObject(object) |
|
418 |
+ } |
|
419 |
+ } |
|
420 |
+ |
|
411 | 421 |
kSwaggerSchemaFunc := w.Factory.SwaggerSchema |
412 | 422 |
w.Factory.SwaggerSchema = func(gvk unversioned.GroupVersionKind) (*swagger.ApiDeclaration, error) { |
413 | 423 |
if !latest.OriginKind(gvk) { |
... | ... |
@@ -519,6 +529,16 @@ func getPorts(spec api.PodSpec) []string { |
519 | 519 |
return result |
520 | 520 |
} |
521 | 521 |
|
522 |
+func getProtocols(spec api.PodSpec) map[string]string { |
|
523 |
+ result := make(map[string]string) |
|
524 |
+ for _, container := range spec.Containers { |
|
525 |
+ for _, port := range container.Ports { |
|
526 |
+ result[strconv.Itoa(int(port.ContainerPort))] = string(port.Protocol) |
|
527 |
+ } |
|
528 |
+ } |
|
529 |
+ return result |
|
530 |
+} |
|
531 |
+ |
|
522 | 532 |
func ResourceMapper(f *Factory) *resource.Mapper { |
523 | 533 |
mapper, typer := f.Object(false) |
524 | 534 |
return &resource.Mapper{ |
... | ... |
@@ -73,6 +73,10 @@ func (e ShortcutExpander) RESTMapping(gk unversioned.GroupKind, versions ...stri |
73 | 73 |
return e.RESTMapper.RESTMapping(gk, versions...) |
74 | 74 |
} |
75 | 75 |
|
76 |
+func (e ShortcutExpander) RESTMappings(gk unversioned.GroupKind) ([]*meta.RESTMapping, error) { |
|
77 |
+ return e.RESTMapper.RESTMappings(gk) |
|
78 |
+} |
|
79 |
+ |
|
76 | 80 |
// userResources are the resource names that apply to the primary, user facing resources used by |
77 | 81 |
// client tools. They are in deletion-first order - dependent resources should be last. |
78 | 82 |
var userResources = []string{ |
... | ... |
@@ -20,6 +20,16 @@ import ( |
20 | 20 |
// ErrExit is a marker interface for cli commands indicating that the response has been processed |
21 | 21 |
var ErrExit = fmt.Errorf("exit directly") |
22 | 22 |
|
23 |
+// ReplaceCommandName recursively processes the examples in a given command to change a hardcoded |
|
24 |
+// command name (like 'kubectl' to the appropriate target name). It returns c. |
|
25 |
+func ReplaceCommandName(from, to string, c *cobra.Command) *cobra.Command { |
|
26 |
+ c.Example = strings.Replace(c.Example, from, to, -1) |
|
27 |
+ for _, sub := range c.Commands() { |
|
28 |
+ ReplaceCommandName(from, to, sub) |
|
29 |
+ } |
|
30 |
+ return c |
|
31 |
+} |
|
32 |
+ |
|
23 | 33 |
// RequireNoArguments exits with a usage error if extra arguments are provided. |
24 | 34 |
func RequireNoArguments(c *cobra.Command, args []string) { |
25 | 35 |
if len(args) > 0 { |
... | ... |
@@ -82,7 +92,7 @@ func convertItemsForDisplay(objs []runtime.Object, preferredVersions ...unversio |
82 | 82 |
|
83 | 83 |
for i := range objs { |
84 | 84 |
obj := objs[i] |
85 |
- kind, err := kapi.Scheme.ObjectKind(obj) |
|
85 |
+ kind, _, err := kapi.Scheme.ObjectKind(obj) |
|
86 | 86 |
if err != nil { |
87 | 87 |
return nil, err |
88 | 88 |
} |
... | ... |
@@ -110,7 +120,7 @@ func convertItemsForDisplay(objs []runtime.Object, preferredVersions ...unversio |
110 | 110 |
} |
111 | 111 |
} |
112 | 112 |
|
113 |
- convertedObject, err := kapi.Scheme.ConvertToVersion(obj, actualOutputVersion.String()) |
|
113 |
+ convertedObject, err := kapi.Scheme.ConvertToVersion(obj, actualOutputVersion) |
|
114 | 114 |
if err != nil { |
115 | 115 |
return nil, err |
116 | 116 |
} |
... | ... |
@@ -46,7 +46,8 @@ func (_ *Helper) GetKubeClient() (*KubeDocker, string, error) { |
46 | 46 |
} else { |
47 | 47 |
endpoint = "unix:///var/run/docker.sock" |
48 | 48 |
} |
49 |
- client := dockertools.ConnectToDockerOrDie(endpoint) |
|
49 |
+ // TODO: set a timeout here |
|
50 |
+ client := dockertools.ConnectToDockerOrDie(endpoint, 0) |
|
50 | 51 |
originClient := &KubeDocker{client} |
51 | 52 |
return originClient, endpoint, nil |
52 | 53 |
} |
... | ... |
@@ -76,7 +76,7 @@ func RequestToken(clientCfg *restclient.Config, reader io.Reader, defaultUsernam |
76 | 76 |
unauthorizedError := apierrs.NewUnauthorized("") |
77 | 77 |
// Attempt to read body content and include as an error detail |
78 | 78 |
if details, err := ioutil.ReadAll(resp.Body); err == nil && len(details) > 0 { |
79 |
- unauthorizedError.(*apierrs.StatusError).ErrStatus.Details = &unversioned.StatusDetails{ |
|
79 |
+ unauthorizedError.ErrStatus.Details = &unversioned.StatusDetails{ |
|
80 | 80 |
Causes: []unversioned.StatusCause{ |
81 | 81 |
{Message: string(details)}, |
82 | 82 |
}, |
... | ... |
@@ -38,17 +38,32 @@ type RetryController struct { |
38 | 38 |
|
39 | 39 |
// Queue is a narrow abstraction of a cache.FIFO. |
40 | 40 |
type Queue interface { |
41 |
- Pop() interface{} |
|
41 |
+ Pop(kcache.PopProcessFunc) (interface{}, error) |
|
42 | 42 |
} |
43 | 43 |
|
44 | 44 |
// Run begins processing resources from Queue asynchronously. |
45 | 45 |
func (c *RetryController) Run() { |
46 |
- go utilwait.Forever(func() { c.handleOne(c.Queue.Pop()) }, 0) |
|
46 |
+ go utilwait.Forever(c.pop, 0) |
|
47 | 47 |
} |
48 | 48 |
|
49 | 49 |
// RunUntil begins processing resources from Queue asynchronously until stopCh is closed. |
50 | 50 |
func (c *RetryController) RunUntil(stopCh <-chan struct{}) { |
51 |
- go utilwait.Until(func() { c.handleOne(c.Queue.Pop()) }, 0, stopCh) |
|
51 |
+ go utilwait.Until(c.pop, 0, stopCh) |
|
52 |
+} |
|
53 |
+ |
|
54 |
+// pop removes the next item from the stack and handles it. If Handle returns |
|
55 |
+// a retryable error, the handled resource is passed to the RetryManager. If |
|
56 |
+// no error is returned from Handle, the RetryManager is asked to forget the |
|
57 |
+// processed resource. |
|
58 |
+// TODO: Pop holds the lock on the queue, which means we can't AddIfNotPresent |
|
59 |
+// from within Handle. We need to fix that. |
|
60 |
+func (c *RetryController) pop() { |
|
61 |
+ resource, err := c.Queue.Pop(c.Handle) |
|
62 |
+ if err != nil { |
|
63 |
+ c.Retry(resource, err) |
|
64 |
+ return |
|
65 |
+ } |
|
66 |
+ c.Forget(resource) |
|
52 | 67 |
} |
53 | 68 |
|
54 | 69 |
// handleOne processes resource with Handle. If Handle returns a retryable |
... | ... |
@@ -144,13 +144,13 @@ func TestRetryController_realFifoEventOrdering(t *testing.T) { |
144 | 144 |
} |
145 | 145 |
|
146 | 146 |
fifo.Add(testObj{"a", 1}) |
147 |
- controller.handleOne(fifo.Pop()) |
|
147 |
+ controller.handleOne(kcache.Pop(fifo)) |
|
148 | 148 |
|
149 | 149 |
if e, a := 1, len(fifo.List()); e != a { |
150 | 150 |
t.Fatalf("expected queue length %d, got %d", e, a) |
151 | 151 |
} |
152 | 152 |
|
153 |
- obj := fifo.Pop() |
|
153 |
+ obj := kcache.Pop(fifo) |
|
154 | 154 |
if e, a := 2, obj.(testObj).value; e != a { |
155 | 155 |
t.Fatalf("expected queued value %d, got %d", e, a) |
156 | 156 |
} |
... | ... |
@@ -213,8 +213,10 @@ func (t *testFifo) AddIfNotPresent(obj interface{}) error { |
213 | 213 |
return t.AddIfNotPresentFunc(obj) |
214 | 214 |
} |
215 | 215 |
|
216 |
-func (t *testFifo) Pop() interface{} { |
|
217 |
- return t.PopFunc() |
|
216 |
+func (t *testFifo) Pop(fn kcache.PopProcessFunc) (interface{}, error) { |
|
217 |
+ obj := t.PopFunc() |
|
218 |
+ err := fn(obj) |
|
219 |
+ return obj, err |
|
218 | 220 |
} |
219 | 221 |
|
220 | 222 |
type testRetryManager struct { |
... | ... |
@@ -3,7 +3,7 @@ package test |
3 | 3 |
import ( |
4 | 4 |
kapi "k8s.io/kubernetes/pkg/api" |
5 | 5 |
"k8s.io/kubernetes/pkg/api/resource" |
6 |
- "k8s.io/kubernetes/pkg/apis/extensions" |
|
6 |
+ "k8s.io/kubernetes/pkg/apis/autoscaling" |
|
7 | 7 |
"k8s.io/kubernetes/pkg/util/sets" |
8 | 8 |
|
9 | 9 |
deployapi "github.com/openshift/origin/pkg/deploy/api" |
... | ... |
@@ -223,12 +223,12 @@ func TestDeploymentConfig(config *deployapi.DeploymentConfig) *deployapi.Deploym |
223 | 223 |
return config |
224 | 224 |
} |
225 | 225 |
|
226 |
-func OkHPAForDeploymentConfig(config *deployapi.DeploymentConfig, min, max int) *extensions.HorizontalPodAutoscaler { |
|
226 |
+func OkHPAForDeploymentConfig(config *deployapi.DeploymentConfig, min, max int) *autoscaling.HorizontalPodAutoscaler { |
|
227 | 227 |
newMin := int32(min) |
228 |
- return &extensions.HorizontalPodAutoscaler{ |
|
228 |
+ return &autoscaling.HorizontalPodAutoscaler{ |
|
229 | 229 |
ObjectMeta: kapi.ObjectMeta{Name: config.Name, Namespace: config.Namespace}, |
230 |
- Spec: extensions.HorizontalPodAutoscalerSpec{ |
|
231 |
- ScaleRef: extensions.SubresourceReference{ |
|
230 |
+ Spec: autoscaling.HorizontalPodAutoscalerSpec{ |
|
231 |
+ ScaleTargetRef: autoscaling.CrossVersionObjectReference{ |
|
232 | 232 |
Name: config.Name, |
233 | 233 |
Kind: "DeploymentConfig", |
234 | 234 |
}, |
... | ... |
@@ -5,6 +5,7 @@ import ( |
5 | 5 |
"fmt" |
6 | 6 |
"regexp" |
7 | 7 |
"strconv" |
8 |
+ "strings" |
|
8 | 9 |
|
9 | 10 |
kapi "k8s.io/kubernetes/pkg/api" |
10 | 11 |
unversionedvalidation "k8s.io/kubernetes/pkg/api/unversioned/validation" |
... | ... |
@@ -150,7 +151,7 @@ func ValidateDeploymentConfigRollback(rollback *deployapi.DeploymentConfigRollba |
150 | 150 |
|
151 | 151 |
if len(rollback.Name) == 0 { |
152 | 152 |
result = append(result, field.Required(field.NewPath("name"), "name of the deployment config is missing")) |
153 |
- } else if !kvalidation.IsDNS1123Subdomain(rollback.Name) { |
|
153 |
+ } else if len(kvalidation.IsDNS1123Subdomain(rollback.Name)) != 0 { |
|
154 | 154 |
result = append(result, field.Invalid(field.NewPath("name"), rollback.Name, "name of the deployment config is invalid")) |
155 | 155 |
} |
156 | 156 |
|
... | ... |
@@ -417,7 +418,7 @@ func validateImageChangeParams(params *deployapi.DeploymentTriggerImageChangePar |
417 | 417 |
if err := validateImageStreamTagName(params.From.Name); err != nil { |
418 | 418 |
errs = append(errs, field.Invalid(fromPath.Child("name"), params.From.Name, err.Error())) |
419 | 419 |
} |
420 |
- if len(params.From.Namespace) != 0 && !kvalidation.IsDNS1123Subdomain(params.From.Namespace) { |
|
420 |
+ if len(params.From.Namespace) != 0 && len(kvalidation.IsDNS1123Subdomain(params.From.Namespace)) != 0 { |
|
421 | 421 |
errs = append(errs, field.Invalid(fromPath.Child("namespace"), params.From.Namespace, "namespace must be a valid subdomain")) |
422 | 422 |
} |
423 | 423 |
} |
... | ... |
@@ -434,9 +435,8 @@ func validateImageStreamTagName(istag string) error { |
434 | 434 |
if !ok { |
435 | 435 |
return fmt.Errorf("invalid ImageStreamTag: %s", istag) |
436 | 436 |
} |
437 |
- ok, reason := imageval.ValidateImageStreamName(name, false) |
|
438 |
- if !ok { |
|
439 |
- return errors.New(reason) |
|
437 |
+ if reasons := imageval.ValidateImageStreamName(name, false); len(reasons) != 0 { |
|
438 |
+ return errors.New(strings.Join(reasons, ", ")) |
|
440 | 439 |
} |
441 | 440 |
return nil |
442 | 441 |
} |
... | ... |
@@ -13,6 +13,7 @@ import ( |
13 | 13 |
deployapi "github.com/openshift/origin/pkg/deploy/api" |
14 | 14 |
_ "github.com/openshift/origin/pkg/deploy/api/install" |
15 | 15 |
deploytest "github.com/openshift/origin/pkg/deploy/api/test" |
16 |
+ deployv1 "github.com/openshift/origin/pkg/deploy/api/v1" |
|
16 | 17 |
deployutil "github.com/openshift/origin/pkg/deploy/util" |
17 | 18 |
) |
18 | 19 |
|
... | ... |
@@ -75,12 +76,12 @@ func TestHandle_uncorrelatedPod(t *testing.T) { |
75 | 75 |
controller := &DeployerPodController{ |
76 | 76 |
kClient: kFake, |
77 | 77 |
decodeConfig: func(deployment *kapi.ReplicationController) (*deployapi.DeploymentConfig, error) { |
78 |
- return deployutil.DecodeDeploymentConfig(deployment, kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
78 |
+ return deployutil.DecodeDeploymentConfig(deployment, kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
79 | 79 |
}, |
80 | 80 |
} |
81 | 81 |
|
82 | 82 |
// Verify no-op |
83 |
- deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
83 |
+ deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
84 | 84 |
pod := runningPod(deployment) |
85 | 85 |
pod.Annotations = make(map[string]string) |
86 | 86 |
|
... | ... |
@@ -109,7 +110,7 @@ func TestHandle_orphanedPod(t *testing.T) { |
109 | 109 |
}) |
110 | 110 |
kFake.PrependReactor("list", "pods", func(action ktestclient.Action) (handled bool, ret runtime.Object, err error) { |
111 | 111 |
mkpod := func(suffix string) kapi.Pod { |
112 |
- deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
112 |
+ deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
113 | 113 |
p := okPod(deployment) |
114 | 114 |
p.Name = p.Name + suffix |
115 | 115 |
return *p |
... | ... |
@@ -127,7 +128,7 @@ func TestHandle_orphanedPod(t *testing.T) { |
127 | 127 |
kClient: kFake, |
128 | 128 |
} |
129 | 129 |
|
130 |
- deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
130 |
+ deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
131 | 131 |
err := controller.Handle(runningPod(deployment)) |
132 | 132 |
if err != nil { |
133 | 133 |
t.Fatalf("unexpected error: %v", err) |
... | ... |
@@ -142,7 +143,7 @@ func TestHandle_orphanedPod(t *testing.T) { |
142 | 142 |
// TestHandle_runningPod ensures that a running deployer pod results in a |
143 | 143 |
// transition of the deployment's status to running. |
144 | 144 |
func TestHandle_runningPod(t *testing.T) { |
145 |
- deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
145 |
+ deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
146 | 146 |
deployment.Annotations[deployapi.DeploymentStatusAnnotation] = string(deployapi.DeploymentStatusPending) |
147 | 147 |
var updatedDeployment *kapi.ReplicationController |
148 | 148 |
|
... | ... |
@@ -177,7 +178,7 @@ func TestHandle_runningPod(t *testing.T) { |
177 | 177 |
// TestHandle_podTerminatedOk ensures that a successfully completed deployer |
178 | 178 |
// pod results in a transition of the deployment's status to complete. |
179 | 179 |
func TestHandle_podTerminatedOk(t *testing.T) { |
180 |
- deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
180 |
+ deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
181 | 181 |
deployment.Spec.Replicas = 1 |
182 | 182 |
deployment.Annotations[deployapi.DeploymentStatusAnnotation] = string(deployapi.DeploymentStatusRunning) |
183 | 183 |
var updatedDeployment *kapi.ReplicationController |
... | ... |
@@ -219,7 +220,7 @@ func TestHandle_podTerminatedOk(t *testing.T) { |
219 | 219 |
// TestHandle_podTerminatedOk ensures that a successfully completed deployer |
220 | 220 |
// pod results in a transition of the deployment's status to complete. |
221 | 221 |
func TestHandle_podTerminatedOkTest(t *testing.T) { |
222 |
- deployment, _ := deployutil.MakeDeployment(deploytest.TestDeploymentConfig(deploytest.OkDeploymentConfig(1)), kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
222 |
+ deployment, _ := deployutil.MakeDeployment(deploytest.TestDeploymentConfig(deploytest.OkDeploymentConfig(1)), kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
223 | 223 |
deployment.Spec.Replicas = 1 |
224 | 224 |
deployment.Annotations[deployapi.DeploymentStatusAnnotation] = string(deployapi.DeploymentStatusRunning) |
225 | 225 |
var updatedDeployment *kapi.ReplicationController |
... | ... |
@@ -263,7 +264,7 @@ func TestHandle_podTerminatedOkTest(t *testing.T) { |
263 | 263 |
// deployment's status to failed. |
264 | 264 |
func TestHandle_podTerminatedFailNoContainerStatus(t *testing.T) { |
265 | 265 |
var updatedDeployment *kapi.ReplicationController |
266 |
- deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
266 |
+ deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
267 | 267 |
deployment.Spec.Replicas = 1 |
268 | 268 |
// since we do not set the desired replicas annotation, |
269 | 269 |
// this also tests that the error is just logged and not result in a failure |
... | ... |
@@ -308,7 +309,7 @@ func TestHandle_podTerminatedFailNoContainerStatus(t *testing.T) { |
308 | 308 |
// deployment's status to failed. |
309 | 309 |
func TestHandle_podTerminatedFailNoContainerStatusTest(t *testing.T) { |
310 | 310 |
var updatedDeployment *kapi.ReplicationController |
311 |
- deployment, _ := deployutil.MakeDeployment(deploytest.TestDeploymentConfig(deploytest.OkDeploymentConfig(1)), kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
311 |
+ deployment, _ := deployutil.MakeDeployment(deploytest.TestDeploymentConfig(deploytest.OkDeploymentConfig(1)), kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
312 | 312 |
deployment.Spec.Replicas = 1 |
313 | 313 |
// since we do not set the desired replicas annotation, |
314 | 314 |
// this also tests that the error is just logged and not result in a failure |
... | ... |
@@ -352,7 +353,7 @@ func TestHandle_podTerminatedFailNoContainerStatusTest(t *testing.T) { |
352 | 352 |
// will be cleaned up in a complete deployment and stay around in a failed deployment |
353 | 353 |
func TestHandle_cleanupDesiredReplicasAnnotation(t *testing.T) { |
354 | 354 |
// shared fixtures shouldn't be used in unit tests |
355 |
- shared, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
355 |
+ shared, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
356 | 356 |
|
357 | 357 |
tests := []struct { |
358 | 358 |
name string |
... | ... |
@@ -372,7 +373,7 @@ func TestHandle_cleanupDesiredReplicasAnnotation(t *testing.T) { |
372 | 372 |
} |
373 | 373 |
|
374 | 374 |
for _, test := range tests { |
375 |
- deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
375 |
+ deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
376 | 376 |
var updatedDeployment *kapi.ReplicationController |
377 | 377 |
deployment.Annotations[deployapi.DesiredReplicasAnnotation] = "1" |
378 | 378 |
|
... | ... |
@@ -19,12 +19,13 @@ import ( |
19 | 19 |
deployapi "github.com/openshift/origin/pkg/deploy/api" |
20 | 20 |
_ "github.com/openshift/origin/pkg/deploy/api/install" |
21 | 21 |
deploytest "github.com/openshift/origin/pkg/deploy/api/test" |
22 |
+ deployapiv1 "github.com/openshift/origin/pkg/deploy/api/v1" |
|
22 | 23 |
deployutil "github.com/openshift/origin/pkg/deploy/util" |
23 | 24 |
) |
24 | 25 |
|
25 | 26 |
var ( |
26 | 27 |
env = []kapi.EnvVar{{Name: "ENV1", Value: "VAL1"}} |
27 |
- codec = kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion) |
|
28 |
+ codec = kapi.Codecs.LegacyCodec(deployapiv1.SchemeGroupVersion) |
|
28 | 29 |
) |
29 | 30 |
|
30 | 31 |
func okDeploymentController(fake kclient.Interface, deployment *kapi.ReplicationController, hookPodNames []string, related bool) *DeploymentController { |
... | ... |
@@ -18,6 +18,7 @@ import ( |
18 | 18 |
deployapi "github.com/openshift/origin/pkg/deploy/api" |
19 | 19 |
_ "github.com/openshift/origin/pkg/deploy/api/install" |
20 | 20 |
deploytest "github.com/openshift/origin/pkg/deploy/api/test" |
21 |
+ deployv1 "github.com/openshift/origin/pkg/deploy/api/v1" |
|
21 | 22 |
deployutil "github.com/openshift/origin/pkg/deploy/util" |
22 | 23 |
) |
23 | 24 |
|
... | ... |
@@ -41,7 +42,7 @@ func TestHandleScenarios(t *testing.T) { |
41 | 41 |
if d.test { |
42 | 42 |
config = deploytest.TestDeploymentConfig(config) |
43 | 43 |
} |
44 |
- deployment, _ := deployutil.MakeDeployment(config, kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
44 |
+ deployment, _ := deployutil.MakeDeployment(config, kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
45 | 45 |
deployment.Annotations[deployapi.DeploymentStatusAnnotation] = string(d.status) |
46 | 46 |
if d.cancelled { |
47 | 47 |
deployment.Annotations[deployapi.DeploymentCancelledAnnotation] = deployapi.DeploymentCancelledAnnotationValue |
... | ... |
@@ -642,7 +643,7 @@ func TestHandleScenarios(t *testing.T) { |
642 | 642 |
deployments[rc.Name] = *rc |
643 | 643 |
return true, rc, nil |
644 | 644 |
}) |
645 |
- codec := kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion) |
|
645 |
+ codec := kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion) |
|
646 | 646 |
|
647 | 647 |
dcInformer := framework.NewSharedIndexInformer( |
648 | 648 |
&cache.ListWatch{ |
... | ... |
@@ -9,18 +9,20 @@ import ( |
9 | 9 |
ktestclient "k8s.io/kubernetes/pkg/client/unversioned/testclient" |
10 | 10 |
"k8s.io/kubernetes/pkg/controller/framework" |
11 | 11 |
"k8s.io/kubernetes/pkg/runtime" |
12 |
+ "k8s.io/kubernetes/pkg/util/diff" |
|
12 | 13 |
"k8s.io/kubernetes/pkg/watch" |
13 | 14 |
|
14 | 15 |
"github.com/openshift/origin/pkg/client/testclient" |
15 | 16 |
deployapi "github.com/openshift/origin/pkg/deploy/api" |
16 | 17 |
_ "github.com/openshift/origin/pkg/deploy/api/install" |
17 | 18 |
testapi "github.com/openshift/origin/pkg/deploy/api/test" |
19 |
+ deployv1 "github.com/openshift/origin/pkg/deploy/api/v1" |
|
18 | 20 |
deployutil "github.com/openshift/origin/pkg/deploy/util" |
19 | 21 |
imageapi "github.com/openshift/origin/pkg/image/api" |
20 | 22 |
) |
21 | 23 |
|
22 | 24 |
var ( |
23 |
- codec = kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion) |
|
25 |
+ codec = kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion) |
|
24 | 26 |
mock = &testclient.Fake{} |
25 | 27 |
dcInformer = framework.NewSharedIndexInformer( |
26 | 28 |
&cache.ListWatch{ |
... | ... |
@@ -147,7 +149,7 @@ func TestHandle_changeWithTemplateDiff(t *testing.T) { |
147 | 147 |
config := testapi.OkDeploymentConfig(1) |
148 | 148 |
config.Namespace = kapi.NamespaceDefault |
149 | 149 |
config.Spec.Triggers = []deployapi.DeploymentTriggerPolicy{testapi.OkConfigChangeTrigger()} |
150 |
- deployment, _ := deployutil.MakeDeployment(config, kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
150 |
+ deployment, _ := deployutil.MakeDeployment(config, kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
151 | 151 |
var updated *deployapi.DeploymentConfig |
152 | 152 |
|
153 | 153 |
fake.PrependReactor("update", "deploymentconfigs/status", func(action ktestclient.Action) (handled bool, ret runtime.Object, err error) { |
... | ... |
@@ -168,7 +170,7 @@ func TestHandle_changeWithTemplateDiff(t *testing.T) { |
168 | 168 |
|
169 | 169 |
if !s.changeExpected { |
170 | 170 |
if updated != nil { |
171 |
- t.Errorf("unexpected update to version %d", updated.Status.LatestVersion) |
|
171 |
+ t.Errorf("unexpected update to version %d: %s", updated.Status.LatestVersion, diff.ObjectReflectDiff(config, updated)) |
|
172 | 172 |
} |
173 | 173 |
continue |
174 | 174 |
} |
... | ... |
@@ -267,7 +269,7 @@ func TestHandle_automaticImageUpdates(t *testing.T) { |
267 | 267 |
kFake.PrependReactor("get", "replicationcontrollers", func(action ktestclient.Action) (handled bool, ret runtime.Object, err error) { |
268 | 268 |
// This will always return no template difference. We test template differences in TestHandle_changeWithTemplateDiff |
269 | 269 |
config := testapi.OkDeploymentConfig(0) |
270 |
- deployment, _ := deployutil.MakeDeployment(config, kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
270 |
+ deployment, _ := deployutil.MakeDeployment(config, kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
271 | 271 |
return true, deployment, nil |
272 | 272 |
}) |
273 | 273 |
|
... | ... |
@@ -32,7 +32,7 @@ func mkdeploymentlist(versions ...int64) *kapi.ReplicationControllerList { |
32 | 32 |
|
33 | 33 |
func TestStop(t *testing.T) { |
34 | 34 |
notfound := func() runtime.Object { |
35 |
- return &(kerrors.NewNotFound(kapi.Resource("DeploymentConfig"), "config").(*kerrors.StatusError).ErrStatus) |
|
35 |
+ return &(kerrors.NewNotFound(kapi.Resource("DeploymentConfig"), "config").ErrStatus) |
|
36 | 36 |
} |
37 | 37 |
|
38 | 38 |
tests := []struct { |
... | ... |
@@ -93,7 +93,18 @@ func (r *ScaleREST) Get(ctx kapi.Context, name string) (runtime.Object, error) { |
93 | 93 |
} |
94 | 94 |
|
95 | 95 |
// Update scales the DeploymentConfig for the given Scale subresource, returning the updated Scale. |
96 |
-func (r *ScaleREST) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, bool, error) { |
|
96 |
+func (r *ScaleREST) Update(ctx kapi.Context, name string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) { |
|
97 |
+ deploymentConfig, err := r.registry.GetDeploymentConfig(ctx, name) |
|
98 |
+ if err != nil { |
|
99 |
+ return nil, false, errors.NewNotFound(extensions.Resource("scale"), name) |
|
100 |
+ } |
|
101 |
+ |
|
102 |
+ old := api.ScaleFromConfig(deploymentConfig) |
|
103 |
+ obj, err := objInfo.UpdatedObject(ctx, old) |
|
104 |
+ if err != nil { |
|
105 |
+ return nil, false, err |
|
106 |
+ } |
|
107 |
+ |
|
97 | 108 |
scale, ok := obj.(*extensions.Scale) |
98 | 109 |
if !ok { |
99 | 110 |
return nil, false, errors.NewBadRequest(fmt.Sprintf("wrong object passed to Scale update: %v", obj)) |
... | ... |
@@ -103,17 +114,12 @@ func (r *ScaleREST) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object |
103 | 103 |
return nil, false, errors.NewInvalid(extensions.Kind("Scale"), scale.Name, errs) |
104 | 104 |
} |
105 | 105 |
|
106 |
- deploymentConfig, err := r.registry.GetDeploymentConfig(ctx, scale.Name) |
|
107 |
- if err != nil { |
|
108 |
- return nil, false, errors.NewNotFound(extensions.Resource("scale"), scale.Name) |
|
109 |
- } |
|
110 |
- |
|
111 | 106 |
deploymentConfig.Spec.Replicas = scale.Spec.Replicas |
112 | 107 |
if err := r.registry.UpdateDeploymentConfig(ctx, deploymentConfig); err != nil { |
113 | 108 |
return nil, false, err |
114 | 109 |
} |
115 | 110 |
|
116 |
- return api.ScaleFromConfig(deploymentConfig), false, nil |
|
111 |
+ return scale, false, nil |
|
117 | 112 |
} |
118 | 113 |
|
119 | 114 |
// StatusREST implements the REST endpoint for changing the status of a DeploymentConfig. |
... | ... |
@@ -129,6 +135,6 @@ func (r *StatusREST) New() runtime.Object { |
129 | 129 |
} |
130 | 130 |
|
131 | 131 |
// Update alters the status subset of an deploymentConfig. |
132 |
-func (r *StatusREST) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, bool, error) { |
|
133 |
- return r.store.Update(ctx, obj) |
|
132 |
+func (r *StatusREST) Update(ctx kapi.Context, name string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) { |
|
133 |
+ return r.store.Update(ctx, name, objInfo) |
|
134 | 134 |
} |
... | ... |
@@ -55,7 +55,7 @@ func (s *storage) CreateDeploymentConfig(ctx kapi.Context, deploymentConfig *dep |
55 | 55 |
} |
56 | 56 |
|
57 | 57 |
func (s *storage) UpdateDeploymentConfig(ctx kapi.Context, deploymentConfig *deployapi.DeploymentConfig) error { |
58 |
- _, _, err := s.Update(ctx, deploymentConfig) |
|
58 |
+ _, _, err := s.Update(ctx, deploymentConfig.Name, rest.DefaultUpdatedObjectInfo(deploymentConfig, kapi.Scheme)) |
|
59 | 59 |
return err |
60 | 60 |
} |
61 | 61 |
|
... | ... |
@@ -12,6 +12,7 @@ import ( |
12 | 12 |
deployapi "github.com/openshift/origin/pkg/deploy/api" |
13 | 13 |
_ "github.com/openshift/origin/pkg/deploy/api/install" |
14 | 14 |
deploytest "github.com/openshift/origin/pkg/deploy/api/test" |
15 |
+ deployv1 "github.com/openshift/origin/pkg/deploy/api/v1" |
|
15 | 16 |
deployutil "github.com/openshift/origin/pkg/deploy/util" |
16 | 17 |
) |
17 | 18 |
|
... | ... |
@@ -48,14 +49,14 @@ func TestCreateOkDepr(t *testing.T) { |
48 | 48 |
return &deployapi.DeploymentConfig{}, nil |
49 | 49 |
}, |
50 | 50 |
RCFn: func(ctx kapi.Context, name string) (*kapi.ReplicationController, error) { |
51 |
- deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
51 |
+ deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
52 | 52 |
return deployment, nil |
53 | 53 |
}, |
54 | 54 |
DCFn: func(ctx kapi.Context, name string) (*deployapi.DeploymentConfig, error) { |
55 | 55 |
return deploytest.OkDeploymentConfig(1), nil |
56 | 56 |
}, |
57 | 57 |
}, |
58 |
- codec: kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion), |
|
58 |
+ codec: kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion), |
|
59 | 59 |
} |
60 | 60 |
|
61 | 61 |
obj, err := rest.Create(kapi.NewDefaultContext(), &deployapi.DeploymentConfigRollback{ |
... | ... |
@@ -87,14 +88,14 @@ func TestCreateGeneratorErrorDepr(t *testing.T) { |
87 | 87 |
return nil, kerrors.NewInternalError(fmt.Errorf("something terrible happened")) |
88 | 88 |
}, |
89 | 89 |
RCFn: func(ctx kapi.Context, name string) (*kapi.ReplicationController, error) { |
90 |
- deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
90 |
+ deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
91 | 91 |
return deployment, nil |
92 | 92 |
}, |
93 | 93 |
DCFn: func(ctx kapi.Context, name string) (*deployapi.DeploymentConfig, error) { |
94 | 94 |
return deploytest.OkDeploymentConfig(1), nil |
95 | 95 |
}, |
96 | 96 |
}, |
97 |
- codec: kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion), |
|
97 |
+ codec: kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion), |
|
98 | 98 |
} |
99 | 99 |
|
100 | 100 |
_, err := rest.Create(kapi.NewDefaultContext(), &deployapi.DeploymentConfigRollback{ |
... | ... |
@@ -127,7 +128,7 @@ func TestCreateMissingDeploymentDepr(t *testing.T) { |
127 | 127 |
return nil, kerrors.NewNotFound(deployapi.Resource("deploymentConfig"), name) |
128 | 128 |
}, |
129 | 129 |
}, |
130 |
- codec: kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion), |
|
130 |
+ codec: kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion), |
|
131 | 131 |
} |
132 | 132 |
|
133 | 133 |
obj, err := rest.Create(kapi.NewDefaultContext(), &deployapi.DeploymentConfigRollback{ |
... | ... |
@@ -157,7 +158,7 @@ func TestCreateInvalidDeploymentDepr(t *testing.T) { |
157 | 157 |
}, |
158 | 158 |
RCFn: func(ctx kapi.Context, name string) (*kapi.ReplicationController, error) { |
159 | 159 |
// invalidate the encoded config |
160 |
- deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
160 |
+ deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
161 | 161 |
deployment.Annotations[deployapi.DeploymentEncodedConfigAnnotation] = "" |
162 | 162 |
return deployment, nil |
163 | 163 |
}, |
... | ... |
@@ -167,7 +168,7 @@ func TestCreateInvalidDeploymentDepr(t *testing.T) { |
167 | 167 |
return nil, kerrors.NewNotFound(deployapi.Resource("deploymentConfig"), name) |
168 | 168 |
}, |
169 | 169 |
}, |
170 |
- codec: kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion), |
|
170 |
+ codec: kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion), |
|
171 | 171 |
} |
172 | 172 |
|
173 | 173 |
obj, err := rest.Create(kapi.NewDefaultContext(), &deployapi.DeploymentConfigRollback{ |
... | ... |
@@ -196,14 +197,14 @@ func TestCreateMissingDeploymentConfigDepr(t *testing.T) { |
196 | 196 |
return nil, errors.New("something terrible happened") |
197 | 197 |
}, |
198 | 198 |
RCFn: func(ctx kapi.Context, name string) (*kapi.ReplicationController, error) { |
199 |
- deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
199 |
+ deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
200 | 200 |
return deployment, nil |
201 | 201 |
}, |
202 | 202 |
DCFn: func(ctx kapi.Context, name string) (*deployapi.DeploymentConfig, error) { |
203 | 203 |
return nil, kerrors.NewNotFound(deployapi.Resource("deploymentConfig"), name) |
204 | 204 |
}, |
205 | 205 |
}, |
206 |
- codec: kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion), |
|
206 |
+ codec: kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion), |
|
207 | 207 |
} |
208 | 208 |
|
209 | 209 |
obj, err := rest.Create(kapi.NewDefaultContext(), &deployapi.DeploymentConfigRollback{ |
... | ... |
@@ -226,6 +227,6 @@ func TestCreateMissingDeploymentConfigDepr(t *testing.T) { |
226 | 226 |
|
227 | 227 |
func TestNewDepr(t *testing.T) { |
228 | 228 |
// :) |
229 |
- rest := NewDeprecatedREST(Client{}, kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
229 |
+ rest := NewDeprecatedREST(Client{}, kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
230 | 230 |
rest.New() |
231 | 231 |
} |
... | ... |
@@ -14,10 +14,11 @@ import ( |
14 | 14 |
deployapi "github.com/openshift/origin/pkg/deploy/api" |
15 | 15 |
_ "github.com/openshift/origin/pkg/deploy/api/install" |
16 | 16 |
deploytest "github.com/openshift/origin/pkg/deploy/api/test" |
17 |
+ deployv1 "github.com/openshift/origin/pkg/deploy/api/v1" |
|
17 | 18 |
deployutil "github.com/openshift/origin/pkg/deploy/util" |
18 | 19 |
) |
19 | 20 |
|
20 |
-var codec = kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion) |
|
21 |
+var codec = kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion) |
|
21 | 22 |
|
22 | 23 |
type terribleGenerator struct{} |
23 | 24 |
|
... | ... |
@@ -99,7 +100,7 @@ func TestCreateGeneratorError(t *testing.T) { |
99 | 99 |
generator: &terribleGenerator{}, |
100 | 100 |
dn: oc, |
101 | 101 |
rn: kc, |
102 |
- codec: kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion), |
|
102 |
+ codec: kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion), |
|
103 | 103 |
} |
104 | 104 |
|
105 | 105 |
_, err := rest.Create(kapi.NewDefaultContext(), &deployapi.DeploymentConfigRollback{ |
... | ... |
@@ -11,6 +11,7 @@ import ( |
11 | 11 |
|
12 | 12 |
deployapi "github.com/openshift/origin/pkg/deploy/api" |
13 | 13 |
deploytest "github.com/openshift/origin/pkg/deploy/api/test" |
14 |
+ deployv1 "github.com/openshift/origin/pkg/deploy/api/v1" |
|
14 | 15 |
scalertest "github.com/openshift/origin/pkg/deploy/scaler/test" |
15 | 16 |
"github.com/openshift/origin/pkg/deploy/strategy" |
16 | 17 |
deployutil "github.com/openshift/origin/pkg/deploy/util" |
... | ... |
@@ -121,7 +122,7 @@ func TestRecreate_deploymentPreHookFail(t *testing.T) { |
121 | 121 |
func TestRecreate_deploymentMidHookSuccess(t *testing.T) { |
122 | 122 |
config := deploytest.OkDeploymentConfig(1) |
123 | 123 |
config.Spec.Strategy = recreateParams(30, "", deployapi.LifecycleHookFailurePolicyAbort, "") |
124 |
- deployment, _ := deployutil.MakeDeployment(config, kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
124 |
+ deployment, _ := deployutil.MakeDeployment(config, kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
125 | 125 |
scaler := &scalertest.FakeScaler{} |
126 | 126 |
|
127 | 127 |
hookExecuted := false |
... | ... |
@@ -156,7 +157,7 @@ func TestRecreate_deploymentMidHookSuccess(t *testing.T) { |
156 | 156 |
func TestRecreate_deploymentMidHookFail(t *testing.T) { |
157 | 157 |
config := deploytest.OkDeploymentConfig(1) |
158 | 158 |
config.Spec.Strategy = recreateParams(30, "", deployapi.LifecycleHookFailurePolicyAbort, "") |
159 |
- deployment, _ := deployutil.MakeDeployment(config, kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
159 |
+ deployment, _ := deployutil.MakeDeployment(config, kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
160 | 160 |
scaler := &scalertest.FakeScaler{} |
161 | 161 |
|
162 | 162 |
strategy := &RecreateDeploymentStrategy{ |
... | ... |
@@ -476,7 +476,7 @@ func NewPodWatch(client kclient.PodsNamespacer, namespace, name, resourceVersion |
476 | 476 |
cache.NewReflector(podLW, &kapi.Pod{}, queue, 1*time.Minute).RunUntil(stopChannel) |
477 | 477 |
|
478 | 478 |
return func() *kapi.Pod { |
479 |
- obj := queue.Pop() |
|
479 |
+ obj := cache.Pop(queue) |
|
480 | 480 |
return obj.(*kapi.Pod) |
481 | 481 |
} |
482 | 482 |
} |
... | ... |
@@ -19,6 +19,7 @@ import ( |
19 | 19 |
|
20 | 20 |
deployapi "github.com/openshift/origin/pkg/deploy/api" |
21 | 21 |
deploytest "github.com/openshift/origin/pkg/deploy/api/test" |
22 |
+ deployv1 "github.com/openshift/origin/pkg/deploy/api/v1" |
|
22 | 23 |
deployutil "github.com/openshift/origin/pkg/deploy/util" |
23 | 24 |
namer "github.com/openshift/origin/pkg/util/namer" |
24 | 25 |
|
... | ... |
@@ -33,7 +34,7 @@ func TestHookExecutor_executeExecNewCreatePodFailure(t *testing.T) { |
33 | 33 |
}, |
34 | 34 |
} |
35 | 35 |
|
36 |
- deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
36 |
+ deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
37 | 37 |
|
38 | 38 |
executor := &HookExecutor{ |
39 | 39 |
podClient: &HookExecutorPodClientImpl{ |
... | ... |
@@ -64,7 +65,7 @@ func TestHookExecutor_executeExecNewPodSucceeded(t *testing.T) { |
64 | 64 |
} |
65 | 65 |
|
66 | 66 |
config := deploytest.OkDeploymentConfig(1) |
67 |
- deployment, _ := deployutil.MakeDeployment(config, kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
67 |
+ deployment, _ := deployutil.MakeDeployment(config, kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
68 | 68 |
deployment.Spec.Template.Spec.NodeSelector = map[string]string{"labelKey1": "labelValue1", "labelKey2": "labelValue2"} |
69 | 69 |
|
70 | 70 |
podLogs := &bytes.Buffer{} |
... | ... |
@@ -118,7 +119,7 @@ func TestHookExecutor_executeExecNewPodFailed(t *testing.T) { |
118 | 118 |
}, |
119 | 119 |
} |
120 | 120 |
|
121 |
- deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
121 |
+ deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
122 | 122 |
|
123 | 123 |
var createdPod *kapi.Pod |
124 | 124 |
executor := &HookExecutor{ |
... | ... |
@@ -156,7 +157,7 @@ func TestHookExecutor_makeHookPodInvalidContainerRef(t *testing.T) { |
156 | 156 |
} |
157 | 157 |
|
158 | 158 |
config := deploytest.OkDeploymentConfig(1) |
159 |
- deployment, _ := deployutil.MakeDeployment(config, kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
159 |
+ deployment, _ := deployutil.MakeDeployment(config, kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
160 | 160 |
|
161 | 161 |
_, err := makeHookPod(hook, deployment, &config.Spec.Strategy, "hook") |
162 | 162 |
|
... | ... |
@@ -412,7 +413,7 @@ func TestHookExecutor_makeHookPodRestart(t *testing.T) { |
412 | 412 |
} |
413 | 413 |
|
414 | 414 |
config := deploytest.OkDeploymentConfig(1) |
415 |
- deployment, _ := deployutil.MakeDeployment(config, kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
415 |
+ deployment, _ := deployutil.MakeDeployment(config, kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
416 | 416 |
|
417 | 417 |
pod, err := makeHookPod(hook, deployment, &config.Spec.Strategy, "hook") |
418 | 418 |
if err != nil { |
... | ... |
@@ -513,7 +514,7 @@ func TestAcceptNewlyObservedReadyPods_scenarios(t *testing.T) { |
513 | 513 |
acceptedPods: acceptedPods, |
514 | 514 |
} |
515 | 515 |
|
516 |
- deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
516 |
+ deployment, _ := deployutil.MakeDeployment(deploytest.OkDeploymentConfig(1), kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
517 | 517 |
deployment.Spec.Replicas = 1 |
518 | 518 |
|
519 | 519 |
acceptor.out = &bytes.Buffer{} |
... | ... |
@@ -610,7 +611,7 @@ func deployment(name, namespace string, strategyLabels, strategyAnnotations map[ |
610 | 610 |
}, |
611 | 611 |
}, |
612 | 612 |
} |
613 |
- deployment, _ := deployutil.MakeDeployment(config, kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
613 |
+ deployment, _ := deployutil.MakeDeployment(config, kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
614 | 614 |
deployment.Namespace = namespace |
615 | 615 |
return config, deployment |
616 | 616 |
} |
... | ... |
@@ -11,6 +11,7 @@ import ( |
11 | 11 |
|
12 | 12 |
deployapi "github.com/openshift/origin/pkg/deploy/api" |
13 | 13 |
deploytest "github.com/openshift/origin/pkg/deploy/api/test" |
14 |
+ deployv1 "github.com/openshift/origin/pkg/deploy/api/v1" |
|
14 | 15 |
|
15 | 16 |
_ "github.com/openshift/origin/pkg/api/install" |
16 | 17 |
) |
... | ... |
@@ -65,7 +66,7 @@ func TestPodName(t *testing.T) { |
65 | 65 |
|
66 | 66 |
func TestMakeDeploymentOk(t *testing.T) { |
67 | 67 |
config := deploytest.OkDeploymentConfig(1) |
68 |
- deployment, err := MakeDeployment(config, kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
68 |
+ deployment, err := MakeDeployment(config, kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
69 | 69 |
|
70 | 70 |
if err != nil { |
71 | 71 |
t.Fatalf("unexpected error: %#v", err) |
... | ... |
@@ -99,7 +100,7 @@ func TestMakeDeploymentOk(t *testing.T) { |
99 | 99 |
t.Fatalf("expected deployment with DeploymentEncodedConfigAnnotation annotation") |
100 | 100 |
} |
101 | 101 |
|
102 |
- if decodedConfig, err := DecodeDeploymentConfig(deployment, kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)); err != nil { |
|
102 |
+ if decodedConfig, err := DecodeDeploymentConfig(deployment, kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)); err != nil { |
|
103 | 103 |
t.Fatalf("invalid encoded config on deployment: %v", err) |
104 | 104 |
} else { |
105 | 105 |
if e, a := config.Name, decodedConfig.Name; e != a { |
... | ... |
@@ -135,7 +136,7 @@ func TestMakeDeploymentOk(t *testing.T) { |
135 | 135 |
|
136 | 136 |
func TestDeploymentsByLatestVersion_sorting(t *testing.T) { |
137 | 137 |
mkdeployment := func(version int64) kapi.ReplicationController { |
138 |
- deployment, _ := MakeDeployment(deploytest.OkDeploymentConfig(version), kapi.Codecs.LegacyCodec(deployapi.SchemeGroupVersion)) |
|
138 |
+ deployment, _ := MakeDeployment(deploytest.OkDeploymentConfig(version), kapi.Codecs.LegacyCodec(deployv1.SchemeGroupVersion)) |
|
139 | 139 |
return *deployment |
140 | 140 |
} |
141 | 141 |
deployments := []kapi.ReplicationController{ |
... | ... |
@@ -3,6 +3,7 @@ package dns |
3 | 3 |
import ( |
4 | 4 |
"github.com/golang/glog" |
5 | 5 |
|
6 |
+ "github.com/skynetservices/skydns/metrics" |
|
6 | 7 |
"github.com/skynetservices/skydns/server" |
7 | 8 |
|
8 | 9 |
client "k8s.io/kubernetes/pkg/client/unversioned" |
... | ... |
@@ -44,7 +45,7 @@ func (s *Server) ListenAndServe() error { |
44 | 44 |
resolver := NewServiceResolver(s.Config, s.Services, s.Endpoints, openshiftFallback) |
45 | 45 |
resolvers := server.FirstBackend{resolver} |
46 | 46 |
if len(s.MetricsName) > 0 { |
47 |
- server.RegisterMetrics(s.MetricsName, "") |
|
47 |
+ metrics.RegisterPrometheusMetrics(s.MetricsName, "") |
|
48 | 48 |
} |
49 | 49 |
dns := server.New(resolvers, s.Config) |
50 | 50 |
if s.Stop != nil { |
... | ... |
@@ -6,7 +6,7 @@ import ( |
6 | 6 |
"net" |
7 | 7 |
"strings" |
8 | 8 |
|
9 |
- "github.com/coreos/go-etcd/etcd" |
|
9 |
+ etcd "github.com/coreos/etcd/client" |
|
10 | 10 |
"github.com/golang/glog" |
11 | 11 |
|
12 | 12 |
kapi "k8s.io/kubernetes/pkg/api" |
... | ... |
@@ -33,7 +33,7 @@ type ServiceResolver struct { |
33 | 33 |
var _ server.Backend = &ServiceResolver{} |
34 | 34 |
|
35 | 35 |
// TODO: abstract in upstream SkyDNS |
36 |
-var errNoSuchName = &etcd.EtcdError{ErrorCode: 100} |
|
36 |
+var errNoSuchName = etcd.Error{Code: etcd.ErrorCodeKeyNotFound} |
|
37 | 37 |
|
38 | 38 |
type FallbackFunc func(name string, exact bool) (string, bool) |
39 | 39 |
|
... | ... |
@@ -383,8 +383,8 @@ func simulateOpenShiftMaster(responses []response) (*httptest.Server, *[]string) |
383 | 383 |
response = responses[i] |
384 | 384 |
} |
385 | 385 |
i++ |
386 |
- w.WriteHeader(response.code) |
|
387 | 386 |
w.Header().Set("Content-Type", "application/json") |
387 |
+ w.WriteHeader(response.code) |
|
388 | 388 |
fmt.Fprintln(w, response.body) |
389 | 389 |
actions = append(actions, r.Method+" "+r.URL.Path) |
390 | 390 |
})) |
... | ... |
@@ -466,7 +466,7 @@ func LabelsFromSpec(spec []string) (map[string]string, []string, error) { |
466 | 466 |
func AsVersionedObjects(objects []runtime.Object, typer runtime.ObjectTyper, convertor runtime.ObjectConvertor, versions ...unversioned.GroupVersion) []error { |
467 | 467 |
var errs []error |
468 | 468 |
for i, object := range objects { |
469 |
- kinds, err := typer.ObjectKinds(object) |
|
469 |
+ kinds, _, err := typer.ObjectKinds(object) |
|
470 | 470 |
if err != nil { |
471 | 471 |
errs = append(errs, err) |
472 | 472 |
continue |
... | ... |
@@ -511,7 +511,7 @@ func kindsInVersions(kinds []unversioned.GroupVersionKind, versions []unversione |
511 | 511 |
func tryConvert(convertor runtime.ObjectConvertor, object runtime.Object, versions []unversioned.GroupVersion) (runtime.Object, error) { |
512 | 512 |
var last error |
513 | 513 |
for _, version := range versions { |
514 |
- obj, err := convertor.ConvertToVersion(object, version.String()) |
|
514 |
+ obj, err := convertor.ConvertToVersion(object, version) |
|
515 | 515 |
if err != nil { |
516 | 516 |
last = err |
517 | 517 |
continue |
... | ... |
@@ -263,7 +263,7 @@ func (c *AppConfig) validateBuilders(components app.ComponentReferences) error { |
263 | 263 |
} |
264 | 264 |
|
265 | 265 |
func validateEnforcedName(name string) error { |
266 |
- if ok, _ := validation.ValidateServiceName(name, false); !ok && !app.IsParameterizableValue(name) { |
|
266 |
+ if reasons := validation.ValidateServiceName(name, false); len(reasons) != 0 && !app.IsParameterizableValue(name) { |
|
267 | 267 |
return fmt.Errorf("invalid name: %s. Must be an a lower case alphanumeric (a-z, and 0-9) string with a maximum length of 24 characters, where the first character is a letter (a-z), and the '-' character is allowed anywhere except the first or last character.", name) |
268 | 268 |
} |
269 | 269 |
return nil |
... | ... |
@@ -257,7 +257,7 @@ func (g PipelineGroup) String() string { |
257 | 257 |
var invalidServiceChars = regexp.MustCompile("[^-a-z0-9]") |
258 | 258 |
|
259 | 259 |
func makeValidServiceName(name string) (string, string) { |
260 |
- if ok, _ := validation.ValidateServiceName(name, false); ok { |
|
260 |
+ if len(validation.ValidateServiceName(name, false)) == 0 { |
|
261 | 261 |
return name, "" |
262 | 262 |
} |
263 | 263 |
name = strings.ToLower(name) |
... | ... |
@@ -420,11 +420,11 @@ func (a *acceptUnique) Accept(from interface{}) bool { |
420 | 420 |
if err != nil { |
421 | 421 |
return false |
422 | 422 |
} |
423 |
- gvk, err := a.typer.ObjectKind(obj) |
|
423 |
+ gvk, _, err := a.typer.ObjectKinds(obj) |
|
424 | 424 |
if err != nil { |
425 | 425 |
return false |
426 | 426 |
} |
427 |
- key := fmt.Sprintf("%s/%s/%s", gvk.Kind, meta.Namespace, meta.Name) |
|
427 |
+ key := fmt.Sprintf("%s/%s/%s", gvk[0].Kind, meta.Namespace, meta.Name) |
|
428 | 428 |
_, exists := a.objects[key] |
429 | 429 |
if exists { |
430 | 430 |
return false |
... | ... |
@@ -464,11 +464,11 @@ func (a *acceptBuildConfigs) Accept(from interface{}) bool { |
464 | 464 |
if err != nil { |
465 | 465 |
return false |
466 | 466 |
} |
467 |
- gvk, err := a.typer.ObjectKind(obj) |
|
467 |
+ gvk, _, err := a.typer.ObjectKinds(obj) |
|
468 | 468 |
if err != nil { |
469 | 469 |
return false |
470 | 470 |
} |
471 |
- return gvk.GroupKind() == build.Kind("BuildConfig") || gvk.GroupKind() == image.Kind("ImageStream") |
|
471 |
+ return gvk[0].GroupKind() == build.Kind("BuildConfig") || gvk[0].GroupKind() == image.Kind("ImageStream") |
|
472 | 472 |
} |
473 | 473 |
|
474 | 474 |
// NewAcceptBuildConfigs creates an acceptor accepting BuildConfig objects |
... | ... |
@@ -345,7 +345,7 @@ func (r *SourceRepository) AddBuildSecrets(secrets []string, isDockerBuild bool) |
345 | 345 |
if isDockerBuild && filepath.IsAbs(in.Destination) { |
346 | 346 |
return fmt.Errorf("for the docker strategy, the secret destination directory %q must be a relative path", in.Destination) |
347 | 347 |
} |
348 |
- if ok, _ := validation.ValidateSecretName(in.Source, false); !ok { |
|
348 |
+ if len(validation.ValidateSecretName(in.Source, false)) != 0 { |
|
349 | 349 |
return fmt.Errorf("the %q must be valid secret name", in.Source) |
350 | 350 |
} |
351 | 351 |
if secretExists(in.Source) { |
... | ... |
@@ -55,7 +55,7 @@ func TestAdmitImageStreamMapping(t *testing.T) { |
55 | 55 |
continue |
56 | 56 |
} |
57 | 57 |
|
58 |
- attrs := kadmission.NewAttributesRecord(v.imageStreamMapping, |
|
58 |
+ attrs := kadmission.NewAttributesRecord(v.imageStreamMapping, nil, |
|
59 | 59 |
imageapi.Kind("ImageStreamMapping").WithVersion("version"), |
60 | 60 |
v.imageStreamMapping.Namespace, |
61 | 61 |
v.imageStreamMapping.Name, |
... | ... |
@@ -214,7 +214,7 @@ func TestSupports(t *testing.T) { |
214 | 214 |
} |
215 | 215 |
ilr := plugin.(*imageLimitRangerPlugin) |
216 | 216 |
for _, r := range resources { |
217 |
- attr := kadmission.NewAttributesRecord(nil, unversioned.Kind("ImageStreamMapping").WithVersion("version"), "ns", "name", imageapi.Resource(r).WithVersion("version"), "", kadmission.Create, nil) |
|
217 |
+ attr := kadmission.NewAttributesRecord(nil, nil, unversioned.Kind("ImageStreamMapping").WithVersion("version"), "ns", "name", imageapi.Resource(r).WithVersion("version"), "", kadmission.Create, nil) |
|
218 | 218 |
if !ilr.SupportsAttributes(attr) { |
219 | 219 |
t.Errorf("plugin is expected to support %s", r) |
220 | 220 |
} |
... | ... |
@@ -222,7 +222,7 @@ func TestSupports(t *testing.T) { |
222 | 222 |
|
223 | 223 |
badKinds := []string{"ImageStream", "Image", "Pod", "foo"} |
224 | 224 |
for _, k := range badKinds { |
225 |
- attr := kadmission.NewAttributesRecord(nil, unversioned.Kind(k).WithVersion("version"), "ns", "name", imageapi.Resource("bar").WithVersion("version"), "", kadmission.Create, nil) |
|
225 |
+ attr := kadmission.NewAttributesRecord(nil, nil, unversioned.Kind(k).WithVersion("version"), "ns", "name", imageapi.Resource("bar").WithVersion("version"), "", kadmission.Create, nil) |
|
226 | 226 |
if ilr.SupportsAttributes(attr) { |
227 | 227 |
t.Errorf("plugin is not expected to support %s", k) |
228 | 228 |
} |
... | ... |
@@ -36,7 +36,7 @@ func Convert_api_Image_To_v1_Image(in *newer.Image, out *Image, s conversion.Sco |
36 | 36 |
if err != nil { |
37 | 37 |
return err |
38 | 38 |
} |
39 |
- data, err := runtime.Encode(api.Codecs.LegacyCodec(version), &in.DockerImageMetadata, version) |
|
39 |
+ data, err := runtime.Encode(api.Codecs.LegacyCodec(version), &in.DockerImageMetadata) |
|
40 | 40 |
if err != nil { |
41 | 41 |
return err |
42 | 42 |
} |
... | ... |
@@ -3,6 +3,7 @@ package validation |
3 | 3 |
import ( |
4 | 4 |
"fmt" |
5 | 5 |
"regexp" |
6 |
+ "strings" |
|
6 | 7 |
|
7 | 8 |
"github.com/docker/distribution/reference" |
8 | 9 |
"github.com/golang/glog" |
... | ... |
@@ -32,15 +33,15 @@ var RepositoryNameComponentAnchoredRegexp = regexp.MustCompile(`^` + RepositoryN |
32 | 32 |
// Copied from github.com/docker/distribution/registry/api/v2/names.go v2.1.1 |
33 | 33 |
var RepositoryNameRegexp = regexp.MustCompile(`(?:` + RepositoryNameComponentRegexp.String() + `/)*` + RepositoryNameComponentRegexp.String()) |
34 | 34 |
|
35 |
-func ValidateImageStreamName(name string, prefix bool) (bool, string) { |
|
36 |
- if ok, reason := oapi.MinimalNameRequirements(name, prefix); !ok { |
|
37 |
- return ok, reason |
|
35 |
+func ValidateImageStreamName(name string, prefix bool) []string { |
|
36 |
+ if reasons := oapi.MinimalNameRequirements(name, prefix); len(reasons) != 0 { |
|
37 |
+ return reasons |
|
38 | 38 |
} |
39 | 39 |
|
40 | 40 |
if !RepositoryNameComponentAnchoredRegexp.MatchString(name) { |
41 |
- return false, fmt.Sprintf("must match %q", RepositoryNameComponentRegexp.String()) |
|
41 |
+ return []string{fmt.Sprintf("must match %q", RepositoryNameComponentRegexp.String())} |
|
42 | 42 |
} |
43 |
- return true, "" |
|
43 |
+ return nil |
|
44 | 44 |
} |
45 | 45 |
|
46 | 46 |
// ValidateImage tests required fields for an Image. |
... | ... |
@@ -209,8 +210,8 @@ func ValidateImageStreamMapping(mapping *api.ImageStreamMapping) field.ErrorList |
209 | 209 |
result = append(result, field.Required(field.NewPath("dockerImageRepository"), "")) |
210 | 210 |
} |
211 | 211 |
|
212 |
- if ok, msg := validation.ValidateNamespaceName(mapping.Namespace, false); !ok { |
|
213 |
- result = append(result, field.Invalid(field.NewPath("metadata", "namespace"), mapping.Namespace, msg)) |
|
212 |
+ if reasons := validation.ValidateNamespaceName(mapping.Namespace, false); len(reasons) != 0 { |
|
213 |
+ result = append(result, field.Invalid(field.NewPath("metadata", "namespace"), mapping.Namespace, strings.Join(reasons, ", "))) |
|
214 | 214 |
} |
215 | 215 |
if len(mapping.Tag) == 0 { |
216 | 216 |
result = append(result, field.Required(field.NewPath("tag"), "")) |
... | ... |
@@ -377,7 +377,7 @@ func TestValidateImageStream(t *testing.T) { |
377 | 377 |
namespace: "!$", |
378 | 378 |
name: "foo", |
379 | 379 |
expected: field.ErrorList{ |
380 |
- field.Invalid(field.NewPath("metadata", "namespace"), "!$", `must be a DNS label (at most 63 characters, matching regex [a-z0-9]([-a-z0-9]*[a-z0-9])?): e.g. "my-name"`), |
|
380 |
+ field.Invalid(field.NewPath("metadata", "namespace"), "!$", `must match the regex [a-z0-9]([-a-z0-9]*[a-z0-9])? (e.g. 'my-name' or '123-abc')`), |
|
381 | 381 |
}, |
382 | 382 |
}, |
383 | 383 |
"invalid dockerImageRepository": { |
... | ... |
@@ -682,7 +682,7 @@ func TestValidateImageStreamImport(t *testing.T) { |
682 | 682 |
"invalid namespace": { |
683 | 683 |
isi: &api.ImageStreamImport{ObjectMeta: kapi.ObjectMeta{Namespace: "!$", Name: "foo"}, Spec: validSpec}, |
684 | 684 |
expected: field.ErrorList{ |
685 |
- field.Invalid(field.NewPath("metadata", "namespace"), "!$", `must be a DNS label (at most 63 characters, matching regex [a-z0-9]([-a-z0-9]*[a-z0-9])?): e.g. "my-name"`), |
|
685 |
+ field.Invalid(field.NewPath("metadata", "namespace"), "!$", `must match the regex [a-z0-9]([-a-z0-9]*[a-z0-9])? (e.g. 'my-name' or '123-abc')`), |
|
686 | 686 |
}, |
687 | 687 |
}, |
688 | 688 |
"invalid dockerImageRepository": { |
... | ... |
@@ -396,7 +396,7 @@ func TestScheduledImport(t *testing.T) { |
396 | 396 |
} |
397 | 397 |
|
398 | 398 |
// encountering a not found error for image streams should drop the controller |
399 |
- status := apierrs.NewNotFound(api.Resource("imagestream"), "test").(*apierrs.StatusError).ErrStatus |
|
399 |
+ status := apierrs.NewNotFound(api.Resource("imagestream"), "test").ErrStatus |
|
400 | 400 |
fake = client.NewSimpleFake(&status) |
401 | 401 |
b.controller.streams = fake |
402 | 402 |
b.scheduler.RunOnce() |
... | ... |
@@ -480,14 +480,14 @@ func importRepositoryFromDocker(ctx gocontext.Context, retriever RepositoryRetri |
480 | 480 |
func importRepositoryFromDockerV1(ctx gocontext.Context, repository *importRepository, limiter flowcontrol.RateLimiter) { |
481 | 481 |
value := ctx.Value(ContextKeyV1RegistryClient) |
482 | 482 |
if value == nil { |
483 |
- err := kapierrors.NewForbidden(api.Resource(""), "", fmt.Errorf("registry %q does not support the v2 Registry API", repository.Registry.Host)).(*kapierrors.StatusError) |
|
483 |
+ err := kapierrors.NewForbidden(api.Resource(""), "", fmt.Errorf("registry %q does not support the v2 Registry API", repository.Registry.Host)) |
|
484 | 484 |
err.ErrStatus.Reason = "NotV2Registry" |
485 | 485 |
applyErrorToRepository(repository, err) |
486 | 486 |
return |
487 | 487 |
} |
488 | 488 |
client, ok := value.(dockerregistry.Client) |
489 | 489 |
if !ok { |
490 |
- err := kapierrors.NewForbidden(api.Resource(""), "", fmt.Errorf("registry %q does not support the v2 Registry API", repository.Registry.Host)).(*kapierrors.StatusError) |
|
490 |
+ err := kapierrors.NewForbidden(api.Resource(""), "", fmt.Errorf("registry %q does not support the v2 Registry API", repository.Registry.Host)) |
|
491 | 491 |
err.ErrStatus.Reason = "NotV2Registry" |
492 | 492 |
return |
493 | 493 |
} |
... | ... |
@@ -616,9 +616,9 @@ func imageImportStatus(err error, kind, position string) unversioned.Status { |
616 | 616 |
case kapierrors.APIStatus: |
617 | 617 |
return t.Status() |
618 | 618 |
case *field.Error: |
619 |
- return kapierrors.NewInvalid(api.Kind(kind), position, field.ErrorList{t}).(kapierrors.APIStatus).Status() |
|
619 |
+ return kapierrors.NewInvalid(api.Kind(kind), position, field.ErrorList{t}).ErrStatus |
|
620 | 620 |
default: |
621 |
- return kapierrors.NewInternalError(err).(kapierrors.APIStatus).Status() |
|
621 |
+ return kapierrors.NewInternalError(err).ErrStatus |
|
622 | 622 |
} |
623 | 623 |
} |
624 | 624 |
|
... | ... |
@@ -628,5 +628,5 @@ func setImageImportStatus(images *api.ImageStreamImport, i int, tag string, err |
628 | 628 |
} |
629 | 629 |
|
630 | 630 |
func invalidStatus(position string, errs ...*field.Error) unversioned.Status { |
631 |
- return kapierrors.NewInvalid(api.Kind(""), position, errs).(kapierrors.APIStatus).Status() |
|
631 |
+ return kapierrors.NewInvalid(api.Kind(""), position, errs).ErrStatus |
|
632 | 632 |
} |
... | ... |
@@ -4,6 +4,7 @@ import ( |
4 | 4 |
"testing" |
5 | 5 |
|
6 | 6 |
kapi "k8s.io/kubernetes/pkg/api" |
7 |
+ "k8s.io/kubernetes/pkg/api/rest" |
|
7 | 8 |
"k8s.io/kubernetes/pkg/fields" |
8 | 9 |
"k8s.io/kubernetes/pkg/labels" |
9 | 10 |
"k8s.io/kubernetes/pkg/registry/registrytest" |
... | ... |
@@ -387,7 +388,7 @@ func TestUpdateResetsMetadata(t *testing.T) { |
387 | 387 |
|
388 | 388 |
// Copy the resource version into our update object |
389 | 389 |
test.image.ResourceVersion = created.(*api.Image).ResourceVersion |
390 |
- obj, _, err := storage.Update(kapi.NewDefaultContext(), test.image) |
|
390 |
+ obj, _, err := storage.Update(kapi.NewDefaultContext(), test.image.Name, rest.DefaultUpdatedObjectInfo(test.image, kapi.Scheme)) |
|
391 | 391 |
if err != nil { |
392 | 392 |
t.Errorf("%d: Unexpected non-nil error: %#v", i, err) |
393 | 393 |
continue |
... | ... |
@@ -2,6 +2,7 @@ package etcd |
2 | 2 |
|
3 | 3 |
import ( |
4 | 4 |
kapi "k8s.io/kubernetes/pkg/api" |
5 |
+ "k8s.io/kubernetes/pkg/api/rest" |
|
5 | 6 |
"k8s.io/kubernetes/pkg/fields" |
6 | 7 |
"k8s.io/kubernetes/pkg/labels" |
7 | 8 |
"k8s.io/kubernetes/pkg/registry/generic" |
... | ... |
@@ -89,8 +90,8 @@ func (r *StatusREST) New() runtime.Object { |
89 | 89 |
} |
90 | 90 |
|
91 | 91 |
// Update alters the status subset of an object. |
92 |
-func (r *StatusREST) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, bool, error) { |
|
93 |
- return r.store.Update(ctx, obj) |
|
92 |
+func (r *StatusREST) Update(ctx kapi.Context, name string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) { |
|
93 |
+ return r.store.Update(ctx, name, objInfo) |
|
94 | 94 |
} |
95 | 95 |
|
96 | 96 |
// InternalREST implements the REST endpoint for changing both the spec and status of an image stream. |
... | ... |
@@ -108,6 +109,6 @@ func (r *InternalREST) Create(ctx kapi.Context, obj runtime.Object) (runtime.Obj |
108 | 108 |
} |
109 | 109 |
|
110 | 110 |
// Update alters both the spec and status of the object. |
111 |
-func (r *InternalREST) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, bool, error) { |
|
112 |
- return r.store.Update(ctx, obj) |
|
111 |
+func (r *InternalREST) Update(ctx kapi.Context, name string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) { |
|
112 |
+ return r.store.Update(ctx, name, objInfo) |
|
113 | 113 |
} |
... | ... |
@@ -38,7 +38,7 @@ type Storage interface { |
38 | 38 |
rest.Watcher |
39 | 39 |
|
40 | 40 |
Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, error) |
41 |
- Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, bool, error) |
|
41 |
+ Update(ctx kapi.Context, name string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) |
|
42 | 42 |
} |
43 | 43 |
|
44 | 44 |
// storage puts strong typing around storage calls |
... | ... |
@@ -79,7 +79,7 @@ func (s *storage) CreateImageStream(ctx kapi.Context, imageStream *api.ImageStre |
79 | 79 |
} |
80 | 80 |
|
81 | 81 |
func (s *storage) UpdateImageStream(ctx kapi.Context, imageStream *api.ImageStream) (*api.ImageStream, error) { |
82 |
- obj, _, err := s.internal.Update(ctx, imageStream) |
|
82 |
+ obj, _, err := s.internal.Update(ctx, imageStream.Name, rest.DefaultUpdatedObjectInfo(imageStream, kapi.Scheme)) |
|
83 | 83 |
if err != nil { |
84 | 84 |
return nil, err |
85 | 85 |
} |
... | ... |
@@ -87,7 +87,7 @@ func (s *storage) UpdateImageStream(ctx kapi.Context, imageStream *api.ImageStre |
87 | 87 |
} |
88 | 88 |
|
89 | 89 |
func (s *storage) UpdateImageStreamSpec(ctx kapi.Context, imageStream *api.ImageStream) (*api.ImageStream, error) { |
90 |
- obj, _, err := s.Update(ctx, imageStream) |
|
90 |
+ obj, _, err := s.Update(ctx, imageStream.Name, rest.DefaultUpdatedObjectInfo(imageStream, kapi.Scheme)) |
|
91 | 91 |
if err != nil { |
92 | 92 |
return nil, err |
93 | 93 |
} |
... | ... |
@@ -95,7 +95,7 @@ func (s *storage) UpdateImageStreamSpec(ctx kapi.Context, imageStream *api.Image |
95 | 95 |
} |
96 | 96 |
|
97 | 97 |
func (s *storage) UpdateImageStreamStatus(ctx kapi.Context, imageStream *api.ImageStream) (*api.ImageStream, error) { |
98 |
- obj, _, err := s.status.Update(ctx, imageStream) |
|
98 |
+ obj, _, err := s.status.Update(ctx, imageStream.Name, rest.DefaultUpdatedObjectInfo(imageStream, kapi.Scheme)) |
|
99 | 99 |
if err != nil { |
100 | 100 |
return nil, err |
101 | 101 |
} |
... | ... |
@@ -250,7 +250,7 @@ func (r *REST) Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, err |
250 | 250 |
glog.V(4).Infof("updated stream %s", diff.ObjectDiff(original, stream)) |
251 | 251 |
} |
252 | 252 |
stream.Annotations[api.DockerImageRepositoryCheckAnnotation] = now.UTC().Format(time.RFC3339) |
253 |
- obj, _, err = r.internalStreams.Update(ctx, stream) |
|
253 |
+ obj, _, err = r.internalStreams.Update(ctx, stream.Name, rest.DefaultUpdatedObjectInfo(stream, kapi.Scheme)) |
|
254 | 254 |
} |
255 | 255 |
} |
256 | 256 |
|
... | ... |
@@ -426,5 +426,5 @@ func newImportFailedCondition(err error, gen int64, now unversioned.Time) api.Ta |
426 | 426 |
} |
427 | 427 |
|
428 | 428 |
func invalidStatus(kind, position string, errs ...*field.Error) unversioned.Status { |
429 |
- return kapierrors.NewInvalid(api.Kind(kind), position, errs).(kapierrors.APIStatus).Status() |
|
429 |
+ return kapierrors.NewInvalid(api.Kind(kind), position, errs).ErrStatus |
|
430 | 430 |
} |
... | ... |
@@ -99,20 +99,16 @@ func (r *REST) Get(ctx kapi.Context, id string) (runtime.Object, error) { |
99 | 99 |
return newISTag(tag, imageStream, image, false) |
100 | 100 |
} |
101 | 101 |
|
102 |
-func (r *REST) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, bool, error) { |
|
103 |
- istag, ok := obj.(*api.ImageStreamTag) |
|
104 |
- if !ok { |
|
105 |
- return nil, false, kapierrors.NewBadRequest(fmt.Sprintf("obj is not an ImageStreamTag: %#v", obj)) |
|
106 |
- } |
|
107 |
- |
|
108 |
- name, tag, err := nameAndTag(istag.Name) |
|
102 |
+func (r *REST) Update(ctx kapi.Context, tagName string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) { |
|
103 |
+ name, tag, err := nameAndTag(tagName) |
|
109 | 104 |
if err != nil { |
110 | 105 |
return nil, false, err |
111 | 106 |
} |
112 | 107 |
|
108 |
+ create := false |
|
113 | 109 |
imageStream, err := r.imageStreamRegistry.GetImageStream(ctx, name) |
114 | 110 |
if err != nil { |
115 |
- if !kapierrors.IsNotFound(err) || len(istag.ResourceVersion) != 0 { |
|
111 |
+ if !kapierrors.IsNotFound(err) { |
|
116 | 112 |
return nil, false, err |
117 | 113 |
} |
118 | 114 |
namespace, ok := kapi.NamespaceFrom(ctx) |
... | ... |
@@ -120,16 +116,13 @@ func (r *REST) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, boo |
120 | 120 |
return nil, false, kapierrors.NewBadRequest("namespace is required on ImageStreamTags") |
121 | 121 |
} |
122 | 122 |
imageStream = &api.ImageStream{ |
123 |
- ObjectMeta: kapi.ObjectMeta{Namespace: namespace, Name: name}, |
|
123 |
+ ObjectMeta: kapi.ObjectMeta{ |
|
124 |
+ Namespace: namespace, |
|
125 |
+ Name: name, |
|
126 |
+ }, |
|
124 | 127 |
} |
125 |
- } |
|
126 |
- |
|
127 |
- // check for conflict |
|
128 |
- if len(istag.ResourceVersion) == 0 { |
|
129 |
- istag.ResourceVersion = imageStream.ResourceVersion |
|
130 |
- } |
|
131 |
- if imageStream.ResourceVersion != istag.ResourceVersion { |
|
132 |
- return nil, false, kapierrors.NewConflict(api.Resource("imagestreamtags"), istag.Name, fmt.Errorf("another caller has updated the resource version to %s", imageStream.ResourceVersion)) |
|
128 |
+ kapi.FillObjectMetaSystemFields(ctx, &imageStream.ObjectMeta) |
|
129 |
+ create = true |
|
133 | 130 |
} |
134 | 131 |
|
135 | 132 |
// create the synthetic old istag |
... | ... |
@@ -138,7 +131,30 @@ func (r *REST) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, boo |
138 | 138 |
return nil, false, err |
139 | 139 |
} |
140 | 140 |
|
141 |
- if len(istag.ResourceVersion) == 0 { |
|
141 |
+ obj, err := objInfo.UpdatedObject(ctx, old) |
|
142 |
+ if err != nil { |
|
143 |
+ return nil, false, err |
|
144 |
+ } |
|
145 |
+ |
|
146 |
+ istag, ok := obj.(*api.ImageStreamTag) |
|
147 |
+ if !ok { |
|
148 |
+ return nil, false, kapierrors.NewBadRequest(fmt.Sprintf("obj is not an ImageStreamTag: %#v", obj)) |
|
149 |
+ } |
|
150 |
+ |
|
151 |
+ // check for conflict |
|
152 |
+ switch { |
|
153 |
+ case len(istag.ResourceVersion) == 0: |
|
154 |
+ // should disallow blind PUT, but this was previously supported |
|
155 |
+ istag.ResourceVersion = imageStream.ResourceVersion |
|
156 |
+ case len(imageStream.ResourceVersion) == 0: |
|
157 |
+ // image stream did not exist, cannot update |
|
158 |
+ return nil, false, kapierrors.NewNotFound(api.Resource("imagestreamtags"), tagName) |
|
159 |
+ case imageStream.ResourceVersion != istag.ResourceVersion: |
|
160 |
+ // conflicting input and output |
|
161 |
+ return nil, false, kapierrors.NewConflict(api.Resource("imagestreamtags"), istag.Name, fmt.Errorf("another caller has updated the resource version to %s", imageStream.ResourceVersion)) |
|
162 |
+ } |
|
163 |
+ |
|
164 |
+ if create { |
|
142 | 165 |
if err := rest.BeforeCreate(Strategy, ctx, obj); err != nil { |
143 | 166 |
return nil, false, err |
144 | 167 |
} |
... | ... |
@@ -163,7 +179,7 @@ func (r *REST) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, boo |
163 | 163 |
|
164 | 164 |
// mutate the image stream |
165 | 165 |
var newImageStream *api.ImageStream |
166 |
- if imageStream.CreationTimestamp.IsZero() { |
|
166 |
+ if create { |
|
167 | 167 |
newImageStream, err = r.imageStreamRegistry.CreateImageStream(ctx, imageStream) |
168 | 168 |
} else { |
169 | 169 |
newImageStream, err = r.imageStreamRegistry.UpdateImageStream(ctx, imageStream) |
... | ... |
@@ -254,6 +270,7 @@ func newISTag(tag string, imageStream *api.ImageStream, image *api.Image, allowE |
254 | 254 |
CreationTimestamp: event.Created, |
255 | 255 |
Annotations: map[string]string{}, |
256 | 256 |
ResourceVersion: imageStream.ResourceVersion, |
257 |
+ UID: imageStream.UID, |
|
257 | 258 |
}, |
258 | 259 |
Generation: event.Generation, |
259 | 260 |
Conditions: imageStream.Status.Tags[tag].Conditions, |
... | ... |
@@ -17,15 +17,15 @@ import ( |
17 | 17 |
|
18 | 18 |
const MinTokenLength = 32 |
19 | 19 |
|
20 |
-func ValidateTokenName(name string, prefix bool) (bool, string) { |
|
21 |
- if ok, reason := oapi.MinimalNameRequirements(name, prefix); !ok { |
|
22 |
- return ok, reason |
|
20 |
+func ValidateTokenName(name string, prefix bool) []string { |
|
21 |
+ if reasons := oapi.MinimalNameRequirements(name, prefix); len(reasons) != 0 { |
|
22 |
+ return reasons |
|
23 | 23 |
} |
24 | 24 |
|
25 | 25 |
if len(name) < MinTokenLength { |
26 |
- return false, fmt.Sprintf("must be at least %d characters long", MinTokenLength) |
|
26 |
+ return []string{fmt.Sprintf("must be at least %d characters long", MinTokenLength)} |
|
27 | 27 |
} |
28 |
- return true, "" |
|
28 |
+ return nil |
|
29 | 29 |
} |
30 | 30 |
|
31 | 31 |
func ValidateRedirectURI(redirect string) (bool, string) { |
... | ... |
@@ -156,17 +156,17 @@ func ValidateClientUpdate(client *api.OAuthClient, oldClient *api.OAuthClient) f |
156 | 156 |
return allErrs |
157 | 157 |
} |
158 | 158 |
|
159 |
-func ValidateClientAuthorizationName(name string, prefix bool) (bool, string) { |
|
160 |
- if ok, reason := oapi.MinimalNameRequirements(name, prefix); !ok { |
|
161 |
- return ok, reason |
|
159 |
+func ValidateClientAuthorizationName(name string, prefix bool) []string { |
|
160 |
+ if reasons := oapi.MinimalNameRequirements(name, prefix); len(reasons) != 0 { |
|
161 |
+ return reasons |
|
162 | 162 |
} |
163 | 163 |
|
164 | 164 |
lastColon := strings.Index(name, ":") |
165 | 165 |
if lastColon <= 0 || lastColon >= len(name)-1 { |
166 |
- return false, "must be in the format <userName>:<clientName>" |
|
166 |
+ return []string{"must be in the format <userName>:<clientName>"} |
|
167 | 167 |
} |
168 | 168 |
|
169 |
- return true, "" |
|
169 |
+ return nil |
|
170 | 170 |
} |
171 | 171 |
|
172 | 172 |
func ValidateClientAuthorization(clientAuthorization *api.OAuthClientAuthorization) field.ErrorList { |
... | ... |
@@ -214,11 +214,11 @@ func ValidateClientNameField(value string, fldPath *field.Path) field.ErrorList |
214 | 214 |
if len(value) == 0 { |
215 | 215 |
return field.ErrorList{field.Required(fldPath, "")} |
216 | 216 |
} else if _, saName, err := serviceaccount.SplitUsername(value); err == nil { |
217 |
- if ok, errString := validation.ValidateServiceAccountName(saName, false); !ok { |
|
218 |
- return field.ErrorList{field.Invalid(fldPath, value, errString)} |
|
217 |
+ if reasons := validation.ValidateServiceAccountName(saName, false); len(reasons) != 0 { |
|
218 |
+ return field.ErrorList{field.Invalid(fldPath, value, strings.Join(reasons, ", "))} |
|
219 | 219 |
} |
220 |
- } else if ok, msg := validation.NameIsDNSSubdomain(value, false); !ok { |
|
221 |
- return field.ErrorList{field.Invalid(fldPath, value, msg)} |
|
220 |
+ } else if reasons := validation.NameIsDNSSubdomain(value, false); len(reasons) != 0 { |
|
221 |
+ return field.ErrorList{field.Invalid(fldPath, value, strings.Join(reasons, ", "))} |
|
222 | 222 |
} |
223 | 223 |
return field.ErrorList{} |
224 | 224 |
} |
... | ... |
@@ -226,8 +226,8 @@ func ValidateClientNameField(value string, fldPath *field.Path) field.ErrorList |
226 | 226 |
func ValidateUserNameField(value string, fldPath *field.Path) field.ErrorList { |
227 | 227 |
if len(value) == 0 { |
228 | 228 |
return field.ErrorList{field.Required(fldPath, "")} |
229 |
- } else if ok, msg := uservalidation.ValidateUserName(value, false); !ok { |
|
230 |
- return field.ErrorList{field.Invalid(fldPath, value, msg)} |
|
229 |
+ } else if reasons := uservalidation.ValidateUserName(value, false); len(reasons) != 0 { |
|
230 |
+ return field.ErrorList{field.Invalid(fldPath, value, strings.Join(reasons, ", "))} |
|
231 | 231 |
} |
232 | 232 |
return field.ErrorList{} |
233 | 233 |
} |
... | ... |
@@ -63,7 +63,7 @@ func (s *storage) CreateClient(ctx kapi.Context, client *api.OAuthClient) (*api. |
63 | 63 |
} |
64 | 64 |
|
65 | 65 |
func (s *storage) UpdateClient(ctx kapi.Context, client *api.OAuthClient) (*api.OAuthClient, error) { |
66 |
- obj, _, err := s.Update(ctx, client) |
|
66 |
+ obj, _, err := s.Update(ctx, client.Name, rest.DefaultUpdatedObjectInfo(client, kapi.Scheme)) |
|
67 | 67 |
if err != nil { |
68 | 68 |
return nil, err |
69 | 69 |
} |
... | ... |
@@ -63,7 +63,7 @@ func (s *storage) CreateClientAuthorization(ctx kapi.Context, client *api.OAuthC |
63 | 63 |
} |
64 | 64 |
|
65 | 65 |
func (s *storage) UpdateClientAuthorization(ctx kapi.Context, client *api.OAuthClientAuthorization) (*api.OAuthClientAuthorization, error) { |
66 |
- obj, _, err := s.Update(ctx, client) |
|
66 |
+ obj, _, err := s.Update(ctx, client.Name, rest.DefaultUpdatedObjectInfo(client, kapi.Scheme)) |
|
67 | 67 |
if err != nil { |
68 | 68 |
return nil, err |
69 | 69 |
} |
... | ... |
@@ -12,7 +12,7 @@ import ( |
12 | 12 |
"k8s.io/kubernetes/pkg/client/cache" |
13 | 13 |
clientsetfake "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" |
14 | 14 |
"k8s.io/kubernetes/pkg/client/unversioned/testclient" |
15 |
- "k8s.io/kubernetes/pkg/genericapiserver" |
|
15 |
+ genericapiserveroptions "k8s.io/kubernetes/pkg/genericapiserver/options" |
|
16 | 16 |
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client" |
17 | 17 |
"k8s.io/kubernetes/pkg/runtime" |
18 | 18 |
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd" |
... | ... |
@@ -41,7 +41,7 @@ func TestIgnoreThatWhichCannotBeKnown(t *testing.T) { |
41 | 41 |
handler := &lifecycle{} |
42 | 42 |
unknown := &UnknownObject{} |
43 | 43 |
|
44 |
- err := handler.Admit(admission.NewAttributesRecord(unknown, kapi.Kind("kind").WithVersion("version"), "namespace", "name", kapi.Resource("resource").WithVersion("version"), "subresource", "CREATE", nil)) |
|
44 |
+ err := handler.Admit(admission.NewAttributesRecord(unknown, nil, kapi.Kind("kind").WithVersion("version"), "namespace", "name", kapi.Resource("resource").WithVersion("version"), "subresource", "CREATE", nil)) |
|
45 | 45 |
if err != nil { |
46 | 46 |
t.Errorf("Admission control should not error if it finds an object it knows nothing about %v", err) |
47 | 47 |
} |
... | ... |
@@ -84,7 +84,7 @@ func TestAdmissionExists(t *testing.T) { |
84 | 84 |
Phase: buildapi.BuildPhaseNew, |
85 | 85 |
}, |
86 | 86 |
} |
87 |
- err := handler.Admit(admission.NewAttributesRecord(build, kapi.Kind("Build").WithVersion("version"), "namespace", "name", kapi.Resource("builds").WithVersion("version"), "", "CREATE", nil)) |
|
87 |
+ err := handler.Admit(admission.NewAttributesRecord(build, nil, kapi.Kind("Build").WithVersion("version"), "namespace", "name", kapi.Resource("builds").WithVersion("version"), "", "CREATE", nil)) |
|
88 | 88 |
if err == nil { |
89 | 89 |
t.Errorf("Expected an error because namespace does not exist") |
90 | 90 |
} |
... | ... |
@@ -134,7 +134,7 @@ func TestAdmissionLifecycle(t *testing.T) { |
134 | 134 |
Phase: buildapi.BuildPhaseNew, |
135 | 135 |
}, |
136 | 136 |
} |
137 |
- err := handler.Admit(admission.NewAttributesRecord(build, kapi.Kind("Build").WithVersion("version"), build.Namespace, "name", kapi.Resource("builds").WithVersion("version"), "", "CREATE", nil)) |
|
137 |
+ err := handler.Admit(admission.NewAttributesRecord(build, nil, kapi.Kind("Build").WithVersion("version"), build.Namespace, "name", kapi.Resource("builds").WithVersion("version"), "", "CREATE", nil)) |
|
138 | 138 |
if err != nil { |
139 | 139 |
t.Errorf("Unexpected error returned from admission handler: %v", err) |
140 | 140 |
} |
... | ... |
@@ -144,19 +144,19 @@ func TestAdmissionLifecycle(t *testing.T) { |
144 | 144 |
store.Add(namespaceObj) |
145 | 145 |
|
146 | 146 |
// verify create operations in the namespace cause an error |
147 |
- err = handler.Admit(admission.NewAttributesRecord(build, kapi.Kind("Build").WithVersion("version"), build.Namespace, "name", kapi.Resource("builds").WithVersion("version"), "", "CREATE", nil)) |
|
147 |
+ err = handler.Admit(admission.NewAttributesRecord(build, nil, kapi.Kind("Build").WithVersion("version"), build.Namespace, "name", kapi.Resource("builds").WithVersion("version"), "", "CREATE", nil)) |
|
148 | 148 |
if err == nil { |
149 | 149 |
t.Errorf("Expected error rejecting creates in a namespace when it is terminating") |
150 | 150 |
} |
151 | 151 |
|
152 | 152 |
// verify update operations in the namespace can proceed |
153 |
- err = handler.Admit(admission.NewAttributesRecord(build, kapi.Kind("Build").WithVersion("version"), build.Namespace, "name", kapi.Resource("builds").WithVersion("version"), "", "UPDATE", nil)) |
|
153 |
+ err = handler.Admit(admission.NewAttributesRecord(build, build, kapi.Kind("Build").WithVersion("version"), build.Namespace, "name", kapi.Resource("builds").WithVersion("version"), "", "UPDATE", nil)) |
|
154 | 154 |
if err != nil { |
155 | 155 |
t.Errorf("Unexpected error returned from admission handler: %v", err) |
156 | 156 |
} |
157 | 157 |
|
158 | 158 |
// verify delete operations in the namespace can proceed |
159 |
- err = handler.Admit(admission.NewAttributesRecord(nil, kapi.Kind("Build").WithVersion("version"), build.Namespace, "name", kapi.Resource("builds").WithVersion("version"), "", "DELETE", nil)) |
|
159 |
+ err = handler.Admit(admission.NewAttributesRecord(nil, nil, kapi.Kind("Build").WithVersion("version"), build.Namespace, "name", kapi.Resource("builds").WithVersion("version"), "", "DELETE", nil)) |
|
160 | 160 |
if err != nil { |
161 | 161 |
t.Errorf("Unexpected error returned from admission handler: %v", err) |
162 | 162 |
} |
... | ... |
@@ -165,7 +165,7 @@ func TestAdmissionLifecycle(t *testing.T) { |
165 | 165 |
|
166 | 166 |
// TestCreatesAllowedDuringNamespaceDeletion checks to make sure that the resources in the whitelist are allowed |
167 | 167 |
func TestCreatesAllowedDuringNamespaceDeletion(t *testing.T) { |
168 |
- etcdHelper := etcdstorage.NewEtcdStorage(nil, kapi.Codecs.LegacyCodec(), "", false, genericapiserver.DefaultDeserializationCacheSize) |
|
168 |
+ etcdHelper := etcdstorage.NewEtcdStorage(nil, kapi.Codecs.LegacyCodec(), "", false, genericapiserveroptions.DefaultDeserializationCacheSize) |
|
169 | 169 |
|
170 | 170 |
informerFactory := shared.NewInformerFactory(testclient.NewSimpleFake(), otestclient.NewSimpleFake(), shared.DefaultListerWatcherOverrides{}, 1*time.Second) |
171 | 171 |
config := &origin.MasterConfig{ |
... | ... |
@@ -216,7 +216,7 @@ func TestSAR(t *testing.T) { |
216 | 216 |
} |
217 | 217 |
|
218 | 218 |
for k, v := range tests { |
219 |
- err := handler.Admit(admission.NewAttributesRecord(nil, kapi.Kind(v.kind).WithVersion("version"), "foo", "name", kapi.Resource(v.resource).WithVersion("version"), "", "CREATE", nil)) |
|
219 |
+ err := handler.Admit(admission.NewAttributesRecord(nil, nil, kapi.Kind(v.kind).WithVersion("version"), "foo", "name", kapi.Resource(v.resource).WithVersion("version"), "", "CREATE", nil)) |
|
220 | 220 |
if err != nil { |
221 | 221 |
t.Errorf("Unexpected error for %s returned from admission handler: %v", k, err) |
222 | 222 |
} |
... | ... |
@@ -113,7 +113,7 @@ func TestPodAdmission(t *testing.T) { |
113 | 113 |
} |
114 | 114 |
pod.Spec = kapi.PodSpec{NodeSelector: test.podNodeSelector} |
115 | 115 |
|
116 |
- err := handler.Admit(admission.NewAttributesRecord(pod, kapi.Kind("Pod").WithVersion("version"), "namespace", project.ObjectMeta.Name, kapi.Resource("pods").WithVersion("version"), "", admission.Create, nil)) |
|
116 |
+ err := handler.Admit(admission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), "namespace", project.ObjectMeta.Name, kapi.Resource("pods").WithVersion("version"), "", admission.Create, nil)) |
|
117 | 117 |
if test.admit && err != nil { |
118 | 118 |
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err) |
119 | 119 |
} else if !test.admit && err == nil { |
... | ... |
@@ -110,7 +110,7 @@ func (o *projectRequestLimit) maxProjectsByRequester(userName string) (int, bool |
110 | 110 |
} |
111 | 111 |
|
112 | 112 |
// if we aren't a valid username, we came in as cert user for certain, use our cert user rules |
113 |
- if valid, _ := uservalidation.ValidateUserName(userName, false); !valid { |
|
113 |
+ if reasons := uservalidation.ValidateUserName(userName, false); len(reasons) != 0 { |
|
114 | 114 |
if o.config.MaxProjectsForSystemUsers == nil { |
115 | 115 |
return 0, false, nil |
116 | 116 |
} |
... | ... |
@@ -13,20 +13,20 @@ import ( |
13 | 13 |
"github.com/openshift/origin/pkg/util/labelselector" |
14 | 14 |
) |
15 | 15 |
|
16 |
-func ValidateProjectName(name string, prefix bool) (bool, string) { |
|
17 |
- if ok, reason := oapi.MinimalNameRequirements(name, prefix); !ok { |
|
18 |
- return ok, reason |
|
16 |
+func ValidateProjectName(name string, prefix bool) []string { |
|
17 |
+ if reasons := oapi.MinimalNameRequirements(name, prefix); len(reasons) != 0 { |
|
18 |
+ return reasons |
|
19 | 19 |
} |
20 | 20 |
|
21 | 21 |
if len(name) < 2 { |
22 |
- return false, "must be at least 2 characters long" |
|
22 |
+ return []string{"must be at least 2 characters long"} |
|
23 | 23 |
} |
24 | 24 |
|
25 |
- if ok, msg := validation.ValidateNamespaceName(name, false); !ok { |
|
26 |
- return ok, msg |
|
25 |
+ if reasons := validation.ValidateNamespaceName(name, false); len(reasons) != 0 { |
|
26 |
+ return reasons |
|
27 | 27 |
} |
28 | 28 |
|
29 |
- return true, "" |
|
29 |
+ return nil |
|
30 | 30 |
} |
31 | 31 |
|
32 | 32 |
// ValidateProject tests required fields for a Project. |
... | ... |
@@ -131,16 +131,22 @@ func (s *REST) Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, err |
131 | 131 |
|
132 | 132 |
var _ = rest.Updater(&REST{}) |
133 | 133 |
|
134 |
-func (s *REST) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, bool, error) { |
|
135 |
- project, ok := obj.(*api.Project) |
|
136 |
- if !ok { |
|
137 |
- return nil, false, fmt.Errorf("not a project: %#v", obj) |
|
134 |
+func (s *REST) Update(ctx kapi.Context, name string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) { |
|
135 |
+ oldObj, err := s.Get(ctx, name) |
|
136 |
+ if err != nil { |
|
137 |
+ return nil, false, err |
|
138 | 138 |
} |
139 | 139 |
|
140 |
- oldObj, err := s.Get(ctx, project.Name) |
|
140 |
+ obj, err := objInfo.UpdatedObject(ctx, oldObj) |
|
141 | 141 |
if err != nil { |
142 | 142 |
return nil, false, err |
143 | 143 |
} |
144 |
+ |
|
145 |
+ project, ok := obj.(*api.Project) |
|
146 |
+ if !ok { |
|
147 |
+ return nil, false, fmt.Errorf("not a project: %#v", obj) |
|
148 |
+ } |
|
149 |
+ |
|
144 | 150 |
s.updateStrategy.PrepareForUpdate(obj, oldObj) |
145 | 151 |
if errs := s.updateStrategy.ValidateUpdate(ctx, obj, oldObj); len(errs) > 0 { |
146 | 152 |
return nil, false, kerrors.NewInvalid(projectapi.Kind("Project"), project.Name, errs) |
... | ... |
@@ -218,7 +218,7 @@ func (r *REST) List(ctx kapi.Context, options *kapi.ListOptions) (runtime.Object |
218 | 218 |
return &unversioned.Status{Status: unversioned.StatusSuccess}, nil |
219 | 219 |
} |
220 | 220 |
|
221 |
- forbiddenError, _ := kapierror.NewForbidden(projectapi.Resource("projectrequest"), "", errors.New("you may not request a new project via this API.")).(*kapierror.StatusError) |
|
221 |
+ forbiddenError := kapierror.NewForbidden(projectapi.Resource("projectrequest"), "", errors.New("you may not request a new project via this API.")) |
|
222 | 222 |
if len(r.message) > 0 { |
223 | 223 |
forbiddenError.ErrStatus.Message = r.message |
224 | 224 |
forbiddenError.ErrStatus.Details = &unversioned.StatusDetails{ |
... | ... |
@@ -4,11 +4,8 @@ import ( |
4 | 4 |
"fmt" |
5 | 5 |
"io" |
6 | 6 |
|
7 |
- oadmission "github.com/openshift/origin/pkg/cmd/server/admission" |
|
8 |
- configlatest "github.com/openshift/origin/pkg/cmd/server/api/latest" |
|
9 |
- "github.com/openshift/origin/pkg/project/cache" |
|
10 |
- "github.com/openshift/origin/pkg/quota/admission/clusterresourceoverride/api" |
|
11 |
- "github.com/openshift/origin/pkg/quota/admission/clusterresourceoverride/api/validation" |
|
7 |
+ "github.com/golang/glog" |
|
8 |
+ |
|
12 | 9 |
"k8s.io/kubernetes/pkg/admission" |
13 | 10 |
kapi "k8s.io/kubernetes/pkg/api" |
14 | 11 |
"k8s.io/kubernetes/pkg/api/resource" |
... | ... |
@@ -16,8 +13,11 @@ import ( |
16 | 16 |
"k8s.io/kubernetes/pkg/runtime" |
17 | 17 |
"k8s.io/kubernetes/plugin/pkg/admission/limitranger" |
18 | 18 |
|
19 |
- "github.com/golang/glog" |
|
20 |
- "speter.net/go/exp/math/dec/inf" |
|
19 |
+ oadmission "github.com/openshift/origin/pkg/cmd/server/admission" |
|
20 |
+ configlatest "github.com/openshift/origin/pkg/cmd/server/api/latest" |
|
21 |
+ "github.com/openshift/origin/pkg/project/cache" |
|
22 |
+ "github.com/openshift/origin/pkg/quota/admission/clusterresourceoverride/api" |
|
23 |
+ "github.com/openshift/origin/pkg/quota/admission/clusterresourceoverride/api/validation" |
|
21 | 24 |
) |
22 | 25 |
|
23 | 26 |
const ( |
... | ... |
@@ -26,8 +26,6 @@ const ( |
26 | 26 |
) |
27 | 27 |
|
28 | 28 |
var ( |
29 |
- zeroDec = inf.NewDec(0, 0) |
|
30 |
- miDec = inf.NewDec(1024*1024, 0) |
|
31 | 29 |
cpuFloor = resource.MustParse("1m") |
32 | 30 |
memFloor = resource.MustParse("1Mi") |
33 | 31 |
) |
... | ... |
@@ -47,9 +45,9 @@ func init() { |
47 | 47 |
} |
48 | 48 |
|
49 | 49 |
type internalConfig struct { |
50 |
- limitCPUToMemoryRatio *inf.Dec |
|
51 |
- cpuRequestToLimitRatio *inf.Dec |
|
52 |
- memoryRequestToLimitRatio *inf.Dec |
|
50 |
+ limitCPUToMemoryRatio float64 |
|
51 |
+ cpuRequestToLimitRatio float64 |
|
52 |
+ memoryRequestToLimitRatio float64 |
|
53 | 53 |
} |
54 | 54 |
type clusterResourceOverridePlugin struct { |
55 | 55 |
*admission.Handler |
... | ... |
@@ -70,9 +68,9 @@ func newClusterResourceOverride(client clientset.Interface, config *api.ClusterR |
70 | 70 |
var internal *internalConfig |
71 | 71 |
if config != nil { |
72 | 72 |
internal = &internalConfig{ |
73 |
- limitCPUToMemoryRatio: inf.NewDec(config.LimitCPUToMemoryPercent, 2), |
|
74 |
- cpuRequestToLimitRatio: inf.NewDec(config.CPURequestToLimitPercent, 2), |
|
75 |
- memoryRequestToLimitRatio: inf.NewDec(config.MemoryRequestToLimitPercent, 2), |
|
73 |
+ limitCPUToMemoryRatio: float64(config.LimitCPUToMemoryPercent) / 100, |
|
74 |
+ cpuRequestToLimitRatio: float64(config.CPURequestToLimitPercent) / 100, |
|
75 |
+ memoryRequestToLimitRatio: float64(config.MemoryRequestToLimitPercent) / 100, |
|
76 | 76 |
} |
77 | 77 |
} |
78 | 78 |
|
... | ... |
@@ -165,48 +163,46 @@ func (a *clusterResourceOverridePlugin) Admit(attr admission.Attributes) error { |
165 | 165 |
for _, container := range pod.Spec.Containers { |
166 | 166 |
resources := container.Resources |
167 | 167 |
memLimit, memFound := resources.Limits[kapi.ResourceMemory] |
168 |
- if memFound && a.config.memoryRequestToLimitRatio.Cmp(zeroDec) != 0 { |
|
168 |
+ if memFound && a.config.memoryRequestToLimitRatio != 0 { |
|
169 | 169 |
// memory is measured in whole bytes. |
170 | 170 |
// the plugin rounds down to the nearest MiB rather than bytes to improve ease of use for end-users. |
171 |
- amount := multiply(memLimit.Amount, a.config.memoryRequestToLimitRatio) |
|
172 |
- roundDownToNearestMi := multiply(divide(amount, miDec, 0, inf.RoundDown), miDec) |
|
173 |
- value := resource.Quantity{Amount: roundDownToNearestMi, Format: resource.BinarySI} |
|
174 |
- if memFloor.Cmp(value) > 0 { |
|
175 |
- value = *(memFloor.Copy()) |
|
171 |
+ amount := memLimit.Value() * int64(a.config.memoryRequestToLimitRatio*100) / 100 |
|
172 |
+ // TODO: move into resource.Quantity |
|
173 |
+ var mod int64 |
|
174 |
+ switch memLimit.Format { |
|
175 |
+ case resource.BinarySI: |
|
176 |
+ mod = 1024 * 1024 |
|
177 |
+ default: |
|
178 |
+ mod = 1000 * 1000 |
|
179 |
+ } |
|
180 |
+ if rem := amount % mod; rem != 0 { |
|
181 |
+ amount = amount - rem |
|
182 |
+ } |
|
183 |
+ q := resource.NewQuantity(int64(amount), memLimit.Format) |
|
184 |
+ if memFloor.Cmp(*q) > 0 { |
|
185 |
+ q = memFloor.Copy() |
|
176 | 186 |
} |
177 |
- resources.Requests[kapi.ResourceMemory] = value |
|
187 |
+ resources.Requests[kapi.ResourceMemory] = *q |
|
178 | 188 |
} |
179 |
- if memFound && a.config.limitCPUToMemoryRatio.Cmp(zeroDec) != 0 { |
|
180 |
- // float math is necessary here as there is no way to create an inf.Dec to represent cpuBaseScaleFactor < 0.001 |
|
181 |
- // cpu is measured in millicores, so we need to scale and round down the value to nearest millicore scale |
|
182 |
- amount := multiply(inf.NewDec(int64(float64(memLimit.Value())*cpuBaseScaleFactor), 3), a.config.limitCPUToMemoryRatio) |
|
183 |
- amount.Round(amount, 3, inf.RoundDown) |
|
184 |
- value := resource.Quantity{Amount: amount, Format: resource.DecimalSI} |
|
185 |
- if cpuFloor.Cmp(value) > 0 { |
|
186 |
- value = *(cpuFloor.Copy()) |
|
189 |
+ if memFound && a.config.limitCPUToMemoryRatio != 0 { |
|
190 |
+ amount := float64(memLimit.Value()) * a.config.limitCPUToMemoryRatio * cpuBaseScaleFactor |
|
191 |
+ q := resource.NewMilliQuantity(int64(amount), resource.DecimalSI) |
|
192 |
+ if cpuFloor.Cmp(*q) > 0 { |
|
193 |
+ q = cpuFloor.Copy() |
|
187 | 194 |
} |
188 |
- resources.Limits[kapi.ResourceCPU] = value |
|
195 |
+ resources.Limits[kapi.ResourceCPU] = *q |
|
189 | 196 |
} |
197 |
+ |
|
190 | 198 |
cpuLimit, cpuFound := resources.Limits[kapi.ResourceCPU] |
191 |
- if cpuFound && a.config.cpuRequestToLimitRatio.Cmp(zeroDec) != 0 { |
|
192 |
- // cpu is measured in millicores, so we need to scale and round down the value to nearest millicore scale |
|
193 |
- amount := multiply(cpuLimit.Amount, a.config.cpuRequestToLimitRatio) |
|
194 |
- amount.Round(amount, 3, inf.RoundDown) |
|
195 |
- value := resource.Quantity{Amount: amount, Format: resource.DecimalSI} |
|
196 |
- if cpuFloor.Cmp(value) > 0 { |
|
197 |
- value = *(cpuFloor.Copy()) |
|
199 |
+ if cpuFound && a.config.cpuRequestToLimitRatio != 0 { |
|
200 |
+ amount := float64(cpuLimit.MilliValue()) * a.config.cpuRequestToLimitRatio |
|
201 |
+ q := resource.NewMilliQuantity(int64(amount), cpuLimit.Format) |
|
202 |
+ if cpuFloor.Cmp(*q) > 0 { |
|
203 |
+ q = cpuFloor.Copy() |
|
198 | 204 |
} |
199 |
- resources.Requests[kapi.ResourceCPU] = value |
|
205 |
+ resources.Requests[kapi.ResourceCPU] = *q |
|
200 | 206 |
} |
201 | 207 |
} |
202 | 208 |
glog.V(5).Infof("%s: pod limits after overrides are: %#v", api.PluginName, pod.Spec.Containers[0].Resources) |
203 | 209 |
return nil |
204 | 210 |
} |
205 |
- |
|
206 |
-func multiply(x *inf.Dec, y *inf.Dec) *inf.Dec { |
|
207 |
- return inf.NewDec(0, 0).Mul(x, y) |
|
208 |
-} |
|
209 |
- |
|
210 |
-func divide(x *inf.Dec, y *inf.Dec, s inf.Scale, r inf.Rounder) *inf.Dec { |
|
211 |
- return inf.NewDec(0, 0).QuoRound(x, y, s, r) |
|
212 |
-} |
... | ... |
@@ -220,20 +220,20 @@ func TestLimitRequestAdmission(t *testing.T) { |
220 | 220 |
continue |
221 | 221 |
} |
222 | 222 |
c.(*clusterResourceOverridePlugin).SetProjectCache(fakeProjectCache(test.namespace)) |
223 |
- attrs := admission.NewAttributesRecord(test.pod, unversioned.GroupVersionKind{}, test.namespace.Name, "name", kapi.Resource("pods").WithVersion("version"), "", admission.Create, fakeUser()) |
|
223 |
+ attrs := admission.NewAttributesRecord(test.pod, nil, unversioned.GroupVersionKind{}, test.namespace.Name, "name", kapi.Resource("pods").WithVersion("version"), "", admission.Create, fakeUser()) |
|
224 | 224 |
if err = c.Admit(attrs); err != nil { |
225 | 225 |
t.Errorf("%s: admission controller returned error: %v", test.name, err) |
226 | 226 |
continue |
227 | 227 |
} |
228 | 228 |
resources := test.pod.Spec.Containers[0].Resources // only test one container |
229 | 229 |
if actual := resources.Requests[kapi.ResourceMemory]; test.expectedMemRequest.Cmp(actual) != 0 { |
230 |
- t.Errorf("%s: memory requests do not match; %s should be %s", test.name, actual, test.expectedMemRequest) |
|
230 |
+ t.Errorf("%s: memory requests do not match; %v should be %v", test.name, actual, test.expectedMemRequest) |
|
231 | 231 |
} |
232 | 232 |
if actual := resources.Requests[kapi.ResourceCPU]; test.expectedCpuRequest.Cmp(actual) != 0 { |
233 |
- t.Errorf("%s: cpu requests do not match; %s should be %s", test.name, actual, test.expectedCpuRequest) |
|
233 |
+ t.Errorf("%s: cpu requests do not match; %v should be %v", test.name, actual, test.expectedCpuRequest) |
|
234 | 234 |
} |
235 | 235 |
if actual := resources.Limits[kapi.ResourceCPU]; test.expectedCpuLimit.Cmp(actual) != 0 { |
236 |
- t.Errorf("%s: cpu limits do not match; %s should be %s", test.name, actual, test.expectedCpuLimit) |
|
236 |
+ t.Errorf("%s: cpu limits do not match; %v should be %v", test.name, actual, test.expectedCpuLimit) |
|
237 | 237 |
} |
238 | 238 |
} |
239 | 239 |
} |
... | ... |
@@ -43,7 +43,7 @@ func TestOriginQuotaAdmissionIsErrorQuotaExceeded(t *testing.T) { |
43 | 43 |
}, |
44 | 44 |
} |
45 | 45 |
|
46 |
- err := plugin.Admit(admission.NewAttributesRecord(newIS, imageapi.Kind("ImageStream").WithVersion("version"), newIS.Namespace, newIS.Name, kapi.Resource("imageStreams").WithVersion("version"), "", admission.Create, nil)) |
|
46 |
+ err := plugin.Admit(admission.NewAttributesRecord(newIS, nil, imageapi.Kind("ImageStream").WithVersion("version"), newIS.Namespace, newIS.Name, kapi.Resource("imageStreams").WithVersion("version"), "", admission.Create, nil)) |
|
47 | 47 |
if err == nil { |
48 | 48 |
t.Fatalf("Expected an error exceeding quota") |
49 | 49 |
} |
... | ... |
@@ -137,7 +137,7 @@ func TestRunOnceDurationAdmit(t *testing.T) { |
137 | 137 |
runOnceDuration := NewRunOnceDuration(tc.config) |
138 | 138 |
runOnceDuration.(oadmission.WantsProjectCache).SetProjectCache(testCache(tc.projectAnnotations)) |
139 | 139 |
pod := tc.pod |
140 |
- attrs := admission.NewAttributesRecord(pod, kapi.Kind("Pod").WithVersion("version"), "default", "test", kapi.Resource("pods").WithVersion("version"), "", admission.Create, nil) |
|
140 |
+ attrs := admission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), "default", "test", kapi.Resource("pods").WithVersion("version"), "", admission.Create, nil) |
|
141 | 141 |
err := runOnceDuration.Admit(attrs) |
142 | 142 |
if err != nil { |
143 | 143 |
t.Errorf("%s: unexpected admission error: %v", tc.name, err) |
... | ... |
@@ -269,12 +269,12 @@ func TestSyncFunc(t *testing.T) { |
269 | 269 |
} |
270 | 270 |
|
271 | 271 |
// the internal representation doesn't have json tags and I want a better diff, so converting |
272 |
- expectedV1, err := kapi.Scheme.ConvertToVersion(tc.expectedQuota(), quotaapiv1.SchemeGroupVersion.String()) |
|
272 |
+ expectedV1, err := kapi.Scheme.ConvertToVersion(tc.expectedQuota(), quotaapiv1.SchemeGroupVersion) |
|
273 | 273 |
if err != nil { |
274 | 274 |
t.Errorf("%s: unexpected error: %v", tc.name, err) |
275 | 275 |
continue |
276 | 276 |
} |
277 |
- actualV1, err := kapi.Scheme.ConvertToVersion(actualQuota, quotaapiv1.SchemeGroupVersion.String()) |
|
277 |
+ actualV1, err := kapi.Scheme.ConvertToVersion(actualQuota, quotaapiv1.SchemeGroupVersion) |
|
278 | 278 |
if err != nil { |
279 | 279 |
t.Errorf("%s: unexpected error: %v", tc.name, err) |
280 | 280 |
continue |
... | ... |
@@ -27,7 +27,7 @@ func NewSimpleAllocationPlugin(suffix string) (*SimpleAllocationPlugin, error) { |
27 | 27 |
glog.V(4).Infof("Route plugin initialized with suffix=%s", suffix) |
28 | 28 |
|
29 | 29 |
// Check that the DNS suffix is valid. |
30 |
- if !kvalidation.IsDNS1123Subdomain(suffix) { |
|
30 |
+ if len(kvalidation.IsDNS1123Subdomain(suffix)) != 0 { |
|
31 | 31 |
return nil, fmt.Errorf("invalid DNS suffix: %s", suffix) |
32 | 32 |
} |
33 | 33 |
|
... | ... |
@@ -150,7 +150,7 @@ func TestSimpleAllocationPlugin(t *testing.T) { |
150 | 150 |
case tc.empty: |
151 | 151 |
continue |
152 | 152 |
} |
153 |
- if !validation.IsDNS1123Subdomain(name) { |
|
153 |
+ if len(validation.IsDNS1123Subdomain(name)) != 0 { |
|
154 | 154 |
t.Errorf("Test case %s got %s - invalid DNS name.", tc.name, name) |
155 | 155 |
} |
156 | 156 |
} |
... | ... |
@@ -244,7 +244,7 @@ func TestSimpleAllocationPluginViaController(t *testing.T) { |
244 | 244 |
case tc.empty: |
245 | 245 |
continue |
246 | 246 |
} |
247 |
- if !validation.IsDNS1123Subdomain(name) { |
|
247 |
+ if len(validation.IsDNS1123Subdomain(name)) != 0 { |
|
248 | 248 |
t.Errorf("Test case %s got %s - invalid DNS name.", tc.name, name) |
249 | 249 |
} |
250 | 250 |
} |
... | ... |
@@ -26,7 +26,7 @@ func ValidateRoute(route *routeapi.Route) field.ErrorList { |
26 | 26 |
|
27 | 27 |
//host is not required but if it is set ensure it meets DNS requirements |
28 | 28 |
if len(route.Spec.Host) > 0 { |
29 |
- if !kvalidation.IsDNS1123Subdomain(route.Spec.Host) { |
|
29 |
+ if len(kvalidation.IsDNS1123Subdomain(route.Spec.Host)) != 0 { |
|
30 | 30 |
result = append(result, field.Invalid(specPath.Child("host"), route.Spec.Host, "host must conform to DNS 952 subdomain conventions")) |
31 | 31 |
} |
32 | 32 |
} |
... | ... |
@@ -2,6 +2,7 @@ package etcd |
2 | 2 |
|
3 | 3 |
import ( |
4 | 4 |
kapi "k8s.io/kubernetes/pkg/api" |
5 |
+ kapirest "k8s.io/kubernetes/pkg/api/rest" |
|
5 | 6 |
"k8s.io/kubernetes/pkg/fields" |
6 | 7 |
"k8s.io/kubernetes/pkg/labels" |
7 | 8 |
"k8s.io/kubernetes/pkg/registry/generic" |
... | ... |
@@ -65,6 +66,6 @@ func (r *StatusREST) New() runtime.Object { |
65 | 65 |
} |
66 | 66 |
|
67 | 67 |
// Update alters the status subset of an object. |
68 |
-func (r *StatusREST) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, bool, error) { |
|
69 |
- return r.store.Update(ctx, obj) |
|
68 |
+func (r *StatusREST) Update(ctx kapi.Context, name string, objInfo kapirest.UpdatedObjectInfo) (runtime.Object, bool, error) { |
|
69 |
+ return r.store.Update(ctx, name, objInfo) |
|
70 | 70 |
} |
... | ... |
@@ -139,7 +139,7 @@ func TestStatusAdmitsRouteOnForbidden(t *testing.T) { |
139 | 139 |
nowFn = func() unversioned.Time { return now } |
140 | 140 |
touched := unversioned.Time{Time: now.Add(-time.Minute)} |
141 | 141 |
p := &fakePlugin{} |
142 |
- c := testclient.NewSimpleFake(&(errors.NewForbidden(kapi.Resource("Route"), "route1", nil).(*errors.StatusError).ErrStatus)) |
|
142 |
+ c := testclient.NewSimpleFake(&(errors.NewForbidden(kapi.Resource("Route"), "route1", nil).ErrStatus)) |
|
143 | 143 |
admitter := NewStatusAdmitter(p, c, "test") |
144 | 144 |
err := admitter.HandleRoute(watch.Added, &routeapi.Route{ |
145 | 145 |
ObjectMeta: kapi.ObjectMeta{Name: "route1", Namespace: "default", UID: types.UID("uid1")}, |
... | ... |
@@ -168,7 +168,7 @@ func TestStatusBackoffOnConflict(t *testing.T) { |
168 | 168 |
nowFn = func() unversioned.Time { return now } |
169 | 169 |
touched := unversioned.Time{Time: now.Add(-time.Minute)} |
170 | 170 |
p := &fakePlugin{} |
171 |
- c := testclient.NewSimpleFake(&(errors.NewConflict(kapi.Resource("Route"), "route1", nil).(*errors.StatusError).ErrStatus)) |
|
171 |
+ c := testclient.NewSimpleFake(&(errors.NewConflict(kapi.Resource("Route"), "route1", nil).ErrStatus)) |
|
172 | 172 |
admitter := NewStatusAdmitter(p, c, "test") |
173 | 173 |
err := admitter.HandleRoute(watch.Added, &routeapi.Route{ |
174 | 174 |
ObjectMeta: kapi.ObjectMeta{Name: "route1", Namespace: "default", UID: types.UID("uid1")}, |
... | ... |
@@ -361,7 +361,7 @@ func TestStatusRecordRejectionConflict(t *testing.T) { |
361 | 361 |
nowFn = func() unversioned.Time { return now } |
362 | 362 |
touched := unversioned.Time{Time: now.Add(-time.Minute)} |
363 | 363 |
p := &fakePlugin{} |
364 |
- c := testclient.NewSimpleFake(&(errors.NewConflict(kapi.Resource("Route"), "route1", nil).(*errors.StatusError).ErrStatus)) |
|
364 |
+ c := testclient.NewSimpleFake(&(errors.NewConflict(kapi.Resource("Route"), "route1", nil).ErrStatus)) |
|
365 | 365 |
admitter := NewStatusAdmitter(p, c, "test") |
366 | 366 |
admitter.RecordRouteRejection(&routeapi.Route{ |
367 | 367 |
ObjectMeta: kapi.ObjectMeta{Name: "route1", Namespace: "default", UID: types.UID("uid1")}, |
... | ... |
@@ -452,7 +452,7 @@ func TestStatusFightBetweenRouters(t *testing.T) { |
452 | 452 |
now1 := unversioned.Now() |
453 | 453 |
nowFn = func() unversioned.Time { return now1 } |
454 | 454 |
touched1 := unversioned.Time{Time: now1.Add(-time.Minute)} |
455 |
- c1 := testclient.NewSimpleFake(&(errors.NewConflict(kapi.Resource("Route"), "route1", nil).(*errors.StatusError).ErrStatus), &routeapi.Route{}) |
|
455 |
+ c1 := testclient.NewSimpleFake(&(errors.NewConflict(kapi.Resource("Route"), "route1", nil).ErrStatus), &routeapi.Route{}) |
|
456 | 456 |
admitter1 := NewStatusAdmitter(p, c1, "test2") |
457 | 457 |
err := admitter1.HandleRoute(watch.Added, &routeapi.Route{ |
458 | 458 |
ObjectMeta: kapi.ObjectMeta{Name: "route1", Namespace: "default", UID: types.UID("uid1")}, |
... | ... |
@@ -530,7 +530,7 @@ func makePass(t *testing.T, host string, admitter *StatusAdmitter, srcObj *route |
530 | 530 |
// initialize a new client |
531 | 531 |
var c *testclient.Fake |
532 | 532 |
if conflict { |
533 |
- c = testclient.NewSimpleFake(&(errors.NewConflict(kapi.Resource("Route"), "route1", nil).(*errors.StatusError).ErrStatus)) |
|
533 |
+ c = testclient.NewSimpleFake(&(errors.NewConflict(kapi.Resource("Route"), "route1", nil).ErrStatus)) |
|
534 | 534 |
} else { |
535 | 535 |
c = testclient.NewSimpleFake(&routeapi.Route{}) |
536 | 536 |
} |
... | ... |
@@ -69,9 +69,12 @@ var resourcesToCheck = map[unversioned.GroupResource]unversioned.GroupKind{ |
69 | 69 |
kapi.Resource("podtemplates"): kapi.Kind("PodTemplate"), |
70 | 70 |
kapi.Resource("replicationcontrollers"): kapi.Kind("ReplicationController"), |
71 | 71 |
batch.Resource("jobs"): batch.Kind("Job"), |
72 |
+ batch.Resource("jobtemplates"): batch.Kind("JobTemplate"), |
|
73 |
+ batch.Resource("scheduledjobs"): batch.Kind("ScheduledJob"), |
|
72 | 74 |
extensions.Resource("deployments"): extensions.Kind("Deployment"), |
73 | 75 |
extensions.Resource("replicasets"): extensions.Kind("ReplicaSet"), |
74 | 76 |
extensions.Resource("jobs"): extensions.Kind("Job"), |
77 |
+ extensions.Resource("jobtemplates"): extensions.Kind("JobTemplate"), |
|
75 | 78 |
apps.Resource("petsets"): apps.Kind("PetSet"), |
76 | 79 |
deployapi.Resource("deploymentconfigs"): deployapi.Kind("DeploymentConfig"), |
77 | 80 |
securityapi.Resource("podsecuritypolicysubjectreviews"): securityapi.Kind("PodSecurityPolicySubjectReview"), |
... | ... |
@@ -157,6 +160,10 @@ func (o *podNodeConstraints) getPodSpec(attr admission.Attributes) (kapi.PodSpec |
157 | 157 |
return r.Spec.Template.Spec, nil |
158 | 158 |
case *batch.Job: |
159 | 159 |
return r.Spec.Template.Spec, nil |
160 |
+ case *batch.ScheduledJob: |
|
161 |
+ return r.Spec.JobTemplate.Spec.Template.Spec, nil |
|
162 |
+ case *batch.JobTemplate: |
|
163 |
+ return r.Template.Spec.Template.Spec, nil |
|
160 | 164 |
case *deployapi.DeploymentConfig: |
161 | 165 |
return r.Spec.Template.Spec, nil |
162 | 166 |
case *securityapi.PodSecurityPolicySubjectReview: |
... | ... |
@@ -112,7 +112,7 @@ func TestPodNodeConstraints(t *testing.T) { |
112 | 112 |
checkAdmitError(t, err, expectedError, errPrefix) |
113 | 113 |
continue |
114 | 114 |
} |
115 |
- attrs := admission.NewAttributesRecord(tc.resource, kapi.Kind("Pod").WithVersion("version"), ns, "test", kapi.Resource("pods").WithVersion("version"), "", admission.Create, tc.userinfo) |
|
115 |
+ attrs := admission.NewAttributesRecord(tc.resource, nil, kapi.Kind("Pod").WithVersion("version"), ns, "test", kapi.Resource("pods").WithVersion("version"), "", admission.Create, tc.userinfo) |
|
116 | 116 |
if tc.expectedErrorMsg != "" { |
117 | 117 |
expectedError = admission.NewForbidden(attrs, fmt.Errorf(tc.expectedErrorMsg)) |
118 | 118 |
} |
... | ... |
@@ -132,7 +132,7 @@ func TestPodNodeConstraintsPodUpdate(t *testing.T) { |
132 | 132 |
checkAdmitError(t, err, expectedError, errPrefix) |
133 | 133 |
return |
134 | 134 |
} |
135 |
- attrs := admission.NewAttributesRecord(nodeNamePod(), kapi.Kind("Pod").WithVersion("version"), ns, "test", kapi.Resource("pods").WithVersion("version"), "", admission.Update, serviceaccount.UserInfo("", "", "")) |
|
135 |
+ attrs := admission.NewAttributesRecord(nodeNamePod(), nodeNamePod(), kapi.Kind("Pod").WithVersion("version"), ns, "test", kapi.Resource("pods").WithVersion("version"), "", admission.Update, serviceaccount.UserInfo("", "", "")) |
|
136 | 136 |
err = prc.Admit(attrs) |
137 | 137 |
checkAdmitError(t, err, expectedError, errPrefix) |
138 | 138 |
} |
... | ... |
@@ -148,7 +148,7 @@ func TestPodNodeConstraintsNonHandledResources(t *testing.T) { |
148 | 148 |
checkAdmitError(t, err, expectedError, errPrefix) |
149 | 149 |
return |
150 | 150 |
} |
151 |
- attrs := admission.NewAttributesRecord(resourceQuota(), kapi.Kind("ResourceQuota").WithVersion("version"), ns, "test", kapi.Resource("resourcequotas").WithVersion("version"), "", admission.Create, serviceaccount.UserInfo("", "", "")) |
|
151 |
+ attrs := admission.NewAttributesRecord(resourceQuota(), nil, kapi.Kind("ResourceQuota").WithVersion("version"), ns, "test", kapi.Resource("resourcequotas").WithVersion("version"), "", admission.Create, serviceaccount.UserInfo("", "", "")) |
|
152 | 152 |
err = prc.Admit(attrs) |
153 | 153 |
checkAdmitError(t, err, expectedError, errPrefix) |
154 | 154 |
} |
... | ... |
@@ -272,7 +272,7 @@ func TestPodNodeConstraintsResources(t *testing.T) { |
272 | 272 |
checkAdmitError(t, err, expectedError, errPrefix) |
273 | 273 |
continue |
274 | 274 |
} |
275 |
- attrs := admission.NewAttributesRecord(tr.resource(tp.nodeselector), tr.kind.WithVersion("version"), ns, "test", tr.groupresource.WithVersion("version"), "", top.operation, tc.userinfo) |
|
275 |
+ attrs := admission.NewAttributesRecord(tr.resource(tp.nodeselector), nil, tr.kind.WithVersion("version"), ns, "test", tr.groupresource.WithVersion("version"), "", top.operation, tc.userinfo) |
|
276 | 276 |
if tp.expectedErrorMsg != "" { |
277 | 277 |
expectedError = admission.NewForbidden(attrs, fmt.Errorf(tp.expectedErrorMsg)) |
278 | 278 |
} |
... | ... |
@@ -10,6 +10,7 @@ import ( |
10 | 10 |
|
11 | 11 |
kapi "k8s.io/kubernetes/pkg/api" |
12 | 12 |
"k8s.io/kubernetes/pkg/api/resource" |
13 |
+ "k8s.io/kubernetes/pkg/apis/componentconfig" |
|
13 | 14 |
kubeletTypes "k8s.io/kubernetes/pkg/kubelet/container" |
14 | 15 |
knetwork "k8s.io/kubernetes/pkg/kubelet/network" |
15 | 16 |
utilsets "k8s.io/kubernetes/pkg/util/sets" |
... | ... |
@@ -52,7 +53,7 @@ func (plugin *OsdnNode) getExecutable() string { |
52 | 52 |
return "openshift-sdn-ovs" |
53 | 53 |
} |
54 | 54 |
|
55 |
-func (plugin *OsdnNode) Init(host knetwork.Host) error { |
|
55 |
+func (plugin *OsdnNode) Init(host knetwork.Host, _ componentconfig.HairpinMode, _ string) error { |
|
56 | 56 |
return nil |
57 | 57 |
} |
58 | 58 |
|
... | ... |
@@ -133,7 +133,7 @@ func testSCCAdmit(testCaseName string, sccs []*kapi.SecurityContextConstraints, |
133 | 133 |
|
134 | 134 |
plugin := NewTestAdmission(store, tc) |
135 | 135 |
|
136 |
- attrs := kadmission.NewAttributesRecord(pod, kapi.Kind("Pod").WithVersion("version"), "namespace", "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, &user.DefaultInfo{}) |
|
136 |
+ attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), "namespace", "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, &user.DefaultInfo{}) |
|
137 | 137 |
err := plugin.Admit(attrs) |
138 | 138 |
|
139 | 139 |
if shouldPass && err != nil { |
... | ... |
@@ -374,7 +374,7 @@ func TestAdmit(t *testing.T) { |
374 | 374 |
} |
375 | 375 |
|
376 | 376 |
for k, v := range testCases { |
377 |
- attrs := kadmission.NewAttributesRecord(v.pod, kapi.Kind("Pod").WithVersion("version"), "namespace", "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, &user.DefaultInfo{}) |
|
377 |
+ attrs := kadmission.NewAttributesRecord(v.pod, nil, kapi.Kind("Pod").WithVersion("version"), "namespace", "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, &user.DefaultInfo{}) |
|
378 | 378 |
err := p.Admit(attrs) |
379 | 379 |
|
380 | 380 |
if v.shouldAdmit && err != nil { |
... | ... |
@@ -448,7 +448,7 @@ func TestAdmit(t *testing.T) { |
448 | 448 |
|
449 | 449 |
for k, v := range testCases { |
450 | 450 |
if !v.shouldAdmit { |
451 |
- attrs := kadmission.NewAttributesRecord(v.pod, kapi.Kind("Pod").WithVersion("version"), "namespace", "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, &user.DefaultInfo{}) |
|
451 |
+ attrs := kadmission.NewAttributesRecord(v.pod, nil, kapi.Kind("Pod").WithVersion("version"), "namespace", "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, &user.DefaultInfo{}) |
|
452 | 452 |
err := p.Admit(attrs) |
453 | 453 |
if err != nil { |
454 | 454 |
t.Errorf("Expected %s to pass with escalated scc but got error %v", k, err) |
... | ... |
@@ -823,7 +823,7 @@ func TestCreateProvidersFromConstraints(t *testing.T) { |
823 | 823 |
scc := v.scc() |
824 | 824 |
|
825 | 825 |
// create the providers, this method only needs the namespace |
826 |
- attributes := kadmission.NewAttributesRecord(nil, kapi.Kind("Pod").WithVersion("version"), v.namespace.Name, "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, nil) |
|
826 |
+ attributes := kadmission.NewAttributesRecord(nil, nil, kapi.Kind("Pod").WithVersion("version"), v.namespace.Name, "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, nil) |
|
827 | 827 |
_, errs := admit.createProvidersFromConstraints(attributes.GetNamespace(), []*kapi.SecurityContextConstraints{scc}) |
828 | 828 |
|
829 | 829 |
if !reflect.DeepEqual(scc, v.scc()) { |
... | ... |
@@ -1465,7 +1465,7 @@ func TestAdmitWithPrioritizedSCC(t *testing.T) { |
1465 | 1465 |
// testSCCAdmission is a helper to admit the pod and ensure it was validated against the expected |
1466 | 1466 |
// SCC. |
1467 | 1467 |
func testSCCAdmission(pod *kapi.Pod, plugin kadmission.Interface, expectedSCC string, t *testing.T) { |
1468 |
- attrs := kadmission.NewAttributesRecord(pod, kapi.Kind("Pod").WithVersion("version"), "namespace", "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, &user.DefaultInfo{}) |
|
1468 |
+ attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), "namespace", "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, &user.DefaultInfo{}) |
|
1469 | 1469 |
err := plugin.Admit(attrs) |
1470 | 1470 |
if err != nil { |
1471 | 1471 |
t.Errorf("error admitting pod: %v", err) |
... | ... |
@@ -42,7 +42,7 @@ func (d *sccExecRestrictions) Admit(a admission.Attributes) (err error) { |
42 | 42 |
|
43 | 43 |
// TODO, if we want to actually limit who can use which service account, then we'll need to add logic here to make sure that |
44 | 44 |
// we're allowed to use the SA the pod is using. Otherwise, user-A creates pod and user-B (who can't use the SA) can exec into it. |
45 |
- createAttributes := admission.NewAttributesRecord(pod, kapi.Kind("Pod").WithVersion(""), a.GetNamespace(), a.GetName(), a.GetResource(), "", admission.Create, a.GetUserInfo()) |
|
45 |
+ createAttributes := admission.NewAttributesRecord(pod, pod, kapi.Kind("Pod").WithVersion(""), a.GetNamespace(), a.GetName(), a.GetResource(), "", admission.Create, a.GetUserInfo()) |
|
46 | 46 |
if err := d.constraintAdmission.Admit(createAttributes); err != nil { |
47 | 47 |
return admission.NewForbidden(a, err) |
48 | 48 |
} |
... | ... |
@@ -34,7 +34,7 @@ func TestExecAdmit(t *testing.T) { |
34 | 34 |
resource string |
35 | 35 |
subresource string |
36 | 36 |
|
37 |
- pod *kapi.Pod |
|
37 |
+ pod, oldPod *kapi.Pod |
|
38 | 38 |
shouldAdmit bool |
39 | 39 |
shouldHaveClientAction bool |
40 | 40 |
}{ |
... | ... |
@@ -90,7 +90,7 @@ func TestExecAdmit(t *testing.T) { |
90 | 90 |
// create the admission plugin |
91 | 91 |
p := NewSCCExecRestrictions(tc) |
92 | 92 |
|
93 |
- attrs := kadmission.NewAttributesRecord(v.pod, kapi.Kind("Pod").WithVersion("version"), "namespace", "pod-name", kapi.Resource(v.resource).WithVersion("version"), v.subresource, v.operation, &user.DefaultInfo{}) |
|
93 |
+ attrs := kadmission.NewAttributesRecord(v.pod, v.oldPod, kapi.Kind("Pod").WithVersion("version"), "namespace", "pod-name", kapi.Resource(v.resource).WithVersion("version"), v.subresource, v.operation, &user.DefaultInfo{}) |
|
94 | 94 |
err := p.Admit(attrs) |
95 | 95 |
|
96 | 96 |
if v.shouldAdmit && err != nil { |
... | ... |
@@ -1,6 +1,8 @@ |
1 | 1 |
package validation |
2 | 2 |
|
3 | 3 |
import ( |
4 |
+ "strings" |
|
5 |
+ |
|
4 | 6 |
kapivalidation "k8s.io/kubernetes/pkg/api/validation" |
5 | 7 |
"k8s.io/kubernetes/pkg/util/validation/field" |
6 | 8 |
|
... | ... |
@@ -55,8 +57,8 @@ func validateServiceAccountNames(serviceAccountNames []string, fldPath *field.Pa |
55 | 55 |
case len(sa) == 0: |
56 | 56 |
allErrs = append(allErrs, field.Invalid(idxPath, sa, "")) |
57 | 57 |
case len(sa) > 0: |
58 |
- if ok, msg := kapivalidation.ValidateServiceAccountName(sa, false); !ok { |
|
59 |
- allErrs = append(allErrs, field.Invalid(idxPath, sa, msg)) |
|
58 |
+ if reasons := kapivalidation.ValidateServiceAccountName(sa, false); len(reasons) != 0 { |
|
59 |
+ allErrs = append(allErrs, field.Invalid(idxPath, sa, strings.Join(reasons, ", "))) |
|
60 | 60 |
} |
61 | 61 |
} |
62 | 62 |
} |
... | ... |
@@ -129,13 +129,13 @@ func TestValidatePodSecurityPolicyReview(t *testing.T) { |
129 | 129 |
PodSpec: invalidPodSpec(), |
130 | 130 |
}, |
131 | 131 |
}, |
132 |
- `spec.serviceAccountNames[0]: Invalid value: "my bad sa": must be a DNS subdomain (at most 253 characters, matching regex [a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*): e.g. "example.com"`: { |
|
132 |
+ `spec.serviceAccountNames[0]: Invalid value: "my bad sa": must match the regex [a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)* (e.g. 'example.com')`: { |
|
133 | 133 |
Spec: securityapi.PodSecurityPolicyReviewSpec{ |
134 | 134 |
PodSpec: validPodSpec(), |
135 | 135 |
ServiceAccountNames: []string{"my bad sa"}, |
136 | 136 |
}, |
137 | 137 |
}, |
138 |
- `spec.serviceAccountNames[1]: Invalid value: "my bad sa": must be a DNS subdomain (at most 253 characters, matching regex [a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*): e.g. "example.com"`: { |
|
138 |
+ `spec.serviceAccountNames[1]: Invalid value: "my bad sa": must match the regex [a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)* (e.g. 'example.com')`: { |
|
139 | 139 |
Spec: securityapi.PodSecurityPolicyReviewSpec{ |
140 | 140 |
PodSpec: validPodSpec(), |
141 | 141 |
ServiceAccountNames: []string{"good-service.account", "my bad sa"}, |
... | ... |
@@ -161,7 +161,7 @@ func TestAdmission(t *testing.T) { |
161 | 161 |
svc.Spec.ExternalIPs = test.externalIPs |
162 | 162 |
handler := NewExternalIPRanger(test.rejects, test.admits) |
163 | 163 |
|
164 |
- err := handler.Admit(admission.NewAttributesRecord(svc, kapi.Kind("Service").WithVersion("version"), "namespace", svc.ObjectMeta.Name, kapi.Resource("services").WithVersion("version"), "", test.op, nil)) |
|
164 |
+ err := handler.Admit(admission.NewAttributesRecord(svc, nil, kapi.Kind("Service").WithVersion("version"), "namespace", svc.ObjectMeta.Name, kapi.Resource("services").WithVersion("version"), "", test.op, nil)) |
|
165 | 165 |
if test.admit && err != nil { |
166 | 166 |
t.Errorf("%s: expected no error but got: %s", test.testName, err) |
167 | 167 |
} else if !test.admit && err == nil { |
... | ... |
@@ -17,7 +17,7 @@ func AddObjectsToTemplate(template *Template, objects []runtime.Object, targetVe |
17 | 17 |
return errors.New("cannot add a nil object to a template") |
18 | 18 |
} |
19 | 19 |
|
20 |
- kind, err := kapi.Scheme.ObjectKind(obj) |
|
20 |
+ kind, _, err := kapi.Scheme.ObjectKind(obj) |
|
21 | 21 |
if err != nil { |
22 | 22 |
return err |
23 | 23 |
} |
... | ... |
@@ -11,64 +11,64 @@ import ( |
11 | 11 |
"github.com/openshift/origin/pkg/user/api" |
12 | 12 |
) |
13 | 13 |
|
14 |
-func ValidateUserName(name string, _ bool) (bool, string) { |
|
15 |
- if ok, reason := oapi.MinimalNameRequirements(name, false); !ok { |
|
16 |
- return ok, reason |
|
14 |
+func ValidateUserName(name string, _ bool) []string { |
|
15 |
+ if reasons := oapi.MinimalNameRequirements(name, false); len(reasons) != 0 { |
|
16 |
+ return reasons |
|
17 | 17 |
} |
18 | 18 |
|
19 | 19 |
if strings.Contains(name, ":") { |
20 |
- return false, `may not contain ":"` |
|
20 |
+ return []string{`may not contain ":"`} |
|
21 | 21 |
} |
22 | 22 |
if name == "~" { |
23 |
- return false, `may not equal "~"` |
|
23 |
+ return []string{`may not equal "~"`} |
|
24 | 24 |
} |
25 |
- return true, "" |
|
25 |
+ return nil |
|
26 | 26 |
} |
27 | 27 |
|
28 |
-func ValidateIdentityName(name string, _ bool) (bool, string) { |
|
29 |
- if ok, reason := oapi.MinimalNameRequirements(name, false); !ok { |
|
30 |
- return ok, reason |
|
28 |
+func ValidateIdentityName(name string, _ bool) []string { |
|
29 |
+ if reasons := oapi.MinimalNameRequirements(name, false); len(reasons) != 0 { |
|
30 |
+ return reasons |
|
31 | 31 |
} |
32 | 32 |
|
33 | 33 |
parts := strings.Split(name, ":") |
34 | 34 |
if len(parts) != 2 { |
35 |
- return false, `must be in the format <providerName>:<providerUserName>` |
|
35 |
+ return []string{`must be in the format <providerName>:<providerUserName>`} |
|
36 | 36 |
} |
37 | 37 |
if len(parts[0]) == 0 { |
38 |
- return false, `must be in the format <providerName>:<providerUserName> with a non-empty providerName` |
|
38 |
+ return []string{`must be in the format <providerName>:<providerUserName> with a non-empty providerName`} |
|
39 | 39 |
} |
40 | 40 |
if len(parts[1]) == 0 { |
41 |
- return false, `must be in the format <providerName>:<providerUserName> with a non-empty providerUserName` |
|
41 |
+ return []string{`must be in the format <providerName>:<providerUserName> with a non-empty providerUserName`} |
|
42 | 42 |
} |
43 |
- return true, "" |
|
43 |
+ return nil |
|
44 | 44 |
} |
45 | 45 |
|
46 |
-func ValidateGroupName(name string, _ bool) (bool, string) { |
|
47 |
- if ok, reason := oapi.MinimalNameRequirements(name, false); !ok { |
|
48 |
- return ok, reason |
|
46 |
+func ValidateGroupName(name string, _ bool) []string { |
|
47 |
+ if reasons := oapi.MinimalNameRequirements(name, false); len(reasons) != 0 { |
|
48 |
+ return reasons |
|
49 | 49 |
} |
50 | 50 |
|
51 | 51 |
if strings.Contains(name, ":") { |
52 |
- return false, `may not contain ":"` |
|
52 |
+ return []string{`may not contain ":"`} |
|
53 | 53 |
} |
54 | 54 |
if name == "~" { |
55 |
- return false, `may not equal "~"` |
|
55 |
+ return []string{`may not equal "~"`} |
|
56 | 56 |
} |
57 |
- return true, "" |
|
57 |
+ return nil |
|
58 | 58 |
} |
59 | 59 |
|
60 |
-func ValidateIdentityProviderName(name string) (bool, string) { |
|
61 |
- if ok, reason := oapi.MinimalNameRequirements(name, false); !ok { |
|
62 |
- return ok, reason |
|
60 |
+func ValidateIdentityProviderName(name string) []string { |
|
61 |
+ if reasons := oapi.MinimalNameRequirements(name, false); len(reasons) != 0 { |
|
62 |
+ return reasons |
|
63 | 63 |
} |
64 | 64 |
|
65 | 65 |
if strings.Contains(name, ":") { |
66 |
- return false, `may not contain ":"` |
|
66 |
+ return []string{`may not contain ":"`} |
|
67 | 67 |
} |
68 |
- return true, "" |
|
68 |
+ return nil |
|
69 | 69 |
} |
70 | 70 |
|
71 |
-func ValidateIdentityProviderUserName(name string) (bool, string) { |
|
71 |
+func ValidateIdentityProviderUserName(name string) []string { |
|
72 | 72 |
// Any provider user name must be a valid user name |
73 | 73 |
return ValidateUserName(name, false) |
74 | 74 |
} |
... | ... |
@@ -83,8 +83,8 @@ func ValidateGroup(group *api.Group) field.ErrorList { |
83 | 83 |
allErrs = append(allErrs, field.Invalid(idxPath, user, "may not be empty")) |
84 | 84 |
continue |
85 | 85 |
} |
86 |
- if ok, msg := ValidateUserName(user, false); !ok { |
|
87 |
- allErrs = append(allErrs, field.Invalid(idxPath, user, msg)) |
|
86 |
+ if reasons := ValidateUserName(user, false); len(reasons) != 0 { |
|
87 |
+ allErrs = append(allErrs, field.Invalid(idxPath, user, strings.Join(reasons, ", "))) |
|
88 | 88 |
} |
89 | 89 |
} |
90 | 90 |
|
... | ... |
@@ -102,8 +102,8 @@ func ValidateUser(user *api.User) field.ErrorList { |
102 | 102 |
identitiesPath := field.NewPath("identities") |
103 | 103 |
for index, identity := range user.Identities { |
104 | 104 |
idxPath := identitiesPath.Index(index) |
105 |
- if ok, msg := ValidateIdentityName(identity, false); !ok { |
|
106 |
- allErrs = append(allErrs, field.Invalid(idxPath, identity, msg)) |
|
105 |
+ if reasons := ValidateIdentityName(identity, false); len(reasons) != 0 { |
|
106 |
+ allErrs = append(allErrs, field.Invalid(idxPath, identity, strings.Join(reasons, ", "))) |
|
107 | 107 |
} |
108 | 108 |
} |
109 | 109 |
|
... | ... |
@@ -114,8 +114,8 @@ func ValidateUser(user *api.User) field.ErrorList { |
114 | 114 |
allErrs = append(allErrs, field.Invalid(idxPath, group, "may not be empty")) |
115 | 115 |
continue |
116 | 116 |
} |
117 |
- if ok, msg := ValidateGroupName(group, false); !ok { |
|
118 |
- allErrs = append(allErrs, field.Invalid(idxPath, group, msg)) |
|
117 |
+ if reasons := ValidateGroupName(group, false); len(reasons) != 0 { |
|
118 |
+ allErrs = append(allErrs, field.Invalid(idxPath, group, strings.Join(reasons, ", "))) |
|
119 | 119 |
} |
120 | 120 |
} |
121 | 121 |
|
... | ... |
@@ -133,14 +133,14 @@ func ValidateIdentity(identity *api.Identity) field.ErrorList { |
133 | 133 |
|
134 | 134 |
if len(identity.ProviderName) == 0 { |
135 | 135 |
allErrs = append(allErrs, field.Required(field.NewPath("providerName"), "")) |
136 |
- } else if ok, msg := ValidateIdentityProviderName(identity.ProviderName); !ok { |
|
137 |
- allErrs = append(allErrs, field.Invalid(field.NewPath("providerName"), identity.ProviderName, msg)) |
|
136 |
+ } else if reasons := ValidateIdentityProviderName(identity.ProviderName); len(reasons) != 0 { |
|
137 |
+ allErrs = append(allErrs, field.Invalid(field.NewPath("providerName"), identity.ProviderName, strings.Join(reasons, ", "))) |
|
138 | 138 |
} |
139 | 139 |
|
140 | 140 |
if len(identity.ProviderUserName) == 0 { |
141 | 141 |
allErrs = append(allErrs, field.Required(field.NewPath("providerUserName"), "")) |
142 |
- } else if ok, msg := ValidateIdentityProviderName(identity.ProviderUserName); !ok { |
|
143 |
- allErrs = append(allErrs, field.Invalid(field.NewPath("providerUserName"), identity.ProviderUserName, msg)) |
|
142 |
+ } else if reasons := ValidateIdentityProviderName(identity.ProviderUserName); len(reasons) != 0 { |
|
143 |
+ allErrs = append(allErrs, field.Invalid(field.NewPath("providerUserName"), identity.ProviderUserName, strings.Join(reasons, ", "))) |
|
144 | 144 |
} |
145 | 145 |
|
146 | 146 |
userPath := field.NewPath("user") |
... | ... |
@@ -151,8 +151,8 @@ func ValidateIdentity(identity *api.Identity) field.ErrorList { |
151 | 151 |
} |
152 | 152 |
} |
153 | 153 |
|
154 |
- if ok, msg := ValidateUserName(identity.User.Name, false); !ok { |
|
155 |
- allErrs = append(allErrs, field.Invalid(userPath.Child("name"), identity.User.Name, msg)) |
|
154 |
+ if reasons := ValidateUserName(identity.User.Name, false); len(reasons) != 0 { |
|
155 |
+ allErrs = append(allErrs, field.Invalid(userPath.Child("name"), identity.User.Name, strings.Join(reasons, ", "))) |
|
156 | 156 |
} |
157 | 157 |
if len(identity.User.Name) == 0 && len(identity.User.UID) != 0 { |
158 | 158 |
allErrs = append(allErrs, field.Invalid(userPath.Child("uid"), identity.User.UID, "may not be set if user.name is empty")) |
... | ... |
@@ -65,7 +65,7 @@ func (s *storage) CreateGroup(ctx kapi.Context, group *api.Group) (*api.Group, e |
65 | 65 |
} |
66 | 66 |
|
67 | 67 |
func (s *storage) UpdateGroup(ctx kapi.Context, group *api.Group) (*api.Group, error) { |
68 |
- obj, _, err := s.Update(ctx, group) |
|
68 |
+ obj, _, err := s.Update(ctx, group.Name, rest.DefaultUpdatedObjectInfo(group, kapi.Scheme)) |
|
69 | 69 |
if err != nil { |
70 | 70 |
return nil, err |
71 | 71 |
} |
... | ... |
@@ -32,7 +32,7 @@ type Storage interface { |
32 | 32 |
rest.Getter |
33 | 33 |
|
34 | 34 |
Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, error) |
35 |
- Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, bool, error) |
|
35 |
+ Update(ctx kapi.Context, name string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) |
|
36 | 36 |
} |
37 | 37 |
|
38 | 38 |
// storage puts strong typing around storage calls |
... | ... |
@@ -62,16 +62,16 @@ func (s *storage) GetIdentity(ctx kapi.Context, name string) (*api.Identity, err |
62 | 62 |
return obj.(*api.Identity), nil |
63 | 63 |
} |
64 | 64 |
|
65 |
-func (s *storage) CreateIdentity(ctx kapi.Context, Identity *api.Identity) (*api.Identity, error) { |
|
66 |
- obj, err := s.Create(ctx, Identity) |
|
65 |
+func (s *storage) CreateIdentity(ctx kapi.Context, identity *api.Identity) (*api.Identity, error) { |
|
66 |
+ obj, err := s.Create(ctx, identity) |
|
67 | 67 |
if err != nil { |
68 | 68 |
return nil, err |
69 | 69 |
} |
70 | 70 |
return obj.(*api.Identity), nil |
71 | 71 |
} |
72 | 72 |
|
73 |
-func (s *storage) UpdateIdentity(ctx kapi.Context, Identity *api.Identity) (*api.Identity, error) { |
|
74 |
- obj, _, err := s.Update(ctx, Identity) |
|
73 |
+func (s *storage) UpdateIdentity(ctx kapi.Context, identity *api.Identity) (*api.Identity, error) { |
|
74 |
+ obj, _, err := s.Update(ctx, identity.Name, rest.DefaultUpdatedObjectInfo(identity, kapi.Scheme)) |
|
75 | 75 |
if err != nil { |
76 | 76 |
return nil, err |
77 | 77 |
} |
... | ... |
@@ -2,6 +2,7 @@ package etcd |
2 | 2 |
|
3 | 3 |
import ( |
4 | 4 |
"errors" |
5 |
+ "strings" |
|
5 | 6 |
|
6 | 7 |
kapi "k8s.io/kubernetes/pkg/api" |
7 | 8 |
kerrs "k8s.io/kubernetes/pkg/api/errors" |
... | ... |
@@ -73,8 +74,8 @@ func (r *REST) Get(ctx kapi.Context, name string) (runtime.Object, error) { |
73 | 73 |
contextGroups := sets.NewString(user.GetGroups()...) |
74 | 74 |
contextGroups.Delete(bootstrappolicy.UnauthenticatedGroup, bootstrappolicy.AuthenticatedGroup) |
75 | 75 |
|
76 |
- if ok, _ := validation.ValidateUserName(name, false); !ok { |
|
77 |
- // The user the authentication layer has identified cannot possibly be a persisted user |
|
76 |
+ if reasons := validation.ValidateUserName(name, false); len(reasons) != 0 { |
|
77 |
+ // The user the authentication layer has identified cannot be a valid persisted user |
|
78 | 78 |
// Return an API representation of the virtual user |
79 | 79 |
return &api.User{ObjectMeta: kapi.ObjectMeta{Name: name}, Groups: contextGroups.List()}, nil |
80 | 80 |
} |
... | ... |
@@ -91,8 +92,8 @@ func (r *REST) Get(ctx kapi.Context, name string) (runtime.Object, error) { |
91 | 91 |
return &api.User{ObjectMeta: kapi.ObjectMeta{Name: name}, Groups: contextGroups.List()}, nil |
92 | 92 |
} |
93 | 93 |
|
94 |
- if ok, details := validation.ValidateUserName(name, false); !ok { |
|
95 |
- return nil, field.Invalid(field.NewPath("metadata", "name"), name, details) |
|
94 |
+ if reasons := validation.ValidateUserName(name, false); len(reasons) != 0 { |
|
95 |
+ return nil, field.Invalid(field.NewPath("metadata", "name"), name, strings.Join(reasons, ", ")) |
|
96 | 96 |
} |
97 | 97 |
|
98 | 98 |
return r.Store.Get(ctx, name) |
... | ... |
@@ -27,7 +27,7 @@ type Storage interface { |
27 | 27 |
rest.Getter |
28 | 28 |
|
29 | 29 |
Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, error) |
30 |
- Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, bool, error) |
|
30 |
+ Update(ctx kapi.Context, name string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) |
|
31 | 31 |
} |
32 | 32 |
|
33 | 33 |
// storage puts strong typing around storage calls |
... | ... |
@@ -66,7 +66,7 @@ func (s *storage) CreateUser(ctx kapi.Context, user *api.User) (*api.User, error |
66 | 66 |
} |
67 | 67 |
|
68 | 68 |
func (s *storage) UpdateUser(ctx kapi.Context, user *api.User) (*api.User, error) { |
69 |
- obj, _, err := s.Update(ctx, user) |
|
69 |
+ obj, _, err := s.Update(ctx, user.Name, rest.DefaultUpdatedObjectInfo(user, kapi.Scheme)) |
|
70 | 70 |
if err != nil { |
71 | 71 |
return nil, err |
72 | 72 |
} |
... | ... |
@@ -27,7 +27,7 @@ type Storage interface { |
27 | 27 |
rest.Deleter |
28 | 28 |
|
29 | 29 |
Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, error) |
30 |
- Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, bool, error) |
|
30 |
+ Update(ctx kapi.Context, name string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) |
|
31 | 31 |
} |
32 | 32 |
|
33 | 33 |
// storage puts strong typing around storage calls |
... | ... |
@@ -58,7 +58,7 @@ func (s *storage) CreateUserIdentityMapping(ctx kapi.Context, mapping *api.UserI |
58 | 58 |
} |
59 | 59 |
|
60 | 60 |
func (s *storage) UpdateUserIdentityMapping(ctx kapi.Context, mapping *api.UserIdentityMapping) (*api.UserIdentityMapping, error) { |
61 |
- obj, _, err := s.Update(ctx, mapping) |
|
61 |
+ obj, _, err := s.Update(ctx, mapping.Name, rest.DefaultUpdatedObjectInfo(mapping, kapi.Scheme)) |
|
62 | 62 |
if err != nil { |
63 | 63 |
return nil, err |
64 | 64 |
} |
... | ... |
@@ -55,7 +55,11 @@ func (s *REST) Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, err |
55 | 55 |
// Update associates an identity with a user. |
56 | 56 |
// Both the identity and user must already exist. |
57 | 57 |
// If the identity is associated with another user already, it is disassociated. |
58 |
-func (s *REST) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, bool, error) { |
|
58 |
+func (s *REST) Update(ctx kapi.Context, name string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) { |
|
59 |
+ obj, err := objInfo.UpdatedObject(ctx, nil) |
|
60 |
+ if err != nil { |
|
61 |
+ return nil, false, err |
|
62 |
+ } |
|
59 | 63 |
mapping, ok := obj.(*api.UserIdentityMapping) |
60 | 64 |
if !ok { |
61 | 65 |
return nil, false, kerrs.NewBadRequest("invalid type") |
... | ... |
@@ -8,6 +8,7 @@ import ( |
8 | 8 |
|
9 | 9 |
kapi "k8s.io/kubernetes/pkg/api" |
10 | 10 |
kerrs "k8s.io/kubernetes/pkg/api/errors" |
11 |
+ kapirest "k8s.io/kubernetes/pkg/api/rest" |
|
11 | 12 |
"k8s.io/kubernetes/pkg/runtime" |
12 | 13 |
"k8s.io/kubernetes/pkg/types" |
13 | 14 |
|
... | ... |
@@ -409,7 +410,7 @@ func TestUpdate(t *testing.T) { |
409 | 409 |
} |
410 | 410 |
|
411 | 411 |
actions, _, _, rest := setupRegistries(associatedIdentity1User1, associatedUser1, unassociatedUser2) |
412 |
- createdMapping, created, err := rest.Update(kapi.NewContext(), mapping) |
|
412 |
+ createdMapping, created, err := rest.Update(kapi.NewContext(), mapping.Name, kapirest.DefaultUpdatedObjectInfo(mapping, kapi.Scheme)) |
|
413 | 413 |
|
414 | 414 |
if err != nil { |
415 | 415 |
t.Errorf("Unexpected error: %v", err) |
... | ... |
@@ -440,7 +441,7 @@ func TestUpdateMissingIdentity(t *testing.T) { |
440 | 440 |
} |
441 | 441 |
|
442 | 442 |
actions, _, _, rest := setupRegistries(nil, associatedUser1, unassociatedUser2) |
443 |
- _, _, err := rest.Update(kapi.NewContext(), mapping) |
|
443 |
+ _, _, err := rest.Update(kapi.NewContext(), mapping.Name, kapirest.DefaultUpdatedObjectInfo(mapping, kapi.Scheme)) |
|
444 | 444 |
|
445 | 445 |
if err == nil { |
446 | 446 |
t.Errorf("Expected error: %v", err) |
... | ... |
@@ -473,7 +474,7 @@ func TestUpdateMissingUser(t *testing.T) { |
473 | 473 |
} |
474 | 474 |
|
475 | 475 |
actions, _, _, rest := setupRegistries(associatedIdentity1User1, associatedUser1) |
476 |
- _, _, err := rest.Update(kapi.NewContext(), mapping) |
|
476 |
+ _, _, err := rest.Update(kapi.NewContext(), mapping.Name, kapirest.DefaultUpdatedObjectInfo(mapping, kapi.Scheme)) |
|
477 | 477 |
|
478 | 478 |
if err == nil { |
479 | 479 |
t.Errorf("Expected error: %v", err) |
... | ... |
@@ -500,7 +501,7 @@ func TestUpdateOldUserMatches(t *testing.T) { |
500 | 500 |
} |
501 | 501 |
|
502 | 502 |
actions, _, _, rest := setupRegistries(identity, user) |
503 |
- createdMapping, created, err := rest.Update(kapi.NewContext(), mapping) |
|
503 |
+ createdMapping, created, err := rest.Update(kapi.NewContext(), mapping.Name, kapirest.DefaultUpdatedObjectInfo(mapping, kapi.Scheme)) |
|
504 | 504 |
|
505 | 505 |
if err != nil { |
506 | 506 |
t.Errorf("Unexpected error: %v", err) |
... | ... |
@@ -531,7 +532,7 @@ func TestUpdateWithEmptyResourceVersion(t *testing.T) { |
531 | 531 |
} |
532 | 532 |
|
533 | 533 |
actions, _, _, rest := setupRegistries(associatedIdentity1User1, associatedUser1, unassociatedUser2) |
534 |
- _, _, err := rest.Update(kapi.NewContext(), mapping) |
|
534 |
+ _, _, err := rest.Update(kapi.NewContext(), mapping.Name, kapirest.DefaultUpdatedObjectInfo(mapping, kapi.Scheme)) |
|
535 | 535 |
|
536 | 536 |
if err == nil { |
537 | 537 |
t.Errorf("Expected error") |
... | ... |
@@ -562,7 +563,7 @@ func TestUpdateWithMismatchedResourceVersion(t *testing.T) { |
562 | 562 |
} |
563 | 563 |
|
564 | 564 |
actions, _, _, rest := setupRegistries(associatedIdentity1User1, associatedUser1, unassociatedUser2) |
565 |
- _, _, err := rest.Update(kapi.NewContext(), mapping) |
|
565 |
+ _, _, err := rest.Update(kapi.NewContext(), mapping.Name, kapirest.DefaultUpdatedObjectInfo(mapping, kapi.Scheme)) |
|
566 | 566 |
|
567 | 567 |
if err == nil { |
568 | 568 |
t.Errorf("Expected error") |
... | ... |
@@ -604,7 +605,7 @@ func TestUpdateOldUserUpdateError(t *testing.T) { |
604 | 604 |
|
605 | 605 |
actions, userRegistry, _, rest := setupRegistries(associatedIdentity1User1, associatedUser1, unassociatedUser2) |
606 | 606 |
userRegistry.UpdateErr[unassociatedUser1.Name] = expectedErr |
607 |
- createdMapping, created, err := rest.Update(kapi.NewContext(), mapping) |
|
607 |
+ createdMapping, created, err := rest.Update(kapi.NewContext(), mapping.Name, kapirest.DefaultUpdatedObjectInfo(mapping, kapi.Scheme)) |
|
608 | 608 |
|
609 | 609 |
// An error cleaning up the old user shouldn't manifest as an update failure, since the mapping was successfully updated |
610 | 610 |
if err != nil { |
... | ... |
@@ -644,7 +645,7 @@ func TestUpdateUserUpdateError(t *testing.T) { |
644 | 644 |
|
645 | 645 |
actions, userRegistry, _, rest := setupRegistries(associatedIdentity1User1, associatedUser1, unassociatedUser2) |
646 | 646 |
userRegistry.UpdateErr[associatedUser2.Name] = expectedErr |
647 |
- _, _, err := rest.Update(kapi.NewContext(), mapping) |
|
647 |
+ _, _, err := rest.Update(kapi.NewContext(), mapping.Name, kapirest.DefaultUpdatedObjectInfo(mapping, kapi.Scheme)) |
|
648 | 648 |
|
649 | 649 |
if err == nil { |
650 | 650 |
t.Errorf("Expected error") |
... | ... |
@@ -684,7 +685,7 @@ func TestUpdateIdentityUpdateError(t *testing.T) { |
684 | 684 |
|
685 | 685 |
actions, _, identityRegistry, rest := setupRegistries(associatedIdentity1User1, associatedUser1, unassociatedUser2) |
686 | 686 |
identityRegistry.UpdateErr = expectedErr |
687 |
- _, _, err := rest.Update(kapi.NewContext(), mapping) |
|
687 |
+ _, _, err := rest.Update(kapi.NewContext(), mapping.Name, kapirest.DefaultUpdatedObjectInfo(mapping, kapi.Scheme)) |
|
688 | 688 |
|
689 | 689 |
if err == nil { |
690 | 690 |
t.Errorf("Expected error") |
... | ... |
@@ -342,14 +342,14 @@ func Equals(labels1, labels2 map[string]string) bool { |
342 | 342 |
const qualifiedNameErrorMsg string = "must match regex [" + kvalidation.DNS1123SubdomainFmt + " / ] " + kvalidation.DNS1123LabelFmt |
343 | 343 |
|
344 | 344 |
func validateLabelKey(k string) error { |
345 |
- if !kvalidation.IsQualifiedName(k) { |
|
345 |
+ if len(kvalidation.IsQualifiedName(k)) != 0 { |
|
346 | 346 |
return field.Invalid(field.NewPath("label key"), k, qualifiedNameErrorMsg) |
347 | 347 |
} |
348 | 348 |
return nil |
349 | 349 |
} |
350 | 350 |
|
351 | 351 |
func validateLabelValue(v string) error { |
352 |
- if !kvalidation.IsValidLabelValue(v) { |
|
352 |
+ if len(kvalidation.IsValidLabelValue(v)) != 0 { |
|
353 | 353 |
return field.Invalid(field.NewPath("label value"), v, qualifiedNameErrorMsg) |
354 | 354 |
} |
355 | 355 |
return nil |
... | ... |
@@ -39,14 +39,16 @@ func NewRateLimitedFunction(keyFunc kcache.KeyFunc, interval int, handlerFunc Ha |
39 | 39 |
// RunUntil begins processes the resources from queue asynchronously until |
40 | 40 |
// stopCh is closed. |
41 | 41 |
func (rlf *RateLimitedFunction) RunUntil(stopCh <-chan struct{}) { |
42 |
- go utilwait.Until(func() { rlf.handleOne(rlf.queue.Pop()) }, 0, stopCh) |
|
42 |
+ go utilwait.Until(rlf.pop, 0, stopCh) |
|
43 | 43 |
} |
44 | 44 |
|
45 | 45 |
// handleOne processes a request in the queue invoking the rate limited |
46 | 46 |
// function. |
47 |
-func (rlf *RateLimitedFunction) handleOne(resource interface{}) { |
|
47 |
+func (rlf *RateLimitedFunction) pop() { |
|
48 | 48 |
rlf.RateLimiter.Accept() |
49 |
- if err := rlf.Handler(); err != nil { |
|
49 |
+ if _, err := rlf.queue.Pop(func(_ interface{}) error { |
|
50 |
+ return rlf.Handler() |
|
51 |
+ }); err != nil { |
|
50 | 52 |
utilruntime.HandleError(err) |
51 | 53 |
} |
52 | 54 |
} |
... | ... |
@@ -10,7 +10,7 @@ import ( |
10 | 10 |
kapi "k8s.io/kubernetes/pkg/api" |
11 | 11 |
"k8s.io/kubernetes/pkg/api/rest" |
12 | 12 |
"k8s.io/kubernetes/pkg/api/unversioned" |
13 |
- "k8s.io/kubernetes/pkg/genericapiserver" |
|
13 |
+ genericserveroptions "k8s.io/kubernetes/pkg/genericapiserver/options" |
|
14 | 14 |
genericrest "k8s.io/kubernetes/pkg/registry/generic" |
15 | 15 |
"k8s.io/kubernetes/pkg/registry/generic/registry" |
16 | 16 |
"k8s.io/kubernetes/pkg/runtime" |
... | ... |
@@ -108,7 +108,7 @@ func (g *configRESTOptionsGetter) GetRESTOptions(resource unversioned.GroupResou |
108 | 108 |
// TODO: choose destination group/version based on input group/resource |
109 | 109 |
// TODO: Tune the cache size |
110 | 110 |
groupVersion := unversioned.GroupVersion{Group: "", Version: g.masterOptions.EtcdStorageConfig.OpenShiftStorageVersion} |
111 |
- g.etcdHelper = etcdstorage.NewEtcdStorage(etcdClient, kapi.Codecs.LegacyCodec(groupVersion), g.masterOptions.EtcdStorageConfig.OpenShiftStoragePrefix, false, genericapiserver.DefaultDeserializationCacheSize) |
|
111 |
+ g.etcdHelper = etcdstorage.NewEtcdStorage(etcdClient, kapi.Codecs.LegacyCodec(groupVersion), g.masterOptions.EtcdStorageConfig.OpenShiftStoragePrefix, false, genericserveroptions.DefaultDeserializationCacheSize) |
|
112 | 112 |
} |
113 | 113 |
|
114 | 114 |
configuredCacheSize, specified := g.cacheSizes[resource] |
... | ... |
@@ -3,7 +3,6 @@ package emptydir |
3 | 3 |
import ( |
4 | 4 |
"k8s.io/kubernetes/pkg/api" |
5 | 5 |
"k8s.io/kubernetes/pkg/api/resource" |
6 |
- "k8s.io/kubernetes/pkg/types" |
|
7 | 6 |
"k8s.io/kubernetes/pkg/volume" |
8 | 7 |
) |
9 | 8 |
|
... | ... |
@@ -12,8 +11,9 @@ var _ volume.Mounter = &emptyDirQuotaMounter{} |
12 | 12 |
|
13 | 13 |
// EmptyDirQuotaPlugin is a simple wrapper for the k8s empty dir plugin mounter. |
14 | 14 |
type EmptyDirQuotaPlugin struct { |
15 |
- // wrapped is the actual k8s emptyDir volume plugin we will pass method calls to. |
|
16 |
- Wrapped volume.VolumePlugin |
|
15 |
+ // the actual k8s emptyDir volume plugin we will pass method calls to. |
|
16 |
+ // TODO: do we need to implement unmount |
|
17 |
+ volume.VolumePlugin |
|
17 | 18 |
|
18 | 19 |
// The default quota to apply to each node: |
19 | 20 |
Quota resource.Quantity |
... | ... |
@@ -24,7 +24,7 @@ type EmptyDirQuotaPlugin struct { |
24 | 24 |
} |
25 | 25 |
|
26 | 26 |
func (plugin *EmptyDirQuotaPlugin) NewMounter(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Mounter, error) { |
27 |
- volMounter, err := plugin.Wrapped.NewMounter(spec, pod, opts) |
|
27 |
+ volMounter, err := plugin.VolumePlugin.NewMounter(spec, pod, opts) |
|
28 | 28 |
if err != nil { |
29 | 29 |
return volMounter, err |
30 | 30 |
} |
... | ... |
@@ -49,22 +49,6 @@ func (plugin *EmptyDirQuotaPlugin) NewMounter(spec *volume.Spec, pod *api.Pod, o |
49 | 49 |
return wrapperEmptyDir, err |
50 | 50 |
} |
51 | 51 |
|
52 |
-func (plugin *EmptyDirQuotaPlugin) Init(host volume.VolumeHost) error { |
|
53 |
- return plugin.Wrapped.Init(host) |
|
54 |
-} |
|
55 |
- |
|
56 |
-func (plugin *EmptyDirQuotaPlugin) Name() string { |
|
57 |
- return plugin.Wrapped.Name() |
|
58 |
-} |
|
59 |
- |
|
60 |
-func (plugin *EmptyDirQuotaPlugin) CanSupport(spec *volume.Spec) bool { |
|
61 |
- return plugin.Wrapped.CanSupport(spec) |
|
62 |
-} |
|
63 |
- |
|
64 |
-func (plugin *EmptyDirQuotaPlugin) NewUnmounter(volName string, podUID types.UID) (volume.Unmounter, error) { |
|
65 |
- return plugin.Wrapped.NewUnmounter(volName, podUID) |
|
66 |
-} |
|
67 |
- |
|
68 | 52 |
// emptyDirQuotaMounter is a wrapper plugin mounter for the k8s empty dir mounter itself. |
69 | 53 |
// This plugin just extends and adds the functionality to apply a |
70 | 54 |
// quota for the pods FSGroup on an XFS filesystem. |
... | ... |
@@ -45,8 +45,8 @@ os::cmd::expect_success_and_text 'oc types' 'Deployment Config' |
45 | 45 |
os::cmd::expect_success_and_text 'openshift kubectl' 'Kubernetes cluster' |
46 | 46 |
os::cmd::expect_success_and_text 'oadm' 'Administrative Commands' |
47 | 47 |
os::cmd::expect_success_and_text 'openshift admin' 'Administrative Commands' |
48 |
-os::cmd::expect_success_and_text 'oadm' 'Basic Commands:' |
|
49 |
-os::cmd::expect_success_and_text 'oadm' 'Install Commands:' |
|
48 |
+os::cmd::expect_success_and_text 'oadm' 'Component Installation:' |
|
49 |
+os::cmd::expect_success_and_text 'oadm' 'Security and Policy:' |
|
50 | 50 |
os::cmd::expect_success_and_text 'oadm ca' 'Manage certificates' |
51 | 51 |
os::cmd::expect_success_and_text 'openshift start kubernetes' 'Kubernetes server components' |
52 | 52 |
os::cmd::expect_success_and_text 'oc exec --help' '\[options\] POD \[\-c CONTAINER\] \-\- COMMAND \[args\.\.\.\]$' |
... | ... |
@@ -61,10 +61,7 @@ var _ = Describe("[networking] network isolation", func() { |
61 | 61 |
}) |
62 | 62 |
|
63 | 63 |
func checkPodIsolation(f1, f2 *e2e.Framework, numNodes int) error { |
64 |
- nodes, err := e2e.GetReadyNodes(f1) |
|
65 |
- if err != nil { |
|
66 |
- e2e.Failf("Failed to list nodes: %v", err) |
|
67 |
- } |
|
64 |
+ nodes := e2e.GetReadySchedulableNodesOrDie(f1.Client) |
|
68 | 65 |
var serverNode, clientNode *api.Node |
69 | 66 |
serverNode = &nodes.Items[0] |
70 | 67 |
if numNodes == 2 { |
... | ... |
@@ -68,10 +68,7 @@ var _ = Describe("[networking] services", func() { |
68 | 68 |
}) |
69 | 69 |
|
70 | 70 |
func checkServiceConnectivity(serverFramework, clientFramework *e2e.Framework, numNodes int) error { |
71 |
- nodes, err := e2e.GetReadyNodes(serverFramework) |
|
72 |
- if err != nil { |
|
73 |
- e2e.Failf("Failed to list nodes: %v", err) |
|
74 |
- } |
|
71 |
+ nodes := e2e.GetReadySchedulableNodesOrDie(serverFramework.Client) |
|
75 | 72 |
var serverNode, clientNode *api.Node |
76 | 73 |
serverNode = &nodes.Items[0] |
77 | 74 |
if numNodes == 2 { |
... | ... |
@@ -11,6 +11,7 @@ import ( |
11 | 11 |
|
12 | 12 |
kapi "k8s.io/kubernetes/pkg/api" |
13 | 13 |
"k8s.io/kubernetes/pkg/api/errors" |
14 |
+ "k8s.io/kubernetes/pkg/apis/autoscaling" |
|
14 | 15 |
"k8s.io/kubernetes/pkg/apis/batch" |
15 | 16 |
expapi "k8s.io/kubernetes/pkg/apis/extensions" |
16 | 17 |
"k8s.io/kubernetes/pkg/util/wait" |
... | ... |
@@ -53,15 +54,16 @@ func TestExtensionsAPIDeletion(t *testing.T) { |
53 | 53 |
} |
54 | 54 |
|
55 | 55 |
// create the extensions resources as the project admin |
56 |
- hpa := expapi.HorizontalPodAutoscaler{ |
|
56 |
+ percent := int32(10) |
|
57 |
+ hpa := autoscaling.HorizontalPodAutoscaler{ |
|
57 | 58 |
ObjectMeta: kapi.ObjectMeta{Name: "test-hpa"}, |
58 |
- Spec: expapi.HorizontalPodAutoscalerSpec{ |
|
59 |
- ScaleRef: expapi.SubresourceReference{Kind: "DeploymentConfig", Name: "frontend", APIVersion: "v1", Subresource: "scale"}, |
|
60 |
- MaxReplicas: 10, |
|
61 |
- CPUUtilization: &expapi.CPUTargetUtilization{TargetPercentage: 10}, |
|
59 |
+ Spec: autoscaling.HorizontalPodAutoscalerSpec{ |
|
60 |
+ ScaleTargetRef: autoscaling.CrossVersionObjectReference{Kind: "DeploymentConfig", Name: "frontend", APIVersion: "v1"}, |
|
61 |
+ MaxReplicas: 10, |
|
62 |
+ TargetCPUUtilizationPercentage: &percent, |
|
62 | 63 |
}, |
63 | 64 |
} |
64 |
- if _, err := projectAdminKubeClient.Extensions().HorizontalPodAutoscalers(projName).Create(&hpa); err != nil { |
|
65 |
+ if _, err := projectAdminKubeClient.Autoscaling().HorizontalPodAutoscalers(projName).Create(&hpa); err != nil { |
|
65 | 66 |
t.Fatalf("unexpected error creating the HPA object: %v", err) |
66 | 67 |
} |
67 | 68 |
|
... | ... |
@@ -95,7 +97,7 @@ func TestExtensionsAPIDeletion(t *testing.T) { |
95 | 95 |
t.Fatalf("unexpected error while waiting for project to delete: %v", err) |
96 | 96 |
} |
97 | 97 |
|
98 |
- if _, err := clusterAdminKubeClient.Extensions().HorizontalPodAutoscalers(projName).Get(hpa.Name); err == nil { |
|
98 |
+ if _, err := clusterAdminKubeClient.Autoscaling().HorizontalPodAutoscalers(projName).Get(hpa.Name); err == nil { |
|
99 | 99 |
t.Fatalf("HPA object was still present after project was deleted!") |
100 | 100 |
} else if !errors.IsNotFound(err) { |
101 | 101 |
t.Fatalf("Error trying to get deleted HPA object (not a not-found error): %v", err) |
... | ... |
@@ -10,6 +10,7 @@ import ( |
10 | 10 |
|
11 | 11 |
kapi "k8s.io/kubernetes/pkg/api" |
12 | 12 |
"k8s.io/kubernetes/pkg/api/errors" |
13 |
+ "k8s.io/kubernetes/pkg/apis/autoscaling" |
|
13 | 14 |
"k8s.io/kubernetes/pkg/apis/batch" |
14 | 15 |
expapi "k8s.io/kubernetes/pkg/apis/extensions" |
15 | 16 |
) |
... | ... |
@@ -59,11 +60,11 @@ func TestExtensionsAPIDisabledAutoscaleBatchEnabled(t *testing.T) { |
59 | 59 |
t.Fatalf("unexpected error waiting for policy update: %v", err) |
60 | 60 |
} |
61 | 61 |
|
62 |
- validHPA := &expapi.HorizontalPodAutoscaler{ |
|
62 |
+ validHPA := &autoscaling.HorizontalPodAutoscaler{ |
|
63 | 63 |
ObjectMeta: kapi.ObjectMeta{Name: "myjob"}, |
64 |
- Spec: expapi.HorizontalPodAutoscalerSpec{ |
|
65 |
- ScaleRef: expapi.SubresourceReference{Name: "foo", Kind: "ReplicationController", Subresource: "scale"}, |
|
66 |
- MaxReplicas: 1, |
|
64 |
+ Spec: autoscaling.HorizontalPodAutoscalerSpec{ |
|
65 |
+ ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "foo", Kind: "ReplicationController"}, |
|
66 |
+ MaxReplicas: 1, |
|
67 | 67 |
}, |
68 | 68 |
} |
69 | 69 |
validJob := &batch.Job{ |
... | ... |
@@ -78,11 +79,17 @@ func TestExtensionsAPIDisabledAutoscaleBatchEnabled(t *testing.T) { |
78 | 78 |
}, |
79 | 79 |
} |
80 | 80 |
|
81 |
+ legacyAutoscalers := legacyExtensionsAutoscaling{ |
|
82 |
+ projectAdminKubeClient.Autoscaling().HorizontalPodAutoscalers(projName), |
|
83 |
+ projectAdminKubeClient.ExtensionsClient.RESTClient, |
|
84 |
+ projName, |
|
85 |
+ } |
|
86 |
+ |
|
81 | 87 |
// make sure extensions API objects cannot be listed or created |
82 |
- if _, err := projectAdminKubeClient.Extensions().HorizontalPodAutoscalers(projName).List(kapi.ListOptions{}); !errors.IsNotFound(err) { |
|
88 |
+ if _, err := legacyAutoscalers.List(kapi.ListOptions{}); !errors.IsNotFound(err) { |
|
83 | 89 |
t.Fatalf("expected NotFound error listing HPA, got %v", err) |
84 | 90 |
} |
85 |
- if _, err := projectAdminKubeClient.Extensions().HorizontalPodAutoscalers(projName).Create(validHPA); !errors.IsNotFound(err) { |
|
91 |
+ if _, err := legacyAutoscalers.Create(validHPA); !errors.IsNotFound(err) { |
|
86 | 92 |
t.Fatalf("expected NotFound error creating HPA, got %v", err) |
87 | 93 |
} |
88 | 94 |
if _, err := projectAdminKubeClient.Extensions().Jobs(projName).List(kapi.ListOptions{}); !errors.IsNotFound(err) { |
... | ... |
@@ -180,11 +187,17 @@ func TestExtensionsAPIDisabled(t *testing.T) { |
180 | 180 |
t.Fatalf("unexpected error waiting for policy update: %v", err) |
181 | 181 |
} |
182 | 182 |
|
183 |
+ legacyAutoscalers := legacyExtensionsAutoscaling{ |
|
184 |
+ projectAdminKubeClient.Autoscaling().HorizontalPodAutoscalers(projName), |
|
185 |
+ projectAdminKubeClient.AutoscalingClient.RESTClient, |
|
186 |
+ projName, |
|
187 |
+ } |
|
188 |
+ |
|
183 | 189 |
// make sure extensions API objects cannot be listed or created |
184 |
- if _, err := projectAdminKubeClient.Extensions().HorizontalPodAutoscalers(projName).List(kapi.ListOptions{}); !errors.IsNotFound(err) { |
|
190 |
+ if _, err := legacyAutoscalers.List(kapi.ListOptions{}); !errors.IsNotFound(err) { |
|
185 | 191 |
t.Fatalf("expected NotFound error listing HPA, got %v", err) |
186 | 192 |
} |
187 |
- if _, err := projectAdminKubeClient.Extensions().HorizontalPodAutoscalers(projName).Create(&expapi.HorizontalPodAutoscaler{}); !errors.IsNotFound(err) { |
|
193 |
+ if _, err := legacyAutoscalers.Create(&autoscaling.HorizontalPodAutoscaler{}); !errors.IsNotFound(err) { |
|
188 | 194 |
t.Fatalf("expected NotFound error creating HPA, got %v", err) |
189 | 195 |
} |
190 | 196 |
if _, err := projectAdminKubeClient.Extensions().Jobs(projName).List(kapi.ListOptions{}); !errors.IsNotFound(err) { |
... | ... |
@@ -14,9 +14,11 @@ import ( |
14 | 14 |
|
15 | 15 |
kapi "k8s.io/kubernetes/pkg/api" |
16 | 16 |
"k8s.io/kubernetes/pkg/api/unversioned" |
17 |
+ "k8s.io/kubernetes/pkg/apis/autoscaling" |
|
17 | 18 |
"k8s.io/kubernetes/pkg/apis/batch" |
18 | 19 |
"k8s.io/kubernetes/pkg/apis/extensions" |
19 | 20 |
extensions_v1beta1 "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" |
21 |
+ "k8s.io/kubernetes/pkg/client/restclient" |
|
20 | 22 |
kclient "k8s.io/kubernetes/pkg/client/unversioned" |
21 | 23 |
"k8s.io/kubernetes/pkg/runtime" |
22 | 24 |
) |
... | ... |
@@ -38,6 +40,29 @@ func TestStorageVersionsUnified(t *testing.T) { |
38 | 38 |
) |
39 | 39 |
} |
40 | 40 |
|
41 |
+type legacyExtensionsAutoscaling struct { |
|
42 |
+ kclient.HorizontalPodAutoscalerInterface |
|
43 |
+ client *restclient.RESTClient |
|
44 |
+ namespace string |
|
45 |
+} |
|
46 |
+ |
|
47 |
+// List takes label and field selectors, and returns the list of horizontalPodAutoscalers that match those selectors. |
|
48 |
+func (c legacyExtensionsAutoscaling) List(opts kapi.ListOptions) (result *autoscaling.HorizontalPodAutoscalerList, err error) { |
|
49 |
+ result = &autoscaling.HorizontalPodAutoscalerList{} |
|
50 |
+ err = c.client.Get().Namespace(c.namespace).Resource("horizontalPodAutoscalers").VersionedParams(&opts, kapi.ParameterCodec).Do().Into(result) |
|
51 |
+ return |
|
52 |
+} |
|
53 |
+ |
|
54 |
+func (c legacyExtensionsAutoscaling) Create(hpa *autoscaling.HorizontalPodAutoscaler) (*autoscaling.HorizontalPodAutoscaler, error) { |
|
55 |
+ var result autoscaling.HorizontalPodAutoscaler |
|
56 |
+ return &result, c.client.Post().Resource("horizontalpodautoscalers").Namespace(c.namespace).Body(hpa).Do().Into(&result) |
|
57 |
+} |
|
58 |
+ |
|
59 |
+func (c legacyExtensionsAutoscaling) Get(name string) (*autoscaling.HorizontalPodAutoscaler, error) { |
|
60 |
+ var result autoscaling.HorizontalPodAutoscaler |
|
61 |
+ return &result, c.client.Get().Resource("horizontalpodautoscalers").Namespace(c.namespace).Name(name).Do().Into(&result) |
|
62 |
+} |
|
63 |
+ |
|
41 | 64 |
func runStorageTest(t *testing.T, ns string, autoscalingVersion, batchVersion, extensionsVersion unversioned.GroupVersion) { |
42 | 65 |
etcdServer := testutil.RequireEtcd(t) |
43 | 66 |
|
... | ... |
@@ -126,18 +151,25 @@ func runStorageTest(t *testing.T, ns string, autoscalingVersion, batchVersion, e |
126 | 126 |
} |
127 | 127 |
} |
128 | 128 |
|
129 |
+ legacyClient := legacyExtensionsAutoscaling{ |
|
130 |
+ projectAdminKubeClient.Autoscaling().HorizontalPodAutoscalers(ns), |
|
131 |
+ projectAdminKubeClient.AutoscalingClient.RESTClient, |
|
132 |
+ ns, |
|
133 |
+ } |
|
129 | 134 |
hpaTestcases := map[string]struct { |
130 | 135 |
creator kclient.HorizontalPodAutoscalerInterface |
131 | 136 |
}{ |
132 | 137 |
"autoscaling": {creator: projectAdminKubeClient.Autoscaling().HorizontalPodAutoscalers(ns)}, |
133 |
- "extensions": {creator: projectAdminKubeClient.Extensions().HorizontalPodAutoscalers(ns)}, |
|
138 |
+ "extensions": { |
|
139 |
+ creator: legacyClient, |
|
140 |
+ }, |
|
134 | 141 |
} |
135 | 142 |
for name, testcase := range hpaTestcases { |
136 |
- hpa := extensions.HorizontalPodAutoscaler{ |
|
143 |
+ hpa := autoscaling.HorizontalPodAutoscaler{ |
|
137 | 144 |
ObjectMeta: kapi.ObjectMeta{Name: name + "-hpa"}, |
138 |
- Spec: extensions.HorizontalPodAutoscalerSpec{ |
|
139 |
- MaxReplicas: 1, |
|
140 |
- ScaleRef: extensions.SubresourceReference{Kind: "ReplicationController", Name: "myrc", Subresource: "scale"}, |
|
145 |
+ Spec: autoscaling.HorizontalPodAutoscalerSpec{ |
|
146 |
+ MaxReplicas: 1, |
|
147 |
+ ScaleTargetRef: autoscaling.CrossVersionObjectReference{Kind: "ReplicationController", Name: "myrc"}, |
|
141 | 148 |
}, |
142 | 149 |
} |
143 | 150 |
|
... | ... |
@@ -153,12 +185,12 @@ func runStorageTest(t *testing.T, ns string, autoscalingVersion, batchVersion, e |
153 | 153 |
t.Fatalf("%s: expected api version %s in etcd, got %s reading HPA", name, autoscalingVersion, gvk) |
154 | 154 |
} |
155 | 155 |
|
156 |
- // Make sure it is available from both APIs |
|
156 |
+ // Make sure it is available from the api |
|
157 | 157 |
if _, err := projectAdminKubeClient.Autoscaling().HorizontalPodAutoscalers(ns).Get(hpa.Name); err != nil { |
158 | 158 |
t.Errorf("%s: Error reading HPA.autoscaling from the autoscaling/v1 API: %#v", name, err) |
159 | 159 |
} |
160 |
- if _, err := projectAdminKubeClient.Extensions().HorizontalPodAutoscalers(ns).Get(hpa.Name); err != nil { |
|
161 |
- t.Errorf("%s: Error reading HPA.extensions from the extensions/v1beta1 API: %#v", name, err) |
|
160 |
+ if _, err := legacyClient.Get(hpa.Name); err != nil { |
|
161 |
+ t.Errorf("%s: Error reading HPA.autoscaling from the extensions/v1beta1 API: %#v", name, err) |
|
162 | 162 |
} |
163 | 163 |
} |
164 | 164 |
} |
... | ... |
@@ -49,8 +49,6 @@ func main() { |
49 | 49 |
"k8s.io/kubernetes/pkg/apis/componentconfig/v1alpha1", |
50 | 50 |
"k8s.io/kubernetes/pkg/apis/extensions", |
51 | 51 |
"k8s.io/kubernetes/pkg/apis/extensions/v1beta1", |
52 |
- "k8s.io/kubernetes/pkg/apis/metrics", |
|
53 |
- "k8s.io/kubernetes/pkg/apis/metrics/v1alpha1", |
|
54 | 52 |
"github.com/openshift/origin/pkg/authorization/api/v1", |
55 | 53 |
"github.com/openshift/origin/pkg/authorization/api", |
56 | 54 |
"github.com/openshift/origin/pkg/build/api/v1", |