7
7
"strings"
8
8
9
9
kvalidation "k8s.io/kubernetes/pkg/api/validation"
10
+ kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
10
11
)
11
12
12
13
// pathSpec represents a path (remote or local) given as a source or destination
@@ -46,10 +47,21 @@ func (s *pathSpec) Validate() error {
46
47
return nil
47
48
}
48
49
50
+ // isPathForPod receives a path and returns true
51
+ // if it matches a <podName>:/path format
52
+ func isPathForPod (path string ) bool {
53
+ parts := strings .SplitN (path , ":" , 2 )
54
+ if len (parts ) == 1 || (isWindows () && len (parts [0 ]) == 1 ) {
55
+ return false
56
+ }
57
+
58
+ return true
59
+ }
60
+
49
61
// parsePathSpec parses a string argument into a pathSpec object
50
62
func parsePathSpec (path string ) (* pathSpec , error ) {
51
63
parts := strings .SplitN (path , ":" , 2 )
52
- if len ( parts ) == 1 || ( isWindows () && len ( parts [ 0 ]) == 1 ) {
64
+ if ! isPathForPod ( path ) {
53
65
return & pathSpec {
54
66
Path : path ,
55
67
}, nil
@@ -63,6 +75,46 @@ func parsePathSpec(path string) (*pathSpec, error) {
63
75
}, nil
64
76
}
65
77
78
+ // resolveResourceKindPath determines if a given path contains a resource
79
+ // formatted as resource/kind, and returns the resource name without the
80
+ // <kind/> segment, ensuring that the resource is of type Pod, if it exists.
81
+ func resolveResourceKindPath (f kcmdutil.Factory , path , namespace string ) (string , error ) {
82
+ parts := strings .SplitN (path , ":" , 2 )
83
+ if ! isPathForPod (path ) {
84
+ return path , nil
85
+ }
86
+
87
+ podName := parts [0 ]
88
+
89
+ // if the specified pod name is given in the <kind>/<name> format
90
+ // validate the podName without the <kind/> segment.
91
+ if podSegs := strings .Split (podName , "/" ); len (podSegs ) > 1 {
92
+ podName = podSegs [1 ]
93
+ }
94
+
95
+ r := f .NewBuilder (true ).
96
+ NamespaceParam (namespace ).
97
+ SingleResourceType ().
98
+ ResourceNames ("pods" , podName ).
99
+ Do ()
100
+
101
+ if err := r .Err (); err != nil {
102
+ return "" , err
103
+ }
104
+ infos , err := r .Infos ()
105
+ if err != nil {
106
+ return "" , err
107
+ }
108
+
109
+ // if there were no errors, we should expect
110
+ // one resource to exist
111
+ if len (infos ) == 0 || infos [0 ].Mapping .Resource != "pods" {
112
+ return "" , fmt .Errorf ("error: expected resource to be of type pod, got %q" , infos [0 ].Mapping .Resource )
113
+ }
114
+
115
+ return fmt .Sprintf ("%s:%s" , podName , parts [1 ]), nil
116
+ }
117
+
66
118
// convertWindowsPath converts a windows native path to a path that can be used by
67
119
// the rsync command in windows.
68
120
// It can take one of three forms:
0 commit comments