forked from kubernetes/kubernetes
-
Notifications
You must be signed in to change notification settings - Fork 0
/
resource.go
164 lines (132 loc) · 5.64 KB
/
resource.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/*
Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"fmt"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/spf13/cobra"
)
// ResourceFromArgsOrFile expects two arguments or a valid file with a given type, and extracts
// the fields necessary to uniquely locate a resource. Displays a usageError if that contract is
// not satisfied, or a generic error if any other problems occur.
func ResourceFromArgsOrFile(cmd *cobra.Command, args []string, filename string, typer runtime.ObjectTyper, mapper meta.RESTMapper) (mapping *meta.RESTMapping, namespace, name string) {
// If command line args are passed in, use those preferentially.
if len(args) > 0 && len(args) != 2 {
usageError(cmd, "If passing in command line parameters, must be resource and name")
}
if len(args) == 2 {
resource := kubectl.ExpandResourceShortcut(args[0])
namespace = getKubeNamespace(cmd)
name = args[1]
if len(name) == 0 || len(resource) == 0 {
usageError(cmd, "Must specify filename or command line params")
}
version, kind, err := mapper.VersionAndKindForResource(resource)
if err != nil {
// The error returned by mapper is "no resource defined", which is a usage error
usageError(cmd, err.Error())
}
mapping, err = mapper.RESTMapping(version, kind)
checkErr(err)
return
}
if len(filename) == 0 {
usageError(cmd, "Must specify filename or command line params")
}
mapping, namespace, name, _ = ResourceFromFile(filename, typer, mapper)
if len(name) == 0 {
checkErr(fmt.Errorf("the resource in the provided file has no name (or ID) defined"))
}
return
}
// ResourceFromArgs expects two arguments with a given type, and extracts the fields necessary
// to uniquely locate a resource. Displays a usageError if that contract is not satisfied, or
// a generic error if any other problems occur.
func ResourceFromArgs(cmd *cobra.Command, args []string, mapper meta.RESTMapper) (mapping *meta.RESTMapping, namespace, name string) {
if len(args) != 2 {
usageError(cmd, "Must provide resource and name command line params")
}
resource := kubectl.ExpandResourceShortcut(args[0])
namespace = getKubeNamespace(cmd)
name = args[1]
if len(name) == 0 || len(resource) == 0 {
usageError(cmd, "Must provide resource and name command line params")
}
version, kind, err := mapper.VersionAndKindForResource(resource)
checkErr(err)
mapping, err = mapper.RESTMapping(version, kind)
checkErr(err)
return
}
// ResourceFromArgs expects two arguments with a given type, and extracts the fields necessary
// to uniquely locate a resource. Displays a usageError if that contract is not satisfied, or
// a generic error if any other problems occur.
func ResourceOrTypeFromArgs(cmd *cobra.Command, args []string, mapper meta.RESTMapper) (mapping *meta.RESTMapping, namespace, name string) {
if len(args) == 0 || len(args) > 2 {
usageError(cmd, "Must provide resource or a resource and name as command line params")
}
resource := kubectl.ExpandResourceShortcut(args[0])
if len(resource) == 0 {
usageError(cmd, "Must provide resource or a resource and name as command line params")
}
namespace = getKubeNamespace(cmd)
if len(args) == 2 {
name = args[1]
if len(name) == 0 {
usageError(cmd, "Must provide resource or a resource and name as command line params")
}
}
version, kind, err := mapper.VersionAndKindForResource(resource)
checkErr(err)
mapping, err = mapper.RESTMapping(version, kind)
checkErr(err)
return
}
// ResourceFromFile retrieves the name and namespace from a valid file. If the file does not
// resolve to a known type an error is returned. The returned mapping can be used to determine
// the correct REST endpoint to modify this resource with.
func ResourceFromFile(filename string, typer runtime.ObjectTyper, mapper meta.RESTMapper) (mapping *meta.RESTMapping, namespace, name string, data []byte) {
configData, err := ReadConfigData(filename)
checkErr(err)
data = configData
version, kind, err := typer.DataVersionAndKind(data)
checkErr(err)
// TODO: allow unversioned objects?
if len(version) == 0 {
checkErr(fmt.Errorf("the resource in the provided file has no apiVersion defined"))
}
mapping, err = mapper.RESTMapping(version, kind)
checkErr(err)
obj, err := mapping.Codec.Decode(data)
checkErr(err)
meta := mapping.MetadataAccessor
namespace, err = meta.Namespace(obj)
checkErr(err)
name, err = meta.Name(obj)
checkErr(err)
return
}
// CompareNamespaceFromFile returns an error if the namespace the user has provided on the CLI
// or via the default namespace file does not match the namespace of an input file. This
// prevents a user from unintentionally updating the wrong namespace.
func CompareNamespaceFromFile(cmd *cobra.Command, namespace string) error {
defaultNamespace := getKubeNamespace(cmd)
if len(namespace) > 0 {
if defaultNamespace != namespace {
return fmt.Errorf("the namespace from the provided file %q does not match the namespace %q. You must pass '--namespace=%s' to perform this operation.", namespace, defaultNamespace, namespace)
}
}
return nil
}