mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 19:31:44 +00:00
Merge branch 'master' into util-freebsd
This commit is contained in:
commit
77dee9bb4e
13
Godeps/Godeps.json
generated
13
Godeps/Godeps.json
generated
@ -1707,14 +1707,6 @@
|
||||
"ImportPath": "github.com/gorilla/websocket",
|
||||
"Rev": "6eb6ad425a89d9da7a5549bc6da8f79ba5c17844"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gregjones/httpcache",
|
||||
"Rev": "787624de3eb7bd915c329cba748687a3b22666a6"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gregjones/httpcache/diskcache",
|
||||
"Rev": "787624de3eb7bd915c329cba748687a3b22666a6"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/grpc-ecosystem/go-grpc-prometheus",
|
||||
"Comment": "v1.1-4-g2500245",
|
||||
@ -2247,11 +2239,6 @@
|
||||
"Comment": "v0.3.5-10-g0049ab3",
|
||||
"Rev": "0049ab3dc4c4c70a9eee23087437b69c0dde2130"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/peterbourgon/diskv",
|
||||
"Comment": "v2.0.0-2-g5dfcb07",
|
||||
"Rev": "5dfcb07a075adbaaa4094cddfd160b1e1c77a043"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/pkg/errors",
|
||||
"Comment": "v0.7.0-13-ga221380",
|
||||
|
55
Godeps/LICENSES
generated
55
Godeps/LICENSES
generated
@ -59441,34 +59441,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
================================================================================
|
||||
|
||||
|
||||
================================================================================
|
||||
= vendor/github.com/gregjones/httpcache licensed under: =
|
||||
|
||||
Copyright © 2012 Greg Jones (greg.jones@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
= vendor/github.com/gregjones/httpcache/LICENSE.txt 3cfef421226b2dacde78a4871380ac24 -
|
||||
================================================================================
|
||||
|
||||
|
||||
================================================================================
|
||||
= vendor/github.com/gregjones/httpcache/diskcache licensed under: =
|
||||
|
||||
Copyright © 2012 Greg Jones (greg.jones@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
= vendor/github.com/gregjones/httpcache/LICENSE.txt 3cfef421226b2dacde78a4871380ac24 -
|
||||
================================================================================
|
||||
|
||||
|
||||
================================================================================
|
||||
= vendor/github.com/grpc-ecosystem/go-grpc-prometheus licensed under: =
|
||||
|
||||
@ -71602,33 +71574,6 @@ SOFTWARE.
|
||||
================================================================================
|
||||
|
||||
|
||||
================================================================================
|
||||
= vendor/github.com/peterbourgon/diskv licensed under: =
|
||||
|
||||
Copyright (c) 2011-2012 Peter Bourgon
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
= vendor/github.com/peterbourgon/diskv/LICENSE f9f3e815fc84aa04c4f4db33c553eef9 -
|
||||
================================================================================
|
||||
|
||||
|
||||
================================================================================
|
||||
= vendor/github.com/pkg/errors licensed under: =
|
||||
|
||||
|
2
OWNERS
2
OWNERS
@ -10,7 +10,7 @@ approvers:
|
||||
- brendandburns
|
||||
- dchen1107
|
||||
- jbeda
|
||||
- jregan # To modify BUILD files per proposal #598
|
||||
- monopole # To move code per kubernetes/community#598
|
||||
- lavalamp
|
||||
- smarterclayton
|
||||
- thockin
|
||||
|
@ -53,7 +53,6 @@ aliases:
|
||||
- dchen1107
|
||||
- derekwaynecarr
|
||||
- dims
|
||||
- euank
|
||||
- feiskyer
|
||||
- mtaufen
|
||||
- ncdc
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2982,6 +2982,171 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/apis/apps/v1beta1/namespaces/{namespace}/statefulsets/{name}/scale",
|
||||
"description": "API at /apis/apps/v1beta1",
|
||||
"operations": [
|
||||
{
|
||||
"type": "v1beta1.Scale",
|
||||
"method": "GET",
|
||||
"summary": "read scale of the specified StatefulSet",
|
||||
"nickname": "readNamespacedStatefulSetScale",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "pretty",
|
||||
"description": "If 'true', then the output is pretty printed.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "path",
|
||||
"name": "namespace",
|
||||
"description": "object name and auth scope, such as for teams and projects",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "path",
|
||||
"name": "name",
|
||||
"description": "name of the Scale",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
}
|
||||
],
|
||||
"responseMessages": [
|
||||
{
|
||||
"code": 200,
|
||||
"message": "OK",
|
||||
"responseModel": "v1beta1.Scale"
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/yaml",
|
||||
"application/vnd.kubernetes.protobuf"
|
||||
],
|
||||
"consumes": [
|
||||
"*/*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "v1beta1.Scale",
|
||||
"method": "PUT",
|
||||
"summary": "replace scale of the specified StatefulSet",
|
||||
"nickname": "replaceNamespacedStatefulSetScale",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "pretty",
|
||||
"description": "If 'true', then the output is pretty printed.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "v1beta1.Scale",
|
||||
"paramType": "body",
|
||||
"name": "body",
|
||||
"description": "",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "path",
|
||||
"name": "namespace",
|
||||
"description": "object name and auth scope, such as for teams and projects",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "path",
|
||||
"name": "name",
|
||||
"description": "name of the Scale",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
}
|
||||
],
|
||||
"responseMessages": [
|
||||
{
|
||||
"code": 200,
|
||||
"message": "OK",
|
||||
"responseModel": "v1beta1.Scale"
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/yaml",
|
||||
"application/vnd.kubernetes.protobuf"
|
||||
],
|
||||
"consumes": [
|
||||
"*/*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "v1beta1.Scale",
|
||||
"method": "PATCH",
|
||||
"summary": "partially update scale of the specified StatefulSet",
|
||||
"nickname": "patchNamespacedStatefulSetScale",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "pretty",
|
||||
"description": "If 'true', then the output is pretty printed.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "v1.Patch",
|
||||
"paramType": "body",
|
||||
"name": "body",
|
||||
"description": "",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "path",
|
||||
"name": "namespace",
|
||||
"description": "object name and auth scope, such as for teams and projects",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "path",
|
||||
"name": "name",
|
||||
"description": "name of the Scale",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
}
|
||||
],
|
||||
"responseMessages": [
|
||||
{
|
||||
"code": 200,
|
||||
"message": "OK",
|
||||
"responseModel": "v1beta1.Scale"
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/yaml",
|
||||
"application/vnd.kubernetes.protobuf"
|
||||
],
|
||||
"consumes": [
|
||||
"application/json-patch+json",
|
||||
"application/merge-patch+json",
|
||||
"application/strategic-merge-patch+json"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/apis/apps/v1beta1/namespaces/{namespace}/statefulsets/{name}/status",
|
||||
"description": "API at /apis/apps/v1beta1",
|
||||
@ -3645,7 +3810,7 @@
|
||||
},
|
||||
"rollbackTo": {
|
||||
"$ref": "v1beta1.RollbackConfig",
|
||||
"description": "The config this deployment is rolling back to. Will be cleared after rollback is done."
|
||||
"description": "DEPRECATED. The config this deployment is rolling back to. Will be cleared after rollback is done."
|
||||
},
|
||||
"progressDeadlineSeconds": {
|
||||
"type": "integer",
|
||||
@ -4466,22 +4631,18 @@
|
||||
"v1.FCVolumeSource": {
|
||||
"id": "v1.FCVolumeSource",
|
||||
"description": "Represents a Fibre Channel volume. Fibre Channel volumes can only be mounted as read/write once. Fibre Channel volumes support ownership management and SELinux relabeling.",
|
||||
"required": [
|
||||
"targetWWNs",
|
||||
"lun"
|
||||
],
|
||||
"properties": {
|
||||
"targetWWNs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Required: FC target worldwide names (WWNs)"
|
||||
"description": "Optional: FC target worldwide names (WWNs)"
|
||||
},
|
||||
"lun": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "Required: FC target lun number"
|
||||
"description": "Optional: FC target lun number"
|
||||
},
|
||||
"fsType": {
|
||||
"type": "string",
|
||||
@ -4490,6 +4651,13 @@
|
||||
"readOnly": {
|
||||
"type": "boolean",
|
||||
"description": "Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts."
|
||||
},
|
||||
"wwids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Optional: FC volume world wide identifiers (wwids) Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously."
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -5544,7 +5712,7 @@
|
||||
"items": {
|
||||
"$ref": "v1.PodAffinityTerm"
|
||||
},
|
||||
"description": "NOT YET IMPLEMENTED. TODO: Uncomment field once it is implemented. If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system will try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. RequiredDuringSchedulingRequiredDuringExecution []PodAffinityTerm `json:\"requiredDuringSchedulingRequiredDuringExecution,omitempty\"` If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied."
|
||||
"description": "If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied."
|
||||
},
|
||||
"preferredDuringSchedulingIgnoredDuringExecution": {
|
||||
"type": "array",
|
||||
@ -5604,7 +5772,7 @@
|
||||
"items": {
|
||||
"$ref": "v1.PodAffinityTerm"
|
||||
},
|
||||
"description": "NOT YET IMPLEMENTED. TODO: Uncomment field once it is implemented. If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system will try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. RequiredDuringSchedulingRequiredDuringExecution []PodAffinityTerm `json:\"requiredDuringSchedulingRequiredDuringExecution,omitempty\"` If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied."
|
||||
"description": "If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied."
|
||||
},
|
||||
"preferredDuringSchedulingIgnoredDuringExecution": {
|
||||
"type": "array",
|
||||
@ -5689,6 +5857,7 @@
|
||||
},
|
||||
"v1beta1.RollbackConfig": {
|
||||
"id": "v1beta1.RollbackConfig",
|
||||
"description": "DEPRECATED.",
|
||||
"properties": {
|
||||
"revision": {
|
||||
"type": "integer",
|
||||
@ -5781,7 +5950,7 @@
|
||||
},
|
||||
"v1beta1.DeploymentRollback": {
|
||||
"id": "v1beta1.DeploymentRollback",
|
||||
"description": "DeploymentRollback stores the information required to rollback a deployment.",
|
||||
"description": "DEPRECATED. DeploymentRollback stores the information required to rollback a deployment.",
|
||||
"required": [
|
||||
"name",
|
||||
"rollbackTo"
|
||||
@ -6110,6 +6279,11 @@
|
||||
"updateRevision": {
|
||||
"type": "string",
|
||||
"description": "updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence [replicas-updatedReplicas,replicas)"
|
||||
},
|
||||
"collisionCount": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "collisionCount is the count of hash collisions for the StatefulSet. The StatefulSet controller uses this field as a collision avoidance mechanism when it needs to create the name for the newest ControllerRevision."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1895,67 +1895,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/apis/apps/v1beta2/namespaces/{namespace}/deployments/{name}/rollback",
|
||||
"description": "API at /apis/apps/v1beta2",
|
||||
"operations": [
|
||||
{
|
||||
"type": "v1beta2.DeploymentRollback",
|
||||
"method": "POST",
|
||||
"summary": "create rollback of a Deployment",
|
||||
"nickname": "createNamespacedDeploymentRollback",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "pretty",
|
||||
"description": "If 'true', then the output is pretty printed.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "v1beta2.DeploymentRollback",
|
||||
"paramType": "body",
|
||||
"name": "body",
|
||||
"description": "",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "path",
|
||||
"name": "namespace",
|
||||
"description": "object name and auth scope, such as for teams and projects",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "path",
|
||||
"name": "name",
|
||||
"description": "name of the DeploymentRollback",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
}
|
||||
],
|
||||
"responseMessages": [
|
||||
{
|
||||
"code": 200,
|
||||
"message": "OK",
|
||||
"responseModel": "v1beta2.DeploymentRollback"
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/yaml",
|
||||
"application/vnd.kubernetes.protobuf"
|
||||
],
|
||||
"consumes": [
|
||||
"*/*"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/apis/apps/v1beta2/namespaces/{namespace}/deployments/{name}/scale",
|
||||
"description": "API at /apis/apps/v1beta2",
|
||||
@ -4338,6 +4277,171 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/apis/apps/v1beta2/namespaces/{namespace}/statefulsets/{name}/scale",
|
||||
"description": "API at /apis/apps/v1beta2",
|
||||
"operations": [
|
||||
{
|
||||
"type": "v1beta2.Scale",
|
||||
"method": "GET",
|
||||
"summary": "read scale of the specified StatefulSet",
|
||||
"nickname": "readNamespacedStatefulSetScale",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "pretty",
|
||||
"description": "If 'true', then the output is pretty printed.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "path",
|
||||
"name": "namespace",
|
||||
"description": "object name and auth scope, such as for teams and projects",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "path",
|
||||
"name": "name",
|
||||
"description": "name of the Scale",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
}
|
||||
],
|
||||
"responseMessages": [
|
||||
{
|
||||
"code": 200,
|
||||
"message": "OK",
|
||||
"responseModel": "v1beta2.Scale"
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/yaml",
|
||||
"application/vnd.kubernetes.protobuf"
|
||||
],
|
||||
"consumes": [
|
||||
"*/*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "v1beta2.Scale",
|
||||
"method": "PUT",
|
||||
"summary": "replace scale of the specified StatefulSet",
|
||||
"nickname": "replaceNamespacedStatefulSetScale",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "pretty",
|
||||
"description": "If 'true', then the output is pretty printed.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "v1beta2.Scale",
|
||||
"paramType": "body",
|
||||
"name": "body",
|
||||
"description": "",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "path",
|
||||
"name": "namespace",
|
||||
"description": "object name and auth scope, such as for teams and projects",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "path",
|
||||
"name": "name",
|
||||
"description": "name of the Scale",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
}
|
||||
],
|
||||
"responseMessages": [
|
||||
{
|
||||
"code": 200,
|
||||
"message": "OK",
|
||||
"responseModel": "v1beta2.Scale"
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/yaml",
|
||||
"application/vnd.kubernetes.protobuf"
|
||||
],
|
||||
"consumes": [
|
||||
"*/*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "v1beta2.Scale",
|
||||
"method": "PATCH",
|
||||
"summary": "partially update scale of the specified StatefulSet",
|
||||
"nickname": "patchNamespacedStatefulSetScale",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "query",
|
||||
"name": "pretty",
|
||||
"description": "If 'true', then the output is pretty printed.",
|
||||
"required": false,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "v1.Patch",
|
||||
"paramType": "body",
|
||||
"name": "body",
|
||||
"description": "",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "path",
|
||||
"name": "namespace",
|
||||
"description": "object name and auth scope, such as for teams and projects",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"paramType": "path",
|
||||
"name": "name",
|
||||
"description": "name of the Scale",
|
||||
"required": true,
|
||||
"allowMultiple": false
|
||||
}
|
||||
],
|
||||
"responseMessages": [
|
||||
{
|
||||
"code": 200,
|
||||
"message": "OK",
|
||||
"responseModel": "v1beta2.Scale"
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/yaml",
|
||||
"application/vnd.kubernetes.protobuf"
|
||||
],
|
||||
"consumes": [
|
||||
"application/json-patch+json",
|
||||
"application/merge-patch+json",
|
||||
"application/strategic-merge-patch+json"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/apis/apps/v1beta2/namespaces/{namespace}/statefulsets/{name}/status",
|
||||
"description": "API at /apis/apps/v1beta2",
|
||||
@ -5682,22 +5786,18 @@
|
||||
"v1.FCVolumeSource": {
|
||||
"id": "v1.FCVolumeSource",
|
||||
"description": "Represents a Fibre Channel volume. Fibre Channel volumes can only be mounted as read/write once. Fibre Channel volumes support ownership management and SELinux relabeling.",
|
||||
"required": [
|
||||
"targetWWNs",
|
||||
"lun"
|
||||
],
|
||||
"properties": {
|
||||
"targetWWNs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Required: FC target worldwide names (WWNs)"
|
||||
"description": "Optional: FC target worldwide names (WWNs)"
|
||||
},
|
||||
"lun": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "Required: FC target lun number"
|
||||
"description": "Optional: FC target lun number"
|
||||
},
|
||||
"fsType": {
|
||||
"type": "string",
|
||||
@ -5706,6 +5806,13 @@
|
||||
"readOnly": {
|
||||
"type": "boolean",
|
||||
"description": "Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts."
|
||||
},
|
||||
"wwids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Optional: FC volume world wide identifiers (wwids) Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously."
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -6760,7 +6867,7 @@
|
||||
"items": {
|
||||
"$ref": "v1.PodAffinityTerm"
|
||||
},
|
||||
"description": "NOT YET IMPLEMENTED. TODO: Uncomment field once it is implemented. If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system will try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. RequiredDuringSchedulingRequiredDuringExecution []PodAffinityTerm `json:\"requiredDuringSchedulingRequiredDuringExecution,omitempty\"` If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied."
|
||||
"description": "If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied."
|
||||
},
|
||||
"preferredDuringSchedulingIgnoredDuringExecution": {
|
||||
"type": "array",
|
||||
@ -6820,7 +6927,7 @@
|
||||
"items": {
|
||||
"$ref": "v1.PodAffinityTerm"
|
||||
},
|
||||
"description": "NOT YET IMPLEMENTED. TODO: Uncomment field once it is implemented. If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system will try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. RequiredDuringSchedulingRequiredDuringExecution []PodAffinityTerm `json:\"requiredDuringSchedulingRequiredDuringExecution,omitempty\"` If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied."
|
||||
"description": "If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied."
|
||||
},
|
||||
"preferredDuringSchedulingIgnoredDuringExecution": {
|
||||
"type": "array",
|
||||
@ -6881,7 +6988,7 @@
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Type of daemon set update. Can be \"RollingUpdate\" or \"OnDelete\". Default is OnDelete."
|
||||
"description": "Type of daemon set update. Can be \"RollingUpdate\" or \"OnDelete\". Default is RollingUpdate."
|
||||
},
|
||||
"rollingUpdate": {
|
||||
"$ref": "v1beta2.RollingUpdateDaemonSet",
|
||||
@ -7117,10 +7224,6 @@
|
||||
"type": "boolean",
|
||||
"description": "Indicates that the deployment is paused."
|
||||
},
|
||||
"rollbackTo": {
|
||||
"$ref": "v1beta2.RollbackConfig",
|
||||
"description": "The config this deployment is rolling back to. Will be cleared after rollback is done."
|
||||
},
|
||||
"progressDeadlineSeconds": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
@ -7156,17 +7259,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1beta2.RollbackConfig": {
|
||||
"id": "v1beta2.RollbackConfig",
|
||||
"description": "WIP: This is not ready to be used and we plan to make breaking changes to it.",
|
||||
"properties": {
|
||||
"revision": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "The revision to rollback to. If set to 0, rollback to the last revision."
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1beta2.DeploymentStatus": {
|
||||
"id": "v1beta2.DeploymentStatus",
|
||||
"description": "WIP: This is not ready to be used and we plan to make breaking changes to it. DeploymentStatus is the most recently observed status of the Deployment.",
|
||||
@ -7249,36 +7341,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1beta2.DeploymentRollback": {
|
||||
"id": "v1beta2.DeploymentRollback",
|
||||
"description": "WIP: This is not ready to be used and we plan to make breaking changes to it. DeploymentRollback stores the information required to rollback a deployment.",
|
||||
"required": [
|
||||
"name",
|
||||
"rollbackTo"
|
||||
],
|
||||
"properties": {
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds"
|
||||
},
|
||||
"apiVersion": {
|
||||
"type": "string",
|
||||
"description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Required: This must match the Name of a deployment."
|
||||
},
|
||||
"updatedAnnotations": {
|
||||
"type": "object",
|
||||
"description": "The annotations to be updated to a deployment"
|
||||
},
|
||||
"rollbackTo": {
|
||||
"$ref": "v1beta2.RollbackConfig",
|
||||
"description": "The config of this deployment rollback."
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1beta2.Scale": {
|
||||
"id": "v1beta2.Scale",
|
||||
"description": "WIP: This is not ready to be used and we plan to make breaking changes to it. Scale represents a scaling request for a resource.",
|
||||
@ -7671,7 +7733,7 @@
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Type indicates the type of the StatefulSetUpdateStrategy."
|
||||
"description": "Type indicates the type of the StatefulSetUpdateStrategy. Default is RollingUpdate."
|
||||
},
|
||||
"rollingUpdate": {
|
||||
"$ref": "v1beta2.RollingUpdateStatefulSetStrategy",
|
||||
@ -7686,7 +7748,7 @@
|
||||
"partition": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "Partition indicates the ordinal at which the StatefulSet should be partitioned."
|
||||
"description": "Partition indicates the ordinal at which the StatefulSet should be partitioned. Default value is 0."
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -7729,6 +7791,11 @@
|
||||
"updateRevision": {
|
||||
"type": "string",
|
||||
"description": "updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence [replicas-updatedReplicas,replicas)"
|
||||
},
|
||||
"collisionCount": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "collisionCount is the count of hash collisions for the StatefulSet. The StatefulSet controller uses this field as a collision avoidance mechanism when it needs to create the name for the newest ControllerRevision."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -2213,22 +2213,18 @@
|
||||
"v1.FCVolumeSource": {
|
||||
"id": "v1.FCVolumeSource",
|
||||
"description": "Represents a Fibre Channel volume. Fibre Channel volumes can only be mounted as read/write once. Fibre Channel volumes support ownership management and SELinux relabeling.",
|
||||
"required": [
|
||||
"targetWWNs",
|
||||
"lun"
|
||||
],
|
||||
"properties": {
|
||||
"targetWWNs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Required: FC target worldwide names (WWNs)"
|
||||
"description": "Optional: FC target worldwide names (WWNs)"
|
||||
},
|
||||
"lun": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "Required: FC target lun number"
|
||||
"description": "Optional: FC target lun number"
|
||||
},
|
||||
"fsType": {
|
||||
"type": "string",
|
||||
@ -2237,6 +2233,13 @@
|
||||
"readOnly": {
|
||||
"type": "boolean",
|
||||
"description": "Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts."
|
||||
},
|
||||
"wwids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Optional: FC volume world wide identifiers (wwids) Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously."
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -3291,7 +3294,7 @@
|
||||
"items": {
|
||||
"$ref": "v1.PodAffinityTerm"
|
||||
},
|
||||
"description": "NOT YET IMPLEMENTED. TODO: Uncomment field once it is implemented. If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system will try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. RequiredDuringSchedulingRequiredDuringExecution []PodAffinityTerm `json:\"requiredDuringSchedulingRequiredDuringExecution,omitempty\"` If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied."
|
||||
"description": "If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied."
|
||||
},
|
||||
"preferredDuringSchedulingIgnoredDuringExecution": {
|
||||
"type": "array",
|
||||
@ -3351,7 +3354,7 @@
|
||||
"items": {
|
||||
"$ref": "v1.PodAffinityTerm"
|
||||
},
|
||||
"description": "NOT YET IMPLEMENTED. TODO: Uncomment field once it is implemented. If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system will try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. RequiredDuringSchedulingRequiredDuringExecution []PodAffinityTerm `json:\"requiredDuringSchedulingRequiredDuringExecution,omitempty\"` If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied."
|
||||
"description": "If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied."
|
||||
},
|
||||
"preferredDuringSchedulingIgnoredDuringExecution": {
|
||||
"type": "array",
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -7323,22 +7323,18 @@
|
||||
"v1.FCVolumeSource": {
|
||||
"id": "v1.FCVolumeSource",
|
||||
"description": "Represents a Fibre Channel volume. Fibre Channel volumes can only be mounted as read/write once. Fibre Channel volumes support ownership management and SELinux relabeling.",
|
||||
"required": [
|
||||
"targetWWNs",
|
||||
"lun"
|
||||
],
|
||||
"properties": {
|
||||
"targetWWNs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Required: FC target worldwide names (WWNs)"
|
||||
"description": "Optional: FC target worldwide names (WWNs)"
|
||||
},
|
||||
"lun": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "Required: FC target lun number"
|
||||
"description": "Optional: FC target lun number"
|
||||
},
|
||||
"fsType": {
|
||||
"type": "string",
|
||||
@ -7347,6 +7343,13 @@
|
||||
"readOnly": {
|
||||
"type": "boolean",
|
||||
"description": "Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts."
|
||||
},
|
||||
"wwids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Optional: FC volume world wide identifiers (wwids) Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously."
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -8401,7 +8404,7 @@
|
||||
"items": {
|
||||
"$ref": "v1.PodAffinityTerm"
|
||||
},
|
||||
"description": "NOT YET IMPLEMENTED. TODO: Uncomment field once it is implemented. If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system will try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. RequiredDuringSchedulingRequiredDuringExecution []PodAffinityTerm `json:\"requiredDuringSchedulingRequiredDuringExecution,omitempty\"` If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied."
|
||||
"description": "If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied."
|
||||
},
|
||||
"preferredDuringSchedulingIgnoredDuringExecution": {
|
||||
"type": "array",
|
||||
@ -8461,7 +8464,7 @@
|
||||
"items": {
|
||||
"$ref": "v1.PodAffinityTerm"
|
||||
},
|
||||
"description": "NOT YET IMPLEMENTED. TODO: Uncomment field once it is implemented. If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system will try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. RequiredDuringSchedulingRequiredDuringExecution []PodAffinityTerm `json:\"requiredDuringSchedulingRequiredDuringExecution,omitempty\"` If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied."
|
||||
"description": "If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied."
|
||||
},
|
||||
"preferredDuringSchedulingIgnoredDuringExecution": {
|
||||
"type": "array",
|
||||
@ -8759,7 +8762,7 @@
|
||||
},
|
||||
"rollbackTo": {
|
||||
"$ref": "v1beta1.RollbackConfig",
|
||||
"description": "The config this deployment is rolling back to. Will be cleared after rollback is done."
|
||||
"description": "DEPRECATED. The config this deployment is rolling back to. Will be cleared after rollback is done."
|
||||
},
|
||||
"progressDeadlineSeconds": {
|
||||
"type": "integer",
|
||||
@ -8798,6 +8801,7 @@
|
||||
},
|
||||
"v1beta1.RollbackConfig": {
|
||||
"id": "v1beta1.RollbackConfig",
|
||||
"description": "DEPRECATED.",
|
||||
"properties": {
|
||||
"revision": {
|
||||
"type": "integer",
|
||||
@ -8890,7 +8894,7 @@
|
||||
},
|
||||
"v1beta1.DeploymentRollback": {
|
||||
"id": "v1beta1.DeploymentRollback",
|
||||
"description": "DeploymentRollback stores the information required to rollback a deployment.",
|
||||
"description": "DEPRECATED. DeploymentRollback stores the information required to rollback a deployment.",
|
||||
"required": [
|
||||
"name",
|
||||
"rollbackTo"
|
||||
|
3652
api/swagger-spec/rbac.authorization.k8s.io_v1.json
Normal file
3652
api/swagger-spec/rbac.authorization.k8s.io_v1.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -105,6 +105,10 @@
|
||||
"path": "/apis/rbac.authorization.k8s.io/v1beta1",
|
||||
"description": "API at /apis/rbac.authorization.k8s.io/v1beta1"
|
||||
},
|
||||
{
|
||||
"path": "/apis/rbac.authorization.k8s.io/v1",
|
||||
"description": "API at /apis/rbac.authorization.k8s.io/v1"
|
||||
},
|
||||
{
|
||||
"path": "/apis/rbac.authorization.k8s.io/v1alpha1",
|
||||
"description": "API at /apis/rbac.authorization.k8s.io/v1alpha1"
|
||||
|
@ -2031,22 +2031,18 @@
|
||||
"v1.FCVolumeSource": {
|
||||
"id": "v1.FCVolumeSource",
|
||||
"description": "Represents a Fibre Channel volume. Fibre Channel volumes can only be mounted as read/write once. Fibre Channel volumes support ownership management and SELinux relabeling.",
|
||||
"required": [
|
||||
"targetWWNs",
|
||||
"lun"
|
||||
],
|
||||
"properties": {
|
||||
"targetWWNs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Required: FC target worldwide names (WWNs)"
|
||||
"description": "Optional: FC target worldwide names (WWNs)"
|
||||
},
|
||||
"lun": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "Required: FC target lun number"
|
||||
"description": "Optional: FC target lun number"
|
||||
},
|
||||
"fsType": {
|
||||
"type": "string",
|
||||
@ -2055,6 +2051,13 @@
|
||||
"readOnly": {
|
||||
"type": "boolean",
|
||||
"description": "Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts."
|
||||
},
|
||||
"wwids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Optional: FC volume world wide identifiers (wwids) Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -18318,6 +18318,10 @@
|
||||
"$ref": "v1.Taint"
|
||||
},
|
||||
"description": "If specified, the node's taints."
|
||||
},
|
||||
"configSource": {
|
||||
"$ref": "v1.NodeConfigSource",
|
||||
"description": "If specified, the source to get node configuration from The DynamicKubeletConfig feature gate must be enabled for the Kubelet to use this field"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -18347,6 +18351,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.NodeConfigSource": {
|
||||
"id": "v1.NodeConfigSource",
|
||||
"description": "NodeConfigSource specifies a source of node configuration. Exactly one subfield (excluding metadata) must be non-nil.",
|
||||
"properties": {
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds"
|
||||
},
|
||||
"apiVersion": {
|
||||
"type": "string",
|
||||
"description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources"
|
||||
},
|
||||
"configMapRef": {
|
||||
"$ref": "v1.ObjectReference"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.NodeStatus": {
|
||||
"id": "v1.NodeStatus",
|
||||
"description": "NodeStatus is information about the current status of a node.",
|
||||
@ -19195,22 +19216,18 @@
|
||||
"v1.FCVolumeSource": {
|
||||
"id": "v1.FCVolumeSource",
|
||||
"description": "Represents a Fibre Channel volume. Fibre Channel volumes can only be mounted as read/write once. Fibre Channel volumes support ownership management and SELinux relabeling.",
|
||||
"required": [
|
||||
"targetWWNs",
|
||||
"lun"
|
||||
],
|
||||
"properties": {
|
||||
"targetWWNs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Required: FC target worldwide names (WWNs)"
|
||||
"description": "Optional: FC target worldwide names (WWNs)"
|
||||
},
|
||||
"lun": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "Required: FC target lun number"
|
||||
"description": "Optional: FC target lun number"
|
||||
},
|
||||
"fsType": {
|
||||
"type": "string",
|
||||
@ -19219,6 +19236,13 @@
|
||||
"readOnly": {
|
||||
"type": "boolean",
|
||||
"description": "Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts."
|
||||
},
|
||||
"wwids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Optional: FC volume world wide identifiers (wwids) Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously."
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -20847,7 +20871,7 @@
|
||||
"items": {
|
||||
"$ref": "v1.PodAffinityTerm"
|
||||
},
|
||||
"description": "NOT YET IMPLEMENTED. TODO: Uncomment field once it is implemented. If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system will try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. RequiredDuringSchedulingRequiredDuringExecution []PodAffinityTerm `json:\"requiredDuringSchedulingRequiredDuringExecution,omitempty\"` If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied."
|
||||
"description": "If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied."
|
||||
},
|
||||
"preferredDuringSchedulingIgnoredDuringExecution": {
|
||||
"type": "array",
|
||||
@ -20907,7 +20931,7 @@
|
||||
"items": {
|
||||
"$ref": "v1.PodAffinityTerm"
|
||||
},
|
||||
"description": "NOT YET IMPLEMENTED. TODO: Uncomment field once it is implemented. If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system will try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. RequiredDuringSchedulingRequiredDuringExecution []PodAffinityTerm `json:\"requiredDuringSchedulingRequiredDuringExecution,omitempty\"` If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied."
|
||||
"description": "If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied."
|
||||
},
|
||||
"preferredDuringSchedulingIgnoredDuringExecution": {
|
||||
"type": "array",
|
||||
@ -21790,6 +21814,10 @@
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "healthCheckNodePort specifies the healthcheck nodePort for the service. If not specified, HealthCheckNodePort is created by the service api backend with the allocated nodePort. Will use user-specified nodePort value if specified by the client. Only effects when Type is set to LoadBalancer and ExternalTrafficPolicy is set to Local."
|
||||
},
|
||||
"publishNotReadyAddresses": {
|
||||
"type": "boolean",
|
||||
"description": "publishNotReadyAddresses, when set to true, indicates that DNS implementations must publish the notReadyAddresses of subsets for the Endpoints associated with the Service. The default value is false. The primary use case for setting this field is to use a StatefulSet's Headless Service to propagate SRV records for its Pods without respect to their readiness for purpose of peer discovery. This field will replace the service.alpha.kubernetes.io/tolerate-unready-endpoints when that annotation is deprecated and all clients have been converted to use this field."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -4,6 +4,5 @@
|
||||
"^_.*"
|
||||
],
|
||||
"AddSourcesRules": true,
|
||||
"VendorMultipleBuildFiles": true,
|
||||
"K8sOpenAPIGen": true
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
# gazelle:exclude _artifacts
|
||||
# gazelle:exclude _gopath
|
||||
# gazelle:exclude _output
|
||||
# gazelle:exclude _tmp
|
||||
|
||||
licenses(["notice"])
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_prefix")
|
||||
load("@io_kubernetes_build//defs:build.bzl", "gcs_upload")
|
||||
|
@ -1,15 +1,15 @@
|
||||
http_archive(
|
||||
name = "io_bazel_rules_go",
|
||||
sha256 = "abdea3986d9e850eda27b12163b0b558accdb5bca69ef945b022356f920d430d",
|
||||
strip_prefix = "rules_go-473417ec48310325e1fcb1c154621a83197a17fe",
|
||||
urls = ["https://github.com/bazelbuild/rules_go/archive/473417ec48310325e1fcb1c154621a83197a17fe.tar.gz"],
|
||||
sha256 = "f9cc31e9d66dad1154de3c214158916411040e2c2614e4fbc2bab67330e95f82",
|
||||
strip_prefix = "rules_go-82483596ec203eb9c1849937636f4cbed83733eb",
|
||||
urls = ["https://github.com/bazelbuild/rules_go/archive/82483596ec203eb9c1849937636f4cbed83733eb.tar.gz"],
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "io_kubernetes_build",
|
||||
sha256 = "232fec0ffcb53df5e87fc036ae3e966ea32122fc89ead4c32581b3255c1ab7d0",
|
||||
strip_prefix = "repo-infra-f521b5d472e00e05da5394994942064510a6e8bf",
|
||||
urls = ["https://github.com/kubernetes/repo-infra/archive/f521b5d472e00e05da5394994942064510a6e8bf.tar.gz"],
|
||||
sha256 = "5ba54d17d582ec099ba65d4e409e318e209216b15be819c922a5baae3f4d4283",
|
||||
strip_prefix = "repo-infra-e9d1a126ef355ff5d38e20612c889b07728225a4",
|
||||
urls = ["https://github.com/kubernetes/repo-infra/archive/e9d1a126ef355ff5d38e20612c889b07728225a4.tar.gz"],
|
||||
)
|
||||
|
||||
ETCD_VERSION = "3.0.17"
|
||||
|
@ -360,6 +360,7 @@ package_group(
|
||||
packages = [
|
||||
"//pkg/kubectl",
|
||||
"//pkg/kubectl/cmd",
|
||||
"//pkg/kubectl/proxy",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -3,9 +3,9 @@ reviewers:
|
||||
- dchen1107
|
||||
- ixdy
|
||||
- jbeda
|
||||
- jregan
|
||||
- lavalamp
|
||||
- mikedanese
|
||||
- monopole
|
||||
- pwittrock
|
||||
- smarterclayton
|
||||
- thockin
|
||||
@ -15,9 +15,9 @@ approvers:
|
||||
- dchen1107
|
||||
- ixdy
|
||||
- jbeda
|
||||
- jregan
|
||||
- lavalamp
|
||||
- mikedanese
|
||||
- monopole
|
||||
- pwittrock
|
||||
- smarterclayton
|
||||
- thockin
|
||||
|
@ -2,8 +2,6 @@ package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load("@io_bazel//tools/build_defs/pkg:pkg.bzl", "pkg_tar")
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
|
@ -64,6 +64,26 @@ spec:
|
||||
- name: usr-ca-certs
|
||||
mountPath: /usr/share/ca-certificates
|
||||
readOnly: true
|
||||
- name: prom-to-sd
|
||||
image: gcr.io/google-containers/prometheus-to-sd:v0.2.1
|
||||
command:
|
||||
- /monitor
|
||||
- --source=heapster:http://localhost:8082?whitelisted=stackdriver_requests_count,stackdriver_timeseries_count
|
||||
- --stackdriver-prefix=container.googleapis.com/internal/addons
|
||||
- --pod-id=$(POD_NAME)
|
||||
- --namespace-id=$(POD_NAMESPACE)
|
||||
volumeMounts:
|
||||
- name: ssl-certs
|
||||
mountPath: /etc/ssl/certs
|
||||
env:
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- image: gcr.io/google_containers/addon-resizer:2.0
|
||||
name: heapster-nanny
|
||||
resources:
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
@ -11,13 +9,11 @@ load(
|
||||
go_binary(
|
||||
name = "es-image",
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["elasticsearch_logging_discovery.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset:go_default_library",
|
||||
|
@ -1155,7 +1155,7 @@ function start-cluster-autoscaler {
|
||||
local -r src_file="${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty/cluster-autoscaler.manifest"
|
||||
remove-salt-config-comments "${src_file}"
|
||||
|
||||
local params="${AUTOSCALER_MIG_CONFIG} ${CLOUD_CONFIG_OPT} ${AUTOSCALER_EXPANDER_CONFIG:-}"
|
||||
local params="${AUTOSCALER_MIG_CONFIG} ${CLOUD_CONFIG_OPT} ${AUTOSCALER_EXPANDER_CONFIG:---expander=price}"
|
||||
sed -i -e "s@{{params}}@${params}@g" "${src_file}"
|
||||
sed -i -e "s@{{cloud_config_mount}}@${CLOUD_CONFIG_MOUNT}@g" "${src_file}"
|
||||
sed -i -e "s@{{cloud_config_volume}}@${CLOUD_CONFIG_VOLUME}@g" "${src_file}"
|
||||
|
@ -524,6 +524,8 @@ function create-master-audit-policy {
|
||||
- group: "storage.k8s.io"'
|
||||
|
||||
cat <<EOF >"${path}"
|
||||
apiVersion: audit.k8s.io/v1alpha1
|
||||
kind: Policy
|
||||
rules:
|
||||
# The following requests were manually identified as high-volume and low-risk,
|
||||
# so drop them.
|
||||
@ -1558,7 +1560,7 @@ function start-cluster-autoscaler {
|
||||
local -r src_file="${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty/cluster-autoscaler.manifest"
|
||||
remove-salt-config-comments "${src_file}"
|
||||
|
||||
local params="${AUTOSCALER_MIG_CONFIG} ${CLOUD_CONFIG_OPT} ${AUTOSCALER_EXPANDER_CONFIG:-}"
|
||||
local params="${AUTOSCALER_MIG_CONFIG} ${CLOUD_CONFIG_OPT} ${AUTOSCALER_EXPANDER_CONFIG:---expander=price}"
|
||||
sed -i -e "s@{{params}}@${params}@g" "${src_file}"
|
||||
sed -i -e "s@{{cloud_config_mount}}@${CLOUD_CONFIG_MOUNT}@g" "${src_file}"
|
||||
sed -i -e "s@{{cloud_config_volume}}@${CLOUD_CONFIG_VOLUME}@g" "${src_file}"
|
||||
@ -1606,7 +1608,7 @@ function wait-for-apiserver-and-update-fluentd {
|
||||
kubectl set resources --dry-run --local -f ${fluentd_gcp_yaml} \
|
||||
--limits=memory=${FLUENTD_GCP_MEMORY_LIMIT} \
|
||||
--requests=cpu=${FLUENTD_GCP_CPU_REQUEST},memory=${FLUENTD_GCP_MEMORY_REQUEST} \
|
||||
-o yaml > ${fluentd_gcp_yaml}.tmp
|
||||
--containers=fluentd-gcp -o yaml > ${fluentd_gcp_yaml}.tmp
|
||||
mv ${fluentd_gcp_yaml}.tmp ${fluentd_gcp_yaml}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
@ -11,13 +9,11 @@ load(
|
||||
go_binary(
|
||||
name = "mounter",
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["mounter.go"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
|
@ -953,6 +953,7 @@ function delete-subnetworks() {
|
||||
#
|
||||
# Assumed vars:
|
||||
# KUBE_TEMP: temporary directory
|
||||
# NUM_NODES: #nodes in the cluster
|
||||
#
|
||||
# Args:
|
||||
# $1: host name
|
||||
@ -1044,7 +1045,13 @@ function create-master() {
|
||||
create-certs "${MASTER_RESERVED_IP}"
|
||||
create-etcd-certs ${MASTER_NAME}
|
||||
|
||||
create-master-instance "${MASTER_RESERVED_IP}" &
|
||||
if [[ "${NUM_NODES}" -ge "50" ]]; then
|
||||
# We block on master creation for large clusters to avoid doing too much
|
||||
# unnecessary work in case master start-up fails (like creation of nodes).
|
||||
create-master-instance "${MASTER_RESERVED_IP}"
|
||||
else
|
||||
create-master-instance "${MASTER_RESERVED_IP}" &
|
||||
fi
|
||||
}
|
||||
|
||||
# Adds master replica to etcd cluster.
|
||||
|
@ -56,6 +56,9 @@
|
||||
# Set KUBERNETES_SKIP_DOWNLOAD to skip downloading a release.
|
||||
# Set KUBERNETES_SKIP_CONFIRM to skip the installation confirmation prompt.
|
||||
# Set KUBERNETES_SKIP_CREATE_CLUSTER to skip starting a cluster.
|
||||
# Set KUBERNETES_SKIP_RELEASE_VALIDATION to skip trying to validate the
|
||||
# Kubernetes release string. This implies that you know what you're doing
|
||||
# and have set KUBERNETES_RELEASE and KUBERNETES_RELEASE_URL properly.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
@ -179,13 +182,15 @@ release=${KUBERNETES_RELEASE:-"release/stable"}
|
||||
# Validate Kubernetes release version.
|
||||
# Translate a published version <bucket>/<version> (e.g. "release/stable") to version number.
|
||||
set_binary_version "${release}"
|
||||
if [[ ${KUBE_VERSION} =~ ${KUBE_CI_VERSION_REGEX} ]]; then
|
||||
# Override KUBERNETES_RELEASE_URL to point to the CI bucket;
|
||||
# this will be used by get-kube-binaries.sh.
|
||||
KUBERNETES_RELEASE_URL="${KUBERNETES_CI_RELEASE_URL}"
|
||||
elif ! [[ ${KUBE_VERSION} =~ ${KUBE_RELEASE_VERSION_REGEX} ]]; then
|
||||
echo "Version doesn't match regexp" >&2
|
||||
exit 1
|
||||
if [[ -z "${KUBERNETES_SKIP_RELEASE_VALIDATION-}" ]]; then
|
||||
if [[ ${KUBE_VERSION} =~ ${KUBE_CI_VERSION_REGEX} ]]; then
|
||||
# Override KUBERNETES_RELEASE_URL to point to the CI bucket;
|
||||
# this will be used by get-kube-binaries.sh.
|
||||
KUBERNETES_RELEASE_URL="${KUBERNETES_CI_RELEASE_URL}"
|
||||
elif ! [[ ${KUBE_VERSION} =~ ${KUBE_RELEASE_VERSION_REGEX} ]]; then
|
||||
echo "Version doesn't match regexp" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
kubernetes_tar_url="${KUBERNETES_RELEASE_URL}/${KUBE_VERSION}/${file}"
|
||||
|
||||
|
@ -1,52 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2014 The Kubernetes Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# This script should be sourced as a part of config-test or config-default.
|
||||
# Specifically, the following environment variables are assumed:
|
||||
# - CLUSTER_NAME (the name of the cluster)
|
||||
|
||||
if [ ! -z "${REGION:-}" ] && [ ! -z "${ZONE:-}" ]; then
|
||||
echo "Only one of REGION and ZONE can be set." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${REGION:-}" ]; then
|
||||
ZONE="${ZONE:-us-central1-f}"
|
||||
fi
|
||||
NUM_NODES="${NUM_NODES:-3}"
|
||||
ADDITIONAL_ZONES="${ADDITIONAL_ZONES:-}"
|
||||
CLUSTER_API_VERSION="${CLUSTER_API_VERSION:-}"
|
||||
NETWORK="${NETWORK:-default}"
|
||||
FIREWALL_SSH="${FIREWALL_SSH:-${NETWORK}-allow-ssh}"
|
||||
GCLOUD="${GCLOUD:-gcloud}"
|
||||
CMD_GROUP="${CMD_GROUP:-}"
|
||||
GCLOUD_CONFIG_DIR="${GCLOUD_CONFIG_DIR:-${HOME}/.config/gcloud/kubernetes}"
|
||||
MACHINE_TYPE="${MACHINE_TYPE:-n1-standard-2}"
|
||||
IMAGE_TYPE="${IMAGE_TYPE:-}"
|
||||
if [[ "${FEDERATION:-}" == true ]]; then
|
||||
NODE_SCOPES="${NODE_SCOPES:-compute-rw,storage-ro,https://www.googleapis.com/auth/ndev.clouddns.readwrite}"
|
||||
else
|
||||
NODE_SCOPES="${NODE_SCOPES:-compute-rw,storage-ro}"
|
||||
fi
|
||||
|
||||
# WARNING: any new vars added here must correspond to options that can be
|
||||
# passed to `gcloud {CMD_GROUP} container clusters create`, or they will
|
||||
# have no effect. If you change/add a var used to toggle a value in
|
||||
# cluster/gce/configure-vm.sh, please ping someone on GKE.
|
||||
|
||||
# This is a hack, but I keep setting this when I run commands manually, and
|
||||
# then things grossly fail during normal runs because cluster/kubecfg.sh and
|
||||
# cluster/kubectl.sh both use this if it's set.
|
||||
unset KUBERNETES_MASTER
|
@ -1,56 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2014 The Kubernetes Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# The following are default-specific settings.
|
||||
CLUSTER_NAME="${CLUSTER_NAME:-${USER}-gke}"
|
||||
NETWORK=${KUBE_GKE_NETWORK:-default}
|
||||
|
||||
# For ease of maintenance, extract any pieces that do not vary between default
|
||||
# and test in a common config.
|
||||
source $(dirname "${BASH_SOURCE}")/config-common.sh
|
||||
|
||||
# Optional: Install node logging
|
||||
ENABLE_NODE_LOGGING=false
|
||||
LOGGING_DESTINATION=gcp # options: elasticsearch, gcp
|
||||
|
||||
# Optional: When set to true, Elasticsearch and Kibana will be setup as part of the cluster bring up.
|
||||
ENABLE_CLUSTER_LOGGING=false
|
||||
ELASTICSEARCH_LOGGING_REPLICAS=1
|
||||
|
||||
# Optional: Deploy a L7 loadbalancer controller to fulfill Ingress requests:
|
||||
# glbc - CE L7 Load Balancer Controller
|
||||
ENABLE_L7_LOADBALANCING="${KUBE_ENABLE_L7_LOADBALANCING:-glbc}"
|
||||
|
||||
# Optional: Cluster monitoring to setup as part of the cluster bring up:
|
||||
# none - No cluster monitoring setup
|
||||
# influxdb - Heapster, InfluxDB, and Grafana
|
||||
# google - Heapster, Google Cloud Monitoring, and Google Cloud Logging
|
||||
# standalone - Heapster only. Metrics available via Heapster REST API.
|
||||
ENABLE_CLUSTER_MONITORING="${KUBE_ENABLE_CLUSTER_MONITORING:-standalone}"
|
||||
|
||||
KUBE_DELETE_NETWORK=${KUBE_DELETE_NETWORK:-false}
|
||||
|
||||
# Indicates if the values (i.e. KUBE_USER and KUBE_PASSWORD for basic
|
||||
# authentication) in metadata should be treated as canonical, and therefore disk
|
||||
# copies ought to be recreated/clobbered.
|
||||
METADATA_CLOBBERS_CONFIG=true
|
||||
|
||||
# Fluentd requirements
|
||||
FLUENTD_GCP_MEMORY_LIMIT="${FLUENTD_GCP_MEMORY_LIMIT:-300Mi}"
|
||||
FLUENTD_GCP_CPU_REQUEST="${FLUENTD_GCP_CPU_REQUEST:-100m}"
|
||||
FLUENTD_GCP_MEMORY_REQUEST="${FLUENTD_GCP_MEMORY_REQUEST:-200Mi}"
|
||||
# Adding to PROVIDER_VARS, since this is GCP-specific.
|
||||
PROVIDER_VARS="${PROVIDER_VARS:-} FLUENTD_GCP_MEMORY_LIMIT FLUENTD_GCP_CPU_REQUEST FLUENTD_GCP_MEMORY_REQUEST"
|
@ -1,28 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2014 The Kubernetes Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# The following are test-specific settings.
|
||||
CLUSTER_NAME="${CLUSTER_NAME:-${USER}-gke-e2e}"
|
||||
NETWORK=${KUBE_GKE_NETWORK:-e2e}
|
||||
NODE_TAG="k8s-${CLUSTER_NAME}-node"
|
||||
IMAGE_TYPE="${KUBE_GKE_IMAGE_TYPE:-container_vm}"
|
||||
ENABLE_KUBERNETES_ALPHA="${KUBE_GKE_ENABLE_KUBERNETES_ALPHA:-}"
|
||||
|
||||
KUBE_DELETE_NETWORK=${KUBE_DELETE_NETWORK:-true}
|
||||
|
||||
# For ease of maintenance, extract any pieces that do not vary between default
|
||||
# and test in a common config.
|
||||
source $(dirname "${BASH_SOURCE}")/config-common.sh
|
@ -1,65 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2016 The Kubernetes Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
echo "This is NOT a production-ready tool.\n\
|
||||
IT'S A HACKY, BEST-EFFORT WAY TO \"STOP\" CREATION OF THE GKE CLUSTER."
|
||||
read -n 1 -p "Are you sure you want to proceed (y/N)?: " decision
|
||||
echo ""
|
||||
if [[ "${decision}" != "y" ]]; then
|
||||
echo "Aborting..."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
KUBE_ROOT=$(dirname "${BASH_SOURCE}")/../..
|
||||
|
||||
if [ -f "${KUBE_ROOT}/cluster/env.sh" ]; then
|
||||
source "${KUBE_ROOT}/cluster/env.sh"
|
||||
fi
|
||||
|
||||
source "${KUBE_ROOT}/cluster/gke/util.sh"
|
||||
STAGING_ENDPOINT="CLOUDSDK_API_ENDPOINT_OVERRIDES_CONTAINER=https://staging-container.sandbox.googleapis.com/"
|
||||
|
||||
detect-project
|
||||
cluster=$(gcloud container operations list "--project=${PROJECT}" | grep "CREATE_CLUSTER" | grep "RUNNING" || true)
|
||||
if [ -z "${cluster}" ]; then
|
||||
echo "Couldn't find any cluster being created in production environment. Trying staging..."
|
||||
cluster=$(env ${STAGING_ENDPOINT} gcloud container operations list "--project=${PROJECT}" | grep "CREATE_CLUSTER" | grep "RUNNING" || true)
|
||||
fi
|
||||
|
||||
if [ -z "${cluster}" ]; then
|
||||
echo "No cluster creation in progress found. Aborting."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
zone=$(echo "${cluster}" | tr -s "[:blank:]" | cut -f3 -d" ")
|
||||
cluster_name=$(echo "${cluster}" | tr -s "[:blank:]" | cut -f4 -d" ")
|
||||
gcloud="gcloud"
|
||||
if [ "${zone}" == "us-east1-a" ]; then
|
||||
gcloud="env ${STAGING_ENDPOINT} gcloud"
|
||||
fi
|
||||
|
||||
migs=$(${gcloud} compute instance-groups managed list --project=${PROJECT} --zones=${zone} | grep "gke-${cluster_name}" | cut -f1 -d" ")
|
||||
echo "Managed instance groups for cluster ${cluster_name}: ${migs}"
|
||||
for mig in ${migs}; do
|
||||
echo "Resizing ${mig}..."
|
||||
${gcloud} compute instance-groups managed resize --project="${PROJECT}" --zone="${zone}" "${mig}" --size=1
|
||||
done
|
||||
|
||||
echo "All managed instance groups resized to 1. Cluster creation operation should end soon, and you will be be able to delete the cluster."
|
@ -1,458 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2014 The Kubernetes Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# A library of helper functions and constant for the local config.
|
||||
|
||||
# Uses the config file specified in $KUBE_CONFIG_FILE, or defaults to config-default.sh
|
||||
|
||||
KUBE_PROMPT_FOR_UPDATE=${KUBE_PROMPT_FOR_UPDATE:-"n"}
|
||||
KUBE_ROOT=$(dirname "${BASH_SOURCE}")/../..
|
||||
source "${KUBE_ROOT}/cluster/gke/${KUBE_CONFIG_FILE:-config-default.sh}"
|
||||
source "${KUBE_ROOT}/cluster/common.sh"
|
||||
source "${KUBE_ROOT}/hack/lib/util.sh"
|
||||
|
||||
function with-retry() {
|
||||
local retry_limit=$1
|
||||
local cmd=("${@:2}")
|
||||
|
||||
local retry_count=0
|
||||
local rc=0
|
||||
|
||||
until [[ ${retry_count} -ge ${retry_limit} ]]; do
|
||||
((retry_count+=1))
|
||||
"${cmd[@]}" && rc=0 || rc=$?
|
||||
if [[ ${rc} == 0 ]]; then
|
||||
return 0
|
||||
fi
|
||||
sleep 3
|
||||
done
|
||||
|
||||
echo "Failed to execute '${cmd[@]}' for $retry_limit times." >&2
|
||||
|
||||
return ${rc}
|
||||
}
|
||||
|
||||
# Perform preparations required to run e2e tests
|
||||
#
|
||||
# Assumed vars:
|
||||
# GCLOUD
|
||||
function prepare-e2e() {
|
||||
echo "... in gke:prepare-e2e()" >&2
|
||||
|
||||
# Ensure GCLOUD is set to some gcloud binary.
|
||||
if [[ -z "${GCLOUD:-}" ]]; then
|
||||
echo "GCLOUD environment variable is not set. It should be your gcloud binary. " >&2
|
||||
echo "A sane default is probably \$ export GCLOUD=gcloud" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# Use the gcloud defaults to find the project. If it is already set in the
|
||||
# environment then go with that.
|
||||
#
|
||||
# Assumed vars:
|
||||
# GCLOUD
|
||||
# Vars set:
|
||||
# PROJECT
|
||||
# SCOPE_ARGS
|
||||
function detect-project() {
|
||||
echo "... in gke:detect-project()" >&2
|
||||
if [[ -z "${PROJECT:-}" ]]; then
|
||||
export PROJECT=$("${GCLOUD}" config list project --format 'value(core.project)')
|
||||
echo "... Using project: ${PROJECT}" >&2
|
||||
fi
|
||||
if [[ -z "${PROJECT:-}" ]]; then
|
||||
echo "Could not detect Google Cloud Platform project. Set the default project using " >&2
|
||||
echo "'gcloud config set project <PROJECT>'" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SCOPE_ARGS=(
|
||||
"--project=${PROJECT}"
|
||||
)
|
||||
|
||||
if [[ ! -z "${ZONE:-}" ]]; then
|
||||
SCOPE_ARGS+=("--zone=${ZONE}")
|
||||
fi
|
||||
|
||||
if [[ ! -z "${REGION:-}" ]]; then
|
||||
SCOPE_ARGS+=("--region=${REGION}")
|
||||
fi
|
||||
}
|
||||
|
||||
# Execute prior to running tests to build a release if required for env.
|
||||
#
|
||||
# Assumed Vars:
|
||||
# KUBE_ROOT
|
||||
function test-build-release() {
|
||||
echo "... in gke:test-build-release()" >&2
|
||||
"${KUBE_ROOT}/build/release.sh"
|
||||
}
|
||||
|
||||
# Verify needed binaries exist.
|
||||
function verify-prereqs() {
|
||||
echo "... in gke:verify-prereqs()" >&2
|
||||
if ! which gcloud >/dev/null; then
|
||||
local resp
|
||||
if [[ "${KUBE_PROMPT_FOR_UPDATE}" == "y" ]]; then
|
||||
echo "Can't find gcloud in PATH. Do you wish to install the Google Cloud SDK? [Y/n]"
|
||||
read resp
|
||||
fi
|
||||
if [[ "${resp}" != "n" && "${resp}" != "N" ]]; then
|
||||
curl https://sdk.cloud.google.com | bash
|
||||
fi
|
||||
if ! which gcloud >/dev/null; then
|
||||
echo "Can't find gcloud in PATH, please fix and retry. The Google Cloud "
|
||||
echo "SDK can be downloaded from https://cloud.google.com/sdk/."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
update-or-verify-gcloud
|
||||
}
|
||||
|
||||
# Validate a kubernetes cluster
|
||||
function validate-cluster {
|
||||
# Simply override the NUM_NODES variable if we've spread nodes across multiple
|
||||
# zones before calling into the generic validate-cluster logic.
|
||||
local EXPECTED_NUM_NODES="${NUM_NODES}"
|
||||
if [ ! -z "${REGION:-}" ]; then
|
||||
(( EXPECTED_NUM_NODES *= 3 ))
|
||||
fi
|
||||
for zone in $(echo "${ADDITIONAL_ZONES}" | sed "s/,/ /g")
|
||||
do
|
||||
(( EXPECTED_NUM_NODES += NUM_NODES ))
|
||||
done
|
||||
NUM_NODES=${EXPECTED_NUM_NODES} bash -c "${KUBE_ROOT}/cluster/validate-cluster.sh"
|
||||
}
|
||||
|
||||
# Instantiate a kubernetes cluster
|
||||
#
|
||||
# Assumed vars:
|
||||
# GCLOUD
|
||||
# CLUSTER_NAME
|
||||
# ZONE (optional)
|
||||
# REGION (optional)
|
||||
# CLUSTER_API_VERSION (optional)
|
||||
# NUM_NODES
|
||||
# ADDITIONAL_ZONES (optional)
|
||||
# NODE_SCOPES
|
||||
# MACHINE_TYPE
|
||||
# HEAPSTER_MACHINE_TYPE (optional)
|
||||
# CLUSTER_IP_RANGE (optional)
|
||||
# GKE_CREATE_FLAGS (optional, space delineated)
|
||||
# ENABLE_KUBERNETES_ALPHA (optional)
|
||||
function kube-up() {
|
||||
echo "... in gke:kube-up()" >&2
|
||||
detect-project >&2
|
||||
|
||||
# Make the specified network if we need to.
|
||||
if ! "${GCLOUD}" compute networks --project "${PROJECT}" describe "${NETWORK}" &>/dev/null; then
|
||||
echo "Creating new network: ${NETWORK}" >&2
|
||||
with-retry 3 "${GCLOUD}" compute networks create "${NETWORK}" --project="${PROJECT}" --mode=auto
|
||||
else
|
||||
echo "... Using network: ${NETWORK}" >&2
|
||||
fi
|
||||
|
||||
# Allow SSH on all nodes in the network. This doesn't actually check whether
|
||||
# such a rule exists, only whether we've created this exact rule.
|
||||
if ! "${GCLOUD}" compute firewall-rules --project "${PROJECT}" describe "${FIREWALL_SSH}" &>/dev/null; then
|
||||
echo "Creating new firewall for SSH: ${FIREWALL_SSH}" >&2
|
||||
with-retry 3 "${GCLOUD}" compute firewall-rules create "${FIREWALL_SSH}" \
|
||||
--allow="tcp:22" \
|
||||
--network="${NETWORK}" \
|
||||
--project="${PROJECT}" \
|
||||
--source-ranges="0.0.0.0/0"
|
||||
else
|
||||
echo "... Using firewall-rule: ${FIREWALL_SSH}" >&2
|
||||
fi
|
||||
|
||||
local shared_args=(
|
||||
${SCOPE_ARGS[@]}
|
||||
"--scopes=${NODE_SCOPES}"
|
||||
)
|
||||
|
||||
if [[ ! -z "${IMAGE_TYPE:-}" ]]; then
|
||||
shared_args+=("--image-type=${IMAGE_TYPE}")
|
||||
fi
|
||||
|
||||
if [[ -z "${HEAPSTER_MACHINE_TYPE:-}" ]]; then
|
||||
local -r nodes="${NUM_NODES}"
|
||||
else
|
||||
local -r nodes=$(( NUM_NODES - 1 ))
|
||||
fi
|
||||
|
||||
local create_args=(
|
||||
${shared_args[@]}
|
||||
"--num-nodes=${nodes}"
|
||||
"--network=${NETWORK}"
|
||||
"--cluster-version=${CLUSTER_API_VERSION}"
|
||||
"--machine-type=${MACHINE_TYPE}"
|
||||
"--quiet"
|
||||
)
|
||||
|
||||
if [[ ! -z "${ENABLE_KUBERNETES_ALPHA:-}" ]]; then
|
||||
create_args+=("--enable-kubernetes-alpha")
|
||||
fi
|
||||
|
||||
if [[ ! -z "${ADDITIONAL_ZONES:-}" ]]; then
|
||||
create_args+=("--additional-zones=${ADDITIONAL_ZONES}")
|
||||
fi
|
||||
|
||||
if [[ ! -z "${CLUSTER_IP_RANGE:-}" ]]; then
|
||||
create_args+=("--cluster-ipv4-cidr=${CLUSTER_IP_RANGE}")
|
||||
fi
|
||||
|
||||
if [[ ! -z "${ENABLE_LEGACY_ABAC:-}" ]]; then
|
||||
if [[ "${ENABLE_LEGACY_ABAC:-}" == "true" ]]; then
|
||||
create_args+=("--enable-legacy-authorization")
|
||||
else
|
||||
create_args+=("--no-enable-legacy-authorization")
|
||||
fi
|
||||
fi
|
||||
|
||||
create_args+=( ${GKE_CREATE_FLAGS:-} )
|
||||
|
||||
# Bring up the cluster.
|
||||
"${GCLOUD}" ${CMD_GROUP:-} container clusters create "${CLUSTER_NAME}" "${create_args[@]}"
|
||||
|
||||
create-kubeconfig-for-federation
|
||||
|
||||
if [[ ! -z "${HEAPSTER_MACHINE_TYPE:-}" ]]; then
|
||||
"${GCLOUD}" ${CMD_GROUP:-} container node-pools create "heapster-pool" --cluster "${CLUSTER_NAME}" --num-nodes=1 --machine-type="${HEAPSTER_MACHINE_TYPE}" "${shared_args[@]}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Execute prior to running tests to initialize required structure. This is
|
||||
# called from hack/e2e-go only when running -up (it is run after kube-up, so
|
||||
# the cluster already exists at this point).
|
||||
#
|
||||
# Assumed vars:
|
||||
# CLUSTER_NAME
|
||||
# GCLOUD
|
||||
# ZONE
|
||||
# Vars set:
|
||||
# NODE_TAG
|
||||
function test-setup() {
|
||||
echo "... in gke:test-setup()" >&2
|
||||
# Detect the project into $PROJECT if it isn't set
|
||||
detect-project >&2
|
||||
|
||||
"${KUBE_ROOT}/cluster/kube-up.sh"
|
||||
|
||||
detect-nodes >&2
|
||||
|
||||
# At this point, CLUSTER_NAME should have been used, so its value is final.
|
||||
NODE_TAG=$($GCLOUD compute instances list ${NODE_NAMES[0]} --project="${PROJECT}" --format='value(tags.items)' | grep -o "gke-${CLUSTER_NAME}-.\{8\}-node")
|
||||
OLD_NODE_TAG="k8s-${CLUSTER_NAME}-node"
|
||||
|
||||
# Open up port 80 & 8080 so common containers on minions can be reached.
|
||||
with-retry 3 "${GCLOUD}" compute firewall-rules create \
|
||||
"${CLUSTER_NAME}-http-alt" \
|
||||
--allow tcp:80,tcp:8080 \
|
||||
--project "${PROJECT}" \
|
||||
--target-tags "${NODE_TAG},${OLD_NODE_TAG}" \
|
||||
--network="${NETWORK}" &
|
||||
|
||||
with-retry 3 "${GCLOUD}" compute firewall-rules create \
|
||||
"${CLUSTER_NAME}-nodeports" \
|
||||
--allow tcp:30000-32767,udp:30000-32767 \
|
||||
--project "${PROJECT}" \
|
||||
--target-tags "${NODE_TAG},${OLD_NODE_TAG}" \
|
||||
--network="${NETWORK}" &
|
||||
|
||||
# Wait for firewall rules.
|
||||
kube::util::wait-for-jobs || {
|
||||
echo "... gke:test-setup(): Could not create firewall" >&2
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
# Detect the IP for the master. Note that on GKE, we don't know the name of the
|
||||
# master, so KUBE_MASTER is not set.
|
||||
#
|
||||
# Assumed vars:
|
||||
# ZONE
|
||||
# CLUSTER_NAME
|
||||
# Vars set:
|
||||
# KUBE_MASTER_IP
|
||||
function detect-master() {
|
||||
echo "... in gke:detect-master()" >&2
|
||||
detect-project >&2
|
||||
KUBE_MASTER_IP=$("${GCLOUD}" ${CMD_GROUP:-} container clusters describe \
|
||||
${SCOPE_ARGS[@]} --format='value(endpoint)' \
|
||||
"${CLUSTER_NAME}")
|
||||
}
|
||||
|
||||
# Assumed vars:
|
||||
# none
|
||||
# Vars set:
|
||||
# NODE_NAMES
|
||||
function detect-nodes() {
|
||||
echo "... in gke:detect-nodes()" >&2
|
||||
detect-node-names
|
||||
}
|
||||
|
||||
# Detect minions created in the minion group
|
||||
#
|
||||
# Note that for zonal clusters this will only select nodes in the same zone as the
|
||||
# cluster, meaning that it won't include all nodes in a multi-zone cluster.
|
||||
# For regional clusters, this will select nodes only from arbitrarily chosen node instance group.
|
||||
#
|
||||
# Assumed vars:
|
||||
# GCLOUD
|
||||
# PROJECT
|
||||
# ZONE (optional)
|
||||
# REGION (optional)
|
||||
# CLUSTER_NAME
|
||||
# Vars set:
|
||||
# NODE_NAMES
|
||||
function detect-node-names {
|
||||
echo "... in gke:detect-node-names()" >&2
|
||||
detect-project
|
||||
detect-node-instance-groups
|
||||
|
||||
NODE_NAMES=()
|
||||
for group in "${NODE_INSTANCE_GROUPS[@]:-}"; do
|
||||
# We can't simply use --zone "${ZONE}" as ZONE may not be set (e.g. when REGION is set).
|
||||
local igm_zone=$(gcloud compute instance-groups managed list "${group}" --format='value(zone)')
|
||||
NODE_NAMES+=($(gcloud compute instance-groups managed list-instances \
|
||||
"${group}" --zone "${igm_zone}" \
|
||||
--project "${PROJECT}" --format='value(instance)'))
|
||||
done
|
||||
echo "NODE_NAMES=${NODE_NAMES[*]:-}"
|
||||
}
|
||||
|
||||
# Detect instance group name generated by gke.
|
||||
#
|
||||
# Note that for zonal clusters the NODE_INSTANCE_GROUPS var will only have instance groups in the
|
||||
# same zone as the cluster, meaning that it won't include all groups in a
|
||||
# multi-zone cluster.
|
||||
# For regional clusters, NODE_INSTANCE_GROUPS is set to arbitrarily chosen node instance group.
|
||||
# The ALL_INSTANCE_GROUP_URLS will contain all the instance group URLs,
|
||||
# which include multi-zone groups.
|
||||
#
|
||||
# Assumed vars:
|
||||
# GCLOUD
|
||||
# SCOPE_ARGS
|
||||
# ZONE (optional)
|
||||
# REGION (optional)
|
||||
# CLUSTER_NAME
|
||||
# Vars set:
|
||||
# NODE_INSTANCE_GROUPS
|
||||
# ALL_INSTANCE_GROUP_URLS
|
||||
function detect-node-instance-groups {
|
||||
echo "... in gke:detect-node-instance-groups()" >&2
|
||||
local urls=$("${GCLOUD}" ${CMD_GROUP:-} container clusters describe \
|
||||
${SCOPE_ARGS[@]} --format='value(instanceGroupUrls)' "${CLUSTER_NAME}")
|
||||
urls=(${urls//;/ })
|
||||
ALL_INSTANCE_GROUP_URLS=${urls[*]}
|
||||
NODE_INSTANCE_GROUPS=()
|
||||
if [[ ! -z "${ZONE:-}" ]]; then
|
||||
for url in "${urls[@]:-}"; do
|
||||
local igm_zone=$(expr ${url} : '.*/zones/\([a-z0-9-]*\)/')
|
||||
if [[ "${igm_zone}" == "${ZONE}" ]]; then
|
||||
NODE_INSTANCE_GROUPS+=("${url##*/}")
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if [[ ! -z "${REGION:-}" ]]; then
|
||||
NODE_INSTANCE_GROUPS+=("${urls[0]}")
|
||||
fi
|
||||
}
|
||||
|
||||
# SSH to a node by name ($1) and run a command ($2).
|
||||
#
|
||||
# Assumed vars:
|
||||
# GCLOUD
|
||||
# ZONE
|
||||
function ssh-to-node() {
|
||||
echo "... in gke:ssh-to-node()" >&2
|
||||
detect-project >&2
|
||||
|
||||
local node="$1"
|
||||
local cmd="$2"
|
||||
# Loop until we can successfully ssh into the box
|
||||
for try in {1..5}; do
|
||||
if gcloud compute ssh --ssh-flag="-o LogLevel=quiet" --ssh-flag="-o ConnectTimeout=30" --project "${PROJECT}" --zone="${ZONE}" "${node}" --command "echo test > /dev/null"; then
|
||||
break
|
||||
fi
|
||||
sleep 5
|
||||
done
|
||||
# Then actually try the command.
|
||||
gcloud compute ssh --ssh-flag="-o LogLevel=quiet" --ssh-flag="-o ConnectTimeout=30" --project "${PROJECT}" --zone="${ZONE}" "${node}" --command "${cmd}"
|
||||
}
|
||||
|
||||
# Execute after running tests to perform any required clean-up. This is called
|
||||
# from hack/e2e.go. This calls kube-down, so the cluster still exists when this
|
||||
# is called.
|
||||
#
|
||||
# Assumed vars:
|
||||
# CLUSTER_NAME
|
||||
# GCLOUD
|
||||
# KUBE_ROOT
|
||||
# ZONE
|
||||
function test-teardown() {
|
||||
echo "... in gke:test-teardown()" >&2
|
||||
|
||||
detect-project >&2
|
||||
|
||||
# Tear down the cluster first.
|
||||
"${KUBE_ROOT}/cluster/kube-down.sh" || true
|
||||
|
||||
# Then remove the firewall rules. We do it in this order because the
|
||||
# time to delete a firewall is actually dependent on the number of
|
||||
# instances, but we can safely delete the cluster before the firewall.
|
||||
#
|
||||
# NOTE: Keep in sync with names above in test-setup.
|
||||
for fw in "${CLUSTER_NAME}-http-alt" "${CLUSTER_NAME}-nodeports" "${FIREWALL_SSH}"; do
|
||||
if [[ -n $("${GCLOUD}" compute firewall-rules --project "${PROJECT}" describe "${fw}" --format='value(name)' 2>/dev/null || true) ]]; then
|
||||
with-retry 3 "${GCLOUD}" compute firewall-rules delete "${fw}" --project="${PROJECT}" --quiet &
|
||||
fi
|
||||
done
|
||||
|
||||
# Wait for firewall rule teardown.
|
||||
kube::util::wait-for-jobs || true
|
||||
|
||||
# It's unfortunate that the $FIREWALL_SSH rule and network are created in
|
||||
# kube-up, but we can only really delete them in test-teardown. So much for
|
||||
# symmetry.
|
||||
if [[ "${KUBE_DELETE_NETWORK}" == "true" ]]; then
|
||||
if [[ -n $("${GCLOUD}" compute networks --project "${PROJECT}" describe "${NETWORK}" --format='value(name)' 2>/dev/null || true) ]]; then
|
||||
if ! with-retry 3 "${GCLOUD}" compute networks delete --project "${PROJECT}" --quiet "${NETWORK}"; then
|
||||
echo "Failed to delete network '${NETWORK}'. Listing firewall-rules:"
|
||||
"${GCLOUD}" compute firewall-rules --project "${PROJECT}" list --filter="network=${NETWORK}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Actually take down the cluster. This is called from test-teardown.
|
||||
#
|
||||
# Assumed vars:
|
||||
# GCLOUD
|
||||
# SCOPE_ARGS
|
||||
# ZONE (optional)
|
||||
# REGION (optional)
|
||||
# CLUSTER_NAME
|
||||
function kube-down() {
|
||||
echo "... in gke:kube-down()" >&2
|
||||
detect-project >&2
|
||||
if "${GCLOUD}" ${CMD_GROUP:-} container clusters describe ${SCOPE_ARGS[@]} "${CLUSTER_NAME}" --quiet &>/dev/null; then
|
||||
with-retry 3 "${GCLOUD}" ${CMD_GROUP:-} container clusters delete ${SCOPE_ARGS[@]} \
|
||||
"${CLUSTER_NAME}" --quiet
|
||||
fi
|
||||
}
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
@ -11,13 +9,11 @@ load(
|
||||
go_binary(
|
||||
name = "etcd-version-monitor",
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["etcd-version-monitor.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
@ -11,13 +9,11 @@ load(
|
||||
go_binary(
|
||||
name = "attachlease",
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["attachlease.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//vendor/github.com/coreos/etcd/clientv3:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
@ -11,13 +9,11 @@ load(
|
||||
go_binary(
|
||||
name = "rollback",
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["rollback.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//third_party/forked/etcd221/wal:go_default_library",
|
||||
"//vendor/github.com/coreos/etcd/etcdserver:go_default_library",
|
||||
|
@ -173,7 +173,7 @@ function dump_masters() {
|
||||
echo "Master SSH not supported for ${KUBERNETES_PROVIDER}"
|
||||
return
|
||||
else
|
||||
if ! (detect-master &> /dev/null); then
|
||||
if ! (detect-master); then
|
||||
echo "Master not detected. Is the cluster up?"
|
||||
return
|
||||
fi
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
@ -24,6 +22,7 @@ filegroup(
|
||||
"//cmd/genyaml:all-srcs",
|
||||
"//cmd/gke-certificates-controller:all-srcs",
|
||||
"//cmd/hyperkube:all-srcs",
|
||||
"//cmd/importverifier:all-srcs",
|
||||
"//cmd/kube-apiserver:all-srcs",
|
||||
"//cmd/kube-controller-manager:all-srcs",
|
||||
"//cmd/kube-proxy:all-srcs",
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
@ -11,13 +9,11 @@ load(
|
||||
go_binary(
|
||||
name = "clicheck",
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["check_cli_conventions.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/kubectl/cmd:go_default_library",
|
||||
"//pkg/kubectl/cmd/util:go_default_library",
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
@ -18,14 +16,12 @@ go_binary(
|
||||
"-static",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
x_defs = version_x_defs(),
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["controller-manager.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/cloud-controller-manager/app:go_default_library",
|
||||
"//cmd/cloud-controller-manager/app/options:go_default_library",
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
@ -10,7 +8,6 @@ load(
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["controllermanager.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/cloud-controller-manager/app/options:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
@ -10,7 +8,6 @@ load(
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["options.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/apis/componentconfig:go_default_library",
|
||||
"//pkg/client/leaderelectionconfig:go_default_library",
|
||||
|
@ -71,6 +71,8 @@ func (s *CloudControllerManagerServer) AddFlags(fs *pflag.FlagSet) {
|
||||
fs.Var(componentconfig.IPVar{Val: &s.Address}, "address", "The IP address to serve on (set to 0.0.0.0 for all interfaces)")
|
||||
fs.StringVar(&s.CloudProvider, "cloud-provider", s.CloudProvider, "The provider of cloud services. Cannot be empty.")
|
||||
fs.StringVar(&s.CloudConfigFile, "cloud-config", s.CloudConfigFile, "The path to the cloud provider configuration file. Empty string for no configuration file.")
|
||||
fs.BoolVar(&s.AllowUntaggedCloud, "allow-untagged-cloud", false, "Allow the cluster to run without the cluster-id on cloud instances. This is a legacy mode of operation and a cluster-id will be required in the future.")
|
||||
fs.MarkDeprecated("allow-untagged-cloud", "This flag is deprecated and will be removed in a future release. A cluster-id will be required on cloud instances")
|
||||
fs.DurationVar(&s.MinResyncPeriod.Duration, "min-resync-period", s.MinResyncPeriod.Duration, "The resync period in reflectors will be random between MinResyncPeriod and 2*MinResyncPeriod")
|
||||
fs.DurationVar(&s.NodeMonitorPeriod.Duration, "node-monitor-period", s.NodeMonitorPeriod.Duration,
|
||||
"The period for syncing NodeStatus in NodeController.")
|
||||
|
@ -61,6 +61,14 @@ func main() {
|
||||
glog.Fatalf("Cloud provider could not be initialized: %v", err)
|
||||
}
|
||||
|
||||
if cloud.HasClusterID() == false {
|
||||
if s.AllowUntaggedCloud == true {
|
||||
glog.Warning("detected a cluster without a ClusterID. A ClusterID will be required in the future. Please tag your cluster to avoid any future issues")
|
||||
} else {
|
||||
glog.Fatalf("no ClusterID Found. A ClusterID is required for the cloud provider to function properly. This check can be bypassed by setting the allow-untagged-cloud option")
|
||||
}
|
||||
}
|
||||
|
||||
if err := app.Run(s, cloud); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||
os.Exit(1)
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
@ -11,13 +9,11 @@ load(
|
||||
go_binary(
|
||||
name = "gendocs",
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["gen_kubectl_docs.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/genutils:go_default_library",
|
||||
"//pkg/kubectl/cmd:go_default_library",
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
@ -11,13 +9,11 @@ load(
|
||||
go_binary(
|
||||
name = "genkubedocs",
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["gen_kube_docs.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/cloud-controller-manager/app:go_default_library",
|
||||
"//cmd/genutils:go_default_library",
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
@ -11,13 +9,11 @@ load(
|
||||
go_binary(
|
||||
name = "genman",
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["gen_kube_man.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/cloud-controller-manager/app:go_default_library",
|
||||
"//cmd/genutils:go_default_library",
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
@ -11,13 +9,11 @@ load(
|
||||
go_binary(
|
||||
name = "genslateyaml",
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["gen_slate_yaml.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/kubectl/cmd:go_default_library",
|
||||
"//pkg/kubectl/cmd/util:go_default_library",
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
@ -11,13 +9,11 @@ load(
|
||||
go_binary(
|
||||
name = "genswaggertypedocs",
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["swagger_type_docs.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
@ -11,14 +9,12 @@ load(
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["genutils.go"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["genutils_test.go"],
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
@ -11,13 +9,11 @@ load(
|
||||
go_binary(
|
||||
name = "genyaml",
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["gen_kubectl_yaml.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/genutils:go_default_library",
|
||||
"//pkg/kubectl/cmd:go_default_library",
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
@ -11,10 +9,9 @@ load(
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["main.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/gke-certificates-controller/app:go_default_library",
|
||||
"//pkg/util/logs:go_default_library",
|
||||
"//pkg/kubectl/util/logs:go_default_library",
|
||||
"//pkg/version/verflag:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library",
|
||||
@ -40,5 +37,4 @@ filegroup(
|
||||
go_binary(
|
||||
name = "gke-certificates-controller",
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
@ -15,7 +13,6 @@ go_library(
|
||||
"gke_signer.go",
|
||||
"options.go",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/apis/certificates/install:go_default_library",
|
||||
@ -56,7 +53,6 @@ go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["gke_signer_test.go"],
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/api/certificates/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/record:go_default_library",
|
||||
|
@ -25,7 +25,7 @@ import (
|
||||
|
||||
"k8s.io/apiserver/pkg/util/flag"
|
||||
"k8s.io/kubernetes/cmd/gke-certificates-controller/app"
|
||||
"k8s.io/kubernetes/pkg/util/logs"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/logs"
|
||||
"k8s.io/kubernetes/pkg/version/verflag"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
@ -13,7 +11,6 @@ load("//pkg/version:def.bzl", "version_x_defs")
|
||||
go_binary(
|
||||
name = "hyperkube",
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
x_defs = version_x_defs(),
|
||||
)
|
||||
|
||||
@ -21,7 +18,6 @@ go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["hyperkube_test.go"],
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
@ -44,7 +40,6 @@ go_library(
|
||||
"main.go",
|
||||
"server.go",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/kube-apiserver/app:go_default_library",
|
||||
"//cmd/kube-apiserver/app/options:go_default_library",
|
||||
|
@ -23,8 +23,12 @@ import (
|
||||
|
||||
// NewKubelet creates a new hyperkube Server object that includes the
|
||||
// description and flags.
|
||||
func NewKubelet() *Server {
|
||||
s := options.NewKubeletServer()
|
||||
func NewKubelet() (*Server, error) {
|
||||
s, err := options.NewKubeletServer()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hks := Server{
|
||||
name: "kubelet",
|
||||
SimpleUsage: "kubelet",
|
||||
@ -39,5 +43,5 @@ func NewKubelet() *Server {
|
||||
},
|
||||
}
|
||||
s.AddFlags(hks.Flags())
|
||||
return &hks
|
||||
return &hks, nil
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
|
||||
@ -36,7 +37,12 @@ func main() {
|
||||
hk.AddServer(NewKubeAPIServer())
|
||||
hk.AddServer(NewKubeControllerManager())
|
||||
hk.AddServer(NewScheduler())
|
||||
hk.AddServer(NewKubelet())
|
||||
if kubelet, err := NewKubelet(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
||||
os.Exit(1)
|
||||
} else {
|
||||
hk.AddServer(kubelet)
|
||||
}
|
||||
hk.AddServer(NewKubeProxy())
|
||||
hk.AddServer(NewKubeAggregator())
|
||||
|
||||
|
@ -1,17 +1,19 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_binary(
|
||||
name = "importverifier",
|
||||
library = ":go_default_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["diskcache.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = ["//vendor/github.com/peterbourgon/diskv:go_default_library"],
|
||||
srcs = ["importverifier.go"],
|
||||
)
|
||||
|
||||
filegroup(
|
268
cmd/importverifier/importverifier.go
Normal file
268
cmd/importverifier/importverifier.go
Normal file
@ -0,0 +1,268 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Package is a subset of cmd/go.Package
|
||||
type Package struct {
|
||||
Dir string `json:",omitempty"` // directory containing package sources
|
||||
ImportPath string `json:",omitempty"` // import path of package in dir
|
||||
Imports []string `json:",omitempty"` // import paths used by this package
|
||||
TestImports []string `json:",omitempty"` // imports from TestGoFiles
|
||||
XTestImports []string `json:",omitempty"` // imports from XTestGoFiles
|
||||
}
|
||||
|
||||
// ImportRestriction describes a set of allowable import
|
||||
// trees for a tree of source code
|
||||
type ImportRestriction struct {
|
||||
// BaseDir is the root of the package tree that is
|
||||
// restricted by this configuration, given as a
|
||||
// relative path from the root of the repository
|
||||
BaseDir string `json:"baseImportPath"`
|
||||
// IgnoredSubTrees are roots of sub-trees of the
|
||||
// BaseDir for which we do not want to enforce
|
||||
// any import restrictions whatsoever, given as
|
||||
// relative paths from the root of the repository
|
||||
IgnoredSubTrees []string `json:"ignoredSubTrees,omitempty"`
|
||||
// AllowedImports are roots of package trees that
|
||||
// are allowed to be imported from the BaseDir,
|
||||
// given as paths that would be used in a Go
|
||||
// import statement
|
||||
AllowedImports []string `json:"allowedImports"`
|
||||
}
|
||||
|
||||
// ForbiddenImportsFor determines all of the forbidden
|
||||
// imports for a package given the import restrictions
|
||||
func (i *ImportRestriction) ForbiddenImportsFor(pkg Package) ([]string, error) {
|
||||
if restricted, err := i.isRestrictedDir(pkg.Dir); err != nil {
|
||||
return []string{}, err
|
||||
} else if !restricted {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
return i.forbiddenImportsFor(pkg), nil
|
||||
}
|
||||
|
||||
// isRestrictedDir determines if the source directory has
|
||||
// any restrictions placed on it by this configuration.
|
||||
// A path will be restricted if:
|
||||
// - it falls under the base import path
|
||||
// - it does not fall under any of the ignored sub-trees
|
||||
func (i *ImportRestriction) isRestrictedDir(dir string) (bool, error) {
|
||||
if under, err := isPathUnder(i.BaseDir, dir); err != nil {
|
||||
return false, err
|
||||
} else if !under {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
for _, ignored := range i.IgnoredSubTrees {
|
||||
if under, err := isPathUnder(ignored, dir); err != nil {
|
||||
return false, err
|
||||
} else if under {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// isPathUnder determines if path is under base
|
||||
func isPathUnder(base, path string) (bool, error) {
|
||||
absBase, err := filepath.Abs(base)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
absPath, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
relPath, err := filepath.Rel(absBase, absPath)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// if path is below base, the relative path
|
||||
// from base to path will not start with `../`
|
||||
return !strings.HasPrefix(relPath, "."), nil
|
||||
}
|
||||
|
||||
// forbiddenImportsFor determines all of the forbidden
|
||||
// imports for a package given the import restrictions
|
||||
// and returns a deduplicated list of them
|
||||
func (i *ImportRestriction) forbiddenImportsFor(pkg Package) []string {
|
||||
forbiddenImportSet := map[string]struct{}{}
|
||||
for _, imp := range append(pkg.Imports, append(pkg.TestImports, pkg.XTestImports...)...) {
|
||||
path := extractVendorPath(imp)
|
||||
if i.isForbidden(path) {
|
||||
forbiddenImportSet[path] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
var forbiddenImports []string
|
||||
for imp := range forbiddenImportSet {
|
||||
forbiddenImports = append(forbiddenImports, imp)
|
||||
}
|
||||
return forbiddenImports
|
||||
}
|
||||
|
||||
// extractVendorPath removes a vendor prefix if one exists
|
||||
func extractVendorPath(path string) string {
|
||||
vendorPath := "/vendor/"
|
||||
if !strings.Contains(path, vendorPath) {
|
||||
return path
|
||||
}
|
||||
|
||||
return path[strings.Index(path, vendorPath)+len(vendorPath):]
|
||||
}
|
||||
|
||||
// isForbidden determines if an import is forbidden,
|
||||
// which is true when the import is:
|
||||
// - of a package under the rootPackage
|
||||
// - is not of the base import path or a sub-package of it
|
||||
// - is not of an allowed path or a sub-package of one
|
||||
func (i *ImportRestriction) isForbidden(imp string) bool {
|
||||
importsBelowRoot := strings.HasPrefix(imp, rootPackage)
|
||||
importsBelowBase := strings.HasPrefix(imp, i.BaseDir)
|
||||
importsAllowed := false
|
||||
for _, allowed := range i.AllowedImports {
|
||||
importsAllowed = importsAllowed || strings.HasPrefix(imp, allowed)
|
||||
}
|
||||
|
||||
return importsBelowRoot && !importsBelowBase && !importsAllowed
|
||||
}
|
||||
|
||||
var rootPackage string
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 3 {
|
||||
log.Fatalf("Usage: %s ROOT RESTRICTIONS.json", os.Args[0])
|
||||
}
|
||||
|
||||
rootPackage = os.Args[1]
|
||||
configFile := os.Args[2]
|
||||
importRestrictions, err := loadImportRestrictions(configFile)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to load import restrictions: %v", err)
|
||||
}
|
||||
|
||||
foundForbiddenImports := false
|
||||
for _, restriction := range importRestrictions {
|
||||
log.Printf("Inspecting imports under %s...\n", restriction.BaseDir)
|
||||
packages, err := resolvePackageTree(restriction.BaseDir)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to resolve package tree: %v", err)
|
||||
} else if len(packages) == 0 {
|
||||
log.Fatalf("Found no packages under tree %s", restriction.BaseDir)
|
||||
}
|
||||
|
||||
log.Printf("- validating imports for %d packages in the tree", len(packages))
|
||||
restrictionViolated := false
|
||||
for _, pkg := range packages {
|
||||
if forbidden, err := restriction.ForbiddenImportsFor(pkg); err != nil {
|
||||
log.Fatalf("-- failed to validate imports: %v", err)
|
||||
} else if len(forbidden) != 0 {
|
||||
logForbiddenPackages(pkg.ImportPath, forbidden)
|
||||
restrictionViolated = true
|
||||
}
|
||||
}
|
||||
if restrictionViolated {
|
||||
foundForbiddenImports = true
|
||||
log.Println("- FAIL")
|
||||
} else {
|
||||
log.Println("- OK")
|
||||
}
|
||||
}
|
||||
|
||||
if foundForbiddenImports {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func loadImportRestrictions(configFile string) ([]ImportRestriction, error) {
|
||||
config, err := ioutil.ReadFile(configFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load configuration from %s: %v", configFile, err)
|
||||
}
|
||||
|
||||
var importRestrictions []ImportRestriction
|
||||
if err := json.Unmarshal(config, &importRestrictions); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal from %s: %v", configFile, err)
|
||||
}
|
||||
|
||||
return importRestrictions, nil
|
||||
}
|
||||
|
||||
func resolvePackageTree(treeBase string) ([]Package, error) {
|
||||
cmd := "go"
|
||||
args := []string{"list", "-json", fmt.Sprintf("%s...", treeBase)}
|
||||
stdout, err := exec.Command(cmd, args...).Output()
|
||||
if err != nil {
|
||||
var message string
|
||||
if ee, ok := err.(*exec.ExitError); ok {
|
||||
message = fmt.Sprintf("%v\n%v", ee, ee.Stderr)
|
||||
} else {
|
||||
message = fmt.Sprintf("%v", err)
|
||||
}
|
||||
return nil, fmt.Errorf("failed to run `%s %s`: %v", cmd, strings.Join(args, " "), message)
|
||||
}
|
||||
|
||||
packages, err := decodePackages(bytes.NewReader(stdout))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decode packages: %v", err)
|
||||
}
|
||||
|
||||
return packages, nil
|
||||
}
|
||||
|
||||
func decodePackages(r io.Reader) ([]Package, error) {
|
||||
// `go list -json` concatenates package definitions
|
||||
// instead of emitting a single valid JSON, so we
|
||||
// need to stream the output to decode it into the
|
||||
// data we are looking for instead of just using a
|
||||
// simple JSON decoder on stdout
|
||||
var packages []Package
|
||||
decoder := json.NewDecoder(r)
|
||||
for decoder.More() {
|
||||
var pkg Package
|
||||
if err := decoder.Decode(&pkg); err != nil {
|
||||
return nil, fmt.Errorf("invalid package: %v", err)
|
||||
}
|
||||
packages = append(packages, pkg)
|
||||
}
|
||||
|
||||
return packages, nil
|
||||
}
|
||||
|
||||
func logForbiddenPackages(base string, forbidden []string) {
|
||||
log.Printf("-- found forbidden imports for %s:\n", base)
|
||||
for _, forbiddenPackage := range forbidden {
|
||||
log.Printf("--- %s\n", forbiddenPackage)
|
||||
}
|
||||
}
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
@ -18,14 +16,12 @@ go_binary(
|
||||
"-static",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
x_defs = version_x_defs(),
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["apiserver.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/kube-apiserver/app:go_default_library",
|
||||
"//cmd/kube-apiserver/app/options:go_default_library",
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
@ -15,7 +13,6 @@ go_library(
|
||||
"plugins.go",
|
||||
"server.go",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/kube-apiserver/app/options:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
|
@ -186,6 +186,7 @@ var apiVersionPriorities = map[schema.GroupVersion]priority{
|
||||
{Group: "certificates.k8s.io", Version: "v1beta1"}: {group: 17300, version: 9},
|
||||
{Group: "networking.k8s.io", Version: "v1"}: {group: 17200, version: 15},
|
||||
{Group: "policy", Version: "v1beta1"}: {group: 17100, version: 9},
|
||||
{Group: "rbac.authorization.k8s.io", Version: "v1"}: {group: 17000, version: 15},
|
||||
{Group: "rbac.authorization.k8s.io", Version: "v1beta1"}: {group: 17000, version: 12},
|
||||
{Group: "rbac.authorization.k8s.io", Version: "v1alpha1"}: {group: 17000, version: 9},
|
||||
{Group: "settings.k8s.io", Version: "v1alpha1"}: {group: 16900, version: 9},
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
@ -14,7 +12,6 @@ go_library(
|
||||
"options.go",
|
||||
"validation.go",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/validation:go_default_library",
|
||||
@ -33,7 +30,6 @@ go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["options_test.go"],
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/kubeapiserver/options:go_default_library",
|
||||
|
@ -166,7 +166,9 @@ func TestAddFlagsFlag(t *testing.T) {
|
||||
ServiceAccounts: &kubeoptions.ServiceAccountAuthenticationOptions{
|
||||
Lookup: true,
|
||||
},
|
||||
TokenFile: &kubeoptions.TokenFileAuthenticationOptions{},
|
||||
TokenFile: &kubeoptions.TokenFileAuthenticationOptions{},
|
||||
TokenSuccessCacheTTL: 10 * time.Second,
|
||||
TokenFailureCacheTTL: 0,
|
||||
},
|
||||
Authorization: &kubeoptions.BuiltInAuthorizationOptions{
|
||||
Mode: "AlwaysDeny",
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
@ -12,7 +10,6 @@ go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["server_test.go"],
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/api/admissionregistration/v1alpha1:go_default_library",
|
||||
"//vendor/k8s.io/api/apps/v1beta1:go_default_library",
|
||||
@ -33,7 +30,6 @@ go_test(
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["testserver.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/kube-apiserver/app:go_default_library",
|
||||
"//cmd/kube-apiserver/app/options:go_default_library",
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
@ -18,14 +16,12 @@ go_binary(
|
||||
"-static",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
x_defs = version_x_defs(),
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["controller-manager.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/kube-controller-manager/app:go_default_library",
|
||||
"//cmd/kube-controller-manager/app/options:go_default_library",
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
@ -23,7 +21,6 @@ go_library(
|
||||
"plugins.go",
|
||||
"policy.go",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/kube-controller-manager/app/options:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
@ -63,6 +60,7 @@ go_library(
|
||||
"//pkg/controller/job:go_default_library",
|
||||
"//pkg/controller/namespace:go_default_library",
|
||||
"//pkg/controller/node:go_default_library",
|
||||
"//pkg/controller/node/ipam:go_default_library",
|
||||
"//pkg/controller/podautoscaler:go_default_library",
|
||||
"//pkg/controller/podautoscaler/metrics:go_default_library",
|
||||
"//pkg/controller/podgc:go_default_library",
|
||||
@ -152,6 +150,5 @@ go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["controller_manager_test.go"],
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
deps = ["//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library"],
|
||||
)
|
||||
|
@ -163,7 +163,12 @@ func Run(s *options.CMServer) error {
|
||||
ClientConfig: kubeconfig,
|
||||
}
|
||||
var clientBuilder controller.ControllerClientBuilder
|
||||
if len(s.ServiceAccountKeyFile) > 0 && s.UseServiceAccountCredentials {
|
||||
if s.UseServiceAccountCredentials {
|
||||
if len(s.ServiceAccountKeyFile) > 0 {
|
||||
// It's possible another controller process is creating the tokens for us.
|
||||
// If one isn't, we'll timeout and exit when our client builder is unable to create the tokens.
|
||||
glog.Warningf("--use-service-account-credentials was specified without providing a --service-account-private-key-file")
|
||||
}
|
||||
clientBuilder = controller.SAControllerClientBuilder{
|
||||
ClientConfig: restclient.AnonymousClientConfig(kubeconfig),
|
||||
CoreClient: kubeClient.CoreV1(),
|
||||
@ -342,6 +347,7 @@ func NewControllerInitializers() map[string]InitFunc {
|
||||
func GetAvailableResources(clientBuilder controller.ControllerClientBuilder) (map[schema.GroupVersionResource]bool, error) {
|
||||
var discoveryClient discovery.DiscoveryInterface
|
||||
|
||||
var healthzContent string
|
||||
// If apiserver is not running we should wait for some time and fail only then. This is particularly
|
||||
// important when we start apiserver and controller manager at the same time.
|
||||
err := wait.PollImmediate(time.Second, 10*time.Second, func() (bool, error) {
|
||||
@ -352,17 +358,19 @@ func GetAvailableResources(clientBuilder controller.ControllerClientBuilder) (ma
|
||||
}
|
||||
|
||||
healthStatus := 0
|
||||
client.Discovery().RESTClient().Get().AbsPath("/healthz").Do().StatusCode(&healthStatus)
|
||||
resp := client.Discovery().RESTClient().Get().AbsPath("/healthz").Do().StatusCode(&healthStatus)
|
||||
if healthStatus != http.StatusOK {
|
||||
glog.Errorf("Server isn't healthy yet. Waiting a little while.")
|
||||
return false, nil
|
||||
}
|
||||
content, _ := resp.Raw()
|
||||
healthzContent = string(content)
|
||||
|
||||
discoveryClient = client.Discovery()
|
||||
return true, nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get api versions from server: %v", err)
|
||||
return nil, fmt.Errorf("failed to get api versions from server: %v: %v", healthzContent, err)
|
||||
}
|
||||
|
||||
resourceMap, err := discoveryClient.ServerResources()
|
||||
@ -403,6 +411,14 @@ func CreateControllerContext(s *options.CMServer, rootClientBuilder, clientBuild
|
||||
if cloud != nil {
|
||||
// Initialize the cloud provider with a reference to the clientBuilder
|
||||
cloud.Initialize(rootClientBuilder)
|
||||
|
||||
if cloud.HasClusterID() == false {
|
||||
if s.AllowUntaggedCloud == true {
|
||||
glog.Warning("detected a cluster without a ClusterID. A ClusterID will be required in the future. Please tag your cluster to avoid any future issues")
|
||||
} else {
|
||||
return ControllerContext{}, fmt.Errorf("no ClusterID Found. A ClusterID is required for the cloud provider to function properly. This check can be bypassed by setting the allow-untagged-cloud option")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx := ControllerContext{
|
||||
|
@ -42,6 +42,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/controller/garbagecollector"
|
||||
namespacecontroller "k8s.io/kubernetes/pkg/controller/namespace"
|
||||
nodecontroller "k8s.io/kubernetes/pkg/controller/node"
|
||||
"k8s.io/kubernetes/pkg/controller/node/ipam"
|
||||
"k8s.io/kubernetes/pkg/controller/podgc"
|
||||
replicationcontroller "k8s.io/kubernetes/pkg/controller/replication"
|
||||
resourcequotacontroller "k8s.io/kubernetes/pkg/controller/resourcequota"
|
||||
@ -108,7 +109,7 @@ func startNodeController(ctx ControllerContext) (bool, error) {
|
||||
serviceCIDR,
|
||||
int(ctx.Options.NodeCIDRMaskSize),
|
||||
ctx.Options.AllocateNodeCIDRs,
|
||||
nodecontroller.CIDRAllocatorType(ctx.Options.CIDRAllocatorType),
|
||||
ipam.CIDRAllocatorType(ctx.Options.CIDRAllocatorType),
|
||||
ctx.Options.EnableTaintManager,
|
||||
utilfeature.DefaultFeatureGate.Enabled(features.TaintBasedEvictions),
|
||||
)
|
||||
@ -339,7 +340,7 @@ func startGarbageCollectorController(ctx ControllerContext) (bool, error) {
|
||||
|
||||
// Periodically refresh the RESTMapper with new discovery information and sync
|
||||
// the garbage collector.
|
||||
go garbageCollector.Sync(restMapper, discoveryClient, 30*time.Second, ctx.Stop)
|
||||
go garbageCollector.Sync(gcClientset.Discovery(), 30*time.Second, ctx.Stop)
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
@ -10,7 +8,6 @@ load(
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["options.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/apis/componentconfig:go_default_library",
|
||||
"//pkg/client/leaderelectionconfig:go_default_library",
|
||||
|
@ -134,6 +134,8 @@ func (s *CMServer) AddFlags(fs *pflag.FlagSet, allControllers []string, disabled
|
||||
fs.BoolVar(&s.UseServiceAccountCredentials, "use-service-account-credentials", s.UseServiceAccountCredentials, "If true, use individual service account credentials for each controller.")
|
||||
fs.StringVar(&s.CloudProvider, "cloud-provider", s.CloudProvider, "The provider for cloud services. Empty string for no provider.")
|
||||
fs.StringVar(&s.CloudConfigFile, "cloud-config", s.CloudConfigFile, "The path to the cloud provider configuration file. Empty string for no configuration file.")
|
||||
fs.BoolVar(&s.AllowUntaggedCloud, "allow-untagged-cloud", false, "Allow the cluster to run without the cluster-id on cloud instances. This is a legacy mode of operation and a cluster-id will be required in the future.")
|
||||
fs.MarkDeprecated("allow-untagged-cloud", "This flag is deprecated and will be removed in a future release. A cluster-id will be required on cloud instances")
|
||||
fs.Int32Var(&s.ConcurrentEndpointSyncs, "concurrent-endpoint-syncs", s.ConcurrentEndpointSyncs, "The number of endpoint syncing operations that will be done concurrently. Larger number = faster endpoint updating, but more CPU (and network) load")
|
||||
fs.Int32Var(&s.ConcurrentServiceSyncs, "concurrent-service-syncs", s.ConcurrentServiceSyncs, "The number of services that are allowed to sync concurrently. Larger number = more responsive service management, but more CPU (and network) load")
|
||||
fs.Int32Var(&s.ConcurrentRCSyncs, "concurrent_rc_syncs", s.ConcurrentRCSyncs, "The number of replication controllers that are allowed to sync concurrently. Larger number = more responsive replica management, but more CPU (and network) load")
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
@ -18,14 +16,12 @@ go_binary(
|
||||
"-static",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
x_defs = version_x_defs(),
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["proxy.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/kube-proxy/app:go_default_library",
|
||||
"//pkg/client/metrics/prometheus:go_default_library",
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
@ -14,7 +12,6 @@ go_library(
|
||||
"conntrack.go",
|
||||
"server.go",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/apis/componentconfig:go_default_library",
|
||||
@ -69,7 +66,6 @@ go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["server_test.go"],
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/apis/componentconfig:go_default_library",
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
@ -18,14 +16,12 @@ go_binary(
|
||||
"-static",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
x_defs = version_x_defs(),
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["kubeadm.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = ["//cmd/kubeadm/app:go_default_library"],
|
||||
)
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
@ -10,7 +8,6 @@ load(
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["kubeadm.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm/install:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd:go_default_library",
|
||||
@ -38,12 +35,15 @@ filegroup(
|
||||
"//cmd/kubeadm/app/node:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/addons:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/apiconfig:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/bootstraptoken/clusterinfo:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/bootstraptoken/node:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/certs:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/controlplane:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/kubeconfig:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/markmaster:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/selfhosting:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/token:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/uploadconfig:all-srcs",
|
||||
"//cmd/kubeadm/app/preflight:all-srcs",
|
||||
"//cmd/kubeadm/app/util:all-srcs",
|
||||
],
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
@ -15,7 +13,6 @@ go_library(
|
||||
"types.go",
|
||||
"zz_generated.deepcopy.go",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
@ -10,7 +8,6 @@ load(
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["fuzzer.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//vendor/github.com/google/gofuzz:go_default_library",
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
@ -14,7 +12,6 @@ go_library(
|
||||
"doc.go",
|
||||
"install.go",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/v1alpha1:go_default_library",
|
||||
@ -42,7 +39,6 @@ go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["install_test.go"],
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm/fuzzer:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/testing/roundtrip:go_default_library",
|
||||
|
@ -39,11 +39,6 @@ type MasterConfiguration struct {
|
||||
Token string
|
||||
TokenTTL time.Duration
|
||||
|
||||
// SelfHosted enables an alpha deployment type where the apiserver, scheduler, and
|
||||
// controller manager are managed by Kubernetes itself. This option is likely to
|
||||
// become the default in the future.
|
||||
SelfHosted bool
|
||||
|
||||
APIServerExtraArgs map[string]string
|
||||
ControllerManagerExtraArgs map[string]string
|
||||
SchedulerExtraArgs map[string]string
|
||||
@ -105,6 +100,21 @@ type NodeConfiguration struct {
|
||||
NodeName string
|
||||
TLSBootstrapToken string
|
||||
Token string
|
||||
|
||||
// DiscoveryTokenCACertHashes specifies a set of public key pins to verify
|
||||
// when token-based discovery is used. The root CA found during discovery
|
||||
// must match one of these values. Specifying an empty set disables root CA
|
||||
// pinning, which can be unsafe. Each hash is specified as "<type>:<value>",
|
||||
// where the only currently supported type is "sha256". This is a hex-encoded
|
||||
// SHA-256 hash of the Subject Public Key Info (SPKI) object in DER-encoded
|
||||
// ASN.1. These hashes can be calculated using, for example, OpenSSL:
|
||||
// openssl x509 -pubkey -in ca.crt openssl rsa -pubin -outform der 2>&/dev/null | openssl dgst -sha256 -hex
|
||||
DiscoveryTokenCACertHashes []string
|
||||
|
||||
// DiscoveryTokenUnsafeSkipCAVerification allows token-based discovery
|
||||
// without CA verification via DiscoveryTokenCACertHashes. This can weaken
|
||||
// the security of kubeadm since other nodes can impersonate the master.
|
||||
DiscoveryTokenUnsafeSkipCAVerification bool
|
||||
}
|
||||
|
||||
func (cfg *MasterConfiguration) GetMasterEndpoint() string {
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
@ -17,7 +15,6 @@ go_library(
|
||||
"zz_generated.deepcopy.go",
|
||||
"zz_generated.defaults.go",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/constants:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
|
@ -38,11 +38,6 @@ type MasterConfiguration struct {
|
||||
Token string `json:"token"`
|
||||
TokenTTL time.Duration `json:"tokenTTL"`
|
||||
|
||||
// SelfHosted enables an alpha deployment type where the apiserver, scheduler, and
|
||||
// controller manager are managed by Kubernetes itself. This option is likely to
|
||||
// become the default in the future.
|
||||
SelfHosted bool `json:"selfHosted"`
|
||||
|
||||
APIServerExtraArgs map[string]string `json:"apiServerExtraArgs"`
|
||||
ControllerManagerExtraArgs map[string]string `json:"controllerManagerExtraArgs"`
|
||||
SchedulerExtraArgs map[string]string `json:"schedulerExtraArgs"`
|
||||
@ -103,4 +98,19 @@ type NodeConfiguration struct {
|
||||
NodeName string `json:"nodeName"`
|
||||
TLSBootstrapToken string `json:"tlsBootstrapToken"`
|
||||
Token string `json:"token"`
|
||||
|
||||
// DiscoveryTokenCACertHashes specifies a set of public key pins to verify
|
||||
// when token-based discovery is used. The root CA found during discovery
|
||||
// must match one of these values. Specifying an empty set disables root CA
|
||||
// pinning, which can be unsafe. Each hash is specified as "<type>:<value>",
|
||||
// where the only currently supported type is "sha256". This is a hex-encoded
|
||||
// SHA-256 hash of the Subject Public Key Info (SPKI) object in DER-encoded
|
||||
// ASN.1. These hashes can be calculated using, for example, OpenSSL:
|
||||
// openssl x509 -pubkey -in ca.crt openssl rsa -pubin -outform der 2>&/dev/null | openssl dgst -sha256 -hex
|
||||
DiscoveryTokenCACertHashes []string `json:"discoveryTokenCACertHashes"`
|
||||
|
||||
// DiscoveryTokenUnsafeSkipCAVerification allows token-based discovery
|
||||
// without CA verification via DiscoveryTokenCACertHashes. This can weaken
|
||||
// the security of kubeadm since other nodes can impersonate the master.
|
||||
DiscoveryTokenUnsafeSkipCAVerification bool `json:"discoveryTokenUnsafeSkipCAVerification"`
|
||||
}
|
||||
|
@ -194,6 +194,11 @@ func (in *NodeConfiguration) DeepCopyInto(out *NodeConfiguration) {
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.DiscoveryTokenCACertHashes != nil {
|
||||
in, out := &in.DiscoveryTokenCACertHashes, &out.DiscoveryTokenCACertHashes
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
@ -12,7 +10,6 @@ go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["validation_test.go"],
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
@ -23,7 +20,6 @@ go_test(
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["validation.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/features:go_default_library",
|
||||
|
@ -137,6 +137,17 @@ func ValidateArgSelection(cfg *kubeadm.NodeConfiguration, fldPath *field.Path) f
|
||||
if len(cfg.DiscoveryTokenAPIServers) < 1 && len(cfg.DiscoveryToken) != 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath, "DiscoveryTokenAPIServers not set"))
|
||||
}
|
||||
|
||||
if len(cfg.DiscoveryFile) != 0 && len(cfg.DiscoveryTokenCACertHashes) != 0 {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, "", "DiscoveryTokenCACertHashes cannot be used with DiscoveryFile"))
|
||||
}
|
||||
|
||||
// TODO: convert this warning to an error after v1.8
|
||||
if len(cfg.DiscoveryFile) == 0 && len(cfg.DiscoveryTokenCACertHashes) == 0 && !cfg.DiscoveryTokenUnsafeSkipCAVerification {
|
||||
fmt.Println("[validation] WARNING: using token-based discovery without DiscoveryTokenCACertHashes can be unsafe (see https://kubernetes.io/docs/admin/kubeadm/#kubeadm-join).")
|
||||
fmt.Println("[validation] WARNING: Pass --discovery-token-unsafe-skip-ca-verification to disable this warning. This warning will become an error in Kubernetes 1.9.")
|
||||
}
|
||||
|
||||
// TODO remove once we support multiple api servers
|
||||
if len(cfg.DiscoveryTokenAPIServers) > 1 {
|
||||
fmt.Println("[validation] WARNING: kubeadm doesn't fully support multiple API Servers yet")
|
||||
|
@ -199,6 +199,11 @@ func (in *NodeConfiguration) DeepCopyInto(out *NodeConfiguration) {
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.DiscoveryTokenCACertHashes != nil {
|
||||
in, out := &in.DiscoveryTokenCACertHashes, &out.DiscoveryTokenCACertHashes
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
@ -19,25 +17,29 @@ go_library(
|
||||
"token.go",
|
||||
"version.go",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/v1alpha1:go_default_library",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/validation:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/features:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/phases:go_default_library",
|
||||
"//cmd/kubeadm/app/constants:go_default_library",
|
||||
"//cmd/kubeadm/app/discovery:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/addons:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/apiconfig:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/bootstraptoken/clusterinfo:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/bootstraptoken/node:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/controlplane:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/markmaster:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/selfhosting:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/token:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/uploadconfig:go_default_library",
|
||||
"//cmd/kubeadm/app/preflight:go_default_library",
|
||||
"//cmd/kubeadm/app/util:go_default_library",
|
||||
"//cmd/kubeadm/app/util/config:go_default_library",
|
||||
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
|
||||
"//cmd/kubeadm/app/util/pubkeypin:go_default_library",
|
||||
"//cmd/kubeadm/app/util/token:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/bootstrap/api:go_default_library",
|
||||
@ -69,7 +71,6 @@ go_test(
|
||||
"token_test.go",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/constants:go_default_library",
|
||||
"//cmd/kubeadm/app/preflight:go_default_library",
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
@ -10,7 +8,6 @@ load(
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["features.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = ["//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library"],
|
||||
)
|
||||
|
||||
|
@ -31,6 +31,12 @@ const (
|
||||
// FeatureList represents a list of feature gates
|
||||
type FeatureList map[utilfeature.Feature]utilfeature.FeatureSpec
|
||||
|
||||
// Enabled indicates whether a feature name has been enabled
|
||||
func Enabled(featureList map[string]bool, featureName utilfeature.Feature) bool {
|
||||
_, ok := featureList[string(featureName)]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Supports indicates whether a feature name is supported on the given
|
||||
// feature set
|
||||
func Supports(featureList FeatureList, featureName string) bool {
|
||||
|
@ -31,18 +31,23 @@ import (
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/features"
|
||||
cmdphases "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
addonsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons"
|
||||
apiconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/apiconfig"
|
||||
clusterinfophase "k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo"
|
||||
nodebootstraptokenphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/node"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil"
|
||||
controlplanephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane"
|
||||
kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
|
||||
markmasterphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/markmaster"
|
||||
selfhostingphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/selfhosting"
|
||||
tokenphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/token"
|
||||
uploadconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/uploadconfig"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/pubkeypin"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/util/version"
|
||||
)
|
||||
@ -64,7 +69,7 @@ var (
|
||||
You can now join any number of machines by running the following on each node
|
||||
as root:
|
||||
|
||||
kubeadm join --token {{.Token}} {{.MasterIP}}:{{.MasterPort}}
|
||||
kubeadm join --token {{.Token}} {{.MasterIP}}:{{.MasterPort}} --discovery-token-ca-cert-hash {{.CAPubKeyPin}}
|
||||
|
||||
`)))
|
||||
)
|
||||
@ -147,10 +152,6 @@ func NewCmdInit(out io.Writer) *cobra.Command {
|
||||
&skipTokenPrint, "skip-token-print", skipTokenPrint,
|
||||
"Skip printing of the default bootstrap token generated by 'kubeadm init'",
|
||||
)
|
||||
cmd.PersistentFlags().BoolVar(
|
||||
&cfg.SelfHosted, "self-hosted", cfg.SelfHosted,
|
||||
"[experimental] If kubeadm should make this control plane self-hosted",
|
||||
)
|
||||
|
||||
cmd.PersistentFlags().StringVar(
|
||||
&cfg.Token, "token", cfg.Token,
|
||||
@ -224,62 +225,76 @@ func (i *Init) Validate(cmd *cobra.Command) error {
|
||||
// Run executes master node provisioning, including certificates, needed static pod manifests, etc.
|
||||
func (i *Init) Run(out io.Writer) error {
|
||||
|
||||
// PHASE 1: Generate certificates
|
||||
err := cmdphases.CreatePKIAssets(i.cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// PHASE 2: Generate kubeconfig files for the admin and the kubelet
|
||||
err = kubeconfigphase.CreateInitKubeConfigFiles(kubeadmconstants.KubernetesDir, i.cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// PHASE 3: Bootstrap the control plane
|
||||
if err := controlplanephase.WriteStaticPodManifests(i.cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
adminKubeConfigPath := filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.AdminKubeConfigFileName)
|
||||
client, err := kubeadmutil.CreateClientAndWaitForAPI(adminKubeConfigPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := markmasterphase.MarkMaster(client, i.cfg.NodeName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// PHASE 4: Set up the bootstrap tokens
|
||||
if !i.skipTokenPrint {
|
||||
fmt.Printf("[token] Using token: %s\n", i.cfg.Token)
|
||||
}
|
||||
|
||||
tokenDescription := "The default bootstrap token generated by 'kubeadm init'."
|
||||
if err := tokenphase.UpdateOrCreateToken(client, i.cfg.Token, false, i.cfg.TokenTTL, kubeadmconstants.DefaultTokenUsages, tokenDescription); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tokenphase.CreateBootstrapConfigMapIfNotExists(client, adminKubeConfigPath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// PHASE 5: Install and deploy all addons, and configure things as necessary
|
||||
|
||||
k8sVersion, err := version.ParseSemantic(i.cfg.KubernetesVersion)
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't parse kubernetes version %q: %v", i.cfg.KubernetesVersion, err)
|
||||
}
|
||||
|
||||
// Create the necessary ServiceAccounts
|
||||
err = apiconfigphase.CreateServiceAccounts(client)
|
||||
// PHASE 1: Generate certificates
|
||||
if err := cmdphases.CreatePKIAssets(i.cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// PHASE 2: Generate kubeconfig files for the admin and the kubelet
|
||||
if err := kubeconfigphase.CreateInitKubeConfigFiles(kubeadmconstants.KubernetesDir, i.cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// PHASE 3: Bootstrap the control plane
|
||||
if err := controlplanephase.WriteStaticPodManifests(i.cfg, k8sVersion, kubeadmconstants.GetStaticPodDirectory()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client, err := kubeadmutil.CreateClientAndWaitForAPI(kubeadmconstants.GetAdminKubeConfigPath())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = apiconfigphase.CreateRBACRules(client, k8sVersion)
|
||||
if err != nil {
|
||||
// PHASE 4: Mark the master with the right label/taint
|
||||
if err := markmasterphase.MarkMaster(client, i.cfg.NodeName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// PHASE 5: Set up the node bootstrap tokens
|
||||
if !i.skipTokenPrint {
|
||||
fmt.Printf("[token] Using token: %s\n", i.cfg.Token)
|
||||
}
|
||||
|
||||
// Create the default node bootstrap token
|
||||
tokenDescription := "The default bootstrap token generated by 'kubeadm init'."
|
||||
if err := nodebootstraptokenphase.UpdateOrCreateToken(client, i.cfg.Token, false, i.cfg.TokenTTL, kubeadmconstants.DefaultTokenUsages, tokenDescription); err != nil {
|
||||
return err
|
||||
}
|
||||
// Create RBAC rules that makes the bootstrap tokens able to post CSRs
|
||||
if err := nodebootstraptokenphase.AllowBootstrapTokensToPostCSRs(client); err != nil {
|
||||
return err
|
||||
}
|
||||
// Create RBAC rules that makes the bootstrap tokens able to get their CSRs approved automatically
|
||||
if err := nodebootstraptokenphase.AutoApproveNodeBootstrapTokens(client, k8sVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create the cluster-info ConfigMap with the associated RBAC rules
|
||||
if err := clusterinfophase.CreateBootstrapConfigMapIfNotExists(client, kubeadmconstants.GetAdminKubeConfigPath()); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := clusterinfophase.CreateClusterInfoRBACRules(client); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// PHASE 6: Install and deploy all addons, and configure things as necessary
|
||||
|
||||
// Upload currently used configuration to the cluster
|
||||
if err := uploadconfigphase.UploadConfiguration(i.cfg, client); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create the necessary ServiceAccounts
|
||||
if err := apiconfigphase.CreateServiceAccounts(client); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := apiconfigphase.CreateRBACRules(client, k8sVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -287,8 +302,8 @@ func (i *Init) Run(out io.Writer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Is deployment type self-hosted?
|
||||
if i.cfg.SelfHosted {
|
||||
// PHASE 7: Make the control plane self-hosted if feature gate is enabled
|
||||
if features.Enabled(i.cfg.FeatureFlags, features.SelfHosting) {
|
||||
// Temporary control plane is up, now we create our self hosted control
|
||||
// plane components and remove the static manifests:
|
||||
fmt.Println("[self-hosted] Creating self-hosted control plane...")
|
||||
@ -297,10 +312,17 @@ func (i *Init) Run(out io.Writer) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Load the CA certificate from so we can pin its public key
|
||||
caCert, err := pkiutil.TryLoadCertFromDisk(i.cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx := map[string]string{
|
||||
"KubeConfigPath": filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.AdminKubeConfigFileName),
|
||||
"KubeConfigName": kubeadmconstants.AdminKubeConfigFileName,
|
||||
"Token": i.cfg.Token,
|
||||
"CAPubKeyPin": pubkeypin.Hash(caCert),
|
||||
"MasterIP": i.cfg.API.AdvertiseAddress,
|
||||
"MasterPort": strconv.Itoa(int(i.cfg.API.BindPort)),
|
||||
}
|
||||
|
@ -77,6 +77,21 @@ func NewCmdJoin(out io.Writer) *cobra.Command {
|
||||
the discovery information is loaded from a URL, HTTPS must be used and
|
||||
the host installed CA bundle is used to verify the connection.
|
||||
|
||||
If you use a shared token for discovery, you should also pass the
|
||||
--discovery-token-ca-cert-hash flag to validate the public key of the
|
||||
root certificate authority (CA) presented by the Kubernetes Master. The
|
||||
value of this flag is specified as "<hash-type>:<hex-encoded-value>",
|
||||
where the supported hash type is "sha256". The hash is calculated over
|
||||
the bytes of the Subject Public Key Info (SPKI) object (as in RFC7469).
|
||||
This value is available in the output of "kubeadm init" or can be
|
||||
calcuated using standard tools. The --discovery-token-ca-cert-hash flag
|
||||
may be repeated multiple times to allow more than one public key.
|
||||
|
||||
If you cannot know the CA public key hash ahead of time, you can pass
|
||||
the --discovery-token-unsafe-skip-ca-verification flag to disable this
|
||||
verification. This weakens the kubeadm security model since other nodes
|
||||
can potentially impersonate the Kubernetes Master.
|
||||
|
||||
The TLS bootstrap mechanism is also driven via a shared token. This is
|
||||
used to temporarily authenticate with the Kubernetes Master to submit a
|
||||
certificate signing request (CSR) for a locally created key pair. By
|
||||
@ -117,6 +132,13 @@ func NewCmdJoin(out io.Writer) *cobra.Command {
|
||||
cmd.PersistentFlags().StringVar(
|
||||
&cfg.TLSBootstrapToken, "tls-bootstrap-token", "",
|
||||
"A token used for TLS bootstrapping")
|
||||
cmd.PersistentFlags().StringSliceVar(
|
||||
&cfg.DiscoveryTokenCACertHashes, "discovery-token-ca-cert-hash", []string{},
|
||||
"For token-based discovery, validate that the root CA public key matches this hash (format: \"<type>:<value>\").")
|
||||
cmd.PersistentFlags().BoolVar(
|
||||
&cfg.DiscoveryTokenUnsafeSkipCAVerification, "discovery-token-unsafe-skip-ca-verification", false,
|
||||
"For token-based discovery, allow joining without --discovery-token-ca-cert-hash pinning.")
|
||||
|
||||
cmd.PersistentFlags().StringVar(
|
||||
&cfg.Token, "token", "",
|
||||
"Use this token for both discovery-token and tls-bootstrap-token")
|
||||
|
@ -1,7 +1,5 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
@ -11,30 +9,35 @@ load(
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"bootstraptoken.go",
|
||||
"certs.go",
|
||||
"kubeconfig.go",
|
||||
"markmaster.go",
|
||||
"phase.go",
|
||||
"preflight.go",
|
||||
"selfhosting.go",
|
||||
"uploadconfig.go",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/v1alpha1:go_default_library",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/validation:go_default_library",
|
||||
"//cmd/kubeadm/app/constants:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/bootstraptoken/clusterinfo:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/bootstraptoken/node:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/certs:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/markmaster:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/selfhosting:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/uploadconfig:go_default_library",
|
||||
"//cmd/kubeadm/app/preflight:go_default_library",
|
||||
"//cmd/kubeadm/app/util:go_default_library",
|
||||
"//cmd/kubeadm/app/util/config:go_default_library",
|
||||
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/util/version:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@ -43,9 +46,9 @@ go_test(
|
||||
srcs = [
|
||||
"certs_test.go",
|
||||
"kubeconfig_test.go",
|
||||
"phase_test.go",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/install:go_default_library",
|
||||
|
139
cmd/kubeadm/app/cmd/phases/bootstraptoken.go
Normal file
139
cmd/kubeadm/app/cmd/phases/bootstraptoken.go
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package phases
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/node"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||
versionutil "k8s.io/kubernetes/pkg/util/version"
|
||||
)
|
||||
|
||||
// NewCmdBootstrapToken returns the Cobra command for running the mark-master phase
|
||||
func NewCmdBootstrapToken() *cobra.Command {
|
||||
var kubeConfigFile string
|
||||
cmd := &cobra.Command{
|
||||
Use: "bootstrap-token",
|
||||
Short: "Manage kubeadm-specific Bootstrap Token functions.",
|
||||
Aliases: []string{"bootstraptoken"},
|
||||
RunE: subCmdRunE("bootstrap-token"),
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().StringVar(&kubeConfigFile, "kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use for talking to the cluster")
|
||||
|
||||
// Add subcommands
|
||||
cmd.AddCommand(NewSubCmdClusterInfo(&kubeConfigFile))
|
||||
cmd.AddCommand(NewSubCmdNodeBootstrapToken(&kubeConfigFile))
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// NewSubCmdClusterInfo returns the Cobra command for running the cluster-info sub-phase
|
||||
func NewSubCmdClusterInfo(kubeConfigFile *string) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "cluster-info <clusterinfo-file>",
|
||||
Short: "Uploads and exposes the cluster-info ConfigMap publicly from the given cluster-info file",
|
||||
Aliases: []string{"clusterinfo"},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
err := validateExactArgNumber(args, []string{"clusterinfo-file"})
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
client, err := kubeconfigutil.ClientSetFromFile(*kubeConfigFile)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
// Here it's safe to get args[0], since we've validated that the argument exists above in validateExactArgNumber
|
||||
clusterInfoFile := args[0]
|
||||
// Create the cluster-info ConfigMap or update if it already exists
|
||||
err = clusterinfo.CreateBootstrapConfigMapIfNotExists(client, clusterInfoFile)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
// Create the RBAC rules that expose the cluster-info ConfigMap properly
|
||||
err = clusterinfo.CreateClusterInfoRBACRules(client)
|
||||
kubeadmutil.CheckErr(err)
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
// NewSubCmdNodeBootstrapToken returns the Cobra command for running the node sub-phase
|
||||
func NewSubCmdNodeBootstrapToken(kubeConfigFile *string) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "node",
|
||||
Short: "Manages Node Bootstrap Tokens",
|
||||
Aliases: []string{"clusterinfo"},
|
||||
RunE: subCmdRunE("node"),
|
||||
}
|
||||
|
||||
cmd.AddCommand(NewSubCmdNodeBootstrapTokenPostCSRs(kubeConfigFile))
|
||||
cmd.AddCommand(NewSubCmdNodeBootstrapTokenAutoApprove(kubeConfigFile))
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// NewSubCmdNodeBootstrapTokenPostCSRs returns the Cobra command for running the allow-post-csrs sub-phase
|
||||
func NewSubCmdNodeBootstrapTokenPostCSRs(kubeConfigFile *string) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "allow-post-csrs",
|
||||
Short: "Configure RBAC to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
client, err := kubeconfigutil.ClientSetFromFile(*kubeConfigFile)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
err = node.AllowBootstrapTokensToPostCSRs(client)
|
||||
kubeadmutil.CheckErr(err)
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
// NewSubCmdNodeBootstrapToken returns the Cobra command for running the allow-auto-approve sub-phase
|
||||
func NewSubCmdNodeBootstrapTokenAutoApprove(kubeConfigFile *string) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "allow-auto-approve",
|
||||
Short: "Configure RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
client, err := kubeconfigutil.ClientSetFromFile(*kubeConfigFile)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
clusterVersion, err := getClusterVersion(client)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
err = node.AutoApproveNodeBootstrapTokens(client, clusterVersion)
|
||||
kubeadmutil.CheckErr(err)
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
// getClusterVersion fetches the API server version and parses it
|
||||
func getClusterVersion(client clientset.Interface) (*versionutil.Version, error) {
|
||||
clusterVersionInfo, err := client.Discovery().ServerVersion()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to check server version: %v", err)
|
||||
}
|
||||
clusterVersion, err := versionutil.ParseSemantic(clusterVersionInfo.String())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse server version: %v", err)
|
||||
}
|
||||
return clusterVersion, nil
|
||||
}
|
@ -25,7 +25,6 @@ import (
|
||||
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
certphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil"
|
||||
@ -132,24 +131,9 @@ func runCmdFunc(cmdFunc func(cfg *kubeadmapi.MasterConfiguration) error, cfgPath
|
||||
// are shared between sub commands and gets access to current value e.g. flags value.
|
||||
|
||||
return func(cmd *cobra.Command, args []string) {
|
||||
internalcfg := &kubeadmapi.MasterConfiguration{}
|
||||
|
||||
// Takes passed flags into account; the defaulting is executed once again enforcing assignement of
|
||||
// static default values to cfg only for values not provided with flags
|
||||
api.Scheme.Default(cfg)
|
||||
api.Scheme.Convert(cfg, internalcfg, nil)
|
||||
|
||||
// Loads configuration from config file, if provided
|
||||
// Nb. --config overrides command line flags
|
||||
err := configutil.TryLoadMasterConfiguration(*cfgPath, internalcfg)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
// Applies dynamic defaults to settings not provided with flags
|
||||
err = configutil.SetInitDynamicDefaults(internalcfg)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
// Validates cfg (flags/configs + defaults + dynamic defaults)
|
||||
err = validation.ValidateMasterConfiguration(internalcfg).ToAggregate()
|
||||
// This call returns the ready-to-use configuration based on the configuration file that might or might not exist and the default cfg populated by flags
|
||||
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(*cfgPath, cfg)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
// Execute the cmdFunc
|
||||
|
@ -24,7 +24,6 @@ import (
|
||||
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
@ -141,24 +140,9 @@ func runCmdFuncKubeConfig(cmdFunc func(outDir string, cfg *kubeadmapi.MasterConf
|
||||
// are shared between sub commands and gets access to current value e.g. flags value.
|
||||
|
||||
return func(cmd *cobra.Command, args []string) {
|
||||
internalcfg := &kubeadmapi.MasterConfiguration{}
|
||||
|
||||
// Takes passed flags into account; the defaulting is executed once again enforcing assignement of
|
||||
// static default values to cfg only for values not provided with flags
|
||||
api.Scheme.Default(cfg)
|
||||
api.Scheme.Convert(cfg, internalcfg, nil)
|
||||
|
||||
// Loads configuration from config file, if provided
|
||||
// Nb. --config overrides command line flags
|
||||
err := configutil.TryLoadMasterConfiguration(*cfgPath, internalcfg)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
// Applies dynamic defaults to settings not provided with flags
|
||||
err = configutil.SetInitDynamicDefaults(internalcfg)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
// Validates cfg (flags/configs + defaults + dynamic defaults)
|
||||
err = validation.ValidateMasterConfiguration(internalcfg).ToAggregate()
|
||||
// This call returns the ready-to-use configuration based on the configuration file that might or might not exist and the default cfg populated by flags
|
||||
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(*cfgPath, cfg)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
// Execute the cmdFunc
|
||||
|
@ -22,6 +22,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
markmasterphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/markmaster"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||
)
|
||||
|
||||
@ -33,16 +34,11 @@ func NewCmdMarkMaster() *cobra.Command {
|
||||
Short: "Create KubeConfig files from given credentials.",
|
||||
Aliases: []string{"markmaster"},
|
||||
RunE: func(_ *cobra.Command, args []string) error {
|
||||
if len(args) < 1 || len(args[0]) == 0 {
|
||||
return fmt.Errorf("missing required argument node-name")
|
||||
}
|
||||
if len(args) > 1 {
|
||||
return fmt.Errorf("too many arguments, only one argument supported: node-name")
|
||||
}
|
||||
err := validateExactArgNumber(args, []string{"node-name"})
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
client, err := kubeconfigutil.ClientSetFromFile(kubeConfigFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
nodeName := args[0]
|
||||
fmt.Printf("[markmaster] Will mark node %s as master by adding a label and a taint\n", nodeName)
|
||||
|
@ -23,6 +23,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// NewCmdPhase returns the cobra command for the "kubeadm phase" command (currently alpha-gated)
|
||||
func NewCmdPhase(out io.Writer) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "phase",
|
||||
@ -35,6 +36,8 @@ func NewCmdPhase(out io.Writer) *cobra.Command {
|
||||
cmd.AddCommand(NewCmdPreFlight())
|
||||
cmd.AddCommand(NewCmdSelfhosting())
|
||||
cmd.AddCommand(NewCmdMarkMaster())
|
||||
cmd.AddCommand(NewCmdUploadConfig())
|
||||
cmd.AddCommand(NewCmdBootstrapToken())
|
||||
|
||||
return cmd
|
||||
}
|
||||
@ -53,3 +56,22 @@ func subCmdRunE(name string) func(*cobra.Command, []string) error {
|
||||
return fmt.Errorf("invalid subcommand: %q", args[0])
|
||||
}
|
||||
}
|
||||
|
||||
// validateExactArgNumber validates that the required top-level arguments are specified
|
||||
func validateExactArgNumber(args []string, supportedArgs []string) error {
|
||||
validArgs := 0
|
||||
// Disregard possible "" arguments; they are invalid
|
||||
for _, arg := range args {
|
||||
if len(arg) > 0 {
|
||||
validArgs++
|
||||
}
|
||||
}
|
||||
|
||||
if validArgs < len(supportedArgs) {
|
||||
return fmt.Errorf("missing one or more required arguments. Required arguments: %v", supportedArgs)
|
||||
}
|
||||
if validArgs > len(supportedArgs) {
|
||||
return fmt.Errorf("too many arguments, only %d argument(s) supported: %v", validArgs, supportedArgs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
64
cmd/kubeadm/app/cmd/phases/phase_test.go
Normal file
64
cmd/kubeadm/app/cmd/phases/phase_test.go
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package phases
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestValidateExactArgNumber(t *testing.T) {
|
||||
var tests = []struct {
|
||||
args, supportedArgs []string
|
||||
expectedErr bool
|
||||
}{
|
||||
{ // one arg given and one arg expected
|
||||
args: []string{"my-node-1234"},
|
||||
supportedArgs: []string{"node-name"},
|
||||
expectedErr: false,
|
||||
},
|
||||
{ // two args given and two args expected
|
||||
args: []string{"my-node-1234", "foo"},
|
||||
supportedArgs: []string{"node-name", "second-toplevel-arg"},
|
||||
expectedErr: false,
|
||||
},
|
||||
{ // too few supplied args
|
||||
args: []string{},
|
||||
supportedArgs: []string{"node-name"},
|
||||
expectedErr: true,
|
||||
},
|
||||
{ // too few non-empty args
|
||||
args: []string{""},
|
||||
supportedArgs: []string{"node-name"},
|
||||
expectedErr: true,
|
||||
},
|
||||
{ // too many args
|
||||
args: []string{"my-node-1234", "foo"},
|
||||
supportedArgs: []string{"node-name"},
|
||||
expectedErr: true,
|
||||
},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
actual := validateExactArgNumber(rt.args, rt.supportedArgs)
|
||||
if (actual != nil) != rt.expectedErr {
|
||||
t.Errorf(
|
||||
"failed validateExactArgNumber:\n\texpected error: %t\n\t actual error: %t",
|
||||
rt.expectedErr,
|
||||
(actual != nil),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
58
cmd/kubeadm/app/cmd/phases/uploadconfig.go
Normal file
58
cmd/kubeadm/app/cmd/phases/uploadconfig.go
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package phases
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/uploadconfig"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||
)
|
||||
|
||||
// NewCmdUploadConfig returns the Cobra command for running the uploadconfig phase
|
||||
func NewCmdUploadConfig() *cobra.Command {
|
||||
var cfgPath, kubeConfigFile string
|
||||
cmd := &cobra.Command{
|
||||
Use: "upload-config",
|
||||
Short: "Upload the currently used configuration for kubeadm to a ConfigMap in the cluster for future use in reconfiguration and upgrades of the cluster.",
|
||||
Aliases: []string{"uploadconfig"},
|
||||
Run: func(_ *cobra.Command, args []string) {
|
||||
if len(cfgPath) == 0 {
|
||||
kubeadmutil.CheckErr(fmt.Errorf("The --config flag is mandatory"))
|
||||
}
|
||||
client, err := kubeconfigutil.ClientSetFromFile(kubeConfigFile)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
defaultcfg := &kubeadmapiext.MasterConfiguration{}
|
||||
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, defaultcfg)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
err = uploadconfig.UploadConfiguration(internalcfg, client)
|
||||
kubeadmutil.CheckErr(err)
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().StringVar(&kubeConfigFile, "kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use for talking to the cluster")
|
||||
cmd.Flags().StringVar(&cfgPath, "config", "", "Path to kubeadm config file (WARNING: Usage of a configuration file is experimental)")
|
||||
|
||||
return cmd
|
||||
}
|
@ -97,7 +97,7 @@ func (r *Reset) Run(out io.Writer) error {
|
||||
|
||||
// Try to unmount mounted directories under /var/lib/kubelet in order to be able to remove the /var/lib/kubelet directory later
|
||||
fmt.Printf("[reset] Unmounting mounted directories in %q\n", "/var/lib/kubelet")
|
||||
umountDirsCmd := "cat /proc/mounts | awk '{print $2}' | grep '/var/lib/kubelet' | xargs -r umount"
|
||||
umountDirsCmd := "awk '$2 ~ path {print $2}' path=/var/lib/kubelet /proc/mounts | xargs -r umount"
|
||||
umountOutputBytes, err := exec.Command("sh", "-c", umountDirsCmd).Output()
|
||||
if err != nil {
|
||||
fmt.Printf("[reset] Failed to unmount mounted directories in /var/lib/kubelet: %s\n", string(umountOutputBytes))
|
||||
|
@ -34,7 +34,7 @@ import (
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
tokenphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/token"
|
||||
tokenphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/node"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||
tokenutil "k8s.io/kubernetes/cmd/kubeadm/app/util/token"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user