-
Notifications
You must be signed in to change notification settings - Fork 263
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve 'source apiserver update --resource' #590
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,7 @@ package apiserver | |
|
||
import ( | ||
"fmt" | ||
"reflect" | ||
"sort" | ||
"strconv" | ||
"strings" | ||
|
@@ -27,6 +28,7 @@ import ( | |
|
||
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1" | ||
hprinters "knative.dev/client/pkg/printers" | ||
"knative.dev/client/pkg/util" | ||
) | ||
|
||
const ( | ||
|
@@ -40,47 +42,101 @@ type APIServerSourceUpdateFlags struct { | |
Resources []string | ||
} | ||
|
||
type resourceSpec struct { | ||
kind string | ||
apiVersion string | ||
isController bool | ||
} | ||
|
||
// GetAPIServerResourceArray is to return an array of ApiServerResource from a string. A sample is Event:v1:true,Pod:v2:false | ||
func (f *APIServerSourceUpdateFlags) GetAPIServerResourceArray() (*[]v1alpha1.ApiServerResource, error) { | ||
// getAPIServerResourceArray is to construct an array of resources. | ||
func (f *APIServerSourceUpdateFlags) getAPIServerResourceArray() ([]v1alpha1.ApiServerResource, error) { | ||
var resourceList []v1alpha1.ApiServerResource | ||
for _, r := range f.Resources { | ||
resourceSpec, err := getValidResource(r) | ||
if err != nil { | ||
return nil, err | ||
} | ||
resourceRef := v1alpha1.ApiServerResource{ | ||
APIVersion: resourceSpec.apiVersion, | ||
Kind: resourceSpec.kind, | ||
Controller: resourceSpec.isController, | ||
resourceList = append(resourceList, *resourceSpec) | ||
} | ||
return resourceList, nil | ||
} | ||
|
||
// updateExistingAPIServerResourceArray is to update an array of resources. | ||
func (f *APIServerSourceUpdateFlags) updateExistingAPIServerResourceArray(existing []v1alpha1.ApiServerResource) ([]v1alpha1.ApiServerResource, error) { | ||
var found bool | ||
|
||
added, removed, err := f.getUpdateAPIServerResourceArray() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if existing == nil { | ||
existing = []v1alpha1.ApiServerResource{} | ||
} | ||
|
||
existing = append(existing, added...) | ||
|
||
for _, item := range removed { | ||
found = false | ||
for i, ref := range existing { | ||
if reflect.DeepEqual(item, ref) { | ||
existing = append(existing[:i], existing[i+1:]...) | ||
found = true | ||
break | ||
} | ||
} | ||
if !found { | ||
return nil, fmt.Errorf("cannot find resource %s:%s:%t to remove", item.Kind, item.APIVersion, item.Controller) | ||
} | ||
resourceList = append(resourceList, resourceRef) | ||
} | ||
return &resourceList, nil | ||
return existing, nil | ||
} | ||
|
||
func getValidResource(resource string) (*resourceSpec, error) { | ||
var isController = false //false as default | ||
// getUpdateAPIServerResourceArray is to construct an array of resources for update action. | ||
func (f *APIServerSourceUpdateFlags) getUpdateAPIServerResourceArray() ([]v1alpha1.ApiServerResource, []v1alpha1.ApiServerResource, error) { | ||
addedArray, removedArray := util.AddedAndRemovalListsFromArray(f.Resources) | ||
added, err := constructApiServerResourceArray(addedArray) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
removed, err := constructApiServerResourceArray(removedArray) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
return added, removed, nil | ||
} | ||
|
||
func constructApiServerResourceArray(s []string) ([]v1alpha1.ApiServerResource, error) { | ||
array := make([]v1alpha1.ApiServerResource, 0) | ||
for _, r := range s { | ||
resourceSpec, err := getValidResource(r) | ||
if err != nil { | ||
return array, err | ||
} | ||
array = append(array, *resourceSpec) | ||
} | ||
return array, nil | ||
} | ||
|
||
//getValidResource is to parse resource spec from a string | ||
func getValidResource(resource string) (*v1alpha1.ApiServerResource, error) { | ||
var isController bool | ||
var err error | ||
|
||
parts := strings.Split(resource, apiVersionSplitChar) | ||
parts := strings.SplitN(resource, apiVersionSplitChar, 3) | ||
if len(parts[0]) == 0 { | ||
return nil, fmt.Errorf("cannot find 'Kind' part in resource specification %s (expected: <Kind:ApiVersion[:controllerFlag]>", resource) | ||
} | ||
kind := parts[0] | ||
if len(parts) < 2 { | ||
return nil, fmt.Errorf("no APIVersion given for resource %s", resource) | ||
|
||
if len(parts) < 2 || len(parts[1]) == 0 { | ||
return nil, fmt.Errorf("cannot find 'APIVersion' part in resource specification %s (expected: <Kind:ApiVersion[:controllerFlag]>", resource) | ||
} | ||
version := parts[1] | ||
if len(parts) >= 3 { | ||
|
||
if len(parts) >= 3 && len(parts[2]) > 0 { | ||
isController, err = strconv.ParseBool(parts[2]) | ||
if err != nil { | ||
return nil, fmt.Errorf("cannot parse controller flage in resource specification %s", resource) | ||
return nil, fmt.Errorf("controller flag is not a boolean in resource specification %s (expected: <Kind:ApiVersion[:controllerFlag]>)", resource) | ||
} | ||
} else { | ||
isController = false | ||
} | ||
return &resourceSpec{apiVersion: version, kind: kind, isController: isController}, nil | ||
return &v1alpha1.ApiServerResource{Kind: kind, APIVersion: version, Controller: isController}, nil | ||
} | ||
|
||
//Add is to set parameters | ||
|
@@ -95,11 +151,11 @@ func (f *APIServerSourceUpdateFlags) Add(cmd *cobra.Command) { | |
`The mode the receive adapter controller runs under:, | ||
"Ref" sends only the reference to the resource, | ||
"Resource" send the full resource.`) | ||
cmd.Flags().StringSliceVar(&f.Resources, | ||
cmd.Flags().StringArrayVar(&f.Resources, | ||
"resource", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why does the name There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
nil, | ||
`Specification for which events to listen, in the format Kind:APIVersion:isController, e.g. Deployment:apps/v1:true. | ||
"isController" can be omitted and is "false" by default.`) | ||
[]string{}, | ||
`Specification for which events to listen, in the format Kind:APIVersion:isController, e.g. "Event:v1:true". | ||
"isController" can be omitted and is "false" by default, e.g. "Event:v1".`) | ||
} | ||
|
||
// APIServerSourceListHandlers handles printing human readable table for `kn source apiserver list` command's output | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like to move this method to parsing_helper.go to provide a general method
UpdateArray
to update existing array.My question is which type (or key word) I should use to describe a general array here ?
I tried to use []interface{} but I get an error:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's not easily possible, see https://golang.org/doc/faq#convert_slice_of_interface
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What you could do is to introduce a simple utility method which converts an
[]ApiServerResource
to a[]interface{}
and feed that into the generic method like inand do the conversion between ApiServerSource and interfaces slices before and after calling the function. But I don't think its worth the hassle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, ok. Then I keep as it is.
Please review the latest version. I have removed AddResource and RemoveResource from Builder.