k8s1.11 명령줄 - 원본 안내를 실현하는kubectl get 자원 대상 가져오기
8253 단어 k8s1.11 소스 안내
func NewCmdGet(parent string, f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := NewGetOptions(parent, streams)
// cmd get
cmd := &cobra.Command{
Use: "get [(-o|--output=)json|yaml|wide|custom-columns=...|custom-columns-file=...|go-template=...|go-template-file=...|jsonpath=...|jsonpath-file=...] (TYPE[.VERSION][.GROUP] [NAME | -l label] | TYPE[.VERSION][.GROUP]/NAME ...) [flags]",
DisableFlagsInUseLine: true,
Short: i18n.T("Display one or many resources"),
Long: getLong + "
" + cmdutil.SuggestApiResources(parent),
Example: getExample,
//
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(o.Validate(cmd))
//get
cmdutil.CheckErr(o.Run(f, cmd, args))
},
SuggestFor: []string{"list", "ps"},
}
o.PrintFlags.AddFlags(cmd)
// flag , , GetOptions
cmd.Flags().StringVar(&o.Raw, "raw", o.Raw, "Raw URI to request from the server. Uses the transport specified by the kubeconfig file.")
cmd.Flags().BoolVarP(&o.Watch, "watch", "w", o.Watch, "After listing/getting the requested object, watch for changes. Uninitialized objects are excluded if no object name is provided.")
cmd.Flags().BoolVar(&o.WatchOnly, "watch-only", o.WatchOnly, "Watch for changes to the requested object(s), without listing/getting first.")
cmd.Flags().Int64Var(&o.ChunkSize, "chunk-size", o.ChunkSize, "Return large lists in chunks rather than all at once. Pass 0 to disable. This flag is beta and may change in the future.")
cmd.Flags().BoolVar(&o.IgnoreNotFound, "ignore-not-found", o.IgnoreNotFound, "If the requested object does not exist the command will return exit code 0.")
cmd.Flags().StringVarP(&o.LabelSelector, "selector", "l", o.LabelSelector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
cmd.Flags().StringVar(&o.FieldSelector, "field-selector", o.FieldSelector, "Selector (field query) to filter on, supports '=', '==', and '!='.(e.g. --field-selector key1=value1,key2=value2). The server only supports a limited number of field queries per type.")
cmd.Flags().BoolVar(&o.AllNamespaces, "all-namespaces", o.AllNamespaces, "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.")
cmdutil.AddIncludeUninitializedFlag(cmd)
addOpenAPIPrintColumnFlags(cmd, o)
addServerPrintColumnFlags(cmd, o)
cmd.Flags().BoolVar(&o.Export, "export", o.Export, "If true, use 'export' for the resources. Exported resources are stripped of cluster-specific information.")
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, "identifying the resource to get from a server.")
return cmd
}
다음은 Get 명령의 구체적인 실현 함수인 Run을 살펴보겠습니다. Run 함수에서 가장 관건적인 단계는 Build-Visitor 메커니즘의 실현입니다.Build-Visitor 메커니즘이란 무엇입니까?
Builder(작성자 모드): 작성자 모드는 부품과 어셈블리 프로세스를 분리하여 한 단계 한 단계 복잡한 객체를 작성합니다.사용자는 복잡한 대상의 유형만 지정하면 그 대상을 얻을 수 있으며, 그 내부의 구체적인 구조 세부 사항을 알 필요가 없다.
Visitor(방문자 모드): 구조와 데이터를 분리하여 방문자를 작성하여 데이터 구조의 요소에 접근한 다음에 각 요소에 대한 처리를 모두 방문자 클래스에 맡긴다.이렇게 하면 새로운 처리가 필요할 때 새로운 방문자 클래스를 작성하여 데이터 구조가 방문자의 방문을 받아들일 수 있도록 하면 된다.하나의 추상류로 이해할 수 있다. 서로 다른 하위 클래스는 모두 이 추상류를 계승하여 각자의 방문 논리(방문자 클래스)를 실현한 다음에 통일된 인터페이스를 통해 데이터 구조에 대한 접근을 한다.
구체적인 구현 코드는 다음과 같습니다.
r := f.NewBuilder().
Unstructured().
NamespaceParam(o.Namespace).DefaultNamespace().AllNamespaces(o.AllNamespaces).
FilenameParam(o.ExplicitNamespace, &o.FilenameOptions).
LabelSelectorParam(o.LabelSelector).
FieldSelectorParam(o.FieldSelector).
ExportParam(o.Export).
RequestChunksOf(o.ChunkSize).
IncludeUninitialized(o.IncludeUninitialized).
ResourceTypeOrNameArgs(true, args...).
ContinueOnError().
Latest().
Flatten().
TransformRequests(func(req *rest.Request) {
// We need full objects if printing with openapi columns
if o.PrintWithOpenAPICols {
return
}
if o.ServerPrint && o.IsHumanReadablePrinter && !o.Sort {
group := metav1beta1.GroupName
version := metav1beta1.SchemeGroupVersion.Version
tableParam := fmt.Sprintf("application/json;as=Table;v=%s;g=%s, application/json", version, group)
req.SetHeader("Accept", tableParam)
}
}).
Do()
이를 통해 알 수 있듯이 이것은 일련의 체인 함수로 모두 Builder 포인터를 가리키며 아래에 각 함수의 기능을 하나하나 분석한다
여기서 Do 함수에 주목해야 할 사항은 다음과 같습니다.
1. Visitor 구축
2. ApiServer에서 자원 객체를 등록하는 방법
type Result struct {
err error
// Visitor
visitor Visitor
sources []Visitor
singleItemImplied bool
targetsSingleItems bool
mapper *mapper
ignoreErrors []utilerrors.Matcher
// populated by a call to Infos
// info ApiServer
info []*Info
}
func (b *Builder) Do() *Result {
r := b.visitorResult()// Visitor
r.mapper = b.Mapper()
if r.err != nil {
return r
}
if b.flatten {
r.visitor = NewFlattenListVisitor(r.visitor, b.objectTyper, b.mapper)
}
//helpers Visitor
helpers := []VisitorFunc{}
//
if b.defaultNamespace {
helpers = append(helpers, SetNamespace(b.namespace))
}
if b.requireNamespace {
helpers = append(helpers, RequireNamespace(b.namespace))
}
helpers = append(helpers, FilterNamespace)
if b.requireObject {
// Apiserver
//RetrieveLazy helper.go API
helpers = append(helpers, RetrieveLazy)
}
//
r.visitor = NewDecoratedVisitor(r.visitor, helpers...)
if b.continueOnError {
r.visitor = ContinueOnErrorVisitor{r.visitor}
}
return r
}
마지막으로 우리가 얻은 자원 대상을 인쇄하면 됩니다. 인쇄의 구체적인 실현 방식은 여기서 더 이상 자세히 설명하지 않겠습니다.