actions.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  1. /*
  2. Copyright 2015 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package testing
  14. import (
  15. "fmt"
  16. "path"
  17. "strings"
  18. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  19. "k8s.io/apimachinery/pkg/fields"
  20. "k8s.io/apimachinery/pkg/labels"
  21. "k8s.io/apimachinery/pkg/runtime"
  22. "k8s.io/apimachinery/pkg/runtime/schema"
  23. "k8s.io/apimachinery/pkg/types"
  24. )
  25. func NewRootGetAction(resource schema.GroupVersionResource, name string) GetActionImpl {
  26. action := GetActionImpl{}
  27. action.Verb = "get"
  28. action.Resource = resource
  29. action.Name = name
  30. return action
  31. }
  32. func NewGetAction(resource schema.GroupVersionResource, namespace, name string) GetActionImpl {
  33. action := GetActionImpl{}
  34. action.Verb = "get"
  35. action.Resource = resource
  36. action.Namespace = namespace
  37. action.Name = name
  38. return action
  39. }
  40. func NewGetSubresourceAction(resource schema.GroupVersionResource, namespace, subresource, name string) GetActionImpl {
  41. action := GetActionImpl{}
  42. action.Verb = "get"
  43. action.Resource = resource
  44. action.Subresource = subresource
  45. action.Namespace = namespace
  46. action.Name = name
  47. return action
  48. }
  49. func NewRootGetSubresourceAction(resource schema.GroupVersionResource, subresource, name string) GetActionImpl {
  50. action := GetActionImpl{}
  51. action.Verb = "get"
  52. action.Resource = resource
  53. action.Subresource = subresource
  54. action.Name = name
  55. return action
  56. }
  57. func NewRootListAction(resource schema.GroupVersionResource, kind schema.GroupVersionKind, opts interface{}) ListActionImpl {
  58. action := ListActionImpl{}
  59. action.Verb = "list"
  60. action.Resource = resource
  61. action.Kind = kind
  62. labelSelector, fieldSelector, _ := ExtractFromListOptions(opts)
  63. action.ListRestrictions = ListRestrictions{labelSelector, fieldSelector}
  64. return action
  65. }
  66. func NewListAction(resource schema.GroupVersionResource, kind schema.GroupVersionKind, namespace string, opts interface{}) ListActionImpl {
  67. action := ListActionImpl{}
  68. action.Verb = "list"
  69. action.Resource = resource
  70. action.Kind = kind
  71. action.Namespace = namespace
  72. labelSelector, fieldSelector, _ := ExtractFromListOptions(opts)
  73. action.ListRestrictions = ListRestrictions{labelSelector, fieldSelector}
  74. return action
  75. }
  76. func NewRootCreateAction(resource schema.GroupVersionResource, object runtime.Object) CreateActionImpl {
  77. action := CreateActionImpl{}
  78. action.Verb = "create"
  79. action.Resource = resource
  80. action.Object = object
  81. return action
  82. }
  83. func NewCreateAction(resource schema.GroupVersionResource, namespace string, object runtime.Object) CreateActionImpl {
  84. action := CreateActionImpl{}
  85. action.Verb = "create"
  86. action.Resource = resource
  87. action.Namespace = namespace
  88. action.Object = object
  89. return action
  90. }
  91. func NewRootCreateSubresourceAction(resource schema.GroupVersionResource, name, subresource string, object runtime.Object) CreateActionImpl {
  92. action := CreateActionImpl{}
  93. action.Verb = "create"
  94. action.Resource = resource
  95. action.Subresource = subresource
  96. action.Name = name
  97. action.Object = object
  98. return action
  99. }
  100. func NewCreateSubresourceAction(resource schema.GroupVersionResource, name, subresource, namespace string, object runtime.Object) CreateActionImpl {
  101. action := CreateActionImpl{}
  102. action.Verb = "create"
  103. action.Resource = resource
  104. action.Namespace = namespace
  105. action.Subresource = subresource
  106. action.Name = name
  107. action.Object = object
  108. return action
  109. }
  110. func NewRootUpdateAction(resource schema.GroupVersionResource, object runtime.Object) UpdateActionImpl {
  111. action := UpdateActionImpl{}
  112. action.Verb = "update"
  113. action.Resource = resource
  114. action.Object = object
  115. return action
  116. }
  117. func NewUpdateAction(resource schema.GroupVersionResource, namespace string, object runtime.Object) UpdateActionImpl {
  118. action := UpdateActionImpl{}
  119. action.Verb = "update"
  120. action.Resource = resource
  121. action.Namespace = namespace
  122. action.Object = object
  123. return action
  124. }
  125. func NewRootPatchAction(resource schema.GroupVersionResource, name string, pt types.PatchType, patch []byte) PatchActionImpl {
  126. action := PatchActionImpl{}
  127. action.Verb = "patch"
  128. action.Resource = resource
  129. action.Name = name
  130. action.PatchType = pt
  131. action.Patch = patch
  132. return action
  133. }
  134. func NewPatchAction(resource schema.GroupVersionResource, namespace string, name string, pt types.PatchType, patch []byte) PatchActionImpl {
  135. action := PatchActionImpl{}
  136. action.Verb = "patch"
  137. action.Resource = resource
  138. action.Namespace = namespace
  139. action.Name = name
  140. action.PatchType = pt
  141. action.Patch = patch
  142. return action
  143. }
  144. func NewRootPatchSubresourceAction(resource schema.GroupVersionResource, name string, pt types.PatchType, patch []byte, subresources ...string) PatchActionImpl {
  145. action := PatchActionImpl{}
  146. action.Verb = "patch"
  147. action.Resource = resource
  148. action.Subresource = path.Join(subresources...)
  149. action.Name = name
  150. action.PatchType = pt
  151. action.Patch = patch
  152. return action
  153. }
  154. func NewPatchSubresourceAction(resource schema.GroupVersionResource, namespace, name string, pt types.PatchType, patch []byte, subresources ...string) PatchActionImpl {
  155. action := PatchActionImpl{}
  156. action.Verb = "patch"
  157. action.Resource = resource
  158. action.Subresource = path.Join(subresources...)
  159. action.Namespace = namespace
  160. action.Name = name
  161. action.PatchType = pt
  162. action.Patch = patch
  163. return action
  164. }
  165. func NewRootUpdateSubresourceAction(resource schema.GroupVersionResource, subresource string, object runtime.Object) UpdateActionImpl {
  166. action := UpdateActionImpl{}
  167. action.Verb = "update"
  168. action.Resource = resource
  169. action.Subresource = subresource
  170. action.Object = object
  171. return action
  172. }
  173. func NewUpdateSubresourceAction(resource schema.GroupVersionResource, subresource string, namespace string, object runtime.Object) UpdateActionImpl {
  174. action := UpdateActionImpl{}
  175. action.Verb = "update"
  176. action.Resource = resource
  177. action.Subresource = subresource
  178. action.Namespace = namespace
  179. action.Object = object
  180. return action
  181. }
  182. func NewRootDeleteAction(resource schema.GroupVersionResource, name string) DeleteActionImpl {
  183. action := DeleteActionImpl{}
  184. action.Verb = "delete"
  185. action.Resource = resource
  186. action.Name = name
  187. return action
  188. }
  189. func NewRootDeleteSubresourceAction(resource schema.GroupVersionResource, subresource string, name string) DeleteActionImpl {
  190. action := DeleteActionImpl{}
  191. action.Verb = "delete"
  192. action.Resource = resource
  193. action.Subresource = subresource
  194. action.Name = name
  195. return action
  196. }
  197. func NewDeleteAction(resource schema.GroupVersionResource, namespace, name string) DeleteActionImpl {
  198. action := DeleteActionImpl{}
  199. action.Verb = "delete"
  200. action.Resource = resource
  201. action.Namespace = namespace
  202. action.Name = name
  203. return action
  204. }
  205. func NewDeleteSubresourceAction(resource schema.GroupVersionResource, subresource, namespace, name string) DeleteActionImpl {
  206. action := DeleteActionImpl{}
  207. action.Verb = "delete"
  208. action.Resource = resource
  209. action.Subresource = subresource
  210. action.Namespace = namespace
  211. action.Name = name
  212. return action
  213. }
  214. func NewRootDeleteCollectionAction(resource schema.GroupVersionResource, opts interface{}) DeleteCollectionActionImpl {
  215. action := DeleteCollectionActionImpl{}
  216. action.Verb = "delete-collection"
  217. action.Resource = resource
  218. labelSelector, fieldSelector, _ := ExtractFromListOptions(opts)
  219. action.ListRestrictions = ListRestrictions{labelSelector, fieldSelector}
  220. return action
  221. }
  222. func NewDeleteCollectionAction(resource schema.GroupVersionResource, namespace string, opts interface{}) DeleteCollectionActionImpl {
  223. action := DeleteCollectionActionImpl{}
  224. action.Verb = "delete-collection"
  225. action.Resource = resource
  226. action.Namespace = namespace
  227. labelSelector, fieldSelector, _ := ExtractFromListOptions(opts)
  228. action.ListRestrictions = ListRestrictions{labelSelector, fieldSelector}
  229. return action
  230. }
  231. func NewRootWatchAction(resource schema.GroupVersionResource, opts interface{}) WatchActionImpl {
  232. action := WatchActionImpl{}
  233. action.Verb = "watch"
  234. action.Resource = resource
  235. labelSelector, fieldSelector, resourceVersion := ExtractFromListOptions(opts)
  236. action.WatchRestrictions = WatchRestrictions{labelSelector, fieldSelector, resourceVersion}
  237. return action
  238. }
  239. func ExtractFromListOptions(opts interface{}) (labelSelector labels.Selector, fieldSelector fields.Selector, resourceVersion string) {
  240. var err error
  241. switch t := opts.(type) {
  242. case metav1.ListOptions:
  243. labelSelector, err = labels.Parse(t.LabelSelector)
  244. if err != nil {
  245. panic(fmt.Errorf("invalid selector %q: %v", t.LabelSelector, err))
  246. }
  247. fieldSelector, err = fields.ParseSelector(t.FieldSelector)
  248. if err != nil {
  249. panic(fmt.Errorf("invalid selector %q: %v", t.FieldSelector, err))
  250. }
  251. resourceVersion = t.ResourceVersion
  252. default:
  253. panic(fmt.Errorf("expect a ListOptions %T", opts))
  254. }
  255. if labelSelector == nil {
  256. labelSelector = labels.Everything()
  257. }
  258. if fieldSelector == nil {
  259. fieldSelector = fields.Everything()
  260. }
  261. return labelSelector, fieldSelector, resourceVersion
  262. }
  263. func NewWatchAction(resource schema.GroupVersionResource, namespace string, opts interface{}) WatchActionImpl {
  264. action := WatchActionImpl{}
  265. action.Verb = "watch"
  266. action.Resource = resource
  267. action.Namespace = namespace
  268. labelSelector, fieldSelector, resourceVersion := ExtractFromListOptions(opts)
  269. action.WatchRestrictions = WatchRestrictions{labelSelector, fieldSelector, resourceVersion}
  270. return action
  271. }
  272. func NewProxyGetAction(resource schema.GroupVersionResource, namespace, scheme, name, port, path string, params map[string]string) ProxyGetActionImpl {
  273. action := ProxyGetActionImpl{}
  274. action.Verb = "get"
  275. action.Resource = resource
  276. action.Namespace = namespace
  277. action.Scheme = scheme
  278. action.Name = name
  279. action.Port = port
  280. action.Path = path
  281. action.Params = params
  282. return action
  283. }
  284. type ListRestrictions struct {
  285. Labels labels.Selector
  286. Fields fields.Selector
  287. }
  288. type WatchRestrictions struct {
  289. Labels labels.Selector
  290. Fields fields.Selector
  291. ResourceVersion string
  292. }
  293. type Action interface {
  294. GetNamespace() string
  295. GetVerb() string
  296. GetResource() schema.GroupVersionResource
  297. GetSubresource() string
  298. Matches(verb, resource string) bool
  299. // DeepCopy is used to copy an action to avoid any risk of accidental mutation. Most people never need to call this
  300. // because the invocation logic deep copies before calls to storage and reactors.
  301. DeepCopy() Action
  302. }
  303. type GenericAction interface {
  304. Action
  305. GetValue() interface{}
  306. }
  307. type GetAction interface {
  308. Action
  309. GetName() string
  310. }
  311. type ListAction interface {
  312. Action
  313. GetListRestrictions() ListRestrictions
  314. }
  315. type CreateAction interface {
  316. Action
  317. GetObject() runtime.Object
  318. }
  319. type UpdateAction interface {
  320. Action
  321. GetObject() runtime.Object
  322. }
  323. type DeleteAction interface {
  324. Action
  325. GetName() string
  326. }
  327. type DeleteCollectionAction interface {
  328. Action
  329. GetListRestrictions() ListRestrictions
  330. }
  331. type PatchAction interface {
  332. Action
  333. GetName() string
  334. GetPatchType() types.PatchType
  335. GetPatch() []byte
  336. }
  337. type WatchAction interface {
  338. Action
  339. GetWatchRestrictions() WatchRestrictions
  340. }
  341. type ProxyGetAction interface {
  342. Action
  343. GetScheme() string
  344. GetName() string
  345. GetPort() string
  346. GetPath() string
  347. GetParams() map[string]string
  348. }
  349. type ActionImpl struct {
  350. Namespace string
  351. Verb string
  352. Resource schema.GroupVersionResource
  353. Subresource string
  354. }
  355. func (a ActionImpl) GetNamespace() string {
  356. return a.Namespace
  357. }
  358. func (a ActionImpl) GetVerb() string {
  359. return a.Verb
  360. }
  361. func (a ActionImpl) GetResource() schema.GroupVersionResource {
  362. return a.Resource
  363. }
  364. func (a ActionImpl) GetSubresource() string {
  365. return a.Subresource
  366. }
  367. func (a ActionImpl) Matches(verb, resource string) bool {
  368. // Stay backwards compatible.
  369. if !strings.Contains(resource, "/") {
  370. return strings.EqualFold(verb, a.Verb) &&
  371. strings.EqualFold(resource, a.Resource.Resource)
  372. }
  373. parts := strings.SplitN(resource, "/", 2)
  374. topresource, subresource := parts[0], parts[1]
  375. return strings.EqualFold(verb, a.Verb) &&
  376. strings.EqualFold(topresource, a.Resource.Resource) &&
  377. strings.EqualFold(subresource, a.Subresource)
  378. }
  379. func (a ActionImpl) DeepCopy() Action {
  380. ret := a
  381. return ret
  382. }
  383. type GenericActionImpl struct {
  384. ActionImpl
  385. Value interface{}
  386. }
  387. func (a GenericActionImpl) GetValue() interface{} {
  388. return a.Value
  389. }
  390. func (a GenericActionImpl) DeepCopy() Action {
  391. return GenericActionImpl{
  392. ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl),
  393. // TODO this is wrong, but no worse than before
  394. Value: a.Value,
  395. }
  396. }
  397. type GetActionImpl struct {
  398. ActionImpl
  399. Name string
  400. }
  401. func (a GetActionImpl) GetName() string {
  402. return a.Name
  403. }
  404. func (a GetActionImpl) DeepCopy() Action {
  405. return GetActionImpl{
  406. ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl),
  407. Name: a.Name,
  408. }
  409. }
  410. type ListActionImpl struct {
  411. ActionImpl
  412. Kind schema.GroupVersionKind
  413. Name string
  414. ListRestrictions ListRestrictions
  415. }
  416. func (a ListActionImpl) GetKind() schema.GroupVersionKind {
  417. return a.Kind
  418. }
  419. func (a ListActionImpl) GetListRestrictions() ListRestrictions {
  420. return a.ListRestrictions
  421. }
  422. func (a ListActionImpl) DeepCopy() Action {
  423. return ListActionImpl{
  424. ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl),
  425. Kind: a.Kind,
  426. Name: a.Name,
  427. ListRestrictions: ListRestrictions{
  428. Labels: a.ListRestrictions.Labels.DeepCopySelector(),
  429. Fields: a.ListRestrictions.Fields.DeepCopySelector(),
  430. },
  431. }
  432. }
  433. type CreateActionImpl struct {
  434. ActionImpl
  435. Name string
  436. Object runtime.Object
  437. }
  438. func (a CreateActionImpl) GetObject() runtime.Object {
  439. return a.Object
  440. }
  441. func (a CreateActionImpl) DeepCopy() Action {
  442. return CreateActionImpl{
  443. ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl),
  444. Name: a.Name,
  445. Object: a.Object.DeepCopyObject(),
  446. }
  447. }
  448. type UpdateActionImpl struct {
  449. ActionImpl
  450. Object runtime.Object
  451. }
  452. func (a UpdateActionImpl) GetObject() runtime.Object {
  453. return a.Object
  454. }
  455. func (a UpdateActionImpl) DeepCopy() Action {
  456. return UpdateActionImpl{
  457. ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl),
  458. Object: a.Object.DeepCopyObject(),
  459. }
  460. }
  461. type PatchActionImpl struct {
  462. ActionImpl
  463. Name string
  464. PatchType types.PatchType
  465. Patch []byte
  466. }
  467. func (a PatchActionImpl) GetName() string {
  468. return a.Name
  469. }
  470. func (a PatchActionImpl) GetPatch() []byte {
  471. return a.Patch
  472. }
  473. func (a PatchActionImpl) GetPatchType() types.PatchType {
  474. return a.PatchType
  475. }
  476. func (a PatchActionImpl) DeepCopy() Action {
  477. patch := make([]byte, len(a.Patch))
  478. copy(patch, a.Patch)
  479. return PatchActionImpl{
  480. ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl),
  481. Name: a.Name,
  482. PatchType: a.PatchType,
  483. Patch: patch,
  484. }
  485. }
  486. type DeleteActionImpl struct {
  487. ActionImpl
  488. Name string
  489. }
  490. func (a DeleteActionImpl) GetName() string {
  491. return a.Name
  492. }
  493. func (a DeleteActionImpl) DeepCopy() Action {
  494. return DeleteActionImpl{
  495. ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl),
  496. Name: a.Name,
  497. }
  498. }
  499. type DeleteCollectionActionImpl struct {
  500. ActionImpl
  501. ListRestrictions ListRestrictions
  502. }
  503. func (a DeleteCollectionActionImpl) GetListRestrictions() ListRestrictions {
  504. return a.ListRestrictions
  505. }
  506. func (a DeleteCollectionActionImpl) DeepCopy() Action {
  507. return DeleteCollectionActionImpl{
  508. ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl),
  509. ListRestrictions: ListRestrictions{
  510. Labels: a.ListRestrictions.Labels.DeepCopySelector(),
  511. Fields: a.ListRestrictions.Fields.DeepCopySelector(),
  512. },
  513. }
  514. }
  515. type WatchActionImpl struct {
  516. ActionImpl
  517. WatchRestrictions WatchRestrictions
  518. }
  519. func (a WatchActionImpl) GetWatchRestrictions() WatchRestrictions {
  520. return a.WatchRestrictions
  521. }
  522. func (a WatchActionImpl) DeepCopy() Action {
  523. return WatchActionImpl{
  524. ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl),
  525. WatchRestrictions: WatchRestrictions{
  526. Labels: a.WatchRestrictions.Labels.DeepCopySelector(),
  527. Fields: a.WatchRestrictions.Fields.DeepCopySelector(),
  528. ResourceVersion: a.WatchRestrictions.ResourceVersion,
  529. },
  530. }
  531. }
  532. type ProxyGetActionImpl struct {
  533. ActionImpl
  534. Scheme string
  535. Name string
  536. Port string
  537. Path string
  538. Params map[string]string
  539. }
  540. func (a ProxyGetActionImpl) GetScheme() string {
  541. return a.Scheme
  542. }
  543. func (a ProxyGetActionImpl) GetName() string {
  544. return a.Name
  545. }
  546. func (a ProxyGetActionImpl) GetPort() string {
  547. return a.Port
  548. }
  549. func (a ProxyGetActionImpl) GetPath() string {
  550. return a.Path
  551. }
  552. func (a ProxyGetActionImpl) GetParams() map[string]string {
  553. return a.Params
  554. }
  555. func (a ProxyGetActionImpl) DeepCopy() Action {
  556. params := map[string]string{}
  557. for k, v := range a.Params {
  558. params[k] = v
  559. }
  560. return ProxyGetActionImpl{
  561. ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl),
  562. Scheme: a.Scheme,
  563. Name: a.Name,
  564. Port: a.Port,
  565. Path: a.Path,
  566. Params: params,
  567. }
  568. }