k8s1.11 명령줄 - 원본 안내를 실현하는kubectl get 자원 대상 가져오기

8253 단어 k8s1.11 소스 안내
이것은kubectl get에서 자원 대상 명령을 가져오는 것을 보십시오. 이것은 New CmdGet 방법에서 이루어집니다
  • GetOptions에 저장된 명령줄에 입력한kubectl get 뒤에 있는 인자 가져오기(예를 들어 --all-namespace, --chunk-size, --output 등)
  • cmd get 명령을 구축하고 get 명령을 등록하는 방법
  • get 명령에 해당하는 파라미터를 추가하여 get 명령의 조작을 제어한다
  • 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 포인터를 가리키며 아래에 각 함수의 기능을 하나하나 분석한다
  • New Builder는 디스크와 서버에서 대상을 불러오는 데 도움이 되고 CLI와 일반 자원의 상호작용을 실현하는 일반적인 모델을 되돌려줍니다.
  • Unstructured는 구조화되지 않은 객체를 요청하고 보낼 수 있도록 빌더를 업데이트합니다.비구조화된 대상은 대상을 바탕으로 하는 JSON 구조로 서버가 보낸 모든 필드를 맵 형식으로 보존합니다. 이것은 클라이언트가 대상을 읽고 쓸 때 데이터를 잃어버리지 않는다는 것을 의미합니다.
  • NamespaceParam,DefaultNamespace,AllNamespaces가 공동으로 자원 대상의 명칭 공간을 확정했다.
  • FilenameParam은 입력을 URL과 파일(파일, 디렉터리, stdIN)으로 나누어 각각 FileVisitor 또는StreamVisitor를 구축하고 밑바닥은 모두StreamVisitor이며 Builder에 추가합니다.path 그룹 중
  • LabelSelectorParam은 로드할 객체 유형에 적용할 선택기를 정의합니다.이것은 디스크나 URL에서 로드된 파일에는 영향을 주지 않습니다.매개변수가 비어 있으면 작업이 없습니다
  • .
  • FieldSelectorParam 기능 동상
  • ExportParam 명령줄에 지정된 --export
  • 수신
  • RequestChunksOf 명령줄에서 지정한 --chunk-size
  • 수신
  • IncludeUninitialized가 이 자원을 받아들인include-uninitialized 브리 값
  • ResourceTypeOrNameArgs 분석 전송된 자원 유형/이름 매개 변수에서 호출된 NormalizeMultipleResourcesargs는 전송된 여러 자원을 자원 모듈로 변환합니다. a, b, c, d는 a/d로 변환하고 b/d, c/d, 예를 들어 get node1 node2는 node/node1로 변환하고 node1은 node2splitourceTypeName는 resource/name에 각각 값을 부여합니다.ResourceTuple {Resource: resource,Name: name} 형식으로 되돌아와 Builder의 ResourceTuples에 저장
  • ContinueOnError는 일부 액세스 반환 오류나 일부 객체가 로드되지 않더라도 가능한 한 많은 객체를 로드하고 액세스하려고 합니다.
  • Latest는 서버의 URL 또는 파일에서 로드된 모든 객체의 최신 사본을 가져옵니다.
  • Flatten은'Items'라는 필드를 가진 모든 대상을 단독 항목으로 변환하고 각각의 항목을 제공한다. 이 필드는runtime이다.Object 호환 유형의 배열입니다.
  • TransformRequests는 Builder에서 시작한 클라이언트의 API 호출 요청을 변경합니다.수식자를 지우기 위해 빈 목록을 전달합니다.
  • Do는 Builder로 식별된 리소스에 액세스하기 위한 Visitor를 포함하는 Result 객체를 반환합니다.

  • 여기서 Do 함수에 주목해야 할 사항은 다음과 같습니다.
    1. Visitor 구축
  • b.path가 비어 있지 않으면 path를 통해 Visitor
  • 를 만듭니다.
  • labelselector 또는fieldselector가 비어 있지 않으면 selector에 따라 Visitor
  • 를 생성합니다
  • ResourceTuples가 비어 있지 않으면 자원 유형과 이름에 따라 Visitor
  • 를 만듭니다.
  • names가 비어 있지 않으면 name에 따라 Visitor
  • 를 만듭니다.
    2. ApiServer에서 자원 객체를 등록하는 방법
  • helper를 구축하여 리셋 함수인 VisitorFunc를 통해 Visitor 인터페이스
  • 를 실현하였다.
  • ApiServer에서 자원 객체를 등록하는 방법RetrieveLazy
  • 등록 반환 데이터에서 자원 정보를 추출하여 발송하는 방법 NewDecoratedVisitor
  • 3. 결과를 result 변수로 되돌려줍니다.result 구조체는 다음과 같습니다.
    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
    }

    마지막으로 우리가 얻은 자원 대상을 인쇄하면 됩니다. 인쇄의 구체적인 실현 방식은 여기서 더 이상 자세히 설명하지 않겠습니다.

    좋은 웹페이지 즐겨찾기