mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	fix godeps on master broken in #26335
This commit is contained in:
		
							
								
								
									
										5
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										5
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							@@ -478,11 +478,6 @@
 | 
			
		||||
			"Comment": "v2.3.0-282-g8b320e7",
 | 
			
		||||
			"Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/coreos/go-etcd/etcd",
 | 
			
		||||
			"Comment": "v2.0.0-38-g003851b",
 | 
			
		||||
			"Rev": "003851be7bb0694fe3cc457a49529a19388ee7cf"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/coreos/go-oidc/http",
 | 
			
		||||
			"Rev": "5cf2aa52da8c574d3aa4458f471ad6ae2240fe6b"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										210
									
								
								Godeps/LICENSES
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										210
									
								
								Godeps/LICENSES
									
									
									
										generated
									
									
									
								
							@@ -18458,216 +18458,6 @@ SOFTWARE.
 | 
			
		||||
================================================================================
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
================================================================================
 | 
			
		||||
= vendor/github.com/coreos/go-etcd/etcd 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/coreos/go-etcd/LICENSE 3b83ef96387f14655fc854ddc3c6bd57  -
 | 
			
		||||
================================================================================
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
================================================================================
 | 
			
		||||
= vendor/github.com/coreos/go-oidc/http licensed under: =
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										202
									
								
								vendor/github.com/coreos/go-etcd/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										202
									
								
								vendor/github.com/coreos/go-etcd/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,202 +0,0 @@
 | 
			
		||||
 | 
			
		||||
                                 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.
 | 
			
		||||
							
								
								
									
										23
									
								
								vendor/github.com/coreos/go-etcd/etcd/add_child.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								vendor/github.com/coreos/go-etcd/etcd/add_child.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,23 +0,0 @@
 | 
			
		||||
package etcd
 | 
			
		||||
 | 
			
		||||
// Add a new directory with a random etcd-generated key under the given path.
 | 
			
		||||
func (c *Client) AddChildDir(key string, ttl uint64) (*Response, error) {
 | 
			
		||||
	raw, err := c.post(key, "", ttl)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return raw.Unmarshal()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Add a new file with a random etcd-generated key under the given path.
 | 
			
		||||
func (c *Client) AddChild(key string, value string, ttl uint64) (*Response, error) {
 | 
			
		||||
	raw, err := c.post(key, value, ttl)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return raw.Unmarshal()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										476
									
								
								vendor/github.com/coreos/go-etcd/etcd/client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										476
									
								
								vendor/github.com/coreos/go-etcd/etcd/client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,476 +0,0 @@
 | 
			
		||||
package etcd
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"crypto/tls"
 | 
			
		||||
	"crypto/x509"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"math/rand"
 | 
			
		||||
	"net"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// See SetConsistency for how to use these constants.
 | 
			
		||||
const (
 | 
			
		||||
	// Using strings rather than iota because the consistency level
 | 
			
		||||
	// could be persisted to disk, so it'd be better to use
 | 
			
		||||
	// human-readable values.
 | 
			
		||||
	STRONG_CONSISTENCY = "STRONG"
 | 
			
		||||
	WEAK_CONSISTENCY   = "WEAK"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	defaultBufferSize = 10
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	rand.Seed(int64(time.Now().Nanosecond()))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Config struct {
 | 
			
		||||
	CertFile    string        `json:"certFile"`
 | 
			
		||||
	KeyFile     string        `json:"keyFile"`
 | 
			
		||||
	CaCertFile  []string      `json:"caCertFiles"`
 | 
			
		||||
	DialTimeout time.Duration `json:"timeout"`
 | 
			
		||||
	Consistency string        `json:"consistency"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type credentials struct {
 | 
			
		||||
	username string
 | 
			
		||||
	password string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Client struct {
 | 
			
		||||
	config      Config   `json:"config"`
 | 
			
		||||
	cluster     *Cluster `json:"cluster"`
 | 
			
		||||
	httpClient  *http.Client
 | 
			
		||||
	credentials *credentials
 | 
			
		||||
	transport   *http.Transport
 | 
			
		||||
	persistence io.Writer
 | 
			
		||||
	cURLch      chan string
 | 
			
		||||
	// CheckRetry can be used to control the policy for failed requests
 | 
			
		||||
	// and modify the cluster if needed.
 | 
			
		||||
	// The client calls it before sending requests again, and
 | 
			
		||||
	// stops retrying if CheckRetry returns some error. The cases that
 | 
			
		||||
	// this function needs to handle include no response and unexpected
 | 
			
		||||
	// http status code of response.
 | 
			
		||||
	// If CheckRetry is nil, client will call the default one
 | 
			
		||||
	// `DefaultCheckRetry`.
 | 
			
		||||
	// Argument cluster is the etcd.Cluster object that these requests have been made on.
 | 
			
		||||
	// Argument numReqs is the number of http.Requests that have been made so far.
 | 
			
		||||
	// Argument lastResp is the http.Responses from the last request.
 | 
			
		||||
	// Argument err is the reason of the failure.
 | 
			
		||||
	CheckRetry func(cluster *Cluster, numReqs int,
 | 
			
		||||
		lastResp http.Response, err error) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewClient create a basic client that is configured to be used
 | 
			
		||||
// with the given machine list.
 | 
			
		||||
func NewClient(machines []string) *Client {
 | 
			
		||||
	config := Config{
 | 
			
		||||
		// default timeout is one second
 | 
			
		||||
		DialTimeout: time.Second,
 | 
			
		||||
		Consistency: WEAK_CONSISTENCY,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	client := &Client{
 | 
			
		||||
		cluster: NewCluster(machines),
 | 
			
		||||
		config:  config,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	client.initHTTPClient()
 | 
			
		||||
	client.saveConfig()
 | 
			
		||||
 | 
			
		||||
	return client
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewTLSClient create a basic client with TLS configuration
 | 
			
		||||
func NewTLSClient(machines []string, cert, key, caCert string) (*Client, error) {
 | 
			
		||||
	// overwrite the default machine to use https
 | 
			
		||||
	if len(machines) == 0 {
 | 
			
		||||
		machines = []string{"https://127.0.0.1:4001"}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	config := Config{
 | 
			
		||||
		// default timeout is one second
 | 
			
		||||
		DialTimeout: time.Second,
 | 
			
		||||
		Consistency: WEAK_CONSISTENCY,
 | 
			
		||||
		CertFile:    cert,
 | 
			
		||||
		KeyFile:     key,
 | 
			
		||||
		CaCertFile:  make([]string, 0),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	client := &Client{
 | 
			
		||||
		cluster: NewCluster(machines),
 | 
			
		||||
		config:  config,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err := client.initHTTPSClient(cert, key)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = client.AddRootCA(caCert)
 | 
			
		||||
 | 
			
		||||
	client.saveConfig()
 | 
			
		||||
 | 
			
		||||
	return client, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewClientFromFile creates a client from a given file path.
 | 
			
		||||
// The given file is expected to use the JSON format.
 | 
			
		||||
func NewClientFromFile(fpath string) (*Client, error) {
 | 
			
		||||
	fi, err := os.Open(fpath)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	defer func() {
 | 
			
		||||
		if err := fi.Close(); err != nil {
 | 
			
		||||
			panic(err)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	return NewClientFromReader(fi)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewClientFromReader creates a Client configured from a given reader.
 | 
			
		||||
// The configuration is expected to use the JSON format.
 | 
			
		||||
func NewClientFromReader(reader io.Reader) (*Client, error) {
 | 
			
		||||
	c := new(Client)
 | 
			
		||||
 | 
			
		||||
	b, err := ioutil.ReadAll(reader)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = json.Unmarshal(b, c)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if c.config.CertFile == "" {
 | 
			
		||||
		c.initHTTPClient()
 | 
			
		||||
	} else {
 | 
			
		||||
		err = c.initHTTPSClient(c.config.CertFile, c.config.KeyFile)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, caCert := range c.config.CaCertFile {
 | 
			
		||||
		if err := c.AddRootCA(caCert); err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return c, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Override the Client's HTTP Transport object
 | 
			
		||||
func (c *Client) SetTransport(tr *http.Transport) {
 | 
			
		||||
	c.httpClient.Transport = tr
 | 
			
		||||
	c.transport = tr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) SetCredentials(username, password string) {
 | 
			
		||||
	c.credentials = &credentials{username, password}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) Close() {
 | 
			
		||||
	c.transport.DisableKeepAlives = true
 | 
			
		||||
	c.transport.CloseIdleConnections()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// initHTTPClient initializes a HTTP client for etcd client
 | 
			
		||||
func (c *Client) initHTTPClient() {
 | 
			
		||||
	c.transport = &http.Transport{
 | 
			
		||||
		Dial: c.DefaultDial,
 | 
			
		||||
		TLSClientConfig: &tls.Config{
 | 
			
		||||
			InsecureSkipVerify: true,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	c.httpClient = &http.Client{Transport: c.transport}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// initHTTPClient initializes a HTTPS client for etcd client
 | 
			
		||||
func (c *Client) initHTTPSClient(cert, key string) error {
 | 
			
		||||
	if cert == "" || key == "" {
 | 
			
		||||
		return errors.New("Require both cert and key path")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tlsCert, err := tls.LoadX509KeyPair(cert, key)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tlsConfig := &tls.Config{
 | 
			
		||||
		Certificates:       []tls.Certificate{tlsCert},
 | 
			
		||||
		InsecureSkipVerify: true,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.transport = &http.Transport{
 | 
			
		||||
		TLSClientConfig: tlsConfig,
 | 
			
		||||
		Dial:            c.DefaultDial,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.httpClient = &http.Client{Transport: c.transport}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetPersistence sets a writer to which the config will be
 | 
			
		||||
// written every time it's changed.
 | 
			
		||||
func (c *Client) SetPersistence(writer io.Writer) {
 | 
			
		||||
	c.persistence = writer
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetConsistency changes the consistency level of the client.
 | 
			
		||||
//
 | 
			
		||||
// When consistency is set to STRONG_CONSISTENCY, all requests,
 | 
			
		||||
// including GET, are sent to the leader.  This means that, assuming
 | 
			
		||||
// the absence of leader failures, GET requests are guaranteed to see
 | 
			
		||||
// the changes made by previous requests.
 | 
			
		||||
//
 | 
			
		||||
// When consistency is set to WEAK_CONSISTENCY, other requests
 | 
			
		||||
// are still sent to the leader, but GET requests are sent to a
 | 
			
		||||
// random server from the server pool.  This reduces the read
 | 
			
		||||
// load on the leader, but it's not guaranteed that the GET requests
 | 
			
		||||
// will see changes made by previous requests (they might have not
 | 
			
		||||
// yet been committed on non-leader servers).
 | 
			
		||||
func (c *Client) SetConsistency(consistency string) error {
 | 
			
		||||
	if !(consistency == STRONG_CONSISTENCY || consistency == WEAK_CONSISTENCY) {
 | 
			
		||||
		return errors.New("The argument must be either STRONG_CONSISTENCY or WEAK_CONSISTENCY.")
 | 
			
		||||
	}
 | 
			
		||||
	c.config.Consistency = consistency
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sets the DialTimeout value
 | 
			
		||||
func (c *Client) SetDialTimeout(d time.Duration) {
 | 
			
		||||
	c.config.DialTimeout = d
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddRootCA adds a root CA cert for the etcd client
 | 
			
		||||
func (c *Client) AddRootCA(caCert string) error {
 | 
			
		||||
	if c.httpClient == nil {
 | 
			
		||||
		return errors.New("Client has not been initialized yet!")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	certBytes, err := ioutil.ReadFile(caCert)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tr, ok := c.httpClient.Transport.(*http.Transport)
 | 
			
		||||
 | 
			
		||||
	if !ok {
 | 
			
		||||
		panic("AddRootCA(): Transport type assert should not fail")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if tr.TLSClientConfig.RootCAs == nil {
 | 
			
		||||
		caCertPool := x509.NewCertPool()
 | 
			
		||||
		ok = caCertPool.AppendCertsFromPEM(certBytes)
 | 
			
		||||
		if ok {
 | 
			
		||||
			tr.TLSClientConfig.RootCAs = caCertPool
 | 
			
		||||
		}
 | 
			
		||||
		tr.TLSClientConfig.InsecureSkipVerify = false
 | 
			
		||||
	} else {
 | 
			
		||||
		ok = tr.TLSClientConfig.RootCAs.AppendCertsFromPEM(certBytes)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !ok {
 | 
			
		||||
		err = errors.New("Unable to load caCert")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.config.CaCertFile = append(c.config.CaCertFile, caCert)
 | 
			
		||||
	c.saveConfig()
 | 
			
		||||
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetCluster updates cluster information using the given machine list.
 | 
			
		||||
func (c *Client) SetCluster(machines []string) bool {
 | 
			
		||||
	success := c.internalSyncCluster(machines)
 | 
			
		||||
	return success
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) GetCluster() []string {
 | 
			
		||||
	return c.cluster.Machines
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SyncCluster updates the cluster information using the internal machine list.
 | 
			
		||||
// If no members are found, the intenral machine list is left untouched.
 | 
			
		||||
func (c *Client) SyncCluster() bool {
 | 
			
		||||
	return c.internalSyncCluster(c.cluster.Machines)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// internalSyncCluster syncs cluster information using the given machine list.
 | 
			
		||||
func (c *Client) internalSyncCluster(machines []string) bool {
 | 
			
		||||
	// comma-separated list of machines in the cluster.
 | 
			
		||||
	members := ""
 | 
			
		||||
 | 
			
		||||
	for _, machine := range machines {
 | 
			
		||||
		httpPath := c.createHttpPath(machine, path.Join(version, "members"))
 | 
			
		||||
		resp, err := c.httpClient.Get(httpPath)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			// try another machine in the cluster
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if resp.StatusCode != http.StatusOK { // fall-back to old endpoint
 | 
			
		||||
			httpPath := c.createHttpPath(machine, path.Join(version, "machines"))
 | 
			
		||||
			resp, err := c.httpClient.Get(httpPath)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				// try another machine in the cluster
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			b, err := ioutil.ReadAll(resp.Body)
 | 
			
		||||
			resp.Body.Close()
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				// try another machine in the cluster
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			members = string(b)
 | 
			
		||||
		} else {
 | 
			
		||||
			b, err := ioutil.ReadAll(resp.Body)
 | 
			
		||||
			resp.Body.Close()
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				// try another machine in the cluster
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			var mCollection memberCollection
 | 
			
		||||
			if err := json.Unmarshal(b, &mCollection); err != nil {
 | 
			
		||||
				// try another machine
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			urls := make([]string, 0)
 | 
			
		||||
			for _, m := range mCollection {
 | 
			
		||||
				urls = append(urls, m.ClientURLs...)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			members = strings.Join(urls, ",")
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// We should never do an empty cluster update.
 | 
			
		||||
		if members == "" {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// update Machines List
 | 
			
		||||
		c.cluster.updateFromStr(members)
 | 
			
		||||
		logger.Debug("sync.machines ", c.cluster.Machines)
 | 
			
		||||
		c.saveConfig()
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// createHttpPath creates a complete HTTP URL.
 | 
			
		||||
// serverName should contain both the host name and a port number, if any.
 | 
			
		||||
func (c *Client) createHttpPath(serverName string, _path string) string {
 | 
			
		||||
	u, err := url.Parse(serverName)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	u.Path = path.Join(u.Path, _path)
 | 
			
		||||
 | 
			
		||||
	if u.Scheme == "" {
 | 
			
		||||
		u.Scheme = "http"
 | 
			
		||||
	}
 | 
			
		||||
	return u.String()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DefaultDial attempts to open a TCP connection to the provided address, explicitly
 | 
			
		||||
// enabling keep-alives with a one-second interval.
 | 
			
		||||
func (c *Client) DefaultDial(network, addr string) (net.Conn, error) {
 | 
			
		||||
	dialer := net.Dialer{
 | 
			
		||||
		Timeout:   c.config.DialTimeout,
 | 
			
		||||
		KeepAlive: time.Second,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return dialer.Dial(network, addr)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) OpenCURL() {
 | 
			
		||||
	c.cURLch = make(chan string, defaultBufferSize)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) CloseCURL() {
 | 
			
		||||
	c.cURLch = nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) sendCURL(command string) {
 | 
			
		||||
	go func() {
 | 
			
		||||
		select {
 | 
			
		||||
		case c.cURLch <- command:
 | 
			
		||||
		default:
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) RecvCURL() string {
 | 
			
		||||
	return <-c.cURLch
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// saveConfig saves the current config using c.persistence.
 | 
			
		||||
func (c *Client) saveConfig() error {
 | 
			
		||||
	if c.persistence != nil {
 | 
			
		||||
		b, err := json.Marshal(c)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		_, err = c.persistence.Write(b)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarshalJSON implements the Marshaller interface
 | 
			
		||||
// as defined by the standard JSON package.
 | 
			
		||||
func (c *Client) MarshalJSON() ([]byte, error) {
 | 
			
		||||
	b, err := json.Marshal(struct {
 | 
			
		||||
		Config  Config   `json:"config"`
 | 
			
		||||
		Cluster *Cluster `json:"cluster"`
 | 
			
		||||
	}{
 | 
			
		||||
		Config:  c.config,
 | 
			
		||||
		Cluster: c.cluster,
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return b, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UnmarshalJSON implements the Unmarshaller interface
 | 
			
		||||
// as defined by the standard JSON package.
 | 
			
		||||
func (c *Client) UnmarshalJSON(b []byte) error {
 | 
			
		||||
	temp := struct {
 | 
			
		||||
		Config  Config   `json:"config"`
 | 
			
		||||
		Cluster *Cluster `json:"cluster"`
 | 
			
		||||
	}{}
 | 
			
		||||
	err := json.Unmarshal(b, &temp)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.cluster = temp.Cluster
 | 
			
		||||
	c.config = temp.Config
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										54
									
								
								vendor/github.com/coreos/go-etcd/etcd/cluster.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										54
									
								
								vendor/github.com/coreos/go-etcd/etcd/cluster.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,54 +0,0 @@
 | 
			
		||||
package etcd
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"math/rand"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Cluster struct {
 | 
			
		||||
	Leader   string   `json:"leader"`
 | 
			
		||||
	Machines []string `json:"machines"`
 | 
			
		||||
	picked   int
 | 
			
		||||
	mu       sync.RWMutex
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewCluster(machines []string) *Cluster {
 | 
			
		||||
	// if an empty slice was sent in then just assume HTTP 4001 on localhost
 | 
			
		||||
	if len(machines) == 0 {
 | 
			
		||||
		machines = []string{"http://127.0.0.1:4001"}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	machines = shuffleStringSlice(machines)
 | 
			
		||||
	logger.Debug("Shuffle cluster machines", machines)
 | 
			
		||||
	// default leader and machines
 | 
			
		||||
	return &Cluster{
 | 
			
		||||
		Leader:   "",
 | 
			
		||||
		Machines: machines,
 | 
			
		||||
		picked:   rand.Intn(len(machines)),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cl *Cluster) failure() {
 | 
			
		||||
	cl.mu.Lock()
 | 
			
		||||
	defer cl.mu.Unlock()
 | 
			
		||||
	cl.picked = (cl.picked + 1) % len(cl.Machines)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cl *Cluster) pick() string {
 | 
			
		||||
	cl.mu.Lock()
 | 
			
		||||
	defer cl.mu.Unlock()
 | 
			
		||||
	return cl.Machines[cl.picked]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cl *Cluster) updateFromStr(machines string) {
 | 
			
		||||
	cl.mu.Lock()
 | 
			
		||||
	defer cl.mu.Unlock()
 | 
			
		||||
 | 
			
		||||
	cl.Machines = strings.Split(machines, ",")
 | 
			
		||||
	for i := range cl.Machines {
 | 
			
		||||
		cl.Machines[i] = strings.TrimSpace(cl.Machines[i])
 | 
			
		||||
	}
 | 
			
		||||
	cl.Machines = shuffleStringSlice(cl.Machines)
 | 
			
		||||
	cl.picked = rand.Intn(len(cl.Machines))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										34
									
								
								vendor/github.com/coreos/go-etcd/etcd/compare_and_delete.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										34
									
								
								vendor/github.com/coreos/go-etcd/etcd/compare_and_delete.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,34 +0,0 @@
 | 
			
		||||
package etcd
 | 
			
		||||
 | 
			
		||||
import "fmt"
 | 
			
		||||
 | 
			
		||||
func (c *Client) CompareAndDelete(key string, prevValue string, prevIndex uint64) (*Response, error) {
 | 
			
		||||
	raw, err := c.RawCompareAndDelete(key, prevValue, prevIndex)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return raw.Unmarshal()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) RawCompareAndDelete(key string, prevValue string, prevIndex uint64) (*RawResponse, error) {
 | 
			
		||||
	if prevValue == "" && prevIndex == 0 {
 | 
			
		||||
		return nil, fmt.Errorf("You must give either prevValue or prevIndex.")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	options := Options{}
 | 
			
		||||
	if prevValue != "" {
 | 
			
		||||
		options["prevValue"] = prevValue
 | 
			
		||||
	}
 | 
			
		||||
	if prevIndex != 0 {
 | 
			
		||||
		options["prevIndex"] = prevIndex
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	raw, err := c.delete(key, options)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return raw, err
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										36
									
								
								vendor/github.com/coreos/go-etcd/etcd/compare_and_swap.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										36
									
								
								vendor/github.com/coreos/go-etcd/etcd/compare_and_swap.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,36 +0,0 @@
 | 
			
		||||
package etcd
 | 
			
		||||
 | 
			
		||||
import "fmt"
 | 
			
		||||
 | 
			
		||||
func (c *Client) CompareAndSwap(key string, value string, ttl uint64,
 | 
			
		||||
	prevValue string, prevIndex uint64) (*Response, error) {
 | 
			
		||||
	raw, err := c.RawCompareAndSwap(key, value, ttl, prevValue, prevIndex)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return raw.Unmarshal()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) RawCompareAndSwap(key string, value string, ttl uint64,
 | 
			
		||||
	prevValue string, prevIndex uint64) (*RawResponse, error) {
 | 
			
		||||
	if prevValue == "" && prevIndex == 0 {
 | 
			
		||||
		return nil, fmt.Errorf("You must give either prevValue or prevIndex.")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	options := Options{}
 | 
			
		||||
	if prevValue != "" {
 | 
			
		||||
		options["prevValue"] = prevValue
 | 
			
		||||
	}
 | 
			
		||||
	if prevIndex != 0 {
 | 
			
		||||
		options["prevIndex"] = prevIndex
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	raw, err := c.put(key, value, ttl, options)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return raw, err
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										55
									
								
								vendor/github.com/coreos/go-etcd/etcd/debug.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										55
									
								
								vendor/github.com/coreos/go-etcd/etcd/debug.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,55 +0,0 @@
 | 
			
		||||
package etcd
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"log"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var logger *etcdLogger
 | 
			
		||||
 | 
			
		||||
func SetLogger(l *log.Logger) {
 | 
			
		||||
	logger = &etcdLogger{l}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetLogger() *log.Logger {
 | 
			
		||||
	return logger.log
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type etcdLogger struct {
 | 
			
		||||
	log *log.Logger
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *etcdLogger) Debug(args ...interface{}) {
 | 
			
		||||
	msg := "DEBUG: " + fmt.Sprint(args...)
 | 
			
		||||
	p.log.Println(msg)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *etcdLogger) Debugf(f string, args ...interface{}) {
 | 
			
		||||
	msg := "DEBUG: " + fmt.Sprintf(f, args...)
 | 
			
		||||
	// Append newline if necessary
 | 
			
		||||
	if !strings.HasSuffix(msg, "\n") {
 | 
			
		||||
		msg = msg + "\n"
 | 
			
		||||
	}
 | 
			
		||||
	p.log.Print(msg)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *etcdLogger) Warning(args ...interface{}) {
 | 
			
		||||
	msg := "WARNING: " + fmt.Sprint(args...)
 | 
			
		||||
	p.log.Println(msg)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *etcdLogger) Warningf(f string, args ...interface{}) {
 | 
			
		||||
	msg := "WARNING: " + fmt.Sprintf(f, args...)
 | 
			
		||||
	// Append newline if necessary
 | 
			
		||||
	if !strings.HasSuffix(msg, "\n") {
 | 
			
		||||
		msg = msg + "\n"
 | 
			
		||||
	}
 | 
			
		||||
	p.log.Print(msg)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	// Default logger uses the go default log.
 | 
			
		||||
	SetLogger(log.New(ioutil.Discard, "go-etcd", log.LstdFlags))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										40
									
								
								vendor/github.com/coreos/go-etcd/etcd/delete.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										40
									
								
								vendor/github.com/coreos/go-etcd/etcd/delete.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,40 +0,0 @@
 | 
			
		||||
package etcd
 | 
			
		||||
 | 
			
		||||
// Delete deletes the given key.
 | 
			
		||||
//
 | 
			
		||||
// When recursive set to false, if the key points to a
 | 
			
		||||
// directory the method will fail.
 | 
			
		||||
//
 | 
			
		||||
// When recursive set to true, if the key points to a file,
 | 
			
		||||
// the file will be deleted; if the key points to a directory,
 | 
			
		||||
// then everything under the directory (including all child directories)
 | 
			
		||||
// will be deleted.
 | 
			
		||||
func (c *Client) Delete(key string, recursive bool) (*Response, error) {
 | 
			
		||||
	raw, err := c.RawDelete(key, recursive, false)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return raw.Unmarshal()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DeleteDir deletes an empty directory or a key value pair
 | 
			
		||||
func (c *Client) DeleteDir(key string) (*Response, error) {
 | 
			
		||||
	raw, err := c.RawDelete(key, false, true)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return raw.Unmarshal()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) RawDelete(key string, recursive bool, dir bool) (*RawResponse, error) {
 | 
			
		||||
	ops := Options{
 | 
			
		||||
		"recursive": recursive,
 | 
			
		||||
		"dir":       dir,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return c.delete(key, ops)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										49
									
								
								vendor/github.com/coreos/go-etcd/etcd/error.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										49
									
								
								vendor/github.com/coreos/go-etcd/etcd/error.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,49 +0,0 @@
 | 
			
		||||
package etcd
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	ErrCodeEtcdNotReachable    = 501
 | 
			
		||||
	ErrCodeUnhandledHTTPStatus = 502
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	errorMap = map[int]string{
 | 
			
		||||
		ErrCodeEtcdNotReachable: "All the given peers are not reachable",
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type EtcdError struct {
 | 
			
		||||
	ErrorCode int    `json:"errorCode"`
 | 
			
		||||
	Message   string `json:"message"`
 | 
			
		||||
	Cause     string `json:"cause,omitempty"`
 | 
			
		||||
	Index     uint64 `json:"index"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e EtcdError) Error() string {
 | 
			
		||||
	return fmt.Sprintf("%v: %v (%v) [%v]", e.ErrorCode, e.Message, e.Cause, e.Index)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newError(errorCode int, cause string, index uint64) *EtcdError {
 | 
			
		||||
	return &EtcdError{
 | 
			
		||||
		ErrorCode: errorCode,
 | 
			
		||||
		Message:   errorMap[errorCode],
 | 
			
		||||
		Cause:     cause,
 | 
			
		||||
		Index:     index,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func handleError(b []byte) error {
 | 
			
		||||
	etcdErr := new(EtcdError)
 | 
			
		||||
 | 
			
		||||
	err := json.Unmarshal(b, etcdErr)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logger.Warningf("cannot unmarshal etcd error: %v", err)
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return etcdErr
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										32
									
								
								vendor/github.com/coreos/go-etcd/etcd/get.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								vendor/github.com/coreos/go-etcd/etcd/get.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,32 +0,0 @@
 | 
			
		||||
package etcd
 | 
			
		||||
 | 
			
		||||
// Get gets the file or directory associated with the given key.
 | 
			
		||||
// If the key points to a directory, files and directories under
 | 
			
		||||
// it will be returned in sorted or unsorted order, depending on
 | 
			
		||||
// the sort flag.
 | 
			
		||||
// If recursive is set to false, contents under child directories
 | 
			
		||||
// will not be returned.
 | 
			
		||||
// If recursive is set to true, all the contents will be returned.
 | 
			
		||||
func (c *Client) Get(key string, sort, recursive bool) (*Response, error) {
 | 
			
		||||
	raw, err := c.RawGet(key, sort, recursive)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return raw.Unmarshal()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) RawGet(key string, sort, recursive bool) (*RawResponse, error) {
 | 
			
		||||
	var q bool
 | 
			
		||||
	if c.config.Consistency == STRONG_CONSISTENCY {
 | 
			
		||||
		q = true
 | 
			
		||||
	}
 | 
			
		||||
	ops := Options{
 | 
			
		||||
		"recursive": recursive,
 | 
			
		||||
		"sorted":    sort,
 | 
			
		||||
		"quorum":    q,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return c.get(key, ops)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								vendor/github.com/coreos/go-etcd/etcd/member.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										30
									
								
								vendor/github.com/coreos/go-etcd/etcd/member.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,30 +0,0 @@
 | 
			
		||||
package etcd
 | 
			
		||||
 | 
			
		||||
import "encoding/json"
 | 
			
		||||
 | 
			
		||||
type Member struct {
 | 
			
		||||
	ID         string   `json:"id"`
 | 
			
		||||
	Name       string   `json:"name"`
 | 
			
		||||
	PeerURLs   []string `json:"peerURLs"`
 | 
			
		||||
	ClientURLs []string `json:"clientURLs"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type memberCollection []Member
 | 
			
		||||
 | 
			
		||||
func (c *memberCollection) UnmarshalJSON(data []byte) error {
 | 
			
		||||
	d := struct {
 | 
			
		||||
		Members []Member
 | 
			
		||||
	}{}
 | 
			
		||||
 | 
			
		||||
	if err := json.Unmarshal(data, &d); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if d.Members == nil {
 | 
			
		||||
		*c = make([]Member, 0)
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*c = d.Members
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										72
									
								
								vendor/github.com/coreos/go-etcd/etcd/options.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										72
									
								
								vendor/github.com/coreos/go-etcd/etcd/options.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,72 +0,0 @@
 | 
			
		||||
package etcd
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"reflect"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Options map[string]interface{}
 | 
			
		||||
 | 
			
		||||
// An internally-used data structure that represents a mapping
 | 
			
		||||
// between valid options and their kinds
 | 
			
		||||
type validOptions map[string]reflect.Kind
 | 
			
		||||
 | 
			
		||||
// Valid options for GET, PUT, POST, DELETE
 | 
			
		||||
// Using CAPITALIZED_UNDERSCORE to emphasize that these
 | 
			
		||||
// values are meant to be used as constants.
 | 
			
		||||
var (
 | 
			
		||||
	VALID_GET_OPTIONS = validOptions{
 | 
			
		||||
		"recursive": reflect.Bool,
 | 
			
		||||
		"quorum":    reflect.Bool,
 | 
			
		||||
		"sorted":    reflect.Bool,
 | 
			
		||||
		"wait":      reflect.Bool,
 | 
			
		||||
		"waitIndex": reflect.Uint64,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	VALID_PUT_OPTIONS = validOptions{
 | 
			
		||||
		"prevValue": reflect.String,
 | 
			
		||||
		"prevIndex": reflect.Uint64,
 | 
			
		||||
		"prevExist": reflect.Bool,
 | 
			
		||||
		"dir":       reflect.Bool,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	VALID_POST_OPTIONS = validOptions{}
 | 
			
		||||
 | 
			
		||||
	VALID_DELETE_OPTIONS = validOptions{
 | 
			
		||||
		"recursive": reflect.Bool,
 | 
			
		||||
		"dir":       reflect.Bool,
 | 
			
		||||
		"prevValue": reflect.String,
 | 
			
		||||
		"prevIndex": reflect.Uint64,
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Convert options to a string of HTML parameters
 | 
			
		||||
func (ops Options) toParameters(validOps validOptions) (string, error) {
 | 
			
		||||
	p := "?"
 | 
			
		||||
	values := url.Values{}
 | 
			
		||||
 | 
			
		||||
	if ops == nil {
 | 
			
		||||
		return "", nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for k, v := range ops {
 | 
			
		||||
		// Check if the given option is valid (that it exists)
 | 
			
		||||
		kind := validOps[k]
 | 
			
		||||
		if kind == reflect.Invalid {
 | 
			
		||||
			return "", fmt.Errorf("Invalid option: %v", k)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Check if the given option is of the valid type
 | 
			
		||||
		t := reflect.TypeOf(v)
 | 
			
		||||
		if kind != t.Kind() {
 | 
			
		||||
			return "", fmt.Errorf("Option %s should be of %v kind, not of %v kind.",
 | 
			
		||||
				k, kind, t.Kind())
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		values.Set(k, fmt.Sprintf("%v", v))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p += values.Encode()
 | 
			
		||||
	return p, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										403
									
								
								vendor/github.com/coreos/go-etcd/etcd/requests.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										403
									
								
								vendor/github.com/coreos/go-etcd/etcd/requests.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,403 +0,0 @@
 | 
			
		||||
package etcd
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"path"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Errors introduced by handling requests
 | 
			
		||||
var (
 | 
			
		||||
	ErrRequestCancelled = errors.New("sending request is cancelled")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type RawRequest struct {
 | 
			
		||||
	Method       string
 | 
			
		||||
	RelativePath string
 | 
			
		||||
	Values       url.Values
 | 
			
		||||
	Cancel       <-chan bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewRawRequest returns a new RawRequest
 | 
			
		||||
func NewRawRequest(method, relativePath string, values url.Values, cancel <-chan bool) *RawRequest {
 | 
			
		||||
	return &RawRequest{
 | 
			
		||||
		Method:       method,
 | 
			
		||||
		RelativePath: relativePath,
 | 
			
		||||
		Values:       values,
 | 
			
		||||
		Cancel:       cancel,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getCancelable issues a cancelable GET request
 | 
			
		||||
func (c *Client) getCancelable(key string, options Options,
 | 
			
		||||
	cancel <-chan bool) (*RawResponse, error) {
 | 
			
		||||
	logger.Debugf("get %s [%s]", key, c.cluster.pick())
 | 
			
		||||
	p := keyToPath(key)
 | 
			
		||||
 | 
			
		||||
	str, err := options.toParameters(VALID_GET_OPTIONS)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	p += str
 | 
			
		||||
 | 
			
		||||
	req := NewRawRequest("GET", p, nil, cancel)
 | 
			
		||||
	resp, err := c.SendRequest(req)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return resp, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// get issues a GET request
 | 
			
		||||
func (c *Client) get(key string, options Options) (*RawResponse, error) {
 | 
			
		||||
	return c.getCancelable(key, options, nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// put issues a PUT request
 | 
			
		||||
func (c *Client) put(key string, value string, ttl uint64,
 | 
			
		||||
	options Options) (*RawResponse, error) {
 | 
			
		||||
 | 
			
		||||
	logger.Debugf("put %s, %s, ttl: %d, [%s]", key, value, ttl, c.cluster.pick())
 | 
			
		||||
	p := keyToPath(key)
 | 
			
		||||
 | 
			
		||||
	str, err := options.toParameters(VALID_PUT_OPTIONS)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	p += str
 | 
			
		||||
 | 
			
		||||
	req := NewRawRequest("PUT", p, buildValues(value, ttl), nil)
 | 
			
		||||
	resp, err := c.SendRequest(req)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return resp, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// post issues a POST request
 | 
			
		||||
func (c *Client) post(key string, value string, ttl uint64) (*RawResponse, error) {
 | 
			
		||||
	logger.Debugf("post %s, %s, ttl: %d, [%s]", key, value, ttl, c.cluster.pick())
 | 
			
		||||
	p := keyToPath(key)
 | 
			
		||||
 | 
			
		||||
	req := NewRawRequest("POST", p, buildValues(value, ttl), nil)
 | 
			
		||||
	resp, err := c.SendRequest(req)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return resp, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// delete issues a DELETE request
 | 
			
		||||
func (c *Client) delete(key string, options Options) (*RawResponse, error) {
 | 
			
		||||
	logger.Debugf("delete %s [%s]", key, c.cluster.pick())
 | 
			
		||||
	p := keyToPath(key)
 | 
			
		||||
 | 
			
		||||
	str, err := options.toParameters(VALID_DELETE_OPTIONS)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	p += str
 | 
			
		||||
 | 
			
		||||
	req := NewRawRequest("DELETE", p, nil, nil)
 | 
			
		||||
	resp, err := c.SendRequest(req)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return resp, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SendRequest sends a HTTP request and returns a Response as defined by etcd
 | 
			
		||||
func (c *Client) SendRequest(rr *RawRequest) (*RawResponse, error) {
 | 
			
		||||
	var req *http.Request
 | 
			
		||||
	var resp *http.Response
 | 
			
		||||
	var httpPath string
 | 
			
		||||
	var err error
 | 
			
		||||
	var respBody []byte
 | 
			
		||||
 | 
			
		||||
	var numReqs = 1
 | 
			
		||||
 | 
			
		||||
	checkRetry := c.CheckRetry
 | 
			
		||||
	if checkRetry == nil {
 | 
			
		||||
		checkRetry = DefaultCheckRetry
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cancelled := make(chan bool, 1)
 | 
			
		||||
	reqLock := new(sync.Mutex)
 | 
			
		||||
 | 
			
		||||
	if rr.Cancel != nil {
 | 
			
		||||
		cancelRoutine := make(chan bool)
 | 
			
		||||
		defer close(cancelRoutine)
 | 
			
		||||
 | 
			
		||||
		go func() {
 | 
			
		||||
			select {
 | 
			
		||||
			case <-rr.Cancel:
 | 
			
		||||
				cancelled <- true
 | 
			
		||||
				logger.Debug("send.request is cancelled")
 | 
			
		||||
			case <-cancelRoutine:
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Repeat canceling request until this thread is stopped
 | 
			
		||||
			// because we have no idea about whether it succeeds.
 | 
			
		||||
			for {
 | 
			
		||||
				reqLock.Lock()
 | 
			
		||||
				c.httpClient.Transport.(*http.Transport).CancelRequest(req)
 | 
			
		||||
				reqLock.Unlock()
 | 
			
		||||
 | 
			
		||||
				select {
 | 
			
		||||
				case <-time.After(100 * time.Millisecond):
 | 
			
		||||
				case <-cancelRoutine:
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// If we connect to a follower and consistency is required, retry until
 | 
			
		||||
	// we connect to a leader
 | 
			
		||||
	sleep := 25 * time.Millisecond
 | 
			
		||||
	maxSleep := time.Second
 | 
			
		||||
 | 
			
		||||
	for attempt := 0; ; attempt++ {
 | 
			
		||||
		if attempt > 0 {
 | 
			
		||||
			select {
 | 
			
		||||
			case <-cancelled:
 | 
			
		||||
				return nil, ErrRequestCancelled
 | 
			
		||||
			case <-time.After(sleep):
 | 
			
		||||
				sleep = sleep * 2
 | 
			
		||||
				if sleep > maxSleep {
 | 
			
		||||
					sleep = maxSleep
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		logger.Debug("Connecting to etcd: attempt ", attempt+1, " for ", rr.RelativePath)
 | 
			
		||||
 | 
			
		||||
		// get httpPath if not set
 | 
			
		||||
		if httpPath == "" {
 | 
			
		||||
			httpPath = c.getHttpPath(rr.RelativePath)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Return a cURL command if curlChan is set
 | 
			
		||||
		if c.cURLch != nil {
 | 
			
		||||
			command := fmt.Sprintf("curl -X %s %s", rr.Method, httpPath)
 | 
			
		||||
			for key, value := range rr.Values {
 | 
			
		||||
				command += fmt.Sprintf(" -d %s=%s", key, value[0])
 | 
			
		||||
			}
 | 
			
		||||
			if c.credentials != nil {
 | 
			
		||||
				command += fmt.Sprintf(" -u %s", c.credentials.username)
 | 
			
		||||
			}
 | 
			
		||||
			c.sendCURL(command)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		logger.Debug("send.request.to ", httpPath, " | method ", rr.Method)
 | 
			
		||||
 | 
			
		||||
		req, err := func() (*http.Request, error) {
 | 
			
		||||
			reqLock.Lock()
 | 
			
		||||
			defer reqLock.Unlock()
 | 
			
		||||
 | 
			
		||||
			if rr.Values == nil {
 | 
			
		||||
				if req, err = http.NewRequest(rr.Method, httpPath, nil); err != nil {
 | 
			
		||||
					return nil, err
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				body := strings.NewReader(rr.Values.Encode())
 | 
			
		||||
				if req, err = http.NewRequest(rr.Method, httpPath, body); err != nil {
 | 
			
		||||
					return nil, err
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				req.Header.Set("Content-Type",
 | 
			
		||||
					"application/x-www-form-urlencoded; param=value")
 | 
			
		||||
			}
 | 
			
		||||
			return req, nil
 | 
			
		||||
		}()
 | 
			
		||||
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if c.credentials != nil {
 | 
			
		||||
			req.SetBasicAuth(c.credentials.username, c.credentials.password)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		resp, err = c.httpClient.Do(req)
 | 
			
		||||
		// clear previous httpPath
 | 
			
		||||
		httpPath = ""
 | 
			
		||||
		defer func() {
 | 
			
		||||
			if resp != nil {
 | 
			
		||||
				resp.Body.Close()
 | 
			
		||||
			}
 | 
			
		||||
		}()
 | 
			
		||||
 | 
			
		||||
		// If the request was cancelled, return ErrRequestCancelled directly
 | 
			
		||||
		select {
 | 
			
		||||
		case <-cancelled:
 | 
			
		||||
			return nil, ErrRequestCancelled
 | 
			
		||||
		default:
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		numReqs++
 | 
			
		||||
 | 
			
		||||
		// network error, change a machine!
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			logger.Debug("network error: ", err.Error())
 | 
			
		||||
			lastResp := http.Response{}
 | 
			
		||||
			if checkErr := checkRetry(c.cluster, numReqs, lastResp, err); checkErr != nil {
 | 
			
		||||
				return nil, checkErr
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			c.cluster.failure()
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// if there is no error, it should receive response
 | 
			
		||||
		logger.Debug("recv.response.from ", httpPath)
 | 
			
		||||
 | 
			
		||||
		if validHttpStatusCode[resp.StatusCode] {
 | 
			
		||||
			// try to read byte code and break the loop
 | 
			
		||||
			respBody, err = ioutil.ReadAll(resp.Body)
 | 
			
		||||
			if err == nil {
 | 
			
		||||
				logger.Debug("recv.success ", httpPath)
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
			// ReadAll error may be caused due to cancel request
 | 
			
		||||
			select {
 | 
			
		||||
			case <-cancelled:
 | 
			
		||||
				return nil, ErrRequestCancelled
 | 
			
		||||
			default:
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if err == io.ErrUnexpectedEOF {
 | 
			
		||||
				// underlying connection was closed prematurely, probably by timeout
 | 
			
		||||
				// TODO: empty body or unexpectedEOF can cause http.Transport to get hosed;
 | 
			
		||||
				// this allows the client to detect that and take evasive action. Need
 | 
			
		||||
				// to revisit once code.google.com/p/go/issues/detail?id=8648 gets fixed.
 | 
			
		||||
				respBody = []byte{}
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if resp.StatusCode == http.StatusTemporaryRedirect {
 | 
			
		||||
			u, err := resp.Location()
 | 
			
		||||
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				logger.Warning(err)
 | 
			
		||||
			} else {
 | 
			
		||||
				// set httpPath for following redirection
 | 
			
		||||
				httpPath = u.String()
 | 
			
		||||
			}
 | 
			
		||||
			resp.Body.Close()
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if checkErr := checkRetry(c.cluster, numReqs, *resp,
 | 
			
		||||
			errors.New("Unexpected HTTP status code")); checkErr != nil {
 | 
			
		||||
			return nil, checkErr
 | 
			
		||||
		}
 | 
			
		||||
		resp.Body.Close()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	r := &RawResponse{
 | 
			
		||||
		StatusCode: resp.StatusCode,
 | 
			
		||||
		Body:       respBody,
 | 
			
		||||
		Header:     resp.Header,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return r, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DefaultCheckRetry defines the retrying behaviour for bad HTTP requests
 | 
			
		||||
// If we have retried 2 * machine number, stop retrying.
 | 
			
		||||
// If status code is InternalServerError, sleep for 200ms.
 | 
			
		||||
func DefaultCheckRetry(cluster *Cluster, numReqs int, lastResp http.Response,
 | 
			
		||||
	err error) error {
 | 
			
		||||
 | 
			
		||||
	if numReqs > 2*len(cluster.Machines) {
 | 
			
		||||
		errStr := fmt.Sprintf("failed to propose on members %v twice [last error: %v]", cluster.Machines, err)
 | 
			
		||||
		return newError(ErrCodeEtcdNotReachable, errStr, 0)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if isEmptyResponse(lastResp) {
 | 
			
		||||
		// always retry if it failed to get response from one machine
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	if !shouldRetry(lastResp) {
 | 
			
		||||
		body := []byte("nil")
 | 
			
		||||
		if lastResp.Body != nil {
 | 
			
		||||
			if b, err := ioutil.ReadAll(lastResp.Body); err == nil {
 | 
			
		||||
				body = b
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		errStr := fmt.Sprintf("unhandled http status [%s] with body [%s]", http.StatusText(lastResp.StatusCode), body)
 | 
			
		||||
		return newError(ErrCodeUnhandledHTTPStatus, errStr, 0)
 | 
			
		||||
	}
 | 
			
		||||
	// sleep some time and expect leader election finish
 | 
			
		||||
	time.Sleep(time.Millisecond * 200)
 | 
			
		||||
	logger.Warning("bad response status code ", lastResp.StatusCode)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func isEmptyResponse(r http.Response) bool { return r.StatusCode == 0 }
 | 
			
		||||
 | 
			
		||||
// shouldRetry returns whether the reponse deserves retry.
 | 
			
		||||
func shouldRetry(r http.Response) bool {
 | 
			
		||||
	// TODO: only retry when the cluster is in leader election
 | 
			
		||||
	// We cannot do it exactly because etcd doesn't support it well.
 | 
			
		||||
	return r.StatusCode == http.StatusInternalServerError
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) getHttpPath(s ...string) string {
 | 
			
		||||
	fullPath := c.cluster.pick() + "/" + version
 | 
			
		||||
	for _, seg := range s {
 | 
			
		||||
		fullPath = fullPath + "/" + seg
 | 
			
		||||
	}
 | 
			
		||||
	return fullPath
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// buildValues builds a url.Values map according to the given value and ttl
 | 
			
		||||
func buildValues(value string, ttl uint64) url.Values {
 | 
			
		||||
	v := url.Values{}
 | 
			
		||||
 | 
			
		||||
	if value != "" {
 | 
			
		||||
		v.Set("value", value)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ttl > 0 {
 | 
			
		||||
		v.Set("ttl", fmt.Sprintf("%v", ttl))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return v
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// convert key string to http path exclude version, including URL escaping
 | 
			
		||||
// for example: key[foo] -> path[keys/foo]
 | 
			
		||||
// key[/%z] -> path[keys/%25z]
 | 
			
		||||
// key[/] -> path[keys/]
 | 
			
		||||
func keyToPath(key string) string {
 | 
			
		||||
	// URL-escape our key, except for slashes
 | 
			
		||||
	p := strings.Replace(url.QueryEscape(path.Join("keys", key)), "%2F", "/", -1)
 | 
			
		||||
 | 
			
		||||
	// corner case: if key is "/" or "//" ect
 | 
			
		||||
	// path join will clear the tailing "/"
 | 
			
		||||
	// we need to add it back
 | 
			
		||||
	if p == "keys" {
 | 
			
		||||
		p = "keys/"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return p
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1587
									
								
								vendor/github.com/coreos/go-etcd/etcd/response.generated.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1587
									
								
								vendor/github.com/coreos/go-etcd/etcd/response.generated.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										93
									
								
								vendor/github.com/coreos/go-etcd/etcd/response.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										93
									
								
								vendor/github.com/coreos/go-etcd/etcd/response.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,93 +0,0 @@
 | 
			
		||||
package etcd
 | 
			
		||||
 | 
			
		||||
//go:generate codecgen -d 1978 -o response.generated.go response.go
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/ugorji/go/codec"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	rawResponse = iota
 | 
			
		||||
	normalResponse
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type responseType int
 | 
			
		||||
 | 
			
		||||
type RawResponse struct {
 | 
			
		||||
	StatusCode int
 | 
			
		||||
	Body       []byte
 | 
			
		||||
	Header     http.Header
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	validHttpStatusCode = map[int]bool{
 | 
			
		||||
		http.StatusCreated:            true,
 | 
			
		||||
		http.StatusOK:                 true,
 | 
			
		||||
		http.StatusBadRequest:         true,
 | 
			
		||||
		http.StatusNotFound:           true,
 | 
			
		||||
		http.StatusPreconditionFailed: true,
 | 
			
		||||
		http.StatusForbidden:          true,
 | 
			
		||||
		http.StatusUnauthorized:       true,
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Unmarshal parses RawResponse and stores the result in Response
 | 
			
		||||
func (rr *RawResponse) Unmarshal() (*Response, error) {
 | 
			
		||||
	if rr.StatusCode != http.StatusOK && rr.StatusCode != http.StatusCreated {
 | 
			
		||||
		return nil, handleError(rr.Body)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	resp := new(Response)
 | 
			
		||||
 | 
			
		||||
	err := codec.NewDecoderBytes(rr.Body, new(codec.JsonHandle)).Decode(resp)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// attach index and term to response
 | 
			
		||||
	resp.EtcdIndex, _ = strconv.ParseUint(rr.Header.Get("X-Etcd-Index"), 10, 64)
 | 
			
		||||
	resp.RaftIndex, _ = strconv.ParseUint(rr.Header.Get("X-Raft-Index"), 10, 64)
 | 
			
		||||
	resp.RaftTerm, _ = strconv.ParseUint(rr.Header.Get("X-Raft-Term"), 10, 64)
 | 
			
		||||
 | 
			
		||||
	return resp, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Response struct {
 | 
			
		||||
	Action    string `json:"action"`
 | 
			
		||||
	Node      *Node  `json:"node"`
 | 
			
		||||
	PrevNode  *Node  `json:"prevNode,omitempty"`
 | 
			
		||||
	EtcdIndex uint64 `json:"etcdIndex"`
 | 
			
		||||
	RaftIndex uint64 `json:"raftIndex"`
 | 
			
		||||
	RaftTerm  uint64 `json:"raftTerm"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Node struct {
 | 
			
		||||
	Key           string     `json:"key, omitempty"`
 | 
			
		||||
	Value         string     `json:"value,omitempty"`
 | 
			
		||||
	Dir           bool       `json:"dir,omitempty"`
 | 
			
		||||
	Expiration    *time.Time `json:"expiration,omitempty"`
 | 
			
		||||
	TTL           int64      `json:"ttl,omitempty"`
 | 
			
		||||
	Nodes         Nodes      `json:"nodes,omitempty"`
 | 
			
		||||
	ModifiedIndex uint64     `json:"modifiedIndex,omitempty"`
 | 
			
		||||
	CreatedIndex  uint64     `json:"createdIndex,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Nodes []*Node
 | 
			
		||||
 | 
			
		||||
// interfaces for sorting
 | 
			
		||||
func (ns Nodes) Len() int {
 | 
			
		||||
	return len(ns)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ns Nodes) Less(i, j int) bool {
 | 
			
		||||
	return ns[i].Key < ns[j].Key
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ns Nodes) Swap(i, j int) {
 | 
			
		||||
	ns[i], ns[j] = ns[j], ns[i]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										137
									
								
								vendor/github.com/coreos/go-etcd/etcd/set_update_create.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										137
									
								
								vendor/github.com/coreos/go-etcd/etcd/set_update_create.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,137 +0,0 @@
 | 
			
		||||
package etcd
 | 
			
		||||
 | 
			
		||||
// Set sets the given key to the given value.
 | 
			
		||||
// It will create a new key value pair or replace the old one.
 | 
			
		||||
// It will not replace a existing directory.
 | 
			
		||||
func (c *Client) Set(key string, value string, ttl uint64) (*Response, error) {
 | 
			
		||||
	raw, err := c.RawSet(key, value, ttl)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return raw.Unmarshal()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetDir sets the given key to a directory.
 | 
			
		||||
// It will create a new directory or replace the old key value pair by a directory.
 | 
			
		||||
// It will not replace a existing directory.
 | 
			
		||||
func (c *Client) SetDir(key string, ttl uint64) (*Response, error) {
 | 
			
		||||
	raw, err := c.RawSetDir(key, ttl)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return raw.Unmarshal()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CreateDir creates a directory. It succeeds only if
 | 
			
		||||
// the given key does not yet exist.
 | 
			
		||||
func (c *Client) CreateDir(key string, ttl uint64) (*Response, error) {
 | 
			
		||||
	raw, err := c.RawCreateDir(key, ttl)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return raw.Unmarshal()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UpdateDir updates the given directory. It succeeds only if the
 | 
			
		||||
// given key already exists.
 | 
			
		||||
func (c *Client) UpdateDir(key string, ttl uint64) (*Response, error) {
 | 
			
		||||
	raw, err := c.RawUpdateDir(key, ttl)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return raw.Unmarshal()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create creates a file with the given value under the given key.  It succeeds
 | 
			
		||||
// only if the given key does not yet exist.
 | 
			
		||||
func (c *Client) Create(key string, value string, ttl uint64) (*Response, error) {
 | 
			
		||||
	raw, err := c.RawCreate(key, value, ttl)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return raw.Unmarshal()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CreateInOrder creates a file with a key that's guaranteed to be higher than other
 | 
			
		||||
// keys in the given directory. It is useful for creating queues.
 | 
			
		||||
func (c *Client) CreateInOrder(dir string, value string, ttl uint64) (*Response, error) {
 | 
			
		||||
	raw, err := c.RawCreateInOrder(dir, value, ttl)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return raw.Unmarshal()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Update updates the given key to the given value.  It succeeds only if the
 | 
			
		||||
// given key already exists.
 | 
			
		||||
func (c *Client) Update(key string, value string, ttl uint64) (*Response, error) {
 | 
			
		||||
	raw, err := c.RawUpdate(key, value, ttl)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return raw.Unmarshal()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) RawUpdateDir(key string, ttl uint64) (*RawResponse, error) {
 | 
			
		||||
	ops := Options{
 | 
			
		||||
		"prevExist": true,
 | 
			
		||||
		"dir":       true,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return c.put(key, "", ttl, ops)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) RawCreateDir(key string, ttl uint64) (*RawResponse, error) {
 | 
			
		||||
	ops := Options{
 | 
			
		||||
		"prevExist": false,
 | 
			
		||||
		"dir":       true,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return c.put(key, "", ttl, ops)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) RawSet(key string, value string, ttl uint64) (*RawResponse, error) {
 | 
			
		||||
	return c.put(key, value, ttl, nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) RawSetDir(key string, ttl uint64) (*RawResponse, error) {
 | 
			
		||||
	ops := Options{
 | 
			
		||||
		"dir": true,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return c.put(key, "", ttl, ops)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) RawUpdate(key string, value string, ttl uint64) (*RawResponse, error) {
 | 
			
		||||
	ops := Options{
 | 
			
		||||
		"prevExist": true,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return c.put(key, value, ttl, ops)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) RawCreate(key string, value string, ttl uint64) (*RawResponse, error) {
 | 
			
		||||
	ops := Options{
 | 
			
		||||
		"prevExist": false,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return c.put(key, value, ttl, ops)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) RawCreateInOrder(dir string, value string, ttl uint64) (*RawResponse, error) {
 | 
			
		||||
	return c.post(dir, value, ttl)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										19
									
								
								vendor/github.com/coreos/go-etcd/etcd/shuffle.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								vendor/github.com/coreos/go-etcd/etcd/shuffle.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,19 +0,0 @@
 | 
			
		||||
package etcd
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"math/rand"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func shuffleStringSlice(cards []string) []string {
 | 
			
		||||
	size := len(cards)
 | 
			
		||||
	//Do not need to copy if nothing changed
 | 
			
		||||
	if size <= 1 {
 | 
			
		||||
		return cards
 | 
			
		||||
	}
 | 
			
		||||
	shuffled := make([]string, size)
 | 
			
		||||
	index := rand.Perm(size)
 | 
			
		||||
	for i := range cards {
 | 
			
		||||
		shuffled[index[i]] = cards[i]
 | 
			
		||||
	}
 | 
			
		||||
	return shuffled
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								vendor/github.com/coreos/go-etcd/etcd/version.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/coreos/go-etcd/etcd/version.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,6 +0,0 @@
 | 
			
		||||
package etcd
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	version        = "v2"
 | 
			
		||||
	packageVersion = "v2.0.0+git"
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										103
									
								
								vendor/github.com/coreos/go-etcd/etcd/watch.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										103
									
								
								vendor/github.com/coreos/go-etcd/etcd/watch.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,103 +0,0 @@
 | 
			
		||||
package etcd
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Errors introduced by the Watch command.
 | 
			
		||||
var (
 | 
			
		||||
	ErrWatchStoppedByUser = errors.New("Watch stopped by the user via stop channel")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// If recursive is set to true the watch returns the first change under the given
 | 
			
		||||
// prefix since the given index.
 | 
			
		||||
//
 | 
			
		||||
// If recursive is set to false the watch returns the first change to the given key
 | 
			
		||||
// since the given index.
 | 
			
		||||
//
 | 
			
		||||
// To watch for the latest change, set waitIndex = 0.
 | 
			
		||||
//
 | 
			
		||||
// If a receiver channel is given, it will be a long-term watch. Watch will block at the
 | 
			
		||||
//channel. After someone receives the channel, it will go on to watch that
 | 
			
		||||
// prefix.  If a stop channel is given, the client can close long-term watch using
 | 
			
		||||
// the stop channel.
 | 
			
		||||
func (c *Client) Watch(prefix string, waitIndex uint64, recursive bool,
 | 
			
		||||
	receiver chan *Response, stop chan bool) (*Response, error) {
 | 
			
		||||
	logger.Debugf("watch %s [%s]", prefix, c.cluster.Leader)
 | 
			
		||||
	if receiver == nil {
 | 
			
		||||
		raw, err := c.watchOnce(prefix, waitIndex, recursive, stop)
 | 
			
		||||
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return raw.Unmarshal()
 | 
			
		||||
	}
 | 
			
		||||
	defer close(receiver)
 | 
			
		||||
 | 
			
		||||
	for {
 | 
			
		||||
		raw, err := c.watchOnce(prefix, waitIndex, recursive, stop)
 | 
			
		||||
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		resp, err := raw.Unmarshal()
 | 
			
		||||
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		waitIndex = resp.Node.ModifiedIndex + 1
 | 
			
		||||
		receiver <- resp
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) RawWatch(prefix string, waitIndex uint64, recursive bool,
 | 
			
		||||
	receiver chan *RawResponse, stop chan bool) (*RawResponse, error) {
 | 
			
		||||
 | 
			
		||||
	logger.Debugf("rawWatch %s [%s]", prefix, c.cluster.Leader)
 | 
			
		||||
	if receiver == nil {
 | 
			
		||||
		return c.watchOnce(prefix, waitIndex, recursive, stop)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for {
 | 
			
		||||
		raw, err := c.watchOnce(prefix, waitIndex, recursive, stop)
 | 
			
		||||
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		resp, err := raw.Unmarshal()
 | 
			
		||||
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		waitIndex = resp.Node.ModifiedIndex + 1
 | 
			
		||||
		receiver <- raw
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// helper func
 | 
			
		||||
// return when there is change under the given prefix
 | 
			
		||||
func (c *Client) watchOnce(key string, waitIndex uint64, recursive bool, stop chan bool) (*RawResponse, error) {
 | 
			
		||||
 | 
			
		||||
	options := Options{
 | 
			
		||||
		"wait": true,
 | 
			
		||||
	}
 | 
			
		||||
	if waitIndex > 0 {
 | 
			
		||||
		options["waitIndex"] = waitIndex
 | 
			
		||||
	}
 | 
			
		||||
	if recursive {
 | 
			
		||||
		options["recursive"] = true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	resp, err := c.getCancelable(key, options, stop)
 | 
			
		||||
 | 
			
		||||
	if err == ErrRequestCancelled {
 | 
			
		||||
		return nil, ErrWatchStoppedByUser
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return resp, err
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user