mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Merge pull request #78033 from rajansandeep/corednsmigration
Add the ability to migrate CoreDNS configmap in kubeadm
This commit is contained in:
		
							
								
								
									
										209
									
								
								Godeps/LICENSES
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										209
									
								
								Godeps/LICENSES
									
									
									
										generated
									
									
									
								
							@@ -4231,6 +4231,215 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
================================================================================
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
================================================================================
 | 
			
		||||
= vendor/github.com/coredns/corefile-migration licensed under: =
 | 
			
		||||
 | 
			
		||||
                                 Apache License
 | 
			
		||||
                           Version 2.0, January 2004
 | 
			
		||||
                        http://www.apache.org/licenses/
 | 
			
		||||
 | 
			
		||||
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
			
		||||
 | 
			
		||||
   1. Definitions.
 | 
			
		||||
 | 
			
		||||
      "License" shall mean the terms and conditions for use, reproduction,
 | 
			
		||||
      and distribution as defined by Sections 1 through 9 of this document.
 | 
			
		||||
 | 
			
		||||
      "Licensor" shall mean the copyright owner or entity authorized by
 | 
			
		||||
      the copyright owner that is granting the License.
 | 
			
		||||
 | 
			
		||||
      "Legal Entity" shall mean the union of the acting entity and all
 | 
			
		||||
      other entities that control, are controlled by, or are under common
 | 
			
		||||
      control with that entity. For the purposes of this definition,
 | 
			
		||||
      "control" means (i) the power, direct or indirect, to cause the
 | 
			
		||||
      direction or management of such entity, whether by contract or
 | 
			
		||||
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
			
		||||
      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
			
		||||
 | 
			
		||||
      "You" (or "Your") shall mean an individual or Legal Entity
 | 
			
		||||
      exercising permissions granted by this License.
 | 
			
		||||
 | 
			
		||||
      "Source" form shall mean the preferred form for making modifications,
 | 
			
		||||
      including but not limited to software source code, documentation
 | 
			
		||||
      source, and configuration files.
 | 
			
		||||
 | 
			
		||||
      "Object" form shall mean any form resulting from mechanical
 | 
			
		||||
      transformation or translation of a Source form, including but
 | 
			
		||||
      not limited to compiled object code, generated documentation,
 | 
			
		||||
      and conversions to other media types.
 | 
			
		||||
 | 
			
		||||
      "Work" shall mean the work of authorship, whether in Source or
 | 
			
		||||
      Object form, made available under the License, as indicated by a
 | 
			
		||||
      copyright notice that is included in or attached to the work
 | 
			
		||||
      (an example is provided in the Appendix below).
 | 
			
		||||
 | 
			
		||||
      "Derivative Works" shall mean any work, whether in Source or Object
 | 
			
		||||
      form, that is based on (or derived from) the Work and for which the
 | 
			
		||||
      editorial revisions, annotations, elaborations, or other modifications
 | 
			
		||||
      represent, as a whole, an original work of authorship. For the purposes
 | 
			
		||||
      of this License, Derivative Works shall not include works that remain
 | 
			
		||||
      separable from, or merely link (or bind by name) to the interfaces of,
 | 
			
		||||
      the Work and Derivative Works thereof.
 | 
			
		||||
 | 
			
		||||
      "Contribution" shall mean any work of authorship, including
 | 
			
		||||
      the original version of the Work and any modifications or additions
 | 
			
		||||
      to that Work or Derivative Works thereof, that is intentionally
 | 
			
		||||
      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
			
		||||
      or by an individual or Legal Entity authorized to submit on behalf of
 | 
			
		||||
      the copyright owner. For the purposes of this definition, "submitted"
 | 
			
		||||
      means any form of electronic, verbal, or written communication sent
 | 
			
		||||
      to the Licensor or its representatives, including but not limited to
 | 
			
		||||
      communication on electronic mailing lists, source code control systems,
 | 
			
		||||
      and issue tracking systems that are managed by, or on behalf of, the
 | 
			
		||||
      Licensor for the purpose of discussing and improving the Work, but
 | 
			
		||||
      excluding communication that is conspicuously marked or otherwise
 | 
			
		||||
      designated in writing by the copyright owner as "Not a Contribution."
 | 
			
		||||
 | 
			
		||||
      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
			
		||||
      on behalf of whom a Contribution has been received by Licensor and
 | 
			
		||||
      subsequently incorporated within the Work.
 | 
			
		||||
 | 
			
		||||
   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      copyright license to reproduce, prepare Derivative Works of,
 | 
			
		||||
      publicly display, publicly perform, sublicense, and distribute the
 | 
			
		||||
      Work and such Derivative Works in Source or Object form.
 | 
			
		||||
 | 
			
		||||
   3. Grant of Patent License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      (except as stated in this section) patent license to make, have made,
 | 
			
		||||
      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
			
		||||
      where such license applies only to those patent claims licensable
 | 
			
		||||
      by such Contributor that are necessarily infringed by their
 | 
			
		||||
      Contribution(s) alone or by combination of their Contribution(s)
 | 
			
		||||
      with the Work to which such Contribution(s) was submitted. If You
 | 
			
		||||
      institute patent litigation against any entity (including a
 | 
			
		||||
      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
			
		||||
      or a Contribution incorporated within the Work constitutes direct
 | 
			
		||||
      or contributory patent infringement, then any patent licenses
 | 
			
		||||
      granted to You under this License for that Work shall terminate
 | 
			
		||||
      as of the date such litigation is filed.
 | 
			
		||||
 | 
			
		||||
   4. Redistribution. You may reproduce and distribute copies of the
 | 
			
		||||
      Work or Derivative Works thereof in any medium, with or without
 | 
			
		||||
      modifications, and in Source or Object form, provided that You
 | 
			
		||||
      meet the following conditions:
 | 
			
		||||
 | 
			
		||||
      (a) You must give any other recipients of the Work or
 | 
			
		||||
          Derivative Works a copy of this License; and
 | 
			
		||||
 | 
			
		||||
      (b) You must cause any modified files to carry prominent notices
 | 
			
		||||
          stating that You changed the files; and
 | 
			
		||||
 | 
			
		||||
      (c) You must retain, in the Source form of any Derivative Works
 | 
			
		||||
          that You distribute, all copyright, patent, trademark, and
 | 
			
		||||
          attribution notices from the Source form of the Work,
 | 
			
		||||
          excluding those notices that do not pertain to any part of
 | 
			
		||||
          the Derivative Works; and
 | 
			
		||||
 | 
			
		||||
      (d) If the Work includes a "NOTICE" text file as part of its
 | 
			
		||||
          distribution, then any Derivative Works that You distribute must
 | 
			
		||||
          include a readable copy of the attribution notices contained
 | 
			
		||||
          within such NOTICE file, excluding those notices that do not
 | 
			
		||||
          pertain to any part of the Derivative Works, in at least one
 | 
			
		||||
          of the following places: within a NOTICE text file distributed
 | 
			
		||||
          as part of the Derivative Works; within the Source form or
 | 
			
		||||
          documentation, if provided along with the Derivative Works; or,
 | 
			
		||||
          within a display generated by the Derivative Works, if and
 | 
			
		||||
          wherever such third-party notices normally appear. The contents
 | 
			
		||||
          of the NOTICE file are for informational purposes only and
 | 
			
		||||
          do not modify the License. You may add Your own attribution
 | 
			
		||||
          notices within Derivative Works that You distribute, alongside
 | 
			
		||||
          or as an addendum to the NOTICE text from the Work, provided
 | 
			
		||||
          that such additional attribution notices cannot be construed
 | 
			
		||||
          as modifying the License.
 | 
			
		||||
 | 
			
		||||
      You may add Your own copyright statement to Your modifications and
 | 
			
		||||
      may provide additional or different license terms and conditions
 | 
			
		||||
      for use, reproduction, or distribution of Your modifications, or
 | 
			
		||||
      for any such Derivative Works as a whole, provided Your use,
 | 
			
		||||
      reproduction, and distribution of the Work otherwise complies with
 | 
			
		||||
      the conditions stated in this License.
 | 
			
		||||
 | 
			
		||||
   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
			
		||||
      any Contribution intentionally submitted for inclusion in the Work
 | 
			
		||||
      by You to the Licensor shall be under the terms and conditions of
 | 
			
		||||
      this License, without any additional terms or conditions.
 | 
			
		||||
      Notwithstanding the above, nothing herein shall supersede or modify
 | 
			
		||||
      the terms of any separate license agreement you may have executed
 | 
			
		||||
      with Licensor regarding such Contributions.
 | 
			
		||||
 | 
			
		||||
   6. Trademarks. This License does not grant permission to use the trade
 | 
			
		||||
      names, trademarks, service marks, or product names of the Licensor,
 | 
			
		||||
      except as required for reasonable and customary use in describing the
 | 
			
		||||
      origin of the Work and reproducing the content of the NOTICE file.
 | 
			
		||||
 | 
			
		||||
   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
			
		||||
      agreed to in writing, Licensor provides the Work (and each
 | 
			
		||||
      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
			
		||||
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
      implied, including, without limitation, any warranties or conditions
 | 
			
		||||
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
			
		||||
      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
			
		||||
      appropriateness of using or redistributing the Work and assume any
 | 
			
		||||
      risks associated with Your exercise of permissions under this License.
 | 
			
		||||
 | 
			
		||||
   8. Limitation of Liability. In no event and under no legal theory,
 | 
			
		||||
      whether in tort (including negligence), contract, or otherwise,
 | 
			
		||||
      unless required by applicable law (such as deliberate and grossly
 | 
			
		||||
      negligent acts) or agreed to in writing, shall any Contributor be
 | 
			
		||||
      liable to You for damages, including any direct, indirect, special,
 | 
			
		||||
      incidental, or consequential damages of any character arising as a
 | 
			
		||||
      result of this License or out of the use or inability to use the
 | 
			
		||||
      Work (including but not limited to damages for loss of goodwill,
 | 
			
		||||
      work stoppage, computer failure or malfunction, or any and all
 | 
			
		||||
      other commercial damages or losses), even if such Contributor
 | 
			
		||||
      has been advised of the possibility of such damages.
 | 
			
		||||
 | 
			
		||||
   9. Accepting Warranty or Additional Liability. While redistributing
 | 
			
		||||
      the Work or Derivative Works thereof, You may choose to offer,
 | 
			
		||||
      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
			
		||||
      or other liability obligations and/or rights consistent with this
 | 
			
		||||
      License. However, in accepting such obligations, You may act only
 | 
			
		||||
      on Your own behalf and on Your sole responsibility, not on behalf
 | 
			
		||||
      of any other Contributor, and only if You agree to indemnify,
 | 
			
		||||
      defend, and hold each Contributor harmless for any liability
 | 
			
		||||
      incurred by, or claims asserted against, such Contributor by reason
 | 
			
		||||
      of your accepting any such warranty or additional liability.
 | 
			
		||||
 | 
			
		||||
   END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
   APPENDIX: How to apply the Apache License to your work.
 | 
			
		||||
 | 
			
		||||
      To apply the Apache License to your work, attach the following
 | 
			
		||||
      boilerplate notice, with the fields enclosed by brackets "[]"
 | 
			
		||||
      replaced with your own identifying information. (Don't include
 | 
			
		||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
			
		||||
      comment syntax for the file format. We also recommend that a
 | 
			
		||||
      file or class name and description of purpose be included on the
 | 
			
		||||
      same "printed page" as the copyright notice for easier
 | 
			
		||||
      identification within third-party archives.
 | 
			
		||||
 | 
			
		||||
   Copyright [yyyy] [name of copyright owner]
 | 
			
		||||
 | 
			
		||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
   you may not use this file except in compliance with the License.
 | 
			
		||||
   You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
   Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
   See the License for the specific language governing permissions and
 | 
			
		||||
   limitations under the License.
 | 
			
		||||
 | 
			
		||||
= vendor/github.com/coredns/corefile-migration/LICENSE 86d3f3a95c324c9479bd8986968f4327
 | 
			
		||||
================================================================================
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
================================================================================
 | 
			
		||||
= vendor/github.com/coreos/bbolt licensed under: =
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -73,7 +73,7 @@ dependencies:
 | 
			
		||||
      match: k8s.gcr.io/coredns
 | 
			
		||||
 | 
			
		||||
  - name: "coredns-kubeadm"
 | 
			
		||||
    version: 1.3.1
 | 
			
		||||
    version: 1.5.0
 | 
			
		||||
    refPaths:
 | 
			
		||||
    - path: cmd/kubeadm/app/constants/constants.go
 | 
			
		||||
      match: CoreDNSVersion =
 | 
			
		||||
 
 | 
			
		||||
@@ -101,6 +101,7 @@
 | 
			
		||||
			"AllowedPrefixes": [
 | 
			
		||||
				"github.com/beorn7/perks/quantile",
 | 
			
		||||
				"github.com/blang/semver",
 | 
			
		||||
				"github.com/coredns/corefile-migration/migration",
 | 
			
		||||
				"github.com/coreos/etcd/auth/authpb",
 | 
			
		||||
				"github.com/coreos/etcd/clientv3",
 | 
			
		||||
				"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes",
 | 
			
		||||
 
 | 
			
		||||
@@ -120,7 +120,7 @@ func enforceRequirements(flags *applyPlanFlags, dryRun bool, newK8sVersion strin
 | 
			
		||||
 | 
			
		||||
	// Ensure the user is root
 | 
			
		||||
	klog.V(1).Info("running preflight checks")
 | 
			
		||||
	if err := runPreflightChecks(ignorePreflightErrorsSet); err != nil {
 | 
			
		||||
	if err := runPreflightChecks(client, ignorePreflightErrorsSet, &cfg.ClusterConfiguration); err != nil {
 | 
			
		||||
		return nil, nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -178,9 +178,17 @@ func printConfiguration(clustercfg *kubeadmapi.ClusterConfiguration, w io.Writer
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// runPreflightChecks runs the root preflight check
 | 
			
		||||
func runPreflightChecks(ignorePreflightErrors sets.String) error {
 | 
			
		||||
func runPreflightChecks(client clientset.Interface, ignorePreflightErrors sets.String, cfg *kubeadmapi.ClusterConfiguration) error {
 | 
			
		||||
	fmt.Println("[preflight] Running pre-flight checks.")
 | 
			
		||||
	return preflight.RunRootCheckOnly(ignorePreflightErrors)
 | 
			
		||||
	err := preflight.RunRootCheckOnly(ignorePreflightErrors)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	err = upgrade.RunCoreDNSMigrationCheck(client, ignorePreflightErrors, cfg.DNS.Type)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getClient gets a real or fake client depending on whether the user is dry-running or not
 | 
			
		||||
 
 | 
			
		||||
@@ -333,7 +333,7 @@ const (
 | 
			
		||||
	KubeDNSVersion = "1.14.13"
 | 
			
		||||
 | 
			
		||||
	// CoreDNSVersion is the version of CoreDNS to be deployed if it is used
 | 
			
		||||
	CoreDNSVersion = "1.3.1"
 | 
			
		||||
	CoreDNSVersion = "1.5.0"
 | 
			
		||||
 | 
			
		||||
	// ClusterConfigurationKind is the string kind value for the ClusterConfiguration struct
 | 
			
		||||
	ClusterConfigurationKind = "ClusterConfiguration"
 | 
			
		||||
 
 | 
			
		||||
@@ -44,9 +44,11 @@ go_library(
 | 
			
		||||
        "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/client-go/kubernetes:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library",
 | 
			
		||||
        "//vendor/github.com/caddyserver/caddy/caddyfile:go_default_library",
 | 
			
		||||
        "//vendor/github.com/coredns/corefile-migration/migration:go_default_library",
 | 
			
		||||
        "//vendor/github.com/pkg/errors:go_default_library",
 | 
			
		||||
        "//vendor/k8s.io/klog:go_default_library",
 | 
			
		||||
        "//vendor/k8s.io/utils/net:go_default_library",
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,7 @@ import (
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/caddyserver/caddy/caddyfile"
 | 
			
		||||
	"github.com/coredns/corefile-migration/migration"
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
 | 
			
		||||
	apps "k8s.io/api/apps/v1"
 | 
			
		||||
@@ -31,6 +32,7 @@ import (
 | 
			
		||||
	apierrors "k8s.io/apimachinery/pkg/api/errors"
 | 
			
		||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
			
		||||
	kuberuntime "k8s.io/apimachinery/pkg/runtime"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/types"
 | 
			
		||||
	clientset "k8s.io/client-go/kubernetes"
 | 
			
		||||
	clientsetscheme "k8s.io/client-go/kubernetes/scheme"
 | 
			
		||||
	"k8s.io/klog"
 | 
			
		||||
@@ -228,9 +230,19 @@ func createCoreDNSAddon(deploymentBytes, serviceBytes, configBytes []byte, clien
 | 
			
		||||
		return errors.Wrapf(err, "%s ConfigMap", unableToDecodeCoreDNS)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Create the ConfigMap for CoreDNS or retain it in case it already exists
 | 
			
		||||
	if err := apiclient.CreateOrRetainConfigMap(client, coreDNSConfigMap, kubeadmconstants.CoreDNSConfigMap); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	// Create the ConfigMap for CoreDNS or update/migrate it in case it already exists
 | 
			
		||||
	_, corefile, currentInstalledCoreDNSVersion, err := GetCoreDNSInfo(client)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return errors.Wrap(err, "unable to fetch CoreDNS current installed version and ConfigMap.")
 | 
			
		||||
	}
 | 
			
		||||
	if IsCoreDNSConfigMapMigrationRequired(corefile) {
 | 
			
		||||
		if err := migrateCoreDNSCorefile(client, coreDNSConfigMap, corefile, currentInstalledCoreDNSVersion); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		if err := apiclient.CreateOrUpdateConfigMap(client, coreDNSConfigMap); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	coreDNSClusterRoles := &rbac.ClusterRole{}
 | 
			
		||||
@@ -298,6 +310,102 @@ func createDNSService(dnsService *v1.Service, serviceBytes []byte, client client
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsCoreDNSConfigMapMigrationRequired checks if a migration of the CoreDNS ConfigMap is required.
 | 
			
		||||
func IsCoreDNSConfigMapMigrationRequired(corefile string) bool {
 | 
			
		||||
	if corefile == "" || migration.Default("", corefile) {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func migrateCoreDNSCorefile(client clientset.Interface, cm *v1.ConfigMap, corefile, currentInstalledCoreDNSVersion string) error {
 | 
			
		||||
	// Take a copy of the Corefile data as `Corefile-backup` and update the ConfigMap
 | 
			
		||||
	// Also point the CoreDNS deployment to the `Corefile-backup` data.
 | 
			
		||||
 | 
			
		||||
	if _, err := client.CoreV1().ConfigMaps(cm.ObjectMeta.Namespace).Update(&v1.ConfigMap{
 | 
			
		||||
		ObjectMeta: metav1.ObjectMeta{
 | 
			
		||||
			Name:      kubeadmconstants.CoreDNSConfigMap,
 | 
			
		||||
			Namespace: metav1.NamespaceSystem,
 | 
			
		||||
		},
 | 
			
		||||
		Data: map[string]string{
 | 
			
		||||
			"Corefile":        corefile,
 | 
			
		||||
			"Corefile-backup": corefile,
 | 
			
		||||
		},
 | 
			
		||||
	}); err != nil {
 | 
			
		||||
		return errors.Wrap(err, "unable to update the CoreDNS ConfigMap with backup Corefile")
 | 
			
		||||
	}
 | 
			
		||||
	if err := patchCoreDNSDeployment(client, "Corefile-backup"); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Since the current configuration present is not the default version, try and migrate it.
 | 
			
		||||
	updatedCorefile, err := migration.Migrate(currentInstalledCoreDNSVersion, kubeadmconstants.CoreDNSVersion, corefile, false)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return errors.Wrap(err, "unable to migrate CoreDNS ConfigMap")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if _, err := client.CoreV1().ConfigMaps(cm.ObjectMeta.Namespace).Update(&v1.ConfigMap{
 | 
			
		||||
		ObjectMeta: metav1.ObjectMeta{
 | 
			
		||||
			Name:      kubeadmconstants.CoreDNSConfigMap,
 | 
			
		||||
			Namespace: metav1.NamespaceSystem,
 | 
			
		||||
		},
 | 
			
		||||
		Data: map[string]string{
 | 
			
		||||
			"Corefile":        updatedCorefile,
 | 
			
		||||
			"Corefile-backup": corefile,
 | 
			
		||||
		},
 | 
			
		||||
	}); err != nil {
 | 
			
		||||
		return errors.Wrap(err, "unable to update the CoreDNS ConfigMap")
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Println("[addons]: Migrating CoreDNS Corefile")
 | 
			
		||||
	changes, err := migration.Deprecated(currentInstalledCoreDNSVersion, kubeadmconstants.CoreDNSVersion, corefile)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return errors.Wrap(err, "unable to get list of changes to the configuration.")
 | 
			
		||||
	}
 | 
			
		||||
	// show the migration changes
 | 
			
		||||
	klog.V(2).Infof("the CoreDNS configuration has been migrated and applied: %v.", updatedCorefile)
 | 
			
		||||
	klog.V(2).Infoln("the old migration has been saved in the CoreDNS ConfigMap under the name [Corefile-backup]")
 | 
			
		||||
	klog.V(2).Infoln("The changes in the new CoreDNS Configuration are as follows:")
 | 
			
		||||
	for _, change := range changes {
 | 
			
		||||
		klog.V(2).Infof("%v", change.ToString())
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetCoreDNSInfo gets the current CoreDNS installed and the current Corefile Configuration of CoreDNS.
 | 
			
		||||
func GetCoreDNSInfo(client clientset.Interface) (*v1.ConfigMap, string, string, error) {
 | 
			
		||||
	coreDNSConfigMap, err := client.CoreV1().ConfigMaps(metav1.NamespaceSystem).Get(kubeadmconstants.CoreDNSConfigMap, metav1.GetOptions{})
 | 
			
		||||
	if err != nil && !apierrors.IsNotFound(err) {
 | 
			
		||||
		return nil, "", "", err
 | 
			
		||||
	}
 | 
			
		||||
	if apierrors.IsNotFound(err) {
 | 
			
		||||
		return nil, "", "", nil
 | 
			
		||||
	}
 | 
			
		||||
	corefile, ok := coreDNSConfigMap.Data["Corefile"]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return nil, "", "", errors.New("unable to find the CoreDNS Corefile data")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, currentCoreDNSversion, err := DeployedDNSAddon(client)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, "", "", err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return coreDNSConfigMap, corefile, currentCoreDNSversion, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func patchCoreDNSDeployment(client clientset.Interface, coreDNSCorefileName string) error {
 | 
			
		||||
	dnsDeployment, err := client.AppsV1().Deployments(metav1.NamespaceSystem).Get(kubeadmconstants.CoreDNSDeploymentName, metav1.GetOptions{})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	patch := fmt.Sprintf(`{"spec":{"template":{"spec":{"volumes":[{"name": "config-volume", "configMap":{"name": "coredns", "items":[{"key": "%s", "path": "%s"}]}}]}}}}`, coreDNSCorefileName, coreDNSCorefileName)
 | 
			
		||||
 | 
			
		||||
	if _, err := client.AppsV1().Deployments(dnsDeployment.ObjectMeta.Namespace).Patch(dnsDeployment.Name, types.StrategicMergePatchType, []byte(patch)); err != nil {
 | 
			
		||||
		return errors.Wrap(err, "unable to patch the CoreDNS deployment")
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// translateStubDomainOfKubeDNSToForwardCoreDNS translates StubDomain Data in kube-dns ConfigMap
 | 
			
		||||
// in the form of Proxy for the CoreDNS Corefile.
 | 
			
		||||
func translateStubDomainOfKubeDNSToForwardCoreDNS(dataField string, kubeDNSConfigMap *v1.ConfigMap) (string, error) {
 | 
			
		||||
@@ -351,7 +459,7 @@ func translateStubDomainOfKubeDNSToForwardCoreDNS(dataField string, kubeDNSConfi
 | 
			
		||||
// in the form of Proxy for the CoreDNS Corefile.
 | 
			
		||||
func translateUpstreamNameServerOfKubeDNSToUpstreamForwardCoreDNS(dataField string, kubeDNSConfigMap *v1.ConfigMap) (string, error) {
 | 
			
		||||
	if kubeDNSConfigMap == nil {
 | 
			
		||||
		return "", nil
 | 
			
		||||
		return "/etc/resolv.conf", nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if upstreamValues, ok := kubeDNSConfigMap.Data[dataField]; ok {
 | 
			
		||||
 
 | 
			
		||||
@@ -568,10 +568,11 @@ func TestDeploymentsHaveSystemClusterCriticalPriorityClassName(t *testing.T) {
 | 
			
		||||
		{
 | 
			
		||||
			name:     "CoreDNSDeployment",
 | 
			
		||||
			manifest: CoreDNSDeployment,
 | 
			
		||||
			data: struct{ DeploymentName, Image, ControlPlaneTaintKey string }{
 | 
			
		||||
			data: struct{ DeploymentName, Image, ControlPlaneTaintKey, CoreDNSConfigMapName string }{
 | 
			
		||||
				DeploymentName:       "foo",
 | 
			
		||||
				Image:                "foo",
 | 
			
		||||
				ControlPlaneTaintKey: "foo",
 | 
			
		||||
				CoreDNSConfigMapName: "foo",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
@@ -588,3 +589,150 @@ func TestDeploymentsHaveSystemClusterCriticalPriorityClassName(t *testing.T) {
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestCreateCoreDNSConfigMap(t *testing.T) {
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		name                 string
 | 
			
		||||
		initialCorefileData  string
 | 
			
		||||
		expectedCorefileData string
 | 
			
		||||
		coreDNSVersion       string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			name: "Remove Deprecated options",
 | 
			
		||||
			initialCorefileData: `.:53 {
 | 
			
		||||
        errors
 | 
			
		||||
        health
 | 
			
		||||
        kubernetes cluster.local in-addr.arpa ip6.arpa {
 | 
			
		||||
           pods insecure
 | 
			
		||||
           upstream
 | 
			
		||||
           fallthrough in-addr.arpa ip6.arpa
 | 
			
		||||
           ttl 30
 | 
			
		||||
        }
 | 
			
		||||
        prometheus :9153
 | 
			
		||||
        forward . /etc/resolv.conf
 | 
			
		||||
        cache 30
 | 
			
		||||
        loop
 | 
			
		||||
        reload
 | 
			
		||||
        loadbalance
 | 
			
		||||
    }`,
 | 
			
		||||
			expectedCorefileData: `.:53 {
 | 
			
		||||
    errors
 | 
			
		||||
    health
 | 
			
		||||
    kubernetes cluster.local in-addr.arpa ip6.arpa {
 | 
			
		||||
        pods insecure
 | 
			
		||||
        fallthrough in-addr.arpa ip6.arpa
 | 
			
		||||
        ttl 30
 | 
			
		||||
    }
 | 
			
		||||
    prometheus :9153
 | 
			
		||||
    forward . /etc/resolv.conf
 | 
			
		||||
    cache 30
 | 
			
		||||
    loop
 | 
			
		||||
    reload
 | 
			
		||||
    loadbalance
 | 
			
		||||
    ready
 | 
			
		||||
}
 | 
			
		||||
`,
 | 
			
		||||
			coreDNSVersion: "1.3.1",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "Update proxy plugin to forward plugin",
 | 
			
		||||
			initialCorefileData: `.:53 {
 | 
			
		||||
        errors
 | 
			
		||||
        health
 | 
			
		||||
        kubernetes cluster.local in-addr.arpa ip6.arpa {
 | 
			
		||||
           pods insecure
 | 
			
		||||
           upstream
 | 
			
		||||
           fallthrough in-addr.arpa ip6.arpa
 | 
			
		||||
        }
 | 
			
		||||
        prometheus :9153
 | 
			
		||||
        proxy . /etc/resolv.conf
 | 
			
		||||
        k8s_external example.com
 | 
			
		||||
        cache 30
 | 
			
		||||
        loop
 | 
			
		||||
        reload
 | 
			
		||||
        loadbalance
 | 
			
		||||
    }`,
 | 
			
		||||
			expectedCorefileData: `.:53 {
 | 
			
		||||
    errors
 | 
			
		||||
    health
 | 
			
		||||
    kubernetes cluster.local in-addr.arpa ip6.arpa {
 | 
			
		||||
        pods insecure
 | 
			
		||||
        fallthrough in-addr.arpa ip6.arpa
 | 
			
		||||
    }
 | 
			
		||||
    prometheus :9153
 | 
			
		||||
    forward . /etc/resolv.conf
 | 
			
		||||
    k8s_external example.com
 | 
			
		||||
    cache 30
 | 
			
		||||
    loop
 | 
			
		||||
    reload
 | 
			
		||||
    loadbalance
 | 
			
		||||
    ready
 | 
			
		||||
}
 | 
			
		||||
`,
 | 
			
		||||
			coreDNSVersion: "1.3.1",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tc := range tests {
 | 
			
		||||
		t.Run(tc.name, func(t *testing.T) {
 | 
			
		||||
			client := createClientAndCoreDNSManifest(t, tc.initialCorefileData, tc.coreDNSVersion)
 | 
			
		||||
			// Get the Corefile and installed CoreDNS version.
 | 
			
		||||
			cm, corefile, currentInstalledCoreDNSVersion, err := GetCoreDNSInfo(client)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				t.Fatalf("unable to fetch CoreDNS current installed version and ConfigMap.")
 | 
			
		||||
			}
 | 
			
		||||
			err = migrateCoreDNSCorefile(client, cm, corefile, currentInstalledCoreDNSVersion)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				t.Fatalf("error creating the CoreDNS ConfigMap: %v", err)
 | 
			
		||||
			}
 | 
			
		||||
			migratedConfigMap, _ := client.CoreV1().ConfigMaps(metav1.NamespaceSystem).Get(kubeadmconstants.CoreDNSConfigMap, metav1.GetOptions{})
 | 
			
		||||
			if !strings.EqualFold(migratedConfigMap.Data["Corefile"], tc.expectedCorefileData) {
 | 
			
		||||
				t.Fatalf("expected to get %v, but got %v", tc.expectedCorefileData, migratedConfigMap.Data["Corefile"])
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func createClientAndCoreDNSManifest(t *testing.T, corefile, coreDNSVersion string) *clientsetfake.Clientset {
 | 
			
		||||
	client := clientsetfake.NewSimpleClientset()
 | 
			
		||||
	_, err := client.CoreV1().ConfigMaps(metav1.NamespaceSystem).Create(&v1.ConfigMap{
 | 
			
		||||
		ObjectMeta: metav1.ObjectMeta{
 | 
			
		||||
			Name:      kubeadmconstants.CoreDNSConfigMap,
 | 
			
		||||
			Namespace: metav1.NamespaceSystem,
 | 
			
		||||
		},
 | 
			
		||||
		Data: map[string]string{
 | 
			
		||||
			"Corefile": corefile,
 | 
			
		||||
		},
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatalf("error creating ConfigMap: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	_, err = client.AppsV1().Deployments(metav1.NamespaceSystem).Create(&apps.Deployment{
 | 
			
		||||
		TypeMeta: metav1.TypeMeta{
 | 
			
		||||
			Kind:       "Deployment",
 | 
			
		||||
			APIVersion: "apps/v1",
 | 
			
		||||
		},
 | 
			
		||||
		ObjectMeta: metav1.ObjectMeta{
 | 
			
		||||
			Name:      kubeadmconstants.CoreDNSConfigMap,
 | 
			
		||||
			Namespace: metav1.NamespaceSystem,
 | 
			
		||||
			Labels: map[string]string{
 | 
			
		||||
				"k8s-app": "kube-dns",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		Spec: apps.DeploymentSpec{
 | 
			
		||||
			Template: v1.PodTemplateSpec{
 | 
			
		||||
				Spec: v1.PodSpec{
 | 
			
		||||
					Containers: []v1.Container{
 | 
			
		||||
						{
 | 
			
		||||
							Image: "test:" + coreDNSVersion,
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatalf("error creating deployment: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	return client
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -281,8 +281,8 @@ spec:
 | 
			
		||||
          failureThreshold: 5
 | 
			
		||||
        readinessProbe:
 | 
			
		||||
          httpGet:
 | 
			
		||||
            path: /health
 | 
			
		||||
            port: 8080
 | 
			
		||||
            path: /ready
 | 
			
		||||
            port: 8181
 | 
			
		||||
            scheme: HTTP
 | 
			
		||||
        securityContext:
 | 
			
		||||
          allowPrivilegeEscalation: false
 | 
			
		||||
@@ -314,9 +314,9 @@ data:
 | 
			
		||||
    .:53 {
 | 
			
		||||
        errors
 | 
			
		||||
        health
 | 
			
		||||
        ready
 | 
			
		||||
        kubernetes {{ .DNSDomain }} in-addr.arpa ip6.arpa {
 | 
			
		||||
           pods insecure
 | 
			
		||||
           upstream
 | 
			
		||||
           fallthrough in-addr.arpa ip6.arpa
 | 
			
		||||
           ttl 30
 | 
			
		||||
        }{{ .Federation }}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@ go_library(
 | 
			
		||||
        "health.go",
 | 
			
		||||
        "policy.go",
 | 
			
		||||
        "postupgrade.go",
 | 
			
		||||
        "preflight.go",
 | 
			
		||||
        "prepull.go",
 | 
			
		||||
        "staticpods.go",
 | 
			
		||||
        "versiongetter.go",
 | 
			
		||||
@@ -44,7 +45,9 @@ go_library(
 | 
			
		||||
        "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/apimachinery/pkg/util/version:go_default_library",
 | 
			
		||||
        "//staging/src/k8s.io/client-go/kubernetes:go_default_library",
 | 
			
		||||
        "//vendor/github.com/coredns/corefile-migration/migration:go_default_library",
 | 
			
		||||
        "//vendor/github.com/pkg/errors:go_default_library",
 | 
			
		||||
        "//vendor/k8s.io/klog:go_default_library",
 | 
			
		||||
        "//vendor/k8s.io/utils/pointer:go_default_library",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										114
									
								
								cmd/kubeadm/app/phases/upgrade/preflight.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								cmd/kubeadm/app/phases/upgrade/preflight.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,114 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2019 The Kubernetes Authors.
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package upgrade
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"os"
 | 
			
		||||
 | 
			
		||||
	"github.com/coredns/corefile-migration/migration"
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
 | 
			
		||||
	"k8s.io/apimachinery/pkg/util/sets"
 | 
			
		||||
	clientset "k8s.io/client-go/kubernetes"
 | 
			
		||||
	"k8s.io/klog"
 | 
			
		||||
	kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
 | 
			
		||||
	kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
 | 
			
		||||
	"k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns"
 | 
			
		||||
	"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// CoreDNSCheck validates installed kubelet version
 | 
			
		||||
type CoreDNSCheck struct {
 | 
			
		||||
	name   string
 | 
			
		||||
	client clientset.Interface
 | 
			
		||||
	f      func(clientset.Interface) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Name is part of the preflight.Checker interface
 | 
			
		||||
func (c CoreDNSCheck) Name() string {
 | 
			
		||||
	return c.name
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Check is part of the preflight.Checker interface
 | 
			
		||||
func (c CoreDNSCheck) Check() (warnings, errors []error) {
 | 
			
		||||
	if err := c.f(c.client); err != nil {
 | 
			
		||||
		return nil, []error{err}
 | 
			
		||||
	}
 | 
			
		||||
	return nil, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RunCoreDNSMigrationCheck initializes checks related to CoreDNS migration.
 | 
			
		||||
func RunCoreDNSMigrationCheck(client clientset.Interface, ignorePreflightErrors sets.String, dnsType kubeadmapi.DNSAddOnType) error {
 | 
			
		||||
	if dnsType != kubeadmapi.CoreDNS {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	migrationChecks := []preflight.Checker{
 | 
			
		||||
		&CoreDNSCheck{
 | 
			
		||||
			name:   "CoreDNSUnsupportedPlugins",
 | 
			
		||||
			client: client,
 | 
			
		||||
			f:      checkUnsupportedPlugins,
 | 
			
		||||
		},
 | 
			
		||||
		&CoreDNSCheck{
 | 
			
		||||
			name:   "CoreDNSMigration",
 | 
			
		||||
			client: client,
 | 
			
		||||
			f:      checkMigration,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return preflight.RunChecks(migrationChecks, os.Stderr, ignorePreflightErrors)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// checkUnsupportedPlugins checks if there are any plugins included in the current configuration
 | 
			
		||||
// that are unsupported for migration.
 | 
			
		||||
func checkUnsupportedPlugins(client clientset.Interface) error {
 | 
			
		||||
	klog.V(1).Infoln("validating if there are any unsupported CoreDNS plugins in the Corefile")
 | 
			
		||||
	_, corefile, currentInstalledCoreDNSversion, err := dns.GetCoreDNSInfo(client)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	unsupportedCoreDNS, err := migration.Unsupported(currentInstalledCoreDNSversion, kubeadmconstants.CoreDNSVersion, corefile)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if unsupportedCoreDNS != nil {
 | 
			
		||||
		var UnsupportedPlugins, UnsupportedVersion string
 | 
			
		||||
		for _, unsup := range unsupportedCoreDNS {
 | 
			
		||||
			UnsupportedPlugins = unsup.Plugin
 | 
			
		||||
			UnsupportedVersion = unsup.Version
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
		if UnsupportedPlugins != "" || UnsupportedVersion != "" {
 | 
			
		||||
			return errors.New("there are unsupported plugins in the CoreDNS Corefile")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// checkMigration validates if migration of the current CoreDNS ConfigMap is possible.
 | 
			
		||||
func checkMigration(client clientset.Interface) error {
 | 
			
		||||
	klog.V(1).Infoln("validating if migration can be done for the current CoreDNS release.")
 | 
			
		||||
	_, corefile, currentInstalledCoreDNSversion, err := dns.GetCoreDNSInfo(client)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, err = migration.Migrate(currentInstalledCoreDNSversion, kubeadmconstants.CoreDNSVersion, corefile, false)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										10
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								go.mod
									
									
									
									
									
								
							@@ -25,7 +25,7 @@ require (
 | 
			
		||||
	github.com/bazelbuild/buildtools v0.0.0-20180226164855-80c7f0d45d7e
 | 
			
		||||
	github.com/blang/semver v3.5.0+incompatible
 | 
			
		||||
	github.com/boltdb/bolt v1.3.1 // indirect
 | 
			
		||||
	github.com/caddyserver/caddy v1.0.1
 | 
			
		||||
	github.com/caddyserver/caddy v1.0.3
 | 
			
		||||
	github.com/cespare/prettybench v0.0.0-20150116022406-03b8cfe5406c
 | 
			
		||||
	github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b // indirect
 | 
			
		||||
	github.com/client9/misspell v0.3.4
 | 
			
		||||
@@ -37,6 +37,7 @@ require (
 | 
			
		||||
	github.com/containerd/containerd v1.0.2 // indirect
 | 
			
		||||
	github.com/containerd/typeurl v0.0.0-20190228175220-2a93cfde8c20 // indirect
 | 
			
		||||
	github.com/containernetworking/cni v0.7.1
 | 
			
		||||
	github.com/coredns/corefile-migration v1.0.2
 | 
			
		||||
	github.com/coreos/etcd v3.3.13+incompatible
 | 
			
		||||
	github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7
 | 
			
		||||
	github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea
 | 
			
		||||
@@ -115,7 +116,7 @@ require (
 | 
			
		||||
	github.com/seccomp/libseccomp-golang v0.9.1 // indirect
 | 
			
		||||
	github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a // indirect
 | 
			
		||||
	github.com/spf13/afero v1.2.2
 | 
			
		||||
	github.com/spf13/cobra v0.0.4
 | 
			
		||||
	github.com/spf13/cobra v0.0.5
 | 
			
		||||
	github.com/spf13/jwalterweatherman v1.1.0 // indirect
 | 
			
		||||
	github.com/spf13/pflag v1.0.3
 | 
			
		||||
	github.com/spf13/viper v1.3.2
 | 
			
		||||
@@ -211,7 +212,7 @@ replace (
 | 
			
		||||
	github.com/bifurcation/mint => github.com/bifurcation/mint v0.0.0-20180715133206-93c51c6ce115
 | 
			
		||||
	github.com/blang/semver => github.com/blang/semver v3.5.0+incompatible
 | 
			
		||||
	github.com/boltdb/bolt => github.com/boltdb/bolt v1.3.1
 | 
			
		||||
	github.com/caddyserver/caddy => github.com/caddyserver/caddy v1.0.1
 | 
			
		||||
	github.com/caddyserver/caddy => github.com/caddyserver/caddy v1.0.3
 | 
			
		||||
	github.com/cenkalti/backoff => github.com/cenkalti/backoff v2.1.1+incompatible
 | 
			
		||||
	github.com/cespare/prettybench => github.com/cespare/prettybench v0.0.0-20150116022406-03b8cfe5406c
 | 
			
		||||
	github.com/chai2010/gettext-go => github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5
 | 
			
		||||
@@ -226,6 +227,7 @@ replace (
 | 
			
		||||
	github.com/containerd/containerd => github.com/containerd/containerd v1.0.2
 | 
			
		||||
	github.com/containerd/typeurl => github.com/containerd/typeurl v0.0.0-20190228175220-2a93cfde8c20
 | 
			
		||||
	github.com/containernetworking/cni => github.com/containernetworking/cni v0.7.1
 | 
			
		||||
	github.com/coredns/corefile-migration => github.com/coredns/corefile-migration v1.0.2
 | 
			
		||||
	github.com/coreos/bbolt => github.com/coreos/bbolt v1.3.1-coreos.6
 | 
			
		||||
	github.com/coreos/etcd => github.com/coreos/etcd v3.3.13+incompatible
 | 
			
		||||
	github.com/coreos/go-etcd => github.com/coreos/go-etcd v2.0.0+incompatible
 | 
			
		||||
@@ -387,7 +389,7 @@ replace (
 | 
			
		||||
	github.com/soheilhy/cmux => github.com/soheilhy/cmux v0.1.3
 | 
			
		||||
	github.com/spf13/afero => github.com/spf13/afero v1.2.2
 | 
			
		||||
	github.com/spf13/cast => github.com/spf13/cast v1.3.0
 | 
			
		||||
	github.com/spf13/cobra => github.com/spf13/cobra v0.0.4
 | 
			
		||||
	github.com/spf13/cobra => github.com/spf13/cobra v0.0.5
 | 
			
		||||
	github.com/spf13/jwalterweatherman => github.com/spf13/jwalterweatherman v1.1.0
 | 
			
		||||
	github.com/spf13/pflag => github.com/spf13/pflag v1.0.3
 | 
			
		||||
	github.com/spf13/viper => github.com/spf13/viper v1.3.2
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								go.sum
									
									
									
									
									
								
							@@ -63,8 +63,8 @@ github.com/blang/semver v3.5.0+incompatible h1:CGxCgetQ64DKk7rdZ++Vfnb1+ogGNnB17
 | 
			
		||||
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
 | 
			
		||||
github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
 | 
			
		||||
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
 | 
			
		||||
github.com/caddyserver/caddy v1.0.1 h1:oor6ep+8NoJOabpFXhvjqjfeldtw1XSzfISVrbfqTKo=
 | 
			
		||||
github.com/caddyserver/caddy v1.0.1/go.mod h1:G+ouvOY32gENkJC+jhgl62TyhvqEsFaDiZ4uw0RzP1E=
 | 
			
		||||
github.com/caddyserver/caddy v1.0.3 h1:i9gRhBgvc5ifchwWtSe7pDpsdS9+Q0Rw9oYQmYUTw1w=
 | 
			
		||||
github.com/caddyserver/caddy v1.0.3/go.mod h1:G+ouvOY32gENkJC+jhgl62TyhvqEsFaDiZ4uw0RzP1E=
 | 
			
		||||
github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
 | 
			
		||||
github.com/cespare/prettybench v0.0.0-20150116022406-03b8cfe5406c h1:p8i+qCbr/dNhS2FoQhRpSS7X5+IlxTa94nRNYXu4fyo=
 | 
			
		||||
github.com/cespare/prettybench v0.0.0-20150116022406-03b8cfe5406c/go.mod h1:Xe6ZsFhtM8HrDku0pxJ3/Lr51rwykrzgFwpmTzleatY=
 | 
			
		||||
@@ -91,6 +91,8 @@ github.com/containerd/typeurl v0.0.0-20190228175220-2a93cfde8c20 h1:14r0i3IeJj6z
 | 
			
		||||
github.com/containerd/typeurl v0.0.0-20190228175220-2a93cfde8c20/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
 | 
			
		||||
github.com/containernetworking/cni v0.7.1 h1:fE3r16wpSEyaqY4Z4oFrLMmIGfBYIKpPrHK31EJ9FzE=
 | 
			
		||||
github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
 | 
			
		||||
github.com/coredns/corefile-migration v1.0.2 h1:kQga1ATFIZdkBtU6c/oJdtASLcCRkDh3fW8vVyVdvUc=
 | 
			
		||||
github.com/coredns/corefile-migration v1.0.2/go.mod h1:OFwBp/Wc9dJt5cAZzHWMNhK1r5L0p0jDwIBc6j8NC8E=
 | 
			
		||||
github.com/coreos/bbolt v1.3.1-coreos.6 h1:uTXKg9gY70s9jMAKdfljFQcuh4e/BXOM+V+d00KFj3A=
 | 
			
		||||
github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
 | 
			
		||||
github.com/coreos/etcd v3.3.13+incompatible h1:8F3hqu9fGYLBifCmRCJsicFqDx/D68Rt3q1JMazcgBQ=
 | 
			
		||||
@@ -389,8 +391,8 @@ github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
 | 
			
		||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
 | 
			
		||||
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
 | 
			
		||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 | 
			
		||||
github.com/spf13/cobra v0.0.4 h1:S0tLZ3VOKl2Te0hpq8+ke0eSJPfCnNTPiDlsfwi1/NE=
 | 
			
		||||
github.com/spf13/cobra v0.0.4/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
 | 
			
		||||
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
 | 
			
		||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
 | 
			
		||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
 | 
			
		||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
 | 
			
		||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@ require (
 | 
			
		||||
	github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d
 | 
			
		||||
	github.com/pborman/uuid v1.2.0
 | 
			
		||||
	github.com/prometheus/client_golang v0.9.2
 | 
			
		||||
	github.com/spf13/cobra v0.0.4
 | 
			
		||||
	github.com/spf13/cobra v0.0.5
 | 
			
		||||
	github.com/spf13/pflag v1.0.3
 | 
			
		||||
	github.com/stretchr/testify v1.3.0
 | 
			
		||||
	gopkg.in/yaml.v2 v2.2.2
 | 
			
		||||
 
 | 
			
		||||
@@ -230,8 +230,8 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B
 | 
			
		||||
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
 | 
			
		||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
 | 
			
		||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 | 
			
		||||
github.com/spf13/cobra v0.0.4 h1:S0tLZ3VOKl2Te0hpq8+ke0eSJPfCnNTPiDlsfwi1/NE=
 | 
			
		||||
github.com/spf13/cobra v0.0.4/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
 | 
			
		||||
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
 | 
			
		||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
 | 
			
		||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
 | 
			
		||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 | 
			
		||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ require (
 | 
			
		||||
	github.com/ghodss/yaml v0.0.0-20180820084758-c7ce16629ff4 // indirect
 | 
			
		||||
	github.com/go-openapi/spec v0.19.2 // indirect
 | 
			
		||||
	github.com/pkg/errors v0.8.0
 | 
			
		||||
	github.com/spf13/cobra v0.0.4
 | 
			
		||||
	github.com/spf13/cobra v0.0.5
 | 
			
		||||
	github.com/spf13/pflag v1.0.3
 | 
			
		||||
	github.com/stretchr/testify v1.3.0
 | 
			
		||||
	golang.org/x/text v0.3.2
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								staging/src/k8s.io/cli-runtime/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								staging/src/k8s.io/cli-runtime/go.sum
									
									
									
										generated
									
									
									
								
							@@ -123,8 +123,8 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR
 | 
			
		||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
 | 
			
		||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
 | 
			
		||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 | 
			
		||||
github.com/spf13/cobra v0.0.4 h1:S0tLZ3VOKl2Te0hpq8+ke0eSJPfCnNTPiDlsfwi1/NE=
 | 
			
		||||
github.com/spf13/cobra v0.0.4/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
 | 
			
		||||
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
 | 
			
		||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
 | 
			
		||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
 | 
			
		||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 | 
			
		||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ require (
 | 
			
		||||
	github.com/go-openapi/spec v0.19.2
 | 
			
		||||
	github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d
 | 
			
		||||
	github.com/prometheus/client_golang v0.9.2
 | 
			
		||||
	github.com/spf13/cobra v0.0.4
 | 
			
		||||
	github.com/spf13/cobra v0.0.5
 | 
			
		||||
	github.com/spf13/pflag v1.0.3
 | 
			
		||||
	github.com/stretchr/testify v1.3.0
 | 
			
		||||
	golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								staging/src/k8s.io/kube-aggregator/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								staging/src/k8s.io/kube-aggregator/go.sum
									
									
									
										generated
									
									
									
								
							@@ -186,8 +186,8 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B
 | 
			
		||||
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
 | 
			
		||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
 | 
			
		||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 | 
			
		||||
github.com/spf13/cobra v0.0.4 h1:S0tLZ3VOKl2Te0hpq8+ke0eSJPfCnNTPiDlsfwi1/NE=
 | 
			
		||||
github.com/spf13/cobra v0.0.4/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
 | 
			
		||||
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
 | 
			
		||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
 | 
			
		||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
 | 
			
		||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 | 
			
		||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,7 @@ require (
 | 
			
		||||
	github.com/opencontainers/go-digest v1.0.0-rc1 // indirect
 | 
			
		||||
	github.com/russross/blackfriday v1.5.2
 | 
			
		||||
	github.com/sirupsen/logrus v1.4.2 // indirect
 | 
			
		||||
	github.com/spf13/cobra v0.0.4
 | 
			
		||||
	github.com/spf13/cobra v0.0.5
 | 
			
		||||
	github.com/spf13/pflag v1.0.3
 | 
			
		||||
	github.com/stretchr/testify v1.3.0
 | 
			
		||||
	golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								staging/src/k8s.io/kubectl/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								staging/src/k8s.io/kubectl/go.sum
									
									
									
										generated
									
									
									
								
							@@ -173,8 +173,8 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd
 | 
			
		||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
 | 
			
		||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
 | 
			
		||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 | 
			
		||||
github.com/spf13/cobra v0.0.4 h1:S0tLZ3VOKl2Te0hpq8+ke0eSJPfCnNTPiDlsfwi1/NE=
 | 
			
		||||
github.com/spf13/cobra v0.0.4/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
 | 
			
		||||
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
 | 
			
		||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
 | 
			
		||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
 | 
			
		||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 | 
			
		||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ go 1.12
 | 
			
		||||
require (
 | 
			
		||||
	github.com/go-openapi/spec v0.19.2
 | 
			
		||||
	github.com/google/gofuzz v1.0.0
 | 
			
		||||
	github.com/spf13/cobra v0.0.4
 | 
			
		||||
	github.com/spf13/cobra v0.0.5
 | 
			
		||||
	k8s.io/apimachinery v0.0.0
 | 
			
		||||
	k8s.io/apiserver v0.0.0
 | 
			
		||||
	k8s.io/client-go v0.0.0
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								staging/src/k8s.io/sample-apiserver/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								staging/src/k8s.io/sample-apiserver/go.sum
									
									
									
										generated
									
									
									
								
							@@ -183,8 +183,8 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B
 | 
			
		||||
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
 | 
			
		||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
 | 
			
		||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 | 
			
		||||
github.com/spf13/cobra v0.0.4 h1:S0tLZ3VOKl2Te0hpq8+ke0eSJPfCnNTPiDlsfwi1/NE=
 | 
			
		||||
github.com/spf13/cobra v0.0.4/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
 | 
			
		||||
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
 | 
			
		||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
 | 
			
		||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
 | 
			
		||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 | 
			
		||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ module k8s.io/sample-cli-plugin
 | 
			
		||||
go 1.12
 | 
			
		||||
 | 
			
		||||
require (
 | 
			
		||||
	github.com/spf13/cobra v0.0.4
 | 
			
		||||
	github.com/spf13/cobra v0.0.5
 | 
			
		||||
	github.com/spf13/pflag v1.0.3
 | 
			
		||||
	k8s.io/cli-runtime v0.0.0
 | 
			
		||||
	k8s.io/client-go v0.0.0
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								staging/src/k8s.io/sample-cli-plugin/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								staging/src/k8s.io/sample-cli-plugin/go.sum
									
									
									
										generated
									
									
									
								
							@@ -123,8 +123,8 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR
 | 
			
		||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
 | 
			
		||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
 | 
			
		||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 | 
			
		||||
github.com/spf13/cobra v0.0.4 h1:S0tLZ3VOKl2Te0hpq8+ke0eSJPfCnNTPiDlsfwi1/NE=
 | 
			
		||||
github.com/spf13/cobra v0.0.4/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
 | 
			
		||||
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
 | 
			
		||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
 | 
			
		||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
 | 
			
		||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 | 
			
		||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								vendor/BUILD
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/BUILD
									
									
									
									
										vendored
									
									
								
							@@ -101,6 +101,7 @@ filegroup(
 | 
			
		||||
        "//vendor/github.com/containernetworking/cni/pkg/invoke:all-srcs",
 | 
			
		||||
        "//vendor/github.com/containernetworking/cni/pkg/types:all-srcs",
 | 
			
		||||
        "//vendor/github.com/containernetworking/cni/pkg/version:all-srcs",
 | 
			
		||||
        "//vendor/github.com/coredns/corefile-migration/migration:all-srcs",
 | 
			
		||||
        "//vendor/github.com/coreos/bbolt:all-srcs",
 | 
			
		||||
        "//vendor/github.com/coreos/etcd/alarm:all-srcs",
 | 
			
		||||
        "//vendor/github.com/coreos/etcd/auth:all-srcs",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										201
									
								
								vendor/github.com/coredns/corefile-migration/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								vendor/github.com/coredns/corefile-migration/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,201 @@
 | 
			
		||||
                                 Apache License
 | 
			
		||||
                           Version 2.0, January 2004
 | 
			
		||||
                        http://www.apache.org/licenses/
 | 
			
		||||
 | 
			
		||||
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
			
		||||
 | 
			
		||||
   1. Definitions.
 | 
			
		||||
 | 
			
		||||
      "License" shall mean the terms and conditions for use, reproduction,
 | 
			
		||||
      and distribution as defined by Sections 1 through 9 of this document.
 | 
			
		||||
 | 
			
		||||
      "Licensor" shall mean the copyright owner or entity authorized by
 | 
			
		||||
      the copyright owner that is granting the License.
 | 
			
		||||
 | 
			
		||||
      "Legal Entity" shall mean the union of the acting entity and all
 | 
			
		||||
      other entities that control, are controlled by, or are under common
 | 
			
		||||
      control with that entity. For the purposes of this definition,
 | 
			
		||||
      "control" means (i) the power, direct or indirect, to cause the
 | 
			
		||||
      direction or management of such entity, whether by contract or
 | 
			
		||||
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
			
		||||
      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
			
		||||
 | 
			
		||||
      "You" (or "Your") shall mean an individual or Legal Entity
 | 
			
		||||
      exercising permissions granted by this License.
 | 
			
		||||
 | 
			
		||||
      "Source" form shall mean the preferred form for making modifications,
 | 
			
		||||
      including but not limited to software source code, documentation
 | 
			
		||||
      source, and configuration files.
 | 
			
		||||
 | 
			
		||||
      "Object" form shall mean any form resulting from mechanical
 | 
			
		||||
      transformation or translation of a Source form, including but
 | 
			
		||||
      not limited to compiled object code, generated documentation,
 | 
			
		||||
      and conversions to other media types.
 | 
			
		||||
 | 
			
		||||
      "Work" shall mean the work of authorship, whether in Source or
 | 
			
		||||
      Object form, made available under the License, as indicated by a
 | 
			
		||||
      copyright notice that is included in or attached to the work
 | 
			
		||||
      (an example is provided in the Appendix below).
 | 
			
		||||
 | 
			
		||||
      "Derivative Works" shall mean any work, whether in Source or Object
 | 
			
		||||
      form, that is based on (or derived from) the Work and for which the
 | 
			
		||||
      editorial revisions, annotations, elaborations, or other modifications
 | 
			
		||||
      represent, as a whole, an original work of authorship. For the purposes
 | 
			
		||||
      of this License, Derivative Works shall not include works that remain
 | 
			
		||||
      separable from, or merely link (or bind by name) to the interfaces of,
 | 
			
		||||
      the Work and Derivative Works thereof.
 | 
			
		||||
 | 
			
		||||
      "Contribution" shall mean any work of authorship, including
 | 
			
		||||
      the original version of the Work and any modifications or additions
 | 
			
		||||
      to that Work or Derivative Works thereof, that is intentionally
 | 
			
		||||
      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
			
		||||
      or by an individual or Legal Entity authorized to submit on behalf of
 | 
			
		||||
      the copyright owner. For the purposes of this definition, "submitted"
 | 
			
		||||
      means any form of electronic, verbal, or written communication sent
 | 
			
		||||
      to the Licensor or its representatives, including but not limited to
 | 
			
		||||
      communication on electronic mailing lists, source code control systems,
 | 
			
		||||
      and issue tracking systems that are managed by, or on behalf of, the
 | 
			
		||||
      Licensor for the purpose of discussing and improving the Work, but
 | 
			
		||||
      excluding communication that is conspicuously marked or otherwise
 | 
			
		||||
      designated in writing by the copyright owner as "Not a Contribution."
 | 
			
		||||
 | 
			
		||||
      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
			
		||||
      on behalf of whom a Contribution has been received by Licensor and
 | 
			
		||||
      subsequently incorporated within the Work.
 | 
			
		||||
 | 
			
		||||
   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      copyright license to reproduce, prepare Derivative Works of,
 | 
			
		||||
      publicly display, publicly perform, sublicense, and distribute the
 | 
			
		||||
      Work and such Derivative Works in Source or Object form.
 | 
			
		||||
 | 
			
		||||
   3. Grant of Patent License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      (except as stated in this section) patent license to make, have made,
 | 
			
		||||
      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
			
		||||
      where such license applies only to those patent claims licensable
 | 
			
		||||
      by such Contributor that are necessarily infringed by their
 | 
			
		||||
      Contribution(s) alone or by combination of their Contribution(s)
 | 
			
		||||
      with the Work to which such Contribution(s) was submitted. If You
 | 
			
		||||
      institute patent litigation against any entity (including a
 | 
			
		||||
      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
			
		||||
      or a Contribution incorporated within the Work constitutes direct
 | 
			
		||||
      or contributory patent infringement, then any patent licenses
 | 
			
		||||
      granted to You under this License for that Work shall terminate
 | 
			
		||||
      as of the date such litigation is filed.
 | 
			
		||||
 | 
			
		||||
   4. Redistribution. You may reproduce and distribute copies of the
 | 
			
		||||
      Work or Derivative Works thereof in any medium, with or without
 | 
			
		||||
      modifications, and in Source or Object form, provided that You
 | 
			
		||||
      meet the following conditions:
 | 
			
		||||
 | 
			
		||||
      (a) You must give any other recipients of the Work or
 | 
			
		||||
          Derivative Works a copy of this License; and
 | 
			
		||||
 | 
			
		||||
      (b) You must cause any modified files to carry prominent notices
 | 
			
		||||
          stating that You changed the files; and
 | 
			
		||||
 | 
			
		||||
      (c) You must retain, in the Source form of any Derivative Works
 | 
			
		||||
          that You distribute, all copyright, patent, trademark, and
 | 
			
		||||
          attribution notices from the Source form of the Work,
 | 
			
		||||
          excluding those notices that do not pertain to any part of
 | 
			
		||||
          the Derivative Works; and
 | 
			
		||||
 | 
			
		||||
      (d) If the Work includes a "NOTICE" text file as part of its
 | 
			
		||||
          distribution, then any Derivative Works that You distribute must
 | 
			
		||||
          include a readable copy of the attribution notices contained
 | 
			
		||||
          within such NOTICE file, excluding those notices that do not
 | 
			
		||||
          pertain to any part of the Derivative Works, in at least one
 | 
			
		||||
          of the following places: within a NOTICE text file distributed
 | 
			
		||||
          as part of the Derivative Works; within the Source form or
 | 
			
		||||
          documentation, if provided along with the Derivative Works; or,
 | 
			
		||||
          within a display generated by the Derivative Works, if and
 | 
			
		||||
          wherever such third-party notices normally appear. The contents
 | 
			
		||||
          of the NOTICE file are for informational purposes only and
 | 
			
		||||
          do not modify the License. You may add Your own attribution
 | 
			
		||||
          notices within Derivative Works that You distribute, alongside
 | 
			
		||||
          or as an addendum to the NOTICE text from the Work, provided
 | 
			
		||||
          that such additional attribution notices cannot be construed
 | 
			
		||||
          as modifying the License.
 | 
			
		||||
 | 
			
		||||
      You may add Your own copyright statement to Your modifications and
 | 
			
		||||
      may provide additional or different license terms and conditions
 | 
			
		||||
      for use, reproduction, or distribution of Your modifications, or
 | 
			
		||||
      for any such Derivative Works as a whole, provided Your use,
 | 
			
		||||
      reproduction, and distribution of the Work otherwise complies with
 | 
			
		||||
      the conditions stated in this License.
 | 
			
		||||
 | 
			
		||||
   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
			
		||||
      any Contribution intentionally submitted for inclusion in the Work
 | 
			
		||||
      by You to the Licensor shall be under the terms and conditions of
 | 
			
		||||
      this License, without any additional terms or conditions.
 | 
			
		||||
      Notwithstanding the above, nothing herein shall supersede or modify
 | 
			
		||||
      the terms of any separate license agreement you may have executed
 | 
			
		||||
      with Licensor regarding such Contributions.
 | 
			
		||||
 | 
			
		||||
   6. Trademarks. This License does not grant permission to use the trade
 | 
			
		||||
      names, trademarks, service marks, or product names of the Licensor,
 | 
			
		||||
      except as required for reasonable and customary use in describing the
 | 
			
		||||
      origin of the Work and reproducing the content of the NOTICE file.
 | 
			
		||||
 | 
			
		||||
   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
			
		||||
      agreed to in writing, Licensor provides the Work (and each
 | 
			
		||||
      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
			
		||||
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
      implied, including, without limitation, any warranties or conditions
 | 
			
		||||
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
			
		||||
      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
			
		||||
      appropriateness of using or redistributing the Work and assume any
 | 
			
		||||
      risks associated with Your exercise of permissions under this License.
 | 
			
		||||
 | 
			
		||||
   8. Limitation of Liability. In no event and under no legal theory,
 | 
			
		||||
      whether in tort (including negligence), contract, or otherwise,
 | 
			
		||||
      unless required by applicable law (such as deliberate and grossly
 | 
			
		||||
      negligent acts) or agreed to in writing, shall any Contributor be
 | 
			
		||||
      liable to You for damages, including any direct, indirect, special,
 | 
			
		||||
      incidental, or consequential damages of any character arising as a
 | 
			
		||||
      result of this License or out of the use or inability to use the
 | 
			
		||||
      Work (including but not limited to damages for loss of goodwill,
 | 
			
		||||
      work stoppage, computer failure or malfunction, or any and all
 | 
			
		||||
      other commercial damages or losses), even if such Contributor
 | 
			
		||||
      has been advised of the possibility of such damages.
 | 
			
		||||
 | 
			
		||||
   9. Accepting Warranty or Additional Liability. While redistributing
 | 
			
		||||
      the Work or Derivative Works thereof, You may choose to offer,
 | 
			
		||||
      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
			
		||||
      or other liability obligations and/or rights consistent with this
 | 
			
		||||
      License. However, in accepting such obligations, You may act only
 | 
			
		||||
      on Your own behalf and on Your sole responsibility, not on behalf
 | 
			
		||||
      of any other Contributor, and only if You agree to indemnify,
 | 
			
		||||
      defend, and hold each Contributor harmless for any liability
 | 
			
		||||
      incurred by, or claims asserted against, such Contributor by reason
 | 
			
		||||
      of your accepting any such warranty or additional liability.
 | 
			
		||||
 | 
			
		||||
   END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
   APPENDIX: How to apply the Apache License to your work.
 | 
			
		||||
 | 
			
		||||
      To apply the Apache License to your work, attach the following
 | 
			
		||||
      boilerplate notice, with the fields enclosed by brackets "[]"
 | 
			
		||||
      replaced with your own identifying information. (Don't include
 | 
			
		||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
			
		||||
      comment syntax for the file format. We also recommend that a
 | 
			
		||||
      file or class name and description of purpose be included on the
 | 
			
		||||
      same "printed page" as the copyright notice for easier
 | 
			
		||||
      identification within third-party archives.
 | 
			
		||||
 | 
			
		||||
   Copyright [yyyy] [name of copyright owner]
 | 
			
		||||
 | 
			
		||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
   you may not use this file except in compliance with the License.
 | 
			
		||||
   You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
   Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
   See the License for the specific language governing permissions and
 | 
			
		||||
   limitations under the License.
 | 
			
		||||
							
								
								
									
										31
									
								
								vendor/github.com/coredns/corefile-migration/migration/BUILD
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								vendor/github.com/coredns/corefile-migration/migration/BUILD
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
 | 
			
		||||
 | 
			
		||||
go_library(
 | 
			
		||||
    name = "go_default_library",
 | 
			
		||||
    srcs = [
 | 
			
		||||
        "migrate.go",
 | 
			
		||||
        "notice.go",
 | 
			
		||||
        "versions.go",
 | 
			
		||||
    ],
 | 
			
		||||
    importmap = "k8s.io/kubernetes/vendor/github.com/coredns/corefile-migration/migration",
 | 
			
		||||
    importpath = "github.com/coredns/corefile-migration/migration",
 | 
			
		||||
    visibility = ["//visibility:public"],
 | 
			
		||||
    deps = ["//vendor/github.com/coredns/corefile-migration/migration/corefile:go_default_library"],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
filegroup(
 | 
			
		||||
    name = "package-srcs",
 | 
			
		||||
    srcs = glob(["**"]),
 | 
			
		||||
    tags = ["automanaged"],
 | 
			
		||||
    visibility = ["//visibility:private"],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
filegroup(
 | 
			
		||||
    name = "all-srcs",
 | 
			
		||||
    srcs = [
 | 
			
		||||
        ":package-srcs",
 | 
			
		||||
        "//vendor/github.com/coredns/corefile-migration/migration/corefile:all-srcs",
 | 
			
		||||
    ],
 | 
			
		||||
    tags = ["automanaged"],
 | 
			
		||||
    visibility = ["//visibility:public"],
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										24
									
								
								vendor/github.com/coredns/corefile-migration/migration/corefile/BUILD
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								vendor/github.com/coredns/corefile-migration/migration/corefile/BUILD
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
 | 
			
		||||
 | 
			
		||||
go_library(
 | 
			
		||||
    name = "go_default_library",
 | 
			
		||||
    srcs = ["corefile.go"],
 | 
			
		||||
    importmap = "k8s.io/kubernetes/vendor/github.com/coredns/corefile-migration/migration/corefile",
 | 
			
		||||
    importpath = "github.com/coredns/corefile-migration/migration/corefile",
 | 
			
		||||
    visibility = ["//visibility:public"],
 | 
			
		||||
    deps = ["//vendor/github.com/caddyserver/caddy/caddyfile:go_default_library"],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
filegroup(
 | 
			
		||||
    name = "package-srcs",
 | 
			
		||||
    srcs = glob(["**"]),
 | 
			
		||||
    tags = ["automanaged"],
 | 
			
		||||
    visibility = ["//visibility:private"],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
filegroup(
 | 
			
		||||
    name = "all-srcs",
 | 
			
		||||
    srcs = [":package-srcs"],
 | 
			
		||||
    tags = ["automanaged"],
 | 
			
		||||
    visibility = ["//visibility:public"],
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										179
									
								
								vendor/github.com/coredns/corefile-migration/migration/corefile/corefile.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								vendor/github.com/coredns/corefile-migration/migration/corefile/corefile.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,179 @@
 | 
			
		||||
package corefile
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/caddyserver/caddy/caddyfile"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Corefile struct {
 | 
			
		||||
	Servers []*Server
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Server struct {
 | 
			
		||||
	DomPorts []string
 | 
			
		||||
	Plugins  []*Plugin
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Plugin struct {
 | 
			
		||||
	Name    string
 | 
			
		||||
	Args    []string
 | 
			
		||||
	Options []*Option
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Option struct {
 | 
			
		||||
	Name string
 | 
			
		||||
	Args []string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func New(s string) (*Corefile, error) {
 | 
			
		||||
	c := Corefile{}
 | 
			
		||||
	cc := caddyfile.NewDispenser("migration", strings.NewReader(s))
 | 
			
		||||
	depth := 0
 | 
			
		||||
	var cSvr *Server
 | 
			
		||||
	var cPlg *Plugin
 | 
			
		||||
	for cc.Next() {
 | 
			
		||||
		if cc.Val() == "{" {
 | 
			
		||||
			depth += 1
 | 
			
		||||
			continue
 | 
			
		||||
		} else if cc.Val() == "}" {
 | 
			
		||||
			depth -= 1
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		val := cc.Val()
 | 
			
		||||
		args := cc.RemainingArgs()
 | 
			
		||||
		switch depth {
 | 
			
		||||
		case 0:
 | 
			
		||||
			c.Servers = append(c.Servers,
 | 
			
		||||
				&Server{
 | 
			
		||||
					DomPorts: append([]string{val}, args...),
 | 
			
		||||
				})
 | 
			
		||||
			cSvr = c.Servers[len(c.Servers)-1]
 | 
			
		||||
		case 1:
 | 
			
		||||
			cSvr.Plugins = append(cSvr.Plugins,
 | 
			
		||||
				&Plugin{
 | 
			
		||||
					Name: val,
 | 
			
		||||
					Args: args,
 | 
			
		||||
				})
 | 
			
		||||
			cPlg = cSvr.Plugins[len(cSvr.Plugins)-1]
 | 
			
		||||
		case 2:
 | 
			
		||||
			cPlg.Options = append(cPlg.Options,
 | 
			
		||||
				&Option{
 | 
			
		||||
					Name: val,
 | 
			
		||||
					Args: args,
 | 
			
		||||
				})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return &c, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Corefile) ToString() (out string) {
 | 
			
		||||
	strs := []string{}
 | 
			
		||||
	for _, s := range c.Servers {
 | 
			
		||||
		strs = append(strs, s.ToString())
 | 
			
		||||
	}
 | 
			
		||||
	return strings.Join(strs, "\n")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Server) ToString() (out string) {
 | 
			
		||||
	str := strings.Join(s.DomPorts, " ")
 | 
			
		||||
	strs := []string{}
 | 
			
		||||
	for _, p := range s.Plugins {
 | 
			
		||||
		strs = append(strs, strings.Repeat(" ", indent)+p.ToString())
 | 
			
		||||
	}
 | 
			
		||||
	if len(strs) > 0 {
 | 
			
		||||
		str += " {\n" + strings.Join(strs, "\n") + "\n}\n"
 | 
			
		||||
	}
 | 
			
		||||
	return str
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Plugin) ToString() (out string) {
 | 
			
		||||
	str := strings.Join(append([]string{p.Name}, p.Args...), " ")
 | 
			
		||||
	strs := []string{}
 | 
			
		||||
	for _, o := range p.Options {
 | 
			
		||||
		strs = append(strs, strings.Repeat(" ", indent*2)+o.ToString())
 | 
			
		||||
	}
 | 
			
		||||
	if len(strs) > 0 {
 | 
			
		||||
		str += " {\n" + strings.Join(strs, "\n") + "\n" + strings.Repeat(" ", indent*1) + "}"
 | 
			
		||||
	}
 | 
			
		||||
	return str
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o *Option) ToString() (out string) {
 | 
			
		||||
	str := strings.Join(append([]string{o.Name}, o.Args...), " ")
 | 
			
		||||
	return str
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Server) FindMatch(def []*Server) (*Server, bool) {
 | 
			
		||||
NextServer:
 | 
			
		||||
	for _, sDef := range def {
 | 
			
		||||
		for i, dp := range sDef.DomPorts {
 | 
			
		||||
			if dp == "*" {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			if dp == "***" {
 | 
			
		||||
				return sDef, true
 | 
			
		||||
			}
 | 
			
		||||
			if i >= len(s.DomPorts) || dp != s.DomPorts[i] {
 | 
			
		||||
				continue NextServer
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if len(sDef.DomPorts) != len(s.DomPorts) {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		return sDef, true
 | 
			
		||||
	}
 | 
			
		||||
	return nil, false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Plugin) FindMatch(def []*Plugin) (*Plugin, bool) {
 | 
			
		||||
NextPlugin:
 | 
			
		||||
	for _, pDef := range def {
 | 
			
		||||
		if pDef.Name != p.Name {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		for i, arg := range pDef.Args {
 | 
			
		||||
			if arg == "*" {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			if arg == "***" {
 | 
			
		||||
				return pDef, true
 | 
			
		||||
			}
 | 
			
		||||
			if i >= len(p.Args) || arg != p.Args[i] {
 | 
			
		||||
				continue NextPlugin
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if len(pDef.Args) != len(p.Args) {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		return pDef, true
 | 
			
		||||
	}
 | 
			
		||||
	return nil, false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o *Option) FindMatch(def []*Option) (*Option, bool) {
 | 
			
		||||
NextPlugin:
 | 
			
		||||
	for _, oDef := range def {
 | 
			
		||||
		if oDef.Name != o.Name {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		for i, arg := range oDef.Args {
 | 
			
		||||
			if arg == "*" {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			if arg == "***" {
 | 
			
		||||
				return oDef, true
 | 
			
		||||
			}
 | 
			
		||||
			if i >= len(o.Args) || arg != o.Args[i] {
 | 
			
		||||
				continue NextPlugin
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if len(oDef.Args) != len(o.Args) {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		return oDef, true
 | 
			
		||||
	}
 | 
			
		||||
	return nil, false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const indent = 4
 | 
			
		||||
							
								
								
									
										445
									
								
								vendor/github.com/coredns/corefile-migration/migration/migrate.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										445
									
								
								vendor/github.com/coredns/corefile-migration/migration/migrate.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,445 @@
 | 
			
		||||
package migration
 | 
			
		||||
 | 
			
		||||
// This package provides a set of functions to help handle migrations of CoreDNS Corefiles to be compatible with new
 | 
			
		||||
// versions of CoreDNS. The task of upgrading CoreDNS is the responsibility of a variety of Kubernetes management tools
 | 
			
		||||
// (e.g. kubeadm and others), and the precise behavior may be different for each one. This library abstracts some basic
 | 
			
		||||
// helper functions that make this easier to implement.
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"sort"
 | 
			
		||||
 | 
			
		||||
	"github.com/coredns/corefile-migration/migration/corefile"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Deprecated returns a list of deprecation notifications affecting the guven Corefile.  Notifications are returned for
 | 
			
		||||
// any deprecated, removed, or ignored plugins/directives present in the Corefile.  Notifications are also returned for
 | 
			
		||||
// any new default plugins that would be added in a migration.
 | 
			
		||||
func Deprecated(fromCoreDNSVersion, toCoreDNSVersion, corefileStr string) ([]Notice, error) {
 | 
			
		||||
	return getStatus(fromCoreDNSVersion, toCoreDNSVersion, corefileStr, all)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Unsupported returns a list notifications of plugins/options that are not handled supported by this migration tool,
 | 
			
		||||
// but may still be valid in CoreDNS.
 | 
			
		||||
func Unsupported(fromCoreDNSVersion, toCoreDNSVersion, corefileStr string) ([]Notice, error) {
 | 
			
		||||
	return getStatus(fromCoreDNSVersion, toCoreDNSVersion, corefileStr, unsupported)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getStatus(fromCoreDNSVersion, toCoreDNSVersion, corefileStr, status string) ([]Notice, error) {
 | 
			
		||||
	if fromCoreDNSVersion == toCoreDNSVersion {
 | 
			
		||||
		return nil, nil
 | 
			
		||||
	}
 | 
			
		||||
	err := validUpMigration(fromCoreDNSVersion, toCoreDNSVersion)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	cf, err := corefile.New(corefileStr)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	notices := []Notice{}
 | 
			
		||||
	v := fromCoreDNSVersion
 | 
			
		||||
	for {
 | 
			
		||||
		v = Versions[v].nextVersion
 | 
			
		||||
		for _, s := range cf.Servers {
 | 
			
		||||
			for _, p := range s.Plugins {
 | 
			
		||||
				vp, present := Versions[v].plugins[p.Name]
 | 
			
		||||
				if status == unsupported {
 | 
			
		||||
					if present {
 | 
			
		||||
						continue
 | 
			
		||||
					}
 | 
			
		||||
					notices = append(notices, Notice{Plugin: p.Name, Severity: status, Version: v})
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
				if !present {
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
				if vp.status != "" && vp.status != newdefault {
 | 
			
		||||
					notices = append(notices, Notice{
 | 
			
		||||
						Plugin:     p.Name,
 | 
			
		||||
						Severity:   vp.status,
 | 
			
		||||
						Version:    v,
 | 
			
		||||
						ReplacedBy: vp.replacedBy,
 | 
			
		||||
						Additional: vp.additional,
 | 
			
		||||
					})
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
				for _, o := range p.Options {
 | 
			
		||||
					vo, present := Versions[v].plugins[p.Name].options[o.Name]
 | 
			
		||||
					if status == unsupported {
 | 
			
		||||
						if present {
 | 
			
		||||
							continue
 | 
			
		||||
						}
 | 
			
		||||
						notices = append(notices, Notice{
 | 
			
		||||
							Plugin:     p.Name,
 | 
			
		||||
							Option:     o.Name,
 | 
			
		||||
							Severity:   status,
 | 
			
		||||
							Version:    v,
 | 
			
		||||
							ReplacedBy: vo.replacedBy,
 | 
			
		||||
							Additional: vo.additional,
 | 
			
		||||
						})
 | 
			
		||||
						continue
 | 
			
		||||
					}
 | 
			
		||||
					if !present {
 | 
			
		||||
						continue
 | 
			
		||||
					}
 | 
			
		||||
					if vo.status != "" && vo.status != newdefault {
 | 
			
		||||
						notices = append(notices, Notice{Plugin: p.Name, Option: o.Name, Severity: vo.status, Version: v})
 | 
			
		||||
						continue
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if status != unsupported {
 | 
			
		||||
				CheckForNewOptions:
 | 
			
		||||
					for name, vo := range Versions[v].plugins[p.Name].options {
 | 
			
		||||
						if vo.status != newdefault {
 | 
			
		||||
							continue
 | 
			
		||||
						}
 | 
			
		||||
						for _, o := range p.Options {
 | 
			
		||||
							if name == o.Name {
 | 
			
		||||
								continue CheckForNewOptions
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
						notices = append(notices, Notice{Plugin: p.Name, Option: name, Severity: newdefault, Version: v})
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if status != unsupported {
 | 
			
		||||
			CheckForNewPlugins:
 | 
			
		||||
				for name, vp := range Versions[v].plugins {
 | 
			
		||||
					if vp.status != newdefault {
 | 
			
		||||
						continue
 | 
			
		||||
					}
 | 
			
		||||
					for _, p := range s.Plugins {
 | 
			
		||||
						if name == p.Name {
 | 
			
		||||
							continue CheckForNewPlugins
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					notices = append(notices, Notice{Plugin: name, Option: "", Severity: newdefault, Version: v})
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if v == toCoreDNSVersion {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return notices, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Migrate returns the Corefile converted to toCoreDNSVersion, or an error if it cannot.  This function only accepts
 | 
			
		||||
// a forward migration, where the destination version is => the start version.
 | 
			
		||||
// If deprecations is true, deprecated plugins/options will be migrated as soon as they are deprecated.
 | 
			
		||||
// If deprecations is false, deprecated plugins/options will be migrated only once they become removed or ignored.
 | 
			
		||||
func Migrate(fromCoreDNSVersion, toCoreDNSVersion, corefileStr string, deprecations bool) (string, error) {
 | 
			
		||||
	if fromCoreDNSVersion == toCoreDNSVersion {
 | 
			
		||||
		return corefileStr, nil
 | 
			
		||||
	}
 | 
			
		||||
	err := validUpMigration(fromCoreDNSVersion, toCoreDNSVersion)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	cf, err := corefile.New(corefileStr)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	v := fromCoreDNSVersion
 | 
			
		||||
	for {
 | 
			
		||||
		v = Versions[v].nextVersion
 | 
			
		||||
		newSrvs := []*corefile.Server{}
 | 
			
		||||
		for _, s := range cf.Servers {
 | 
			
		||||
			newPlugs := []*corefile.Plugin{}
 | 
			
		||||
			for _, p := range s.Plugins {
 | 
			
		||||
				vp, present := Versions[v].plugins[p.Name]
 | 
			
		||||
				if !present {
 | 
			
		||||
					newPlugs = append(newPlugs, p)
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
				if !deprecations && vp.status == deprecated {
 | 
			
		||||
					newPlugs = append(newPlugs, p)
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
				if vp.action != nil {
 | 
			
		||||
					p, err := vp.action(p)
 | 
			
		||||
					if err != nil {
 | 
			
		||||
						return "", err
 | 
			
		||||
					}
 | 
			
		||||
					if p == nil {
 | 
			
		||||
						// remove plugin, skip options processing
 | 
			
		||||
						continue
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				newOpts := []*corefile.Option{}
 | 
			
		||||
				for _, o := range p.Options {
 | 
			
		||||
					vo, present := Versions[v].plugins[p.Name].options[o.Name]
 | 
			
		||||
					if !present {
 | 
			
		||||
						newOpts = append(newOpts, o)
 | 
			
		||||
						continue
 | 
			
		||||
					}
 | 
			
		||||
					if !deprecations && vo.status == deprecated {
 | 
			
		||||
						newOpts = append(newOpts, o)
 | 
			
		||||
						continue
 | 
			
		||||
					}
 | 
			
		||||
					if vo.action == nil {
 | 
			
		||||
						newOpts = append(newOpts, o)
 | 
			
		||||
						continue
 | 
			
		||||
					}
 | 
			
		||||
					o, err := vo.action(o)
 | 
			
		||||
					if err != nil {
 | 
			
		||||
						return "", err
 | 
			
		||||
					}
 | 
			
		||||
					if o == nil {
 | 
			
		||||
						// remove option
 | 
			
		||||
						continue
 | 
			
		||||
					}
 | 
			
		||||
					newOpts = append(newOpts, o)
 | 
			
		||||
				}
 | 
			
		||||
				newPlug := &corefile.Plugin{
 | 
			
		||||
					Name:    p.Name,
 | 
			
		||||
					Args:    p.Args,
 | 
			
		||||
					Options: newOpts,
 | 
			
		||||
				}
 | 
			
		||||
			CheckForNewOptions:
 | 
			
		||||
				for name, vo := range Versions[v].plugins[p.Name].options {
 | 
			
		||||
					if vo.status != newdefault {
 | 
			
		||||
						continue
 | 
			
		||||
					}
 | 
			
		||||
					for _, o := range p.Options {
 | 
			
		||||
						if name == o.Name {
 | 
			
		||||
							continue CheckForNewOptions
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					newPlug, err = vo.add(newPlug)
 | 
			
		||||
					if err != nil {
 | 
			
		||||
						return "", err
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				newPlugs = append(newPlugs, newPlug)
 | 
			
		||||
			}
 | 
			
		||||
			newSrv := &corefile.Server{
 | 
			
		||||
				DomPorts: s.DomPorts,
 | 
			
		||||
				Plugins:  newPlugs,
 | 
			
		||||
			}
 | 
			
		||||
		CheckForNewPlugins:
 | 
			
		||||
			for name, vp := range Versions[v].plugins {
 | 
			
		||||
				if vp.status != newdefault {
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
				for _, p := range s.Plugins {
 | 
			
		||||
					if name == p.Name {
 | 
			
		||||
						continue CheckForNewPlugins
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				newSrv, err = vp.add(newSrv)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return "", err
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			newSrvs = append(newSrvs, newSrv)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		cf = &corefile.Corefile{Servers: newSrvs}
 | 
			
		||||
 | 
			
		||||
		// apply any global corefile level post processing
 | 
			
		||||
		if Versions[v].postProcess != nil {
 | 
			
		||||
			cf, err = Versions[v].postProcess(cf)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return "", err
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if v == toCoreDNSVersion {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return cf.ToString(), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MigrateDown returns the Corefile converted to toCoreDNSVersion, or an error if it cannot. This function only accepts
 | 
			
		||||
// a downward migration, where the destination version is <= the start version.
 | 
			
		||||
func MigrateDown(fromCoreDNSVersion, toCoreDNSVersion, corefileStr string) (string, error) {
 | 
			
		||||
	if fromCoreDNSVersion == toCoreDNSVersion {
 | 
			
		||||
		return corefileStr, nil
 | 
			
		||||
	}
 | 
			
		||||
	err := validDownMigration(fromCoreDNSVersion, toCoreDNSVersion)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	cf, err := corefile.New(corefileStr)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	v := fromCoreDNSVersion
 | 
			
		||||
	for {
 | 
			
		||||
		newSrvs := []*corefile.Server{}
 | 
			
		||||
		for _, s := range cf.Servers {
 | 
			
		||||
			newPlugs := []*corefile.Plugin{}
 | 
			
		||||
			for _, p := range s.Plugins {
 | 
			
		||||
				vp, present := Versions[v].plugins[p.Name]
 | 
			
		||||
				if !present {
 | 
			
		||||
					newPlugs = append(newPlugs, p)
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
				if vp.downAction == nil {
 | 
			
		||||
					newPlugs = append(newPlugs, p)
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
				p, err := vp.downAction(p)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return "", err
 | 
			
		||||
				}
 | 
			
		||||
				if p == nil {
 | 
			
		||||
					// remove plugin, skip options processing
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				newOpts := []*corefile.Option{}
 | 
			
		||||
				for _, o := range p.Options {
 | 
			
		||||
					vo, present := Versions[v].plugins[p.Name].options[o.Name]
 | 
			
		||||
					if !present {
 | 
			
		||||
						newOpts = append(newOpts, o)
 | 
			
		||||
						continue
 | 
			
		||||
					}
 | 
			
		||||
					if vo.downAction == nil {
 | 
			
		||||
						newOpts = append(newOpts, o)
 | 
			
		||||
						continue
 | 
			
		||||
					}
 | 
			
		||||
					o, err := vo.downAction(o)
 | 
			
		||||
					if err != nil {
 | 
			
		||||
						return "", err
 | 
			
		||||
					}
 | 
			
		||||
					if o == nil {
 | 
			
		||||
						// remove option
 | 
			
		||||
						continue
 | 
			
		||||
					}
 | 
			
		||||
					newOpts = append(newOpts, o)
 | 
			
		||||
				}
 | 
			
		||||
				newPlug := &corefile.Plugin{
 | 
			
		||||
					Name:    p.Name,
 | 
			
		||||
					Args:    p.Args,
 | 
			
		||||
					Options: newOpts,
 | 
			
		||||
				}
 | 
			
		||||
				newPlugs = append(newPlugs, newPlug)
 | 
			
		||||
			}
 | 
			
		||||
			newSrv := &corefile.Server{
 | 
			
		||||
				DomPorts: s.DomPorts,
 | 
			
		||||
				Plugins:  newPlugs,
 | 
			
		||||
			}
 | 
			
		||||
			newSrvs = append(newSrvs, newSrv)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		cf = &corefile.Corefile{Servers: newSrvs}
 | 
			
		||||
 | 
			
		||||
		if v == toCoreDNSVersion {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		v = Versions[v].priorVersion
 | 
			
		||||
	}
 | 
			
		||||
	return cf.ToString(), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Default returns true if the Corefile is the default for a given version of Kubernetes.
 | 
			
		||||
// Or, if k8sVersion is empty, Default returns true if the Corefile is the default for any version of Kubernetes.
 | 
			
		||||
func Default(k8sVersion, corefileStr string) bool {
 | 
			
		||||
	cf, err := corefile.New(corefileStr)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
NextVersion:
 | 
			
		||||
	for _, v := range Versions {
 | 
			
		||||
		for _, release := range v.k8sReleases {
 | 
			
		||||
			if k8sVersion != "" && k8sVersion != release {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		defCf, err := corefile.New(v.defaultConf)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		// check corefile against k8s release default
 | 
			
		||||
		if len(cf.Servers) != len(defCf.Servers) {
 | 
			
		||||
			continue NextVersion
 | 
			
		||||
		}
 | 
			
		||||
		for _, s := range cf.Servers {
 | 
			
		||||
			defS, found := s.FindMatch(defCf.Servers)
 | 
			
		||||
			if !found {
 | 
			
		||||
				continue NextVersion
 | 
			
		||||
			}
 | 
			
		||||
			if len(s.Plugins) != len(defS.Plugins) {
 | 
			
		||||
				continue NextVersion
 | 
			
		||||
			}
 | 
			
		||||
			for _, p := range s.Plugins {
 | 
			
		||||
				defP, found := p.FindMatch(defS.Plugins)
 | 
			
		||||
				if !found {
 | 
			
		||||
					continue NextVersion
 | 
			
		||||
				}
 | 
			
		||||
				if len(p.Options) != len(defP.Options) {
 | 
			
		||||
					continue NextVersion
 | 
			
		||||
				}
 | 
			
		||||
				for _, o := range p.Options {
 | 
			
		||||
					_, found := o.FindMatch(defP.Options)
 | 
			
		||||
					if !found {
 | 
			
		||||
						continue NextVersion
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Released returns true if dockerImageSHA matches any released image of CoreDNS.
 | 
			
		||||
func Released(dockerImageSHA string) bool {
 | 
			
		||||
	for _, v := range Versions {
 | 
			
		||||
		if v.dockerImageSHA == dockerImageSHA {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ValidVersions returns a list of all versions defined
 | 
			
		||||
func ValidVersions() []string {
 | 
			
		||||
	var vStrs []string
 | 
			
		||||
	for vStr := range Versions {
 | 
			
		||||
		vStrs = append(vStrs, vStr)
 | 
			
		||||
	}
 | 
			
		||||
	sort.Strings(vStrs)
 | 
			
		||||
	return vStrs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func validateVersion(fromCoreDNSVersion string) error {
 | 
			
		||||
	if _, ok := Versions[fromCoreDNSVersion]; !ok {
 | 
			
		||||
		return fmt.Errorf("start version '%v' not supported", fromCoreDNSVersion)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func validUpMigration(fromCoreDNSVersion, toCoreDNSVersion string) error {
 | 
			
		||||
	err := validateVersion(fromCoreDNSVersion)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	for next := Versions[fromCoreDNSVersion].nextVersion; next != ""; next = Versions[next].nextVersion {
 | 
			
		||||
		if next != toCoreDNSVersion {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Errorf("cannot migrate up to '%v' from '%v'", toCoreDNSVersion, fromCoreDNSVersion)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func validDownMigration(fromCoreDNSVersion, toCoreDNSVersion string) error {
 | 
			
		||||
	err := validateVersion(fromCoreDNSVersion)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	for prior := Versions[fromCoreDNSVersion].priorVersion; prior != ""; prior = Versions[prior].priorVersion {
 | 
			
		||||
		if prior != toCoreDNSVersion {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Errorf("cannot migrate down to '%v' from '%v'", toCoreDNSVersion, fromCoreDNSVersion)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										48
									
								
								vendor/github.com/coredns/corefile-migration/migration/notice.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								vendor/github.com/coredns/corefile-migration/migration/notice.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
package migration
 | 
			
		||||
 | 
			
		||||
import "fmt"
 | 
			
		||||
 | 
			
		||||
// Notice is a migration warning
 | 
			
		||||
type Notice struct {
 | 
			
		||||
	Plugin     string
 | 
			
		||||
	Option     string
 | 
			
		||||
	Severity   string // 'deprecated', 'removed', or 'unsupported'
 | 
			
		||||
	ReplacedBy string
 | 
			
		||||
	Additional string
 | 
			
		||||
	Version    string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (n *Notice) ToString() string {
 | 
			
		||||
	s := ""
 | 
			
		||||
	if n.Option == "" {
 | 
			
		||||
		s += fmt.Sprintf(`Plugin "%v" `, n.Plugin)
 | 
			
		||||
	} else {
 | 
			
		||||
		s += fmt.Sprintf(`Option "%v" in plugin "%v" `, n.Option, n.Plugin)
 | 
			
		||||
	}
 | 
			
		||||
	if n.Severity == unsupported {
 | 
			
		||||
		s += "is unsupported by this migration tool in " + n.Version + "."
 | 
			
		||||
	} else if n.Severity == newdefault {
 | 
			
		||||
		s += "is added as a default in " + n.Version + "."
 | 
			
		||||
	} else {
 | 
			
		||||
		s += "is " + n.Severity + " in " + n.Version + "."
 | 
			
		||||
	}
 | 
			
		||||
	if n.ReplacedBy != "" {
 | 
			
		||||
		s += fmt.Sprintf(` It is replaced by "%v".`, n.ReplacedBy)
 | 
			
		||||
	}
 | 
			
		||||
	if n.Additional != "" {
 | 
			
		||||
		s += " " + n.Additional
 | 
			
		||||
	}
 | 
			
		||||
	return s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// The following statuses are used to indicate the state of support/deprecation in a given release.
 | 
			
		||||
	deprecated  = "deprecated"  // deprecated, but still completely functional
 | 
			
		||||
	ignored     = "ignored"     // if included in the corefile, it will be ignored by CoreDNS
 | 
			
		||||
	removed     = "removed"     // completely removed from CoreDNS, and would cause CoreDNS to exit if present in the Corefile
 | 
			
		||||
	newdefault  = "newdefault"  // added to the default corefile.  CoreDNS may not function properly if it is not present in the corefile.
 | 
			
		||||
	unsupported = "unsupported" // the plugin/option is not supported by the migration tool
 | 
			
		||||
 | 
			
		||||
	// The following statuses are used for selecting/filtering notifications
 | 
			
		||||
	all = "all" // show all statuses
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										1504
									
								
								vendor/github.com/coredns/corefile-migration/migration/versions.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1504
									
								
								vendor/github.com/coredns/corefile-migration/migration/versions.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2
									
								
								vendor/github.com/spf13/cobra/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/spf13/cobra/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -34,3 +34,5 @@ tags
 | 
			
		||||
*.exe
 | 
			
		||||
 | 
			
		||||
cobra.test
 | 
			
		||||
 | 
			
		||||
.idea/*
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								vendor/github.com/spf13/cobra/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/spf13/cobra/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -9,6 +9,8 @@ go_library(
 | 
			
		||||
        "command.go",
 | 
			
		||||
        "command_notwin.go",
 | 
			
		||||
        "command_win.go",
 | 
			
		||||
        "powershell_completions.go",
 | 
			
		||||
        "shell_completions.go",
 | 
			
		||||
        "zsh_completions.go",
 | 
			
		||||
    ],
 | 
			
		||||
    importmap = "k8s.io/kubernetes/vendor/github.com/spf13/cobra",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								vendor/github.com/spf13/cobra/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/spf13/cobra/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -23,6 +23,7 @@ Many of the most widely used Go projects are built using Cobra, such as:
 | 
			
		||||
[Istio](https://istio.io),
 | 
			
		||||
[Prototool](https://github.com/uber/prototool),
 | 
			
		||||
[mattermost-server](https://github.com/mattermost/mattermost-server),
 | 
			
		||||
[Gardener](https://github.com/gardener/gardenctl),
 | 
			
		||||
etc.
 | 
			
		||||
 | 
			
		||||
[](https://travis-ci.org/spf13/cobra)
 | 
			
		||||
@@ -48,6 +49,7 @@ etc.
 | 
			
		||||
  * [Suggestions when "unknown command" happens](#suggestions-when-unknown-command-happens)
 | 
			
		||||
  * [Generating documentation for your command](#generating-documentation-for-your-command)
 | 
			
		||||
  * [Generating bash completions](#generating-bash-completions)
 | 
			
		||||
  * [Generating zsh completions](#generating-zsh-completions)
 | 
			
		||||
- [Contributing](#contributing)
 | 
			
		||||
- [License](#license)
 | 
			
		||||
 | 
			
		||||
@@ -336,7 +338,7 @@ rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose out
 | 
			
		||||
A flag can also be assigned locally which will only apply to that specific command.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
rootCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")
 | 
			
		||||
localCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Local Flag on Parent Commands
 | 
			
		||||
@@ -719,6 +721,11 @@ Cobra can generate documentation based on subcommands, flags, etc. in the follow
 | 
			
		||||
 | 
			
		||||
Cobra can generate a bash-completion file. If you add more information to your command, these completions can be amazingly powerful and flexible.  Read more about it in [Bash Completions](bash_completions.md).
 | 
			
		||||
 | 
			
		||||
## Generating zsh completions
 | 
			
		||||
 | 
			
		||||
Cobra can generate zsh-completion file. Read more about it in
 | 
			
		||||
[Zsh Completions](zsh_completions.md).
 | 
			
		||||
 | 
			
		||||
# Contributing
 | 
			
		||||
 | 
			
		||||
1. Fork it
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										48
									
								
								vendor/github.com/spf13/cobra/bash_completions.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										48
									
								
								vendor/github.com/spf13/cobra/bash_completions.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -545,51 +545,3 @@ func (c *Command) GenBashCompletionFile(filename string) error {
 | 
			
		||||
 | 
			
		||||
	return c.GenBashCompletion(outFile)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists,
 | 
			
		||||
// and causes your command to report an error if invoked without the flag.
 | 
			
		||||
func (c *Command) MarkFlagRequired(name string) error {
 | 
			
		||||
	return MarkFlagRequired(c.Flags(), name)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarkPersistentFlagRequired adds the BashCompOneRequiredFlag annotation to the named persistent flag if it exists,
 | 
			
		||||
// and causes your command to report an error if invoked without the flag.
 | 
			
		||||
func (c *Command) MarkPersistentFlagRequired(name string) error {
 | 
			
		||||
	return MarkFlagRequired(c.PersistentFlags(), name)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists,
 | 
			
		||||
// and causes your command to report an error if invoked without the flag.
 | 
			
		||||
func MarkFlagRequired(flags *pflag.FlagSet, name string) error {
 | 
			
		||||
	return flags.SetAnnotation(name, BashCompOneRequiredFlag, []string{"true"})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag, if it exists.
 | 
			
		||||
// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
 | 
			
		||||
func (c *Command) MarkFlagFilename(name string, extensions ...string) error {
 | 
			
		||||
	return MarkFlagFilename(c.Flags(), name, extensions...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarkFlagCustom adds the BashCompCustom annotation to the named flag, if it exists.
 | 
			
		||||
// Generated bash autocompletion will call the bash function f for the flag.
 | 
			
		||||
func (c *Command) MarkFlagCustom(name string, f string) error {
 | 
			
		||||
	return MarkFlagCustom(c.Flags(), name, f)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarkPersistentFlagFilename adds the BashCompFilenameExt annotation to the named persistent flag, if it exists.
 | 
			
		||||
// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
 | 
			
		||||
func (c *Command) MarkPersistentFlagFilename(name string, extensions ...string) error {
 | 
			
		||||
	return MarkFlagFilename(c.PersistentFlags(), name, extensions...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag in the flag set, if it exists.
 | 
			
		||||
// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
 | 
			
		||||
func MarkFlagFilename(flags *pflag.FlagSet, name string, extensions ...string) error {
 | 
			
		||||
	return flags.SetAnnotation(name, BashCompFilenameExt, extensions)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarkFlagCustom adds the BashCompCustom annotation to the named flag in the flag set, if it exists.
 | 
			
		||||
// Generated bash autocompletion will call the bash function f for the flag.
 | 
			
		||||
func MarkFlagCustom(flags *pflag.FlagSet, name string, f string) error {
 | 
			
		||||
	return flags.SetAnnotation(name, BashCompCustom, []string{f})
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										97
									
								
								vendor/github.com/spf13/cobra/command.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										97
									
								
								vendor/github.com/spf13/cobra/command.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -177,8 +177,6 @@ type Command struct {
 | 
			
		||||
	// that we can use on every pflag set and children commands
 | 
			
		||||
	globNormFunc func(f *flag.FlagSet, name string) flag.NormalizedName
 | 
			
		||||
 | 
			
		||||
	// output is an output writer defined by user.
 | 
			
		||||
	output io.Writer
 | 
			
		||||
	// usageFunc is usage func defined by user.
 | 
			
		||||
	usageFunc func(*Command) error
 | 
			
		||||
	// usageTemplate is usage template defined by user.
 | 
			
		||||
@@ -195,6 +193,13 @@ type Command struct {
 | 
			
		||||
	helpCommand *Command
 | 
			
		||||
	// versionTemplate is the version template defined by user.
 | 
			
		||||
	versionTemplate string
 | 
			
		||||
 | 
			
		||||
	// inReader is a reader defined by the user that replaces stdin
 | 
			
		||||
	inReader io.Reader
 | 
			
		||||
	// outWriter is a writer defined by the user that replaces stdout
 | 
			
		||||
	outWriter io.Writer
 | 
			
		||||
	// errWriter is a writer defined by the user that replaces stderr
 | 
			
		||||
	errWriter io.Writer
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetArgs sets arguments for the command. It is set to os.Args[1:] by default, if desired, can be overridden
 | 
			
		||||
@@ -205,8 +210,28 @@ func (c *Command) SetArgs(a []string) {
 | 
			
		||||
 | 
			
		||||
// SetOutput sets the destination for usage and error messages.
 | 
			
		||||
// If output is nil, os.Stderr is used.
 | 
			
		||||
// Deprecated: Use SetOut and/or SetErr instead
 | 
			
		||||
func (c *Command) SetOutput(output io.Writer) {
 | 
			
		||||
	c.output = output
 | 
			
		||||
	c.outWriter = output
 | 
			
		||||
	c.errWriter = output
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetOut sets the destination for usage messages.
 | 
			
		||||
// If newOut is nil, os.Stdout is used.
 | 
			
		||||
func (c *Command) SetOut(newOut io.Writer) {
 | 
			
		||||
	c.outWriter = newOut
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetErr sets the destination for error messages.
 | 
			
		||||
// If newErr is nil, os.Stderr is used.
 | 
			
		||||
func (c *Command) SetErr(newErr io.Writer) {
 | 
			
		||||
	c.errWriter = newErr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetOut sets the source for input data
 | 
			
		||||
// If newIn is nil, os.Stdin is used.
 | 
			
		||||
func (c *Command) SetIn(newIn io.Reader) {
 | 
			
		||||
	c.inReader = newIn
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetUsageFunc sets usage function. Usage can be defined by application.
 | 
			
		||||
@@ -267,9 +292,19 @@ func (c *Command) OutOrStderr() io.Writer {
 | 
			
		||||
	return c.getOut(os.Stderr)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ErrOrStderr returns output to stderr
 | 
			
		||||
func (c *Command) ErrOrStderr() io.Writer {
 | 
			
		||||
	return c.getErr(os.Stderr)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ErrOrStderr returns output to stderr
 | 
			
		||||
func (c *Command) InOrStdin() io.Reader {
 | 
			
		||||
	return c.getIn(os.Stdin)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Command) getOut(def io.Writer) io.Writer {
 | 
			
		||||
	if c.output != nil {
 | 
			
		||||
		return c.output
 | 
			
		||||
	if c.outWriter != nil {
 | 
			
		||||
		return c.outWriter
 | 
			
		||||
	}
 | 
			
		||||
	if c.HasParent() {
 | 
			
		||||
		return c.parent.getOut(def)
 | 
			
		||||
@@ -277,6 +312,26 @@ func (c *Command) getOut(def io.Writer) io.Writer {
 | 
			
		||||
	return def
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Command) getErr(def io.Writer) io.Writer {
 | 
			
		||||
	if c.errWriter != nil {
 | 
			
		||||
		return c.errWriter
 | 
			
		||||
	}
 | 
			
		||||
	if c.HasParent() {
 | 
			
		||||
		return c.parent.getErr(def)
 | 
			
		||||
	}
 | 
			
		||||
	return def
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Command) getIn(def io.Reader) io.Reader {
 | 
			
		||||
	if c.inReader != nil {
 | 
			
		||||
		return c.inReader
 | 
			
		||||
	}
 | 
			
		||||
	if c.HasParent() {
 | 
			
		||||
		return c.parent.getIn(def)
 | 
			
		||||
	}
 | 
			
		||||
	return def
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UsageFunc returns either the function set by SetUsageFunc for this command
 | 
			
		||||
// or a parent, or it returns a default usage function.
 | 
			
		||||
func (c *Command) UsageFunc() (f func(*Command) error) {
 | 
			
		||||
@@ -329,13 +384,22 @@ func (c *Command) Help() error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UsageString return usage string.
 | 
			
		||||
// UsageString returns usage string.
 | 
			
		||||
func (c *Command) UsageString() string {
 | 
			
		||||
	tmpOutput := c.output
 | 
			
		||||
	// Storing normal writers
 | 
			
		||||
	tmpOutput := c.outWriter
 | 
			
		||||
	tmpErr := c.errWriter
 | 
			
		||||
 | 
			
		||||
	bb := new(bytes.Buffer)
 | 
			
		||||
	c.SetOutput(bb)
 | 
			
		||||
	c.outWriter = bb
 | 
			
		||||
	c.errWriter = bb
 | 
			
		||||
 | 
			
		||||
	c.Usage()
 | 
			
		||||
	c.output = tmpOutput
 | 
			
		||||
 | 
			
		||||
	// Setting things back to normal
 | 
			
		||||
	c.outWriter = tmpOutput
 | 
			
		||||
	c.errWriter = tmpErr
 | 
			
		||||
 | 
			
		||||
	return bb.String()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1068,6 +1132,21 @@ func (c *Command) Printf(format string, i ...interface{}) {
 | 
			
		||||
	c.Print(fmt.Sprintf(format, i...))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PrintErr is a convenience method to Print to the defined Err output, fallback to Stderr if not set.
 | 
			
		||||
func (c *Command) PrintErr(i ...interface{}) {
 | 
			
		||||
	fmt.Fprint(c.ErrOrStderr(), i...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PrintErrln is a convenience method to Println to the defined Err output, fallback to Stderr if not set.
 | 
			
		||||
func (c *Command) PrintErrln(i ...interface{}) {
 | 
			
		||||
	c.Print(fmt.Sprintln(i...))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PrintErrf is a convenience method to Printf to the defined Err output, fallback to Stderr if not set.
 | 
			
		||||
func (c *Command) PrintErrf(format string, i ...interface{}) {
 | 
			
		||||
	c.Print(fmt.Sprintf(format, i...))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CommandPath returns the full path to this command.
 | 
			
		||||
func (c *Command) CommandPath() string {
 | 
			
		||||
	if c.HasParent() {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										100
									
								
								vendor/github.com/spf13/cobra/powershell_completions.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								vendor/github.com/spf13/cobra/powershell_completions.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,100 @@
 | 
			
		||||
// PowerShell completions are based on the amazing work from clap:
 | 
			
		||||
// https://github.com/clap-rs/clap/blob/3294d18efe5f264d12c9035f404c7d189d4824e1/src/completions/powershell.rs
 | 
			
		||||
//
 | 
			
		||||
// The generated scripts require PowerShell v5.0+ (which comes Windows 10, but
 | 
			
		||||
// can be downloaded separately for windows 7 or 8.1).
 | 
			
		||||
 | 
			
		||||
package cobra
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/spf13/pflag"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var powerShellCompletionTemplate = `using namespace System.Management.Automation
 | 
			
		||||
using namespace System.Management.Automation.Language
 | 
			
		||||
Register-ArgumentCompleter -Native -CommandName '%s' -ScriptBlock {
 | 
			
		||||
    param($wordToComplete, $commandAst, $cursorPosition)
 | 
			
		||||
    $commandElements = $commandAst.CommandElements
 | 
			
		||||
    $command = @(
 | 
			
		||||
        '%s'
 | 
			
		||||
        for ($i = 1; $i -lt $commandElements.Count; $i++) {
 | 
			
		||||
            $element = $commandElements[$i]
 | 
			
		||||
            if ($element -isnot [StringConstantExpressionAst] -or
 | 
			
		||||
                $element.StringConstantType -ne [StringConstantType]::BareWord -or
 | 
			
		||||
                $element.Value.StartsWith('-')) {
 | 
			
		||||
                break
 | 
			
		||||
            }
 | 
			
		||||
            $element.Value
 | 
			
		||||
        }
 | 
			
		||||
    ) -join ';'
 | 
			
		||||
    $completions = @(switch ($command) {%s
 | 
			
		||||
    })
 | 
			
		||||
    $completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
 | 
			
		||||
        Sort-Object -Property ListItemText
 | 
			
		||||
}`
 | 
			
		||||
 | 
			
		||||
func generatePowerShellSubcommandCases(out io.Writer, cmd *Command, previousCommandName string) {
 | 
			
		||||
	var cmdName string
 | 
			
		||||
	if previousCommandName == "" {
 | 
			
		||||
		cmdName = cmd.Name()
 | 
			
		||||
	} else {
 | 
			
		||||
		cmdName = fmt.Sprintf("%s;%s", previousCommandName, cmd.Name())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fmt.Fprintf(out, "\n        '%s' {", cmdName)
 | 
			
		||||
 | 
			
		||||
	cmd.Flags().VisitAll(func(flag *pflag.Flag) {
 | 
			
		||||
		if nonCompletableFlag(flag) {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		usage := escapeStringForPowerShell(flag.Usage)
 | 
			
		||||
		if len(flag.Shorthand) > 0 {
 | 
			
		||||
			fmt.Fprintf(out, "\n            [CompletionResult]::new('-%s', '%s', [CompletionResultType]::ParameterName, '%s')", flag.Shorthand, flag.Shorthand, usage)
 | 
			
		||||
		}
 | 
			
		||||
		fmt.Fprintf(out, "\n            [CompletionResult]::new('--%s', '%s', [CompletionResultType]::ParameterName, '%s')", flag.Name, flag.Name, usage)
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	for _, subCmd := range cmd.Commands() {
 | 
			
		||||
		usage := escapeStringForPowerShell(subCmd.Short)
 | 
			
		||||
		fmt.Fprintf(out, "\n            [CompletionResult]::new('%s', '%s', [CompletionResultType]::ParameterValue, '%s')", subCmd.Name(), subCmd.Name(), usage)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fmt.Fprint(out, "\n            break\n        }")
 | 
			
		||||
 | 
			
		||||
	for _, subCmd := range cmd.Commands() {
 | 
			
		||||
		generatePowerShellSubcommandCases(out, subCmd, cmdName)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func escapeStringForPowerShell(s string) string {
 | 
			
		||||
	return strings.Replace(s, "'", "''", -1)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GenPowerShellCompletion generates PowerShell completion file and writes to the passed writer.
 | 
			
		||||
func (c *Command) GenPowerShellCompletion(w io.Writer) error {
 | 
			
		||||
	buf := new(bytes.Buffer)
 | 
			
		||||
 | 
			
		||||
	var subCommandCases bytes.Buffer
 | 
			
		||||
	generatePowerShellSubcommandCases(&subCommandCases, c, "")
 | 
			
		||||
	fmt.Fprintf(buf, powerShellCompletionTemplate, c.Name(), c.Name(), subCommandCases.String())
 | 
			
		||||
 | 
			
		||||
	_, err := buf.WriteTo(w)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GenPowerShellCompletionFile generates PowerShell completion file.
 | 
			
		||||
func (c *Command) GenPowerShellCompletionFile(filename string) error {
 | 
			
		||||
	outFile, err := os.Create(filename)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	defer outFile.Close()
 | 
			
		||||
 | 
			
		||||
	return c.GenPowerShellCompletion(outFile)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								vendor/github.com/spf13/cobra/powershell_completions.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/spf13/cobra/powershell_completions.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
# Generating PowerShell Completions For Your Own cobra.Command
 | 
			
		||||
 | 
			
		||||
Cobra can generate PowerShell completion scripts. Users need PowerShell version 5.0 or above, which comes with Windows 10 and can be downloaded separately for Windows 7 or 8.1. They can then write the completions to a file and source this file from their PowerShell profile, which is referenced by the `$Profile` environment variable. See `Get-Help about_Profiles` for more info about PowerShell profiles.
 | 
			
		||||
 | 
			
		||||
# What's supported
 | 
			
		||||
 | 
			
		||||
- Completion for subcommands using their `.Short` description
 | 
			
		||||
- Completion for non-hidden flags using their `.Name` and `.Shorthand`
 | 
			
		||||
 | 
			
		||||
# What's not yet supported
 | 
			
		||||
 | 
			
		||||
- Command aliases
 | 
			
		||||
- Required, filename or custom flags (they will work like normal flags)
 | 
			
		||||
- Custom completion scripts
 | 
			
		||||
							
								
								
									
										85
									
								
								vendor/github.com/spf13/cobra/shell_completions.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								vendor/github.com/spf13/cobra/shell_completions.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,85 @@
 | 
			
		||||
package cobra
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/spf13/pflag"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists,
 | 
			
		||||
// and causes your command to report an error if invoked without the flag.
 | 
			
		||||
func (c *Command) MarkFlagRequired(name string) error {
 | 
			
		||||
	return MarkFlagRequired(c.Flags(), name)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarkPersistentFlagRequired adds the BashCompOneRequiredFlag annotation to the named persistent flag if it exists,
 | 
			
		||||
// and causes your command to report an error if invoked without the flag.
 | 
			
		||||
func (c *Command) MarkPersistentFlagRequired(name string) error {
 | 
			
		||||
	return MarkFlagRequired(c.PersistentFlags(), name)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists,
 | 
			
		||||
// and causes your command to report an error if invoked without the flag.
 | 
			
		||||
func MarkFlagRequired(flags *pflag.FlagSet, name string) error {
 | 
			
		||||
	return flags.SetAnnotation(name, BashCompOneRequiredFlag, []string{"true"})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag, if it exists.
 | 
			
		||||
// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
 | 
			
		||||
func (c *Command) MarkFlagFilename(name string, extensions ...string) error {
 | 
			
		||||
	return MarkFlagFilename(c.Flags(), name, extensions...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarkFlagCustom adds the BashCompCustom annotation to the named flag, if it exists.
 | 
			
		||||
// Generated bash autocompletion will call the bash function f for the flag.
 | 
			
		||||
func (c *Command) MarkFlagCustom(name string, f string) error {
 | 
			
		||||
	return MarkFlagCustom(c.Flags(), name, f)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarkPersistentFlagFilename instructs the various shell completion
 | 
			
		||||
// implementations to limit completions for this persistent flag to the
 | 
			
		||||
// specified extensions (patterns).
 | 
			
		||||
//
 | 
			
		||||
// Shell Completion compatibility matrix: bash, zsh
 | 
			
		||||
func (c *Command) MarkPersistentFlagFilename(name string, extensions ...string) error {
 | 
			
		||||
	return MarkFlagFilename(c.PersistentFlags(), name, extensions...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarkFlagFilename instructs the various shell completion implementations to
 | 
			
		||||
// limit completions for this flag to the specified extensions (patterns).
 | 
			
		||||
//
 | 
			
		||||
// Shell Completion compatibility matrix: bash, zsh
 | 
			
		||||
func MarkFlagFilename(flags *pflag.FlagSet, name string, extensions ...string) error {
 | 
			
		||||
	return flags.SetAnnotation(name, BashCompFilenameExt, extensions)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarkFlagCustom instructs the various shell completion implementations to
 | 
			
		||||
// limit completions for this flag to the specified extensions (patterns).
 | 
			
		||||
//
 | 
			
		||||
// Shell Completion compatibility matrix: bash, zsh
 | 
			
		||||
func MarkFlagCustom(flags *pflag.FlagSet, name string, f string) error {
 | 
			
		||||
	return flags.SetAnnotation(name, BashCompCustom, []string{f})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarkFlagDirname instructs the various shell completion implementations to
 | 
			
		||||
// complete only directories with this named flag.
 | 
			
		||||
//
 | 
			
		||||
// Shell Completion compatibility matrix: zsh
 | 
			
		||||
func (c *Command) MarkFlagDirname(name string) error {
 | 
			
		||||
	return MarkFlagDirname(c.Flags(), name)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarkPersistentFlagDirname instructs the various shell completion
 | 
			
		||||
// implementations to complete only directories with this persistent named flag.
 | 
			
		||||
//
 | 
			
		||||
// Shell Completion compatibility matrix: zsh
 | 
			
		||||
func (c *Command) MarkPersistentFlagDirname(name string) error {
 | 
			
		||||
	return MarkFlagDirname(c.PersistentFlags(), name)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarkFlagDirname instructs the various shell completion implementations to
 | 
			
		||||
// complete only directories with this specified flag.
 | 
			
		||||
//
 | 
			
		||||
// Shell Completion compatibility matrix: zsh
 | 
			
		||||
func MarkFlagDirname(flags *pflag.FlagSet, name string) error {
 | 
			
		||||
	zshPattern := "-(/)"
 | 
			
		||||
	return flags.SetAnnotation(name, zshCompDirname, []string{zshPattern})
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										400
									
								
								vendor/github.com/spf13/cobra/zsh_completions.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										400
									
								
								vendor/github.com/spf13/cobra/zsh_completions.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,13 +1,102 @@
 | 
			
		||||
package cobra
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"os"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"text/template"
 | 
			
		||||
 | 
			
		||||
	"github.com/spf13/pflag"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	zshCompArgumentAnnotation   = "cobra_annotations_zsh_completion_argument_annotation"
 | 
			
		||||
	zshCompArgumentFilenameComp = "cobra_annotations_zsh_completion_argument_file_completion"
 | 
			
		||||
	zshCompArgumentWordComp     = "cobra_annotations_zsh_completion_argument_word_completion"
 | 
			
		||||
	zshCompDirname              = "cobra_annotations_zsh_dirname"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	zshCompFuncMap = template.FuncMap{
 | 
			
		||||
		"genZshFuncName":              zshCompGenFuncName,
 | 
			
		||||
		"extractFlags":                zshCompExtractFlag,
 | 
			
		||||
		"genFlagEntryForZshArguments": zshCompGenFlagEntryForArguments,
 | 
			
		||||
		"extractArgsCompletions":      zshCompExtractArgumentCompletionHintsForRendering,
 | 
			
		||||
	}
 | 
			
		||||
	zshCompletionText = `
 | 
			
		||||
{{/* should accept Command (that contains subcommands) as parameter */}}
 | 
			
		||||
{{define "argumentsC" -}}
 | 
			
		||||
{{ $cmdPath := genZshFuncName .}}
 | 
			
		||||
function {{$cmdPath}} {
 | 
			
		||||
  local -a commands
 | 
			
		||||
 | 
			
		||||
  _arguments -C \{{- range extractFlags .}}
 | 
			
		||||
    {{genFlagEntryForZshArguments .}} \{{- end}}
 | 
			
		||||
    "1: :->cmnds" \
 | 
			
		||||
    "*::arg:->args"
 | 
			
		||||
 | 
			
		||||
  case $state in
 | 
			
		||||
  cmnds)
 | 
			
		||||
    commands=({{range .Commands}}{{if not .Hidden}}
 | 
			
		||||
      "{{.Name}}:{{.Short}}"{{end}}{{end}}
 | 
			
		||||
    )
 | 
			
		||||
    _describe "command" commands
 | 
			
		||||
    ;;
 | 
			
		||||
  esac
 | 
			
		||||
 | 
			
		||||
  case "$words[1]" in {{- range .Commands}}{{if not .Hidden}}
 | 
			
		||||
  {{.Name}})
 | 
			
		||||
    {{$cmdPath}}_{{.Name}}
 | 
			
		||||
    ;;{{end}}{{end}}
 | 
			
		||||
  esac
 | 
			
		||||
}
 | 
			
		||||
{{range .Commands}}{{if not .Hidden}}
 | 
			
		||||
{{template "selectCmdTemplate" .}}
 | 
			
		||||
{{- end}}{{end}}
 | 
			
		||||
{{- end}}
 | 
			
		||||
 | 
			
		||||
{{/* should accept Command without subcommands as parameter */}}
 | 
			
		||||
{{define "arguments" -}}
 | 
			
		||||
function {{genZshFuncName .}} {
 | 
			
		||||
{{"  _arguments"}}{{range extractFlags .}} \
 | 
			
		||||
    {{genFlagEntryForZshArguments . -}}
 | 
			
		||||
{{end}}{{range extractArgsCompletions .}} \
 | 
			
		||||
    {{.}}{{end}}
 | 
			
		||||
}
 | 
			
		||||
{{end}}
 | 
			
		||||
 | 
			
		||||
{{/* dispatcher for commands with or without subcommands */}}
 | 
			
		||||
{{define "selectCmdTemplate" -}}
 | 
			
		||||
{{if .Hidden}}{{/* ignore hidden*/}}{{else -}}
 | 
			
		||||
{{if .Commands}}{{template "argumentsC" .}}{{else}}{{template "arguments" .}}{{end}}
 | 
			
		||||
{{- end}}
 | 
			
		||||
{{- end}}
 | 
			
		||||
 | 
			
		||||
{{/* template entry point */}}
 | 
			
		||||
{{define "Main" -}}
 | 
			
		||||
#compdef _{{.Name}} {{.Name}}
 | 
			
		||||
 | 
			
		||||
{{template "selectCmdTemplate" .}}
 | 
			
		||||
{{end}}
 | 
			
		||||
`
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// zshCompArgsAnnotation is used to encode/decode zsh completion for
 | 
			
		||||
// arguments to/from Command.Annotations.
 | 
			
		||||
type zshCompArgsAnnotation map[int]zshCompArgHint
 | 
			
		||||
 | 
			
		||||
type zshCompArgHint struct {
 | 
			
		||||
	// Indicates the type of the completion to use. One of:
 | 
			
		||||
	// zshCompArgumentFilenameComp or zshCompArgumentWordComp
 | 
			
		||||
	Tipe string `json:"type"`
 | 
			
		||||
 | 
			
		||||
	// A value for the type above (globs for file completion or words)
 | 
			
		||||
	Options []string `json:"options"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GenZshCompletionFile generates zsh completion file.
 | 
			
		||||
func (c *Command) GenZshCompletionFile(filename string) error {
 | 
			
		||||
	outFile, err := os.Create(filename)
 | 
			
		||||
@@ -19,108 +108,229 @@ func (c *Command) GenZshCompletionFile(filename string) error {
 | 
			
		||||
	return c.GenZshCompletion(outFile)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GenZshCompletion generates a zsh completion file and writes to the passed writer.
 | 
			
		||||
// GenZshCompletion generates a zsh completion file and writes to the passed
 | 
			
		||||
// writer. The completion always run on the root command regardless of the
 | 
			
		||||
// command it was called from.
 | 
			
		||||
func (c *Command) GenZshCompletion(w io.Writer) error {
 | 
			
		||||
	buf := new(bytes.Buffer)
 | 
			
		||||
 | 
			
		||||
	writeHeader(buf, c)
 | 
			
		||||
	maxDepth := maxDepth(c)
 | 
			
		||||
	writeLevelMapping(buf, maxDepth)
 | 
			
		||||
	writeLevelCases(buf, maxDepth, c)
 | 
			
		||||
 | 
			
		||||
	_, err := buf.WriteTo(w)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func writeHeader(w io.Writer, cmd *Command) {
 | 
			
		||||
	fmt.Fprintf(w, "#compdef %s\n\n", cmd.Name())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func maxDepth(c *Command) int {
 | 
			
		||||
	if len(c.Commands()) == 0 {
 | 
			
		||||
		return 0
 | 
			
		||||
	tmpl, err := template.New("Main").Funcs(zshCompFuncMap).Parse(zshCompletionText)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("error creating zsh completion template: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	maxDepthSub := 0
 | 
			
		||||
	for _, s := range c.Commands() {
 | 
			
		||||
		subDepth := maxDepth(s)
 | 
			
		||||
		if subDepth > maxDepthSub {
 | 
			
		||||
			maxDepthSub = subDepth
 | 
			
		||||
	return tmpl.Execute(w, c.Root())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarkZshCompPositionalArgumentFile marks the specified argument (first
 | 
			
		||||
// argument is 1) as completed by file selection. patterns (e.g. "*.txt") are
 | 
			
		||||
// optional - if not provided the completion will search for all files.
 | 
			
		||||
func (c *Command) MarkZshCompPositionalArgumentFile(argPosition int, patterns ...string) error {
 | 
			
		||||
	if argPosition < 1 {
 | 
			
		||||
		return fmt.Errorf("Invalid argument position (%d)", argPosition)
 | 
			
		||||
	}
 | 
			
		||||
	annotation, err := c.zshCompGetArgsAnnotations()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if c.zshcompArgsAnnotationnIsDuplicatePosition(annotation, argPosition) {
 | 
			
		||||
		return fmt.Errorf("Duplicate annotation for positional argument at index %d", argPosition)
 | 
			
		||||
	}
 | 
			
		||||
	annotation[argPosition] = zshCompArgHint{
 | 
			
		||||
		Tipe:    zshCompArgumentFilenameComp,
 | 
			
		||||
		Options: patterns,
 | 
			
		||||
	}
 | 
			
		||||
	return c.zshCompSetArgsAnnotations(annotation)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarkZshCompPositionalArgumentWords marks the specified positional argument
 | 
			
		||||
// (first argument is 1) as completed by the provided words. At east one word
 | 
			
		||||
// must be provided, spaces within words will be offered completion with
 | 
			
		||||
// "word\ word".
 | 
			
		||||
func (c *Command) MarkZshCompPositionalArgumentWords(argPosition int, words ...string) error {
 | 
			
		||||
	if argPosition < 1 {
 | 
			
		||||
		return fmt.Errorf("Invalid argument position (%d)", argPosition)
 | 
			
		||||
	}
 | 
			
		||||
	if len(words) == 0 {
 | 
			
		||||
		return fmt.Errorf("Trying to set empty word list for positional argument %d", argPosition)
 | 
			
		||||
	}
 | 
			
		||||
	annotation, err := c.zshCompGetArgsAnnotations()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if c.zshcompArgsAnnotationnIsDuplicatePosition(annotation, argPosition) {
 | 
			
		||||
		return fmt.Errorf("Duplicate annotation for positional argument at index %d", argPosition)
 | 
			
		||||
	}
 | 
			
		||||
	annotation[argPosition] = zshCompArgHint{
 | 
			
		||||
		Tipe:    zshCompArgumentWordComp,
 | 
			
		||||
		Options: words,
 | 
			
		||||
	}
 | 
			
		||||
	return c.zshCompSetArgsAnnotations(annotation)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func zshCompExtractArgumentCompletionHintsForRendering(c *Command) ([]string, error) {
 | 
			
		||||
	var result []string
 | 
			
		||||
	annotation, err := c.zshCompGetArgsAnnotations()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	for k, v := range annotation {
 | 
			
		||||
		s, err := zshCompRenderZshCompArgHint(k, v)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		result = append(result, s)
 | 
			
		||||
	}
 | 
			
		||||
	if len(c.ValidArgs) > 0 {
 | 
			
		||||
		if _, positionOneExists := annotation[1]; !positionOneExists {
 | 
			
		||||
			s, err := zshCompRenderZshCompArgHint(1, zshCompArgHint{
 | 
			
		||||
				Tipe:    zshCompArgumentWordComp,
 | 
			
		||||
				Options: c.ValidArgs,
 | 
			
		||||
			})
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
			result = append(result, s)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return 1 + maxDepthSub
 | 
			
		||||
	sort.Strings(result)
 | 
			
		||||
	return result, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func writeLevelMapping(w io.Writer, numLevels int) {
 | 
			
		||||
	fmt.Fprintln(w, `_arguments \`)
 | 
			
		||||
	for i := 1; i <= numLevels; i++ {
 | 
			
		||||
		fmt.Fprintf(w, `  '%d: :->level%d' \`, i, i)
 | 
			
		||||
		fmt.Fprintln(w)
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Fprintf(w, `  '%d: :%s'`, numLevels+1, "_files")
 | 
			
		||||
	fmt.Fprintln(w)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func writeLevelCases(w io.Writer, maxDepth int, root *Command) {
 | 
			
		||||
	fmt.Fprintln(w, "case $state in")
 | 
			
		||||
	defer fmt.Fprintln(w, "esac")
 | 
			
		||||
 | 
			
		||||
	for i := 1; i <= maxDepth; i++ {
 | 
			
		||||
		fmt.Fprintf(w, "  level%d)\n", i)
 | 
			
		||||
		writeLevel(w, root, i)
 | 
			
		||||
		fmt.Fprintln(w, "  ;;")
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Fprintln(w, "  *)")
 | 
			
		||||
	fmt.Fprintln(w, "    _arguments '*: :_files'")
 | 
			
		||||
	fmt.Fprintln(w, "  ;;")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func writeLevel(w io.Writer, root *Command, i int) {
 | 
			
		||||
	fmt.Fprintf(w, "    case $words[%d] in\n", i)
 | 
			
		||||
	defer fmt.Fprintln(w, "    esac")
 | 
			
		||||
 | 
			
		||||
	commands := filterByLevel(root, i)
 | 
			
		||||
	byParent := groupByParent(commands)
 | 
			
		||||
 | 
			
		||||
	for p, c := range byParent {
 | 
			
		||||
		names := names(c)
 | 
			
		||||
		fmt.Fprintf(w, "      %s)\n", p)
 | 
			
		||||
		fmt.Fprintf(w, "        _arguments '%d: :(%s)'\n", i, strings.Join(names, " "))
 | 
			
		||||
		fmt.Fprintln(w, "      ;;")
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Fprintln(w, "      *)")
 | 
			
		||||
	fmt.Fprintln(w, "        _arguments '*: :_files'")
 | 
			
		||||
	fmt.Fprintln(w, "      ;;")
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func filterByLevel(c *Command, l int) []*Command {
 | 
			
		||||
	cs := make([]*Command, 0)
 | 
			
		||||
	if l == 0 {
 | 
			
		||||
		cs = append(cs, c)
 | 
			
		||||
		return cs
 | 
			
		||||
	}
 | 
			
		||||
	for _, s := range c.Commands() {
 | 
			
		||||
		cs = append(cs, filterByLevel(s, l-1)...)
 | 
			
		||||
	}
 | 
			
		||||
	return cs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func groupByParent(commands []*Command) map[string][]*Command {
 | 
			
		||||
	m := make(map[string][]*Command)
 | 
			
		||||
	for _, c := range commands {
 | 
			
		||||
		parent := c.Parent()
 | 
			
		||||
		if parent == nil {
 | 
			
		||||
			continue
 | 
			
		||||
func zshCompRenderZshCompArgHint(i int, z zshCompArgHint) (string, error) {
 | 
			
		||||
	switch t := z.Tipe; t {
 | 
			
		||||
	case zshCompArgumentFilenameComp:
 | 
			
		||||
		var globs []string
 | 
			
		||||
		for _, g := range z.Options {
 | 
			
		||||
			globs = append(globs, fmt.Sprintf(`-g "%s"`, g))
 | 
			
		||||
		}
 | 
			
		||||
		m[parent.Name()] = append(m[parent.Name()], c)
 | 
			
		||||
		return fmt.Sprintf(`'%d: :_files %s'`, i, strings.Join(globs, " ")), nil
 | 
			
		||||
	case zshCompArgumentWordComp:
 | 
			
		||||
		var words []string
 | 
			
		||||
		for _, w := range z.Options {
 | 
			
		||||
			words = append(words, fmt.Sprintf("%q", w))
 | 
			
		||||
		}
 | 
			
		||||
		return fmt.Sprintf(`'%d: :(%s)'`, i, strings.Join(words, " ")), nil
 | 
			
		||||
	default:
 | 
			
		||||
		return "", fmt.Errorf("Invalid zsh argument completion annotation: %s", t)
 | 
			
		||||
	}
 | 
			
		||||
	return m
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func names(commands []*Command) []string {
 | 
			
		||||
	ns := make([]string, len(commands))
 | 
			
		||||
	for i, c := range commands {
 | 
			
		||||
		ns[i] = c.Name()
 | 
			
		||||
	}
 | 
			
		||||
	return ns
 | 
			
		||||
func (c *Command) zshcompArgsAnnotationnIsDuplicatePosition(annotation zshCompArgsAnnotation, position int) bool {
 | 
			
		||||
	_, dup := annotation[position]
 | 
			
		||||
	return dup
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Command) zshCompGetArgsAnnotations() (zshCompArgsAnnotation, error) {
 | 
			
		||||
	annotation := make(zshCompArgsAnnotation)
 | 
			
		||||
	annotationString, ok := c.Annotations[zshCompArgumentAnnotation]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return annotation, nil
 | 
			
		||||
	}
 | 
			
		||||
	err := json.Unmarshal([]byte(annotationString), &annotation)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return annotation, fmt.Errorf("Error unmarshaling zsh argument annotation: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	return annotation, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Command) zshCompSetArgsAnnotations(annotation zshCompArgsAnnotation) error {
 | 
			
		||||
	jsn, err := json.Marshal(annotation)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("Error marshaling zsh argument annotation: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	if c.Annotations == nil {
 | 
			
		||||
		c.Annotations = make(map[string]string)
 | 
			
		||||
	}
 | 
			
		||||
	c.Annotations[zshCompArgumentAnnotation] = string(jsn)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func zshCompGenFuncName(c *Command) string {
 | 
			
		||||
	if c.HasParent() {
 | 
			
		||||
		return zshCompGenFuncName(c.Parent()) + "_" + c.Name()
 | 
			
		||||
	}
 | 
			
		||||
	return "_" + c.Name()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func zshCompExtractFlag(c *Command) []*pflag.Flag {
 | 
			
		||||
	var flags []*pflag.Flag
 | 
			
		||||
	c.LocalFlags().VisitAll(func(f *pflag.Flag) {
 | 
			
		||||
		if !f.Hidden {
 | 
			
		||||
			flags = append(flags, f)
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
	c.InheritedFlags().VisitAll(func(f *pflag.Flag) {
 | 
			
		||||
		if !f.Hidden {
 | 
			
		||||
			flags = append(flags, f)
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
	return flags
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// zshCompGenFlagEntryForArguments returns an entry that matches _arguments
 | 
			
		||||
// zsh-completion parameters. It's too complicated to generate in a template.
 | 
			
		||||
func zshCompGenFlagEntryForArguments(f *pflag.Flag) string {
 | 
			
		||||
	if f.Name == "" || f.Shorthand == "" {
 | 
			
		||||
		return zshCompGenFlagEntryForSingleOptionFlag(f)
 | 
			
		||||
	}
 | 
			
		||||
	return zshCompGenFlagEntryForMultiOptionFlag(f)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func zshCompGenFlagEntryForSingleOptionFlag(f *pflag.Flag) string {
 | 
			
		||||
	var option, multiMark, extras string
 | 
			
		||||
 | 
			
		||||
	if zshCompFlagCouldBeSpecifiedMoreThenOnce(f) {
 | 
			
		||||
		multiMark = "*"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	option = "--" + f.Name
 | 
			
		||||
	if option == "--" {
 | 
			
		||||
		option = "-" + f.Shorthand
 | 
			
		||||
	}
 | 
			
		||||
	extras = zshCompGenFlagEntryExtras(f)
 | 
			
		||||
 | 
			
		||||
	return fmt.Sprintf(`'%s%s[%s]%s'`, multiMark, option, zshCompQuoteFlagDescription(f.Usage), extras)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func zshCompGenFlagEntryForMultiOptionFlag(f *pflag.Flag) string {
 | 
			
		||||
	var options, parenMultiMark, curlyMultiMark, extras string
 | 
			
		||||
 | 
			
		||||
	if zshCompFlagCouldBeSpecifiedMoreThenOnce(f) {
 | 
			
		||||
		parenMultiMark = "*"
 | 
			
		||||
		curlyMultiMark = "\\*"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	options = fmt.Sprintf(`'(%s-%s %s--%s)'{%s-%s,%s--%s}`,
 | 
			
		||||
		parenMultiMark, f.Shorthand, parenMultiMark, f.Name, curlyMultiMark, f.Shorthand, curlyMultiMark, f.Name)
 | 
			
		||||
	extras = zshCompGenFlagEntryExtras(f)
 | 
			
		||||
 | 
			
		||||
	return fmt.Sprintf(`%s'[%s]%s'`, options, zshCompQuoteFlagDescription(f.Usage), extras)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func zshCompGenFlagEntryExtras(f *pflag.Flag) string {
 | 
			
		||||
	if f.NoOptDefVal != "" {
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	extras := ":" // allow options for flag (even without assistance)
 | 
			
		||||
	for key, values := range f.Annotations {
 | 
			
		||||
		switch key {
 | 
			
		||||
		case zshCompDirname:
 | 
			
		||||
			extras = fmt.Sprintf(":filename:_files -g %q", values[0])
 | 
			
		||||
		case BashCompFilenameExt:
 | 
			
		||||
			extras = ":filename:_files"
 | 
			
		||||
			for _, pattern := range values {
 | 
			
		||||
				extras = extras + fmt.Sprintf(` -g "%s"`, pattern)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return extras
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func zshCompFlagCouldBeSpecifiedMoreThenOnce(f *pflag.Flag) bool {
 | 
			
		||||
	return strings.Contains(f.Value.Type(), "Slice") ||
 | 
			
		||||
		strings.Contains(f.Value.Type(), "Array")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func zshCompQuoteFlagDescription(s string) string {
 | 
			
		||||
	return strings.Replace(s, "'", `'\''`, -1)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										39
									
								
								vendor/github.com/spf13/cobra/zsh_completions.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								vendor/github.com/spf13/cobra/zsh_completions.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
## Generating Zsh Completion for your cobra.Command
 | 
			
		||||
 | 
			
		||||
Cobra supports native Zsh completion generated from the root `cobra.Command`.
 | 
			
		||||
The generated completion script should be put somewhere in your `$fpath` named
 | 
			
		||||
`_<YOUR COMMAND>`.
 | 
			
		||||
 | 
			
		||||
### What's Supported
 | 
			
		||||
 | 
			
		||||
* Completion for all non-hidden subcommands using their `.Short` description.
 | 
			
		||||
* Completion for all non-hidden flags using the following rules:
 | 
			
		||||
  * Filename completion works by marking the flag with `cmd.MarkFlagFilename...`
 | 
			
		||||
    family of commands.
 | 
			
		||||
  * The requirement for argument to the flag is decided by the `.NoOptDefVal`
 | 
			
		||||
    flag value - if it's empty then completion will expect an argument.
 | 
			
		||||
  * Flags of one of the various `*Array` and `*Slice` types supports multiple
 | 
			
		||||
    specifications (with or without argument depending on the specific type).
 | 
			
		||||
* Completion of positional arguments using the following rules:
 | 
			
		||||
  * Argument position for all options below starts at `1`. If argument position
 | 
			
		||||
    `0` is requested it will raise an error.
 | 
			
		||||
  * Use `command.MarkZshCompPositionalArgumentFile` to complete filenames. Glob
 | 
			
		||||
    patterns (e.g. `"*.log"`) are optional - if not specified it will offer to
 | 
			
		||||
    complete all file types.
 | 
			
		||||
  * Use `command.MarkZshCompPositionalArgumentWords` to offer specific words for
 | 
			
		||||
    completion. At least one word is required.
 | 
			
		||||
  * It's possible to specify completion for some arguments and leave some
 | 
			
		||||
    unspecified (e.g. offer words for second argument but nothing for first
 | 
			
		||||
    argument). This will cause no completion for first argument but words
 | 
			
		||||
    completion for second argument.
 | 
			
		||||
  * If no argument completion was specified for 1st argument (but optionally was
 | 
			
		||||
    specified for 2nd) and the command has `ValidArgs` it will be used as
 | 
			
		||||
    completion options for 1st argument.
 | 
			
		||||
  * Argument completions only offered for commands with no subcommands.
 | 
			
		||||
 | 
			
		||||
### What's not yet Supported
 | 
			
		||||
 | 
			
		||||
* Custom completion scripts are not supported yet (We should probably create zsh
 | 
			
		||||
  specific one, doesn't make sense to re-use the bash one as the functions will
 | 
			
		||||
  be different).
 | 
			
		||||
* Whatever other feature you're looking for and doesn't exist :)
 | 
			
		||||
							
								
								
									
										7
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							@@ -139,7 +139,7 @@ github.com/bazelbuild/buildtools/wspace
 | 
			
		||||
github.com/beorn7/perks/quantile
 | 
			
		||||
# github.com/blang/semver v3.5.0+incompatible => github.com/blang/semver v3.5.0+incompatible
 | 
			
		||||
github.com/blang/semver
 | 
			
		||||
# github.com/caddyserver/caddy v1.0.1 => github.com/caddyserver/caddy v1.0.1
 | 
			
		||||
# github.com/caddyserver/caddy v1.0.3 => github.com/caddyserver/caddy v1.0.3
 | 
			
		||||
github.com/caddyserver/caddy/caddyfile
 | 
			
		||||
# github.com/cespare/prettybench v0.0.0-20150116022406-03b8cfe5406c => github.com/cespare/prettybench v0.0.0-20150116022406-03b8cfe5406c
 | 
			
		||||
github.com/cespare/prettybench
 | 
			
		||||
@@ -190,6 +190,9 @@ github.com/containernetworking/cni/pkg/types
 | 
			
		||||
github.com/containernetworking/cni/pkg/types/020
 | 
			
		||||
github.com/containernetworking/cni/pkg/types/current
 | 
			
		||||
github.com/containernetworking/cni/pkg/version
 | 
			
		||||
# github.com/coredns/corefile-migration v1.0.2 => github.com/coredns/corefile-migration v1.0.2
 | 
			
		||||
github.com/coredns/corefile-migration/migration
 | 
			
		||||
github.com/coredns/corefile-migration/migration/corefile
 | 
			
		||||
# github.com/coreos/bbolt v1.3.1-coreos.6 => github.com/coreos/bbolt v1.3.1-coreos.6
 | 
			
		||||
github.com/coreos/bbolt
 | 
			
		||||
# github.com/coreos/etcd v3.3.13+incompatible => github.com/coreos/etcd v3.3.13+incompatible
 | 
			
		||||
@@ -743,7 +746,7 @@ github.com/spf13/afero
 | 
			
		||||
github.com/spf13/afero/mem
 | 
			
		||||
# github.com/spf13/cast v1.3.0 => github.com/spf13/cast v1.3.0
 | 
			
		||||
github.com/spf13/cast
 | 
			
		||||
# github.com/spf13/cobra v0.0.4 => github.com/spf13/cobra v0.0.4
 | 
			
		||||
# github.com/spf13/cobra v0.0.5 => github.com/spf13/cobra v0.0.5
 | 
			
		||||
github.com/spf13/cobra
 | 
			
		||||
github.com/spf13/cobra/doc
 | 
			
		||||
# github.com/spf13/jwalterweatherman v1.1.0 => github.com/spf13/jwalterweatherman v1.1.0
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user