Merge branch 'master' into util-freebsd

This commit is contained in:
Ed Schouten 2017-08-11 23:44:13 +02:00
commit 77dee9bb4e
2917 changed files with 62705 additions and 30153 deletions

13
Godeps/Godeps.json generated
View File

@ -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
View File

@ -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
View File

@ -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

View File

@ -53,7 +53,6 @@ aliases:
- dchen1107
- derekwaynecarr
- dims
- euank
- feiskyer
- mtaufen
- ncdc

View File

@ -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

View File

@ -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."
}
}
},

View File

@ -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."
}
}
},

View File

@ -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

View File

@ -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"

File diff suppressed because it is too large Load Diff

View File

@ -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"

View File

@ -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."
}
}
},

View File

@ -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."
}
}
},

View File

@ -4,6 +4,5 @@
"^_.*"
],
"AddSourcesRules": true,
"VendorMultipleBuildFiles": true,
"K8sOpenAPIGen": true
}

View File

@ -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")

View File

@ -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"

View File

@ -360,6 +360,7 @@ package_group(
packages = [
"//pkg/kubectl",
"//pkg/kubectl/cmd",
"//pkg/kubectl/proxy",
],
)

View File

@ -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

View File

@ -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(["**"]),

View File

@ -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:

View File

@ -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",

View File

@ -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}"

View 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}
}

View File

@ -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(

View File

@ -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.

View File

@ -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}"

View 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

View File

@ -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"

View File

@ -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

View File

@ -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."

View File

@ -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
}

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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.")

View File

@ -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)

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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(

View File

@ -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",

View File

@ -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"],
)

View File

@ -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",

View File

@ -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"

View File

@ -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",

View File

@ -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
}

View File

@ -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())

View File

@ -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(

View 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)
}
}

View File

@ -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",

View File

@ -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",

View File

@ -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},

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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"],
)

View File

@ -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{

View File

@ -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
}

View File

@ -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",

View File

@ -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")

View File

@ -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",

View File

@ -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",

View File

@ -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"],
)

View File

@ -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",
],

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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 {

View File

@ -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",

View File

@ -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"`
}

View File

@ -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
}

View File

@ -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",

View File

@ -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")

View File

@ -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
}

View File

@ -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",

View File

@ -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"],
)

View File

@ -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 {

View File

@ -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)),
}

View File

@ -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")

View File

@ -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",

View 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
}

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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
}

View 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),
)
}
}
}

View 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
}

View File

@ -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))

View File

@ -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