Merge remote-tracking branch 'upstream/master' into extra_user-data

This commit is contained in:
Rodrigo Menezes 2017-11-04 17:06:43 -07:00
commit 565afae2c6
360 changed files with 7358 additions and 1405 deletions

3
.gitignore vendored
View File

@ -70,3 +70,6 @@ bazel-out
bazel-testlogs bazel-testlogs
# Ignore default apiserver config # Ignore default apiserver config
apiserver.local.config apiserver.local.config
# Ignore awesome_bot markdown links check output
ab-results-*.json

View File

@ -2,7 +2,8 @@ language: go
go: go:
- 1.8 - 1.8
- 1.9 - 1.9
- tip # removed because of govet issue with apimahcinery
# - tip
go_import_path: k8s.io/kops go_import_path: k8s.io/kops

View File

@ -594,3 +594,12 @@ bazel-push-gce-run: bazel-push
.PHONY: bazel-push-aws-run .PHONY: bazel-push-aws-run
bazel-push-aws-run: bazel-push bazel-push-aws-run: bazel-push
ssh -t ${TARGET} sudo SKIP_PACKAGE_UPDATE=1 /tmp/nodeup --conf=/var/cache/kubernetes-install/kube_env.yaml --v=8 ssh -t ${TARGET} sudo SKIP_PACKAGE_UPDATE=1 /tmp/nodeup --conf=/var/cache/kubernetes-install/kube_env.yaml --v=8
.PHONY: check-markdown-links
check-markdown-links:
docker run -t -v $$PWD:/tmp \
-e LC_ALL=C.UTF-8 \
-e LANG=en_US.UTF-8 \
-e LANGUAGE=en_US.UTF-8 \
rubygem/awesome_bot --allow-dupe --allow-redirect \
$(shell find $$PWD -name "*.md" -mindepth 1 -printf '%P\n' | grep -v vendor | grep -v _vendor | grep -v Changelog.md)

1
OWNERS
View File

@ -4,3 +4,4 @@ approvers:
- chrislovecnm - chrislovecnm
- zmerlynn - zmerlynn
- andrewsykim - andrewsykim
- geojaz

@ -1 +1 @@
Subproject commit 2bf16b94fdd9b01557c4d076e567fe5cbbe5a961 Subproject commit c7551a666c4fee120cc314dce91ba3d0663a86f3

View File

@ -0,0 +1,2 @@
## Usages
channels apply channel kube-state-metrics --yes

View File

@ -0,0 +1,13 @@
kind: Addons
metadata:
name: kube-state-metrics
spec:
addons:
- version: 1.0.1
selector:
k8s-addon: kube-state-metrics.addons.k8s.io
manifest: v1.0.1.yaml
- version: v1.1.0-rc.0
selector:
k8s-addon: kube-state-metrics.addons.k8s.io
manifest: v1.1.0-rc.0.yaml

View File

@ -0,0 +1,158 @@
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: kube-state-metrics
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kube-state-metrics
subjects:
- kind: ServiceAccount
name: kube-state-metrics
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: kube-state-metrics
rules:
- apiGroups: [""]
resources:
- nodes
- pods
- services
- resourcequotas
- replicationcontrollers
- limitranges
- persistentvolumeclaims
- namespaces
verbs: ["list", "watch"]
- apiGroups: ["extensions"]
resources:
- daemonsets
- deployments
- replicasets
verbs: ["list", "watch"]
- apiGroups: ["apps"]
resources:
- statefulsets
verbs: ["list", "watch"]
- apiGroups: ["batch"]
resources:
- cronjobs
- jobs
verbs: ["list", "watch"]
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: kube-state-metrics
namespace: kube-system
spec:
replicas: 1
template:
metadata:
labels:
k8s-app: kube-state-metrics
spec:
serviceAccountName: kube-state-metrics
containers:
- name: kube-state-metrics
image: quay.io/coreos/kube-state-metrics:v1.0.1
ports:
- name: http-metrics
containerPort: 8080
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
timeoutSeconds: 5
resources:
requests:
memory: 100Mi
cpu: 100m
limits:
memory: 200Mi
cpu: 200m
- name: addon-resizer
image: gcr.io/google_containers/addon-resizer:1.0
resources:
limits:
cpu: 100m
memory: 30Mi
requests:
cpu: 100m
memory: 30Mi
env:
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
command:
- /pod_nanny
- --container=kube-state-metrics
- --cpu=100m
- --extra-cpu=1m
- --memory=100Mi
- --extra-memory=2Mi
- --threshold=5
- --deployment=kube-state-metrics
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: kube-state-metrics
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: kube-state-metrics-resizer
subjects:
- kind: ServiceAccount
name: kube-state-metrics
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
namespace: kube-system
name: kube-state-metrics-resizer
rules:
- apiGroups: [""]
resources:
- pods
verbs: ["get"]
- apiGroups: ["extensions"]
resources:
- deployments
resourceNames: ["kube-state-metrics"]
verbs: ["get", "update"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: kube-state-metrics
namespace: kube-system
---
apiVersion: v1
kind: Service
metadata:
name: kube-state-metrics
namespace: kube-system
labels:
k8s-app: kube-state-metrics
annotations:
prometheus.io/scrape: 'true'
spec:
ports:
- name: http-metrics
port: 8080
targetPort: http-metrics
protocol: TCP
selector:
k8s-app: kube-state-metrics

View File

@ -0,0 +1,158 @@
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: kube-state-metrics
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kube-state-metrics
subjects:
- kind: ServiceAccount
name: kube-state-metrics
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: kube-state-metrics
rules:
- apiGroups: [""]
resources:
- nodes
- pods
- services
- resourcequotas
- replicationcontrollers
- limitranges
- persistentvolumeclaims
- namespaces
verbs: ["list", "watch"]
- apiGroups: ["extensions"]
resources:
- daemonsets
- deployments
- replicasets
verbs: ["list", "watch"]
- apiGroups: ["apps"]
resources:
- statefulsets
verbs: ["list", "watch"]
- apiGroups: ["batch"]
resources:
- cronjobs
- jobs
verbs: ["list", "watch"]
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: kube-state-metrics
namespace: kube-system
spec:
replicas: 1
template:
metadata:
labels:
k8s-app: kube-state-metrics
spec:
serviceAccountName: kube-state-metrics
containers:
- name: kube-state-metrics
image: quay.io/coreos/kube-state-metrics:v1.1.0-rc.0
ports:
- name: http-metrics
containerPort: 8080
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
timeoutSeconds: 5
resources:
requests:
memory: 100Mi
cpu: 100m
limits:
memory: 200Mi
cpu: 200m
- name: addon-resizer
image: gcr.io/google_containers/addon-resizer:1.0
resources:
limits:
cpu: 100m
memory: 30Mi
requests:
cpu: 100m
memory: 30Mi
env:
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
command:
- /pod_nanny
- --container=kube-state-metrics
- --cpu=100m
- --extra-cpu=1m
- --memory=100Mi
- --extra-memory=2Mi
- --threshold=5
- --deployment=kube-state-metrics
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: kube-state-metrics
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: kube-state-metrics-resizer
subjects:
- kind: ServiceAccount
name: kube-state-metrics
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
namespace: kube-system
name: kube-state-metrics-resizer
rules:
- apiGroups: [""]
resources:
- pods
verbs: ["get"]
- apiGroups: ["extensions"]
resources:
- deployments
resourceNames: ["kube-state-metrics"]
verbs: ["get", "update"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: kube-state-metrics
namespace: kube-system
---
apiVersion: v1
kind: Service
metadata:
name: kube-state-metrics
namespace: kube-system
labels:
k8s-app: kube-state-metrics
annotations:
prometheus.io/scrape: 'true'
spec:
ports:
- name: http-metrics
port: 8080
targetPort: http-metrics
protocol: TCP
selector:
k8s-app: kube-state-metrics

View File

@ -7,4 +7,9 @@ spec:
selector: selector:
k8s-addon: logging-elasticsearch.addons.k8s.io k8s-addon: logging-elasticsearch.addons.k8s.io
manifest: v1.5.0.yaml manifest: v1.5.0.yaml
kubernetesVersion: ">=1.5.0" # We use statefulsets kubernetesVersion: ">=1.5.0 <1.6.0" # We use statefulsets
- version: 1.6.0
selector:
k8s-addon: logging-elasticsearch.addons.k8s.io
manifest: v1.6.0.yaml
kubernetesVersion: ">=1.6.0" # RBAC v1beta1 is introduced as of v1.6.0

View File

@ -0,0 +1,280 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: elasticsearch-logging
namespace: kube-system
labels:
k8s-app: elasticsearch-logging
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: elasticsearch-logging
labels:
k8s-app: elasticsearch-logging
rules:
- apiGroups:
- ""
resources:
- "services"
- "namespaces"
- "endpoints"
verbs:
- "get"
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
namespace: kube-system
name: elasticsearch-logging
labels:
k8s-app: elasticsearch-logging
subjects:
- kind: ServiceAccount
name: elasticsearch-logging
namespace: kube-system
apiGroup: ""
roleRef:
kind: ClusterRole
name: elasticsearch-logging
apiGroup: ""
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: fluentd-es
namespace: kube-system
labels:
k8s-app: fluentd-es
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: fluentd-es
labels:
k8s-app: fluentd-es
rules:
- apiGroups:
- ""
resources:
- "namespaces"
- "pods"
verbs:
- "get"
- "watch"
- "list"
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: fluentd-es
labels:
k8s-app: fluentd-es
subjects:
- kind: ServiceAccount
name: fluentd-es
namespace: kube-system
apiGroup: ""
roleRef:
kind: ClusterRole
name: fluentd-es
apiGroup: ""
---
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: fluentd-es
namespace: kube-system
labels:
k8s-addon: logging-elasticsearch.addons.k8s.io
k8s-app: fluentd-es
kubernetes.io/cluster-service: "true"
version: v1.22
spec:
template:
metadata:
labels:
k8s-app: fluentd-es
kubernetes.io/cluster-service: "true"
version: v1.22
spec:
serviceAccountName: fluentd-es
containers:
- name: fluentd-es
image: gcr.io/google_containers/fluentd-elasticsearch:1.22
command:
- '/bin/sh'
- '-c'
- '/usr/sbin/td-agent 2>&1 >> /var/log/fluentd.log'
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
#nodeSelector:
# alpha.kubernetes.io/fluentd-ds-ready: "true"
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
---
apiVersion: v1
kind: Service
metadata:
name: elasticsearch-logging
namespace: kube-system
labels:
k8s-addon: logging-elasticsearch.addons.k8s.io
k8s-app: elasticsearch-logging
kubernetes.io/cluster-service: "true"
kubernetes.io/name: "Elasticsearch"
spec:
ports:
- port: 9200
protocol: TCP
targetPort: db
selector:
k8s-app: elasticsearch-logging
---
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
name: elasticsearch-logging
namespace: kube-system
labels:
k8s-addon: logging-elasticsearch.addons.k8s.io
k8s-app: elasticsearch-logging
version: v1
kubernetes.io/cluster-service: "true"
spec:
serviceName: elasticsearch-logging
replicas: 2
template:
metadata:
labels:
k8s-app: elasticsearch-logging
version: v1
kubernetes.io/cluster-service: "true"
spec:
serviceAccountName: elasticsearch-logging
containers:
- image: gcr.io/google_containers/elasticsearch:v2.4.1-2
name: elasticsearch-logging
resources:
# need more cpu upon initialization, therefore burstable class
limits:
cpu: 1000m
requests:
cpu: 100m
ports:
- containerPort: 9200
name: db
protocol: TCP
- containerPort: 9300
name: transport
protocol: TCP
volumeMounts:
- name: es-persistent-storage
mountPath: /data
env:
- name: "NAMESPACE"
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumeClaimTemplates:
- metadata:
name: es-persistent-storage
annotations:
volume.beta.kubernetes.io/storage-class: "default"
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 20Gi
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: kibana-logging
namespace: kube-system
labels:
k8s-addon: logging-elasticsearch.addons.k8s.io
k8s-app: kibana-logging
kubernetes.io/cluster-service: "true"
spec:
replicas: 1
selector:
matchLabels:
k8s-app: kibana-logging
template:
metadata:
labels:
k8s-app: kibana-logging
spec:
containers:
- name: kibana-logging
image: gcr.io/google_containers/kibana:v4.6.1-1
resources:
# keep request = limit to keep this container in guaranteed class
limits:
cpu: 100m
requests:
cpu: 100m
env:
- name: "ELASTICSEARCH_URL"
value: "http://elasticsearch-logging:9200"
- name: "KIBANA_BASE_URL"
value: "/api/v1/proxy/namespaces/kube-system/services/kibana-logging"
ports:
- containerPort: 5601
name: ui
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: kibana-logging
namespace: kube-system
labels:
k8s-addon: logging-elasticsearch.addons.k8s.io
k8s-app: kibana-logging
kubernetes.io/cluster-service: "true"
kubernetes.io/name: "Kibana"
spec:
ports:
- port: 5601
protocol: TCP
targetPort: ui
selector:
k8s-app: kibana-logging

View File

@ -18,8 +18,9 @@ package main
import ( import (
"fmt" "fmt"
"k8s.io/kops/channels/pkg/cmd"
"os" "os"
"k8s.io/kops/channels/pkg/cmd"
) )
func main() { func main() {

View File

@ -18,11 +18,12 @@ package channels
import ( import (
"fmt" "fmt"
"net/url"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
"k8s.io/kops/channels/pkg/api" "k8s.io/kops/channels/pkg/api"
"net/url"
) )
// Addon is a wrapper around a single version of an addon // Addon is a wrapper around a single version of an addon

View File

@ -18,13 +18,14 @@ package channels
import ( import (
"fmt" "fmt"
"net/url"
"strings"
"github.com/blang/semver" "github.com/blang/semver"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kops/channels/pkg/api" "k8s.io/kops/channels/pkg/api"
"k8s.io/kops/upup/pkg/fi/utils" "k8s.io/kops/upup/pkg/fi/utils"
"k8s.io/kops/util/pkg/vfs" "k8s.io/kops/util/pkg/vfs"
"net/url"
"strings"
) )
type Addons struct { type Addons struct {

View File

@ -17,9 +17,10 @@ limitations under the License.
package channels package channels
import ( import (
"testing"
"github.com/blang/semver" "github.com/blang/semver"
"k8s.io/kops/channels/pkg/api" "k8s.io/kops/channels/pkg/api"
"testing"
) )
func Test_Filtering(t *testing.T) { func Test_Filtering(t *testing.T) {

View File

@ -18,13 +18,14 @@ package channels
import ( import (
"fmt" "fmt"
"github.com/golang/glog"
"io/ioutil" "io/ioutil"
"k8s.io/kops/util/pkg/vfs"
"os" "os"
"os/exec" "os/exec"
"path" "path"
"strings" "strings"
"github.com/golang/glog"
"k8s.io/kops/util/pkg/vfs"
) )
// Apply calls kubectl apply to apply the manifest. // Apply calls kubectl apply to apply the manifest.

View File

@ -19,13 +19,14 @@ package channels
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"strings"
"github.com/blang/semver" "github.com/blang/semver"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
"strings"
) )
const AnnotationPrefix = "addons.k8s.io/" const AnnotationPrefix = "addons.k8s.io/"

View File

@ -17,8 +17,9 @@ limitations under the License.
package cmd package cmd
import ( import (
"github.com/spf13/cobra"
"io" "io"
"github.com/spf13/cobra"
) )
func NewCmdApply(f Factory, out io.Writer) *cobra.Command { func NewCmdApply(f Factory, out io.Writer) *cobra.Command {

View File

@ -18,14 +18,15 @@ package cmd
import ( import (
"fmt" "fmt"
"github.com/blang/semver"
"github.com/spf13/cobra"
"io" "io"
"k8s.io/kops/channels/pkg/channels"
"k8s.io/kops/util/pkg/tables"
"net/url" "net/url"
"os" "os"
"strings" "strings"
"github.com/blang/semver"
"github.com/spf13/cobra"
"k8s.io/kops/channels/pkg/channels"
"k8s.io/kops/util/pkg/tables"
) )
type ApplyChannelOptions struct { type ApplyChannelOptions struct {

View File

@ -17,8 +17,9 @@ limitations under the License.
package cmd package cmd
import ( import (
"github.com/spf13/cobra"
"io" "io"
"github.com/spf13/cobra"
) )
func NewCmdGet(f Factory, out io.Writer) *cobra.Command { func NewCmdGet(f Factory, out io.Writer) *cobra.Command {

View File

@ -34,13 +34,14 @@ package cmd
import ( import (
"fmt" "fmt"
"github.com/spf13/cobra"
"io" "io"
"os"
"github.com/spf13/cobra"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kops/channels/pkg/channels" "k8s.io/kops/channels/pkg/channels"
"k8s.io/kops/util/pkg/tables" "k8s.io/kops/util/pkg/tables"
"os"
) )
type GetAddonsOptions struct { type GetAddonsOptions struct {

View File

@ -20,9 +20,10 @@ import (
goflag "flag" goflag "flag"
"fmt" "fmt"
"io"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
"io"
) )
type CmdRootOptions struct { type CmdRootOptions struct {

View File

@ -19,10 +19,11 @@ package mockec2
import ( import (
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"net"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/ec2"
"github.com/golang/glog" "github.com/golang/glog"
"net"
) )
func (m *MockEC2) AllocateAddressRequest(*ec2.AllocateAddressInput) (*request.Request, *ec2.AllocateAddressOutput) { func (m *MockEC2) AllocateAddressRequest(*ec2.AllocateAddressInput) (*request.Request, *ec2.AllocateAddressOutput) {

View File

@ -33,7 +33,7 @@ type MockEC2 struct {
SecurityGroups []*ec2.SecurityGroup SecurityGroups []*ec2.SecurityGroup
subnetNumber int subnetNumber int
Subnets []*ec2.Subnet subnets map[string]*subnetInfo
volumeNumber int volumeNumber int
Volumes []*ec2.Volume Volumes []*ec2.Volume

View File

@ -18,11 +18,12 @@ package mockec2
import ( import (
"fmt" "fmt"
"strings"
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/ec2"
"github.com/golang/glog" "github.com/golang/glog"
"strings"
) )
func (m *MockEC2) DescribeImageAttributeRequest(*ec2.DescribeImageAttributeInput) (*request.Request, *ec2.DescribeImageAttributeOutput) { func (m *MockEC2) DescribeImageAttributeRequest(*ec2.DescribeImageAttributeInput) (*request.Request, *ec2.DescribeImageAttributeOutput) {

View File

@ -18,6 +18,7 @@ package mockec2
import ( import (
"fmt" "fmt"
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/ec2"

View File

@ -18,10 +18,11 @@ package mockec2
import ( import (
"fmt" "fmt"
"strings"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/ec2"
"github.com/golang/glog" "github.com/golang/glog"
"strings"
) )
func (m *MockEC2) CreateSecurityGroupRequest(*ec2.CreateSecurityGroupInput) (*request.Request, *ec2.CreateSecurityGroupOutput) { func (m *MockEC2) CreateSecurityGroupRequest(*ec2.CreateSecurityGroupInput) (*request.Request, *ec2.CreateSecurityGroupOutput) {

View File

@ -18,12 +18,36 @@ package mockec2
import ( import (
"fmt" "fmt"
"strings"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/ec2"
"github.com/golang/glog" "github.com/golang/glog"
"strings"
) )
type subnetInfo struct {
main ec2.Subnet
}
func (m *MockEC2) FindSubnet(id string) *ec2.Subnet {
subnet := m.subnets[id]
if subnet == nil {
return nil
}
copy := subnet.main
copy.Tags = m.getTags(ec2.ResourceTypeSubnet, id)
return &copy
}
func (m *MockEC2) SubnetIds() []string {
var ids []string
for id := range m.subnets {
ids = append(ids, id)
}
return ids
}
func (m *MockEC2) CreateSubnetRequest(*ec2.CreateSubnetInput) (*request.Request, *ec2.CreateSubnetOutput) { func (m *MockEC2) CreateSubnetRequest(*ec2.CreateSubnetInput) (*request.Request, *ec2.CreateSubnetOutput) {
panic("Not implemented") panic("Not implemented")
return nil, nil return nil, nil
@ -40,7 +64,14 @@ func (m *MockEC2) CreateSubnet(request *ec2.CreateSubnetInput) (*ec2.CreateSubne
VpcId: request.VpcId, VpcId: request.VpcId,
CidrBlock: request.CidrBlock, CidrBlock: request.CidrBlock,
} }
m.Subnets = append(m.Subnets, subnet)
if m.subnets == nil {
m.subnets = make(map[string]*subnetInfo)
}
m.subnets[*subnet.SubnetId] = &subnetInfo{
main: *subnet,
}
response := &ec2.CreateSubnetOutput{ response := &ec2.CreateSubnetOutput{
Subnet: subnet, Subnet: subnet,
} }
@ -57,7 +88,7 @@ func (m *MockEC2) DescribeSubnets(request *ec2.DescribeSubnetsInput) (*ec2.Descr
var subnets []*ec2.Subnet var subnets []*ec2.Subnet
for _, subnet := range m.Subnets { for id, subnet := range m.subnets {
allFiltersMatch := true allFiltersMatch := true
for _, filter := range request.Filters { for _, filter := range request.Filters {
match := false match := false
@ -65,7 +96,7 @@ func (m *MockEC2) DescribeSubnets(request *ec2.DescribeSubnetsInput) (*ec2.Descr
default: default:
if strings.HasPrefix(*filter.Name, "tag:") { if strings.HasPrefix(*filter.Name, "tag:") {
match = m.hasTag(ec2.ResourceTypeSubnet, *subnet.SubnetId, filter) match = m.hasTag(ec2.ResourceTypeSubnet, *subnet.main.SubnetId, filter)
} else { } else {
return nil, fmt.Errorf("unknown filter name: %q", *filter.Name) return nil, fmt.Errorf("unknown filter name: %q", *filter.Name)
} }
@ -81,8 +112,8 @@ func (m *MockEC2) DescribeSubnets(request *ec2.DescribeSubnetsInput) (*ec2.Descr
continue continue
} }
copy := *subnet copy := subnet.main
copy.Tags = m.getTags(ec2.ResourceTypeSubnet, *subnet.SubnetId) copy.Tags = m.getTags(ec2.ResourceTypeSubnet, id)
subnets = append(subnets, &copy) subnets = append(subnets, &copy)
} }

View File

@ -18,10 +18,13 @@ package mockec2
import ( import (
"fmt" "fmt"
"sort"
"strings"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/ec2"
"github.com/golang/glog" "github.com/golang/glog"
"strings"
) )
func (m *MockEC2) CreateTagsRequest(*ec2.CreateTagsInput) (*request.Request, *ec2.CreateTagsOutput) { func (m *MockEC2) CreateTagsRequest(*ec2.CreateTagsInput) (*request.Request, *ec2.CreateTagsOutput) {
@ -165,3 +168,14 @@ func (m *MockEC2) DescribeTagsPages(*ec2.DescribeTagsInput, func(*ec2.DescribeTa
panic("Not implemented") panic("Not implemented")
return nil return nil
} }
// SortTags sorts the slice of tags by Key
func SortTags(tags []*ec2.Tag) {
keys := make([]string, len(tags))
for i := range tags {
if tags[i] != nil {
keys[i] = aws.StringValue(tags[i].Key)
}
}
sort.SliceStable(tags, func(i, j int) bool { return keys[i] < keys[j] })
}

View File

@ -18,10 +18,11 @@ package mockec2
import ( import (
"fmt" "fmt"
"strings"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/ec2"
"github.com/golang/glog" "github.com/golang/glog"
"strings"
) )
func (m *MockEC2) DescribeVolumeAttributeRequest(*ec2.DescribeVolumeAttributeInput) (*request.Request, *ec2.DescribeVolumeAttributeOutput) { func (m *MockEC2) DescribeVolumeAttributeRequest(*ec2.DescribeVolumeAttributeInput) (*request.Request, *ec2.DescribeVolumeAttributeOutput) {

View File

@ -18,11 +18,12 @@ package mockec2
import ( import (
"fmt" "fmt"
"strings"
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/ec2"
"github.com/golang/glog" "github.com/golang/glog"
"strings"
) )
type vpcInfo struct { type vpcInfo struct {

View File

@ -17,10 +17,11 @@ limitations under the License.
package mockroute53 package mockroute53
import ( import (
"strings"
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/route53" "github.com/aws/aws-sdk-go/service/route53"
"github.com/aws/aws-sdk-go/service/route53/route53iface" "github.com/aws/aws-sdk-go/service/route53/route53iface"
"strings"
) )
type zoneInfo struct { type zoneInfo struct {

View File

@ -18,6 +18,7 @@ package mockroute53
import ( import (
"fmt" "fmt"
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/service/route53" "github.com/aws/aws-sdk-go/service/route53"

View File

@ -18,6 +18,7 @@ package mockroute53
import ( import (
"fmt" "fmt"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/service/route53" "github.com/aws/aws-sdk-go/service/route53"
"github.com/golang/glog" "github.com/golang/glog"

View File

@ -21,11 +21,12 @@ import (
"os" "os"
"runtime" "runtime"
"math/rand"
"time"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/apiserver/pkg/util/logs" "k8s.io/apiserver/pkg/util/logs"
"k8s.io/kops/pkg/apiserver/cmd/server" "k8s.io/kops/pkg/apiserver/cmd/server"
"math/rand"
"time"
) )
func main() { func main() {

View File

@ -91,6 +91,7 @@ go_library(
"//util/pkg/vfs:go_default_library", "//util/pkg/vfs:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws:go_default_library",
"//vendor/github.com/blang/semver:go_default_library", "//vendor/github.com/blang/semver:go_default_library",
"//vendor/github.com/ghodss/yaml:go_default_library",
"//vendor/github.com/golang/glog:go_default_library", "//vendor/github.com/golang/glog:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library", "//vendor/github.com/spf13/cobra:go_default_library",
"//vendor/github.com/spf13/cobra/doc:go_default_library", "//vendor/github.com/spf13/cobra/doc:go_default_library",

View File

@ -130,6 +130,7 @@ func RunCreate(f *util.Factory, out io.Writer, c *CreateOptions) error {
return fmt.Errorf("error reading file %q: %v", f, err) return fmt.Errorf("error reading file %q: %v", f, err)
} }
// TODO: this does not support a JSON array
sections := bytes.Split(contents, []byte("\n---\n")) sections := bytes.Split(contents, []byte("\n---\n"))
for _, section := range sections { for _, section := range sections {
defaults := &schema.GroupVersionKind{ defaults := &schema.GroupVersionKind{

View File

@ -28,6 +28,7 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
"github.com/spf13/cobra" "github.com/spf13/cobra"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/kops" "k8s.io/kops"
"k8s.io/kops/cmd/kops/util" "k8s.io/kops/cmd/kops/util"
@ -124,6 +125,11 @@ type CreateClusterOptions struct {
// ConfigBase is the location where we will store the configuration, it defaults to the state store // ConfigBase is the location where we will store the configuration, it defaults to the state store
ConfigBase string ConfigBase string
// DryRun mode output a cluster manifest of Output type.
DryRun bool
// Output type during a DryRun
Output string
} }
func (o *CreateClusterOptions) InitDefaults() { func (o *CreateClusterOptions) InitDefaults() {
@ -190,6 +196,11 @@ var (
--project my-gce-project \ --project my-gce-project \
--image "ubuntu-os-cloud/ubuntu-1604-xenial-v20170202" \ --image "ubuntu-os-cloud/ubuntu-1604-xenial-v20170202" \
--yes --yes
# Create manifest for a cluster in AWS
kops create cluster --name=kubernetes-cluster.example.com \
--state=s3://kops-state-1234 --zones=eu-west-1a \
--node-count=2 --dry-run -oyaml
`)) `))
create_cluster_short = i18n.T("Create a Kubernetes cluster.") create_cluster_short = i18n.T("Create a Kubernetes cluster.")
@ -227,7 +238,7 @@ func NewCmdCreateCluster(f *util.Factory, out io.Writer) *cobra.Command {
} }
cmd.Flags().BoolVar(&options.Yes, "yes", options.Yes, "Specify --yes to immediately create the cluster") cmd.Flags().BoolVar(&options.Yes, "yes", options.Yes, "Specify --yes to immediately create the cluster")
cmd.Flags().StringVar(&options.Target, "target", options.Target, "Target - direct, terraform, cloudformation") cmd.Flags().StringVar(&options.Target, "target", options.Target, fmt.Sprintf("Valid targets: %s, %s, %s. Set this flag to %s if you want kops to generate terraform", cloudup.TargetDirect, cloudup.TargetTerraform, cloudup.TargetDirect, cloudup.TargetTerraform))
cmd.Flags().StringVar(&options.Models, "model", options.Models, "Models to apply (separate multiple models with commas)") cmd.Flags().StringVar(&options.Models, "model", options.Models, "Models to apply (separate multiple models with commas)")
// Configuration / state location // Configuration / state location
@ -297,6 +308,10 @@ func NewCmdCreateCluster(f *util.Factory, out io.Writer) *cobra.Command {
cmd.Flags().StringVar(&options.APILoadBalancerType, "api-loadbalancer-type", options.APILoadBalancerType, "Sets the API loadbalancer type to either 'public' or 'internal'") cmd.Flags().StringVar(&options.APILoadBalancerType, "api-loadbalancer-type", options.APILoadBalancerType, "Sets the API loadbalancer type to either 'public' or 'internal'")
// DryRun mode that will print YAML or JSON
cmd.Flags().BoolVar(&options.DryRun, "dry-run", options.DryRun, "If true, only print the object that would be sent, without sending it. This flag can be used to create a cluster YAML or JSON manifest.")
cmd.Flags().StringVarP(&options.Output, "output", "o", options.Output, "Ouput format. One of json|yaml. Used with the --dry-run flag.")
if featureflag.SpecOverrideFlag.Enabled() { if featureflag.SpecOverrideFlag.Enabled() {
cmd.Flags().StringSliceVar(&options.Overrides, "override", options.Overrides, "Directly configure values in the spec") cmd.Flags().StringSliceVar(&options.Overrides, "override", options.Overrides, "Directly configure values in the spec")
} }
@ -326,6 +341,11 @@ func RunCreateCluster(f *util.Factory, out io.Writer, c *CreateClusterOptions) e
isDryrun = true isDryrun = true
targetName = cloudup.TargetDryRun targetName = cloudup.TargetDryRun
} }
if c.DryRun && c.Output == "" {
return fmt.Errorf("unable to execute --dry-run without setting --output")
}
clusterName := c.ClusterName clusterName := c.ClusterName
if clusterName == "" { if clusterName == "" {
return fmt.Errorf("--name is required") return fmt.Errorf("--name is required")
@ -919,8 +939,10 @@ func RunCreateCluster(f *util.Factory, out io.Writer, c *CreateClusterOptions) e
} }
} }
// Use Strict IAM policy and allow AWS ECR by default when creating a new cluster
cluster.Spec.IAM = &api.IAMSpec{ cluster.Spec.IAM = &api.IAMSpec{
Legacy: false, AllowContainerRegistry: true,
Legacy: false,
} }
sshPublicKeys := make(map[string][]byte) sshPublicKeys := make(map[string][]byte)
@ -985,6 +1007,32 @@ func RunCreateCluster(f *util.Factory, out io.Writer, c *CreateClusterOptions) e
return err return err
} }
if c.DryRun {
var obj []runtime.Object
obj = append(obj, cluster)
for _, group := range fullInstanceGroups {
// Cluster name is not populated, and we need it
group.ObjectMeta.Labels = make(map[string]string)
group.ObjectMeta.Labels[api.LabelClusterName] = cluster.ObjectMeta.Name
obj = append(obj, group)
}
switch c.Output {
case OutputYaml:
if err := fullOutputYAML(out, obj...); err != nil {
return fmt.Errorf("error writing cluster yaml to stdout: %v", err)
}
return nil
case OutputJSON:
if err := fullOutputJSON(out, obj...); err != nil {
return fmt.Errorf("error writing cluster json to stdout: %v", err)
}
return nil
default:
return fmt.Errorf("unsupported output type %q", c.Output)
}
}
// Note we perform as much validation as we can, before writing a bad config // Note we perform as much validation as we can, before writing a bad config
err = registry.CreateClusterConfig(clientset, cluster, fullInstanceGroups) err = registry.CreateClusterConfig(clientset, cluster, fullInstanceGroups)
if err != nil { if err != nil {
@ -1008,6 +1056,7 @@ func RunCreateCluster(f *util.Factory, out io.Writer, c *CreateClusterOptions) e
} }
} }
// Can we acutally get to this if??
if targetName != "" { if targetName != "" {
if isDryrun { if isDryrun {
fmt.Fprintf(out, "Previewing changes that will be made:\n\n") fmt.Fprintf(out, "Previewing changes that will be made:\n\n")

View File

@ -39,6 +39,10 @@ import (
type CreateInstanceGroupOptions struct { type CreateInstanceGroupOptions struct {
Role string Role string
Subnets []string Subnets []string
// DryRun mode output an ig manifest of Output type.
DryRun bool
// Output type during a DryRun
Output string
} }
var ( var (
@ -52,6 +56,10 @@ var (
# Create an instancegroup for the k8s-cluster.example.com cluster. # Create an instancegroup for the k8s-cluster.example.com cluster.
kops create ig --name=k8s-cluster.example.com node-example \ kops create ig --name=k8s-cluster.example.com node-example \
--role node --subnet my-subnet-name --role node --subnet my-subnet-name
# Create a YAML manifest for an instancegroup for the k8s-cluster.example.com cluster.
kops create ig --name=k8s-cluster.example.com node-example \
--role node --subnet my-subnet-name --dry-run -oyaml
`)) `))
create_ig_short = i18n.T(`Create an instancegroup.`) create_ig_short = i18n.T(`Create an instancegroup.`)
@ -85,6 +93,9 @@ func NewCmdCreateInstanceGroup(f *util.Factory, out io.Writer) *cobra.Command {
cmd.Flags().StringVar(&options.Role, "role", options.Role, "Type of instance group to create ("+strings.Join(allRoles, ",")+")") cmd.Flags().StringVar(&options.Role, "role", options.Role, "Type of instance group to create ("+strings.Join(allRoles, ",")+")")
cmd.Flags().StringSliceVar(&options.Subnets, "subnet", options.Subnets, "Subnets in which to create instance group") cmd.Flags().StringSliceVar(&options.Subnets, "subnet", options.Subnets, "Subnets in which to create instance group")
// DryRun mode that will print YAML or JSON
cmd.Flags().BoolVar(&options.DryRun, "dry-run", options.DryRun, "If true, only print the object that would be sent, without sending it. This flag can be used to create a cluster YAML or JSON manifest.")
cmd.Flags().StringVarP(&options.Output, "output", "o", options.Output, "Ouput format. One of json|yaml")
return cmd return cmd
} }
@ -142,6 +153,32 @@ func RunCreateInstanceGroup(f *util.Factory, cmd *cobra.Command, args []string,
return err return err
} }
if options.DryRun {
if options.Output == "" {
return fmt.Errorf("must set output flag; yaml or json")
}
// Cluster name is not populated, and we need it
ig.ObjectMeta.Labels = make(map[string]string)
ig.ObjectMeta.Labels[api.LabelClusterName] = cluster.ObjectMeta.Name
switch options.Output {
case OutputYaml:
if err := fullOutputYAML(out, ig); err != nil {
return fmt.Errorf("error writing cluster yaml to stdout: %v", err)
}
return nil
case OutputJSON:
if err := fullOutputJSON(out, ig); err != nil {
return fmt.Errorf("error writing cluster json to stdout: %v", err)
}
return nil
default:
return fmt.Errorf("unsupported output type %q", options.Output)
}
}
var ( var (
edit = editor.NewDefaultEditor(editorEnvs) edit = editor.NewDefaultEditor(editorEnvs)
) )

View File

@ -21,6 +21,7 @@ import (
"io" "io"
"bytes" "bytes"
"github.com/golang/glog" "github.com/golang/glog"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"

View File

@ -17,7 +17,6 @@ limitations under the License.
package main package main
import ( import (
"encoding/json"
"fmt" "fmt"
"io" "io"
@ -153,35 +152,27 @@ func RunGet(context Factory, out io.Writer, options *GetOptions) error {
return err return err
} }
var obj []runtime.Object
if options.output != OutputTable {
obj = append(obj, cluster)
for _, group := range instancegroups {
obj = append(obj, group)
}
}
switch options.output { switch options.output {
case OutputYaml: case OutputYaml:
if err := fullOutputYAML(out, obj...); err != nil {
err = clusterOutputYAML(clusters, out) return fmt.Errorf("error writing cluster yaml to stdout: %v", err)
if err != nil {
return err
} }
if err := writeYAMLSep(out); err != nil { return nil
return err
}
err = igOutputYAML(instancegroups, out)
if err != nil {
return err
}
case OutputJSON: case OutputJSON:
return fmt.Errorf("not implemented") if err := fullOutputJSON(out, obj...); err != nil {
// TODO this is not outputing valid json. Not sure what cluster and instance groups should look like return fmt.Errorf("error writing cluster json to stdout: %v", err)
/* }
err = clusterOutputJson(clusters,out) return nil
if err != nil {
return err
}
err = igOutputJson(instancegroups,out)
if err != nil {
return err
}*/
case OutputTable: case OutputTable:
fmt.Fprintf(os.Stdout, "Cluster\n") fmt.Fprintf(os.Stdout, "Cluster\n")
@ -235,7 +226,7 @@ func marshalYaml(obj runtime.Object) ([]byte, error) {
// obj must be a pointer to a marshalable object // obj must be a pointer to a marshalable object
func marshalJSON(obj runtime.Object) ([]byte, error) { func marshalJSON(obj runtime.Object) ([]byte, error) {
j, err := json.MarshalIndent(obj, "", " ") j, err := kopscodecs.ToVersionedJSON(obj)
if err != nil { if err != nil {
return nil, fmt.Errorf("error marshaling json: %v", err) return nil, fmt.Errorf("error marshaling json: %v", err)
} }

View File

@ -18,13 +18,13 @@ package main
import ( import (
"fmt" "fmt"
"io"
"os" "os"
"strings" "strings"
"io"
"github.com/spf13/cobra" "github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/kops/cmd/kops/util" "k8s.io/kops/cmd/kops/util"
api "k8s.io/kops/pkg/apis/kops" api "k8s.io/kops/pkg/apis/kops"
@ -133,7 +133,7 @@ func RunGetClusters(context Factory, out io.Writer, options *GetClusterOptions)
} }
if len(clusters) == 0 { if len(clusters) == 0 {
return fmt.Errorf("No clusters found") return fmt.Errorf("no clusters found")
} }
if options.FullSpec { if options.FullSpec {
@ -146,14 +146,20 @@ func RunGetClusters(context Factory, out io.Writer, options *GetClusterOptions)
fmt.Fprint(out, get_cluster_full_warning) fmt.Fprint(out, get_cluster_full_warning)
} }
var obj []runtime.Object
if options.output != OutputTable {
for _, c := range clusters {
obj = append(obj, c)
}
}
switch options.output { switch options.output {
case OutputTable: case OutputTable:
return clusterOutputTable(clusters, out) return clusterOutputTable(clusters, out)
case OutputYaml: case OutputYaml:
return clusterOutputYAML(clusters, out) return fullOutputYAML(out, obj...)
case OutputJSON: case OutputJSON:
return clusterOutputJson(clusters, out) return fullOutputJSON(out, obj...)
default: default:
return fmt.Errorf("Unknown output format: %q", options.output) return fmt.Errorf("Unknown output format: %q", options.output)
} }
@ -206,23 +212,47 @@ func clusterOutputTable(clusters []*api.Cluster, out io.Writer) error {
return t.Render(clusters, out, "NAME", "CLOUD", "ZONES") return t.Render(clusters, out, "NAME", "CLOUD", "ZONES")
} }
func clusterOutputJson(clusters []*api.Cluster, out io.Writer) error { // fullOutputJson outputs the marshalled JSON of a list of clusters and instance groups. It will handle
for _, cluster := range clusters { // nils for clusters and instanceGroups slices.
if err := marshalToWriter(cluster, marshalJSON, out); err != nil { func fullOutputJSON(out io.Writer, args ...runtime.Object) error {
argsLen := len(args)
if argsLen > 1 {
if _, err := fmt.Fprint(out, "["); err != nil {
return err return err
} }
} }
for i, arg := range args {
if i != 0 {
if _, err := fmt.Fprint(out, ","); err != nil {
return err
}
}
if err := marshalToWriter(arg, marshalJSON, out); err != nil {
return err
}
}
if argsLen > 1 {
if _, err := fmt.Fprint(out, "]"); err != nil {
return err
}
}
return nil return nil
} }
func clusterOutputYAML(clusters []*api.Cluster, out io.Writer) error { // fullOutputJson outputs the marshalled JSON of a list of clusters and instance groups. It will handle
for i, cluster := range clusters { // nils for clusters and instanceGroups slices.
func fullOutputYAML(out io.Writer, args ...runtime.Object) error {
for i, obj := range args {
if i != 0 { if i != 0 {
if err := writeYAMLSep(out); err != nil { if err := writeYAMLSep(out); err != nil {
return fmt.Errorf("error writing to stdout: %v", err) return fmt.Errorf("error writing to stdout: %v", err)
} }
} }
if err := marshalToWriter(cluster, marshalYaml, out); err != nil { if err := marshalToWriter(obj, marshalYaml, out); err != nil {
return err return err
} }
} }

View File

@ -24,6 +24,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/kops/cmd/kops/util" "k8s.io/kops/cmd/kops/util"
api "k8s.io/kops/pkg/apis/kops" api "k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/util/pkg/tables" "k8s.io/kops/util/pkg/tables"
@ -85,10 +86,16 @@ func RunGetFederations(context Factory, out io.Writer, options *GetFederationOpt
if len(federations) == 0 { if len(federations) == 0 {
return fmt.Errorf("No federations found") return fmt.Errorf("No federations found")
} }
var obj []runtime.Object
if options.output != OutputTable {
for _, c := range federations {
obj = append(obj, c)
}
}
switch options.output { switch options.output {
case OutputTable: case OutputTable:
t := &tables.Table{} t := &tables.Table{}
t.AddColumn("NAME", func(f *api.Federation) string { t.AddColumn("NAME", func(f *api.Federation) string {
return f.ObjectMeta.Name return f.ObjectMeta.Name
@ -102,25 +109,10 @@ func RunGetFederations(context Factory, out io.Writer, options *GetFederationOpt
return t.Render(federations, out, "NAME", "CONTROLLERS", "MEMBERS") return t.Render(federations, out, "NAME", "CONTROLLERS", "MEMBERS")
case OutputYaml: case OutputYaml:
for i, f := range federations { return fullOutputYAML(out, obj...)
if i != 0 {
_, err = out.Write([]byte("\n\n---\n\n"))
if err != nil {
return fmt.Errorf("error writing to stdout: %v", err)
}
}
if err := marshalToWriter(f, marshalYaml, os.Stdout); err != nil {
return err
}
}
case OutputJSON: case OutputJSON:
for _, f := range federations { return fullOutputJSON(out, obj...)
if err := marshalToWriter(f, marshalJSON, os.Stdout); err != nil {
return err
}
}
default: default:
return fmt.Errorf("Unknown output format: %q", options.output) return fmt.Errorf("Unknown output format: %q", options.output)
} }
return nil
} }

View File

@ -24,6 +24,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/kops/cmd/kops/util" "k8s.io/kops/cmd/kops/util"
api "k8s.io/kops/pkg/apis/kops" api "k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/formatter" "k8s.io/kops/pkg/formatter"
@ -112,14 +113,20 @@ func RunGetInstanceGroups(options *GetInstanceGroupsOptions, args []string) erro
return fmt.Errorf("No InstanceGroup objects found") return fmt.Errorf("No InstanceGroup objects found")
} }
switch options.output { var obj []runtime.Object
if options.output != OutputTable {
for _, c := range instancegroups {
obj = append(obj, c)
}
}
switch options.output {
case OutputTable: case OutputTable:
return igOutputTable(cluster, instancegroups, out) return igOutputTable(cluster, instancegroups, out)
case OutputYaml: case OutputYaml:
return igOutputYAML(instancegroups, out) return fullOutputYAML(out, obj...)
case OutputJSON: case OutputJSON:
return igOutputJson(instancegroups, out) return fullOutputJSON(out, obj...)
default: default:
return fmt.Errorf("Unknown output format: %q", options.output) return fmt.Errorf("Unknown output format: %q", options.output)
} }
@ -176,29 +183,6 @@ func igOutputTable(cluster *api.Cluster, instancegroups []*api.InstanceGroup, ou
return t.Render(instancegroups, os.Stdout, "NAME", "ROLE", "MACHINETYPE", "MIN", "MAX", "ZONES") return t.Render(instancegroups, os.Stdout, "NAME", "ROLE", "MACHINETYPE", "MIN", "MAX", "ZONES")
} }
func igOutputJson(instanceGroups []*api.InstanceGroup, out io.Writer) error {
for _, ig := range instanceGroups {
if err := marshalToWriter(ig, marshalJSON, out); err != nil {
return err
}
}
return nil
}
func igOutputYAML(instanceGroups []*api.InstanceGroup, out io.Writer) error {
for i, ig := range instanceGroups {
if i != 0 {
if err := writeYAMLSep(out); err != nil {
return fmt.Errorf("error writing to stdout: %v", err)
}
}
if err := marshalToWriter(ig, marshalYaml, out); err != nil {
return err
}
}
return nil
}
func int32PointerToString(v *int32) string { func int32PointerToString(v *int32) string {
if v == nil { if v == nil {
return "-" return "-"

View File

@ -18,6 +18,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/upup/pkg/fi/cloudup" "k8s.io/kops/upup/pkg/fi/cloudup"

View File

@ -17,12 +17,13 @@ limitations under the License.
package main package main
import ( import (
"bytes"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"os" "os"
"path"
"path/filepath" "path/filepath"
"strings"
"github.com/ghodss/yaml" "github.com/ghodss/yaml"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -139,16 +140,14 @@ func runToolBoxTemplate(f *util.Factory, out io.Writer, options *toolboxTemplate
if err != nil { if err != nil {
return fmt.Errorf("unable to read snippet: %s, error: %s", j, err) return fmt.Errorf("unable to read snippet: %s, error: %s", j, err)
} }
snippets[j] = string(content) snippets[path.Base(j)] = string(content)
} }
} }
b := new(bytes.Buffer) // @step: render each of the templates, splitting on the documents
// @step: render each of the template and write to location
r := templater.NewTemplater() r := templater.NewTemplater()
size := len(templates) - 1 var documents []string
for i, x := range templates { for _, x := range templates {
content, err := ioutil.ReadFile(x) content, err := ioutil.ReadFile(x)
if err != nil { if err != nil {
return fmt.Errorf("unable to read template: %s, error: %s", x, err) return fmt.Errorf("unable to read template: %s, error: %s", x, err)
@ -158,37 +157,35 @@ func runToolBoxTemplate(f *util.Factory, out io.Writer, options *toolboxTemplate
if err != nil { if err != nil {
return fmt.Errorf("unable to render template: %s, error: %s", x, err) return fmt.Errorf("unable to render template: %s, error: %s", x, err)
} }
// @check if we have a zero length string and if so, forgo it // @check if the content is zero ignore it
if len(rendered) <= 0 { if len(rendered) <= 0 {
continue continue
} }
// @check if we need to format the yaml if !options.formatYAML {
if options.formatYAML { documents = append(documents, strings.Split(rendered, "---\n")...)
var data interface{} continue
if err := utils.YamlUnmarshal([]byte(rendered), &data); err != nil { }
for _, x := range strings.Split(rendered, "---\n") {
var data map[string]interface{}
if err := yaml.Unmarshal([]byte(x), &data); err != nil {
return fmt.Errorf("unable to unmarshall content from template: %s, error: %s", x, err) return fmt.Errorf("unable to unmarshall content from template: %s, error: %s", x, err)
} }
// @TODO: i'm not sure how this could happen but best to heck none the less if len(data) <= 0 {
continue
}
formatted, err := yaml.Marshal(&data) formatted, err := yaml.Marshal(&data)
if err != nil { if err != nil {
return fmt.Errorf("unable to marhshal formated content to yaml: %s", err) return fmt.Errorf("unable to marhshal formated content to yaml: %s", err)
} }
rendered = string(formatted) documents = append(documents, string(formatted))
}
if _, err := b.WriteString(rendered); err != nil {
return fmt.Errorf("unable to write template: %s, error: %s", x, err)
}
// @check if we should need to add document separator
if i < size {
if _, err := b.WriteString("---\n"); err != nil {
return fmt.Errorf("unable to write to template: %s, error: %s", x, err)
}
} }
} }
iowriter := out // join in harmony all the YAML documents back together
content := strings.Join(documents, "---\n")
iowriter := out
// @check if we are writing to a file rather than stdout // @check if we are writing to a file rather than stdout
if options.outputPath != "" { if options.outputPath != "" {
w, err := os.OpenFile(utils.ExpandPath(options.outputPath), os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0660) w, err := os.OpenFile(utils.ExpandPath(options.outputPath), os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0660)
@ -199,7 +196,7 @@ func runToolBoxTemplate(f *util.Factory, out io.Writer, options *toolboxTemplate
iowriter = w iowriter = w
} }
if _, err := iowriter.Write(b.Bytes()); err != nil { if _, err := iowriter.Write([]byte(content)); err != nil {
return fmt.Errorf("unable to write template: %s", err) return fmt.Errorf("unable to write template: %s", err)
} }

View File

@ -18,9 +18,10 @@ package dns
import ( import (
"fmt" "fmt"
"strings"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/federation/pkg/dnsprovider" "k8s.io/kubernetes/federation/pkg/dnsprovider"
"strings"
) )
type ZoneSpec struct { type ZoneSpec struct {

View File

@ -56,6 +56,10 @@ kops create cluster
--project my-gce-project \ --project my-gce-project \
--image "ubuntu-os-cloud/ubuntu-1604-xenial-v20170202" \ --image "ubuntu-os-cloud/ubuntu-1604-xenial-v20170202" \
--yes --yes
# Create manifest for a cluster in AWS
kops create cluster --name=kubernetes-cluster.example.com \
--state=s3://kops-state-1234 --zones=eu-west-1a \
--node-count=2 --dry-run -oyaml
``` ```
### Options ### Options
@ -71,6 +75,7 @@ kops create cluster
--cloud-labels string A list of KV pairs used to tag all instance groups in AWS (eg "Owner=John Doe,Team=Some Team"). --cloud-labels string A list of KV pairs used to tag all instance groups in AWS (eg "Owner=John Doe,Team=Some Team").
--dns string DNS hosted zone to use: public|private. Default is 'public'. (default "Public") --dns string DNS hosted zone to use: public|private. Default is 'public'. (default "Public")
--dns-zone string DNS hosted zone to use (defaults to longest matching zone) --dns-zone string DNS hosted zone to use (defaults to longest matching zone)
--dry-run If true, only print the object that would be sent, without sending it. This flag can be used to create a cluster YAML or JSON manifest.
--encrypt-etcd-storage Generate key in aws kms and use it for encrypt etcd volumes --encrypt-etcd-storage Generate key in aws kms and use it for encrypt etcd volumes
--image string Image to use for all instances. --image string Image to use for all instances.
--kubernetes-version string Version of kubernetes to run (defaults to version in channel) --kubernetes-version string Version of kubernetes to run (defaults to version in channel)
@ -89,10 +94,11 @@ kops create cluster
--node-tenancy string The tenancy of the node group on AWS. Can be either default or dedicated. --node-tenancy string The tenancy of the node group on AWS. Can be either default or dedicated.
--node-volume-size int32 Set instance volume size (in GB) for nodes --node-volume-size int32 Set instance volume size (in GB) for nodes
--out string Path to write any local output --out string Path to write any local output
-o, --output string Ouput format. One of json|yaml. Used with the --dry-run flag.
--project string Project to use (must be set on GCE) --project string Project to use (must be set on GCE)
--ssh-access stringSlice Restrict SSH access to this CIDR. If not set, access will not be restricted by IP. (default [0.0.0.0/0]) --ssh-access stringSlice Restrict SSH access to this CIDR. If not set, access will not be restricted by IP. (default [0.0.0.0/0])
--ssh-public-key string SSH public key to use (default "~/.ssh/id_rsa.pub") --ssh-public-key string SSH public key to use (default "~/.ssh/id_rsa.pub")
--target string Target - direct, terraform, cloudformation (default "direct") --target string Valid targets: direct, terraform, direct. Set this flag to terraform if you want kops to generate terraform (default "direct")
-t, --topology string Controls network topology for the cluster. public|private. Default is 'public'. (default "public") -t, --topology string Controls network topology for the cluster. public|private. Default is 'public'. (default "public")
--vpc string Set to use a shared VPC --vpc string Set to use a shared VPC
--yes Specify --yes to immediately create the cluster --yes Specify --yes to immediately create the cluster

View File

@ -20,11 +20,17 @@ kops create instancegroup
# Create an instancegroup for the k8s-cluster.example.com cluster. # Create an instancegroup for the k8s-cluster.example.com cluster.
kops create ig --name=k8s-cluster.example.com node-example \ kops create ig --name=k8s-cluster.example.com node-example \
--role node --subnet my-subnet-name --role node --subnet my-subnet-name
# Create a YAML manifest for an instancegroup for the k8s-cluster.example.com cluster.
kops create ig --name=k8s-cluster.example.com node-example \
--role node --subnet my-subnet-name --dry-run -oyaml
``` ```
### Options ### Options
``` ```
--dry-run If true, only print the object that would be sent, without sending it. This flag can be used to create a cluster YAML or JSON manifest.
-o, --output string Ouput format. One of json|yaml
--role string Type of instance group to create (Node,Master,Bastion) (default "Node") --role string Type of instance group to create (Node,Master,Bastion) (default "Node")
--subnet stringSlice Subnets in which to create instance group --subnet stringSlice Subnets in which to create instance group
``` ```

View File

@ -140,8 +140,11 @@ spec:
auditLogMaxAge: 10 auditLogMaxAge: 10
auditLogMaxBackups: 1 auditLogMaxBackups: 1
auditLogMaxSize: 100 auditLogMaxSize: 100
auditPolicyFile: /srv/kubernetes/audit.conf
``` ```
Note: you could use the fileAssets feature to push an advanced audit policy file on the master nodes.
#### runtimeConfig #### runtimeConfig
Keys and values here are translated into `--runtime-config` values for `kube-apiserver`, separated by commas. Keys and values here are translated into `--runtime-config` values for `kube-apiserver`, separated by commas.

View File

@ -204,7 +204,7 @@ Limitations:
4. Verify the planned changes with `kops update cluster cluster.example.com` 4. Verify the planned changes with `kops update cluster cluster.example.com`
5. Create the cluster with `kops update cluster cluster.example.com --yes` 5. Create the cluster with `kops update cluster cluster.example.com --yes`
6. Wait around for the cluster to fully come up and be available. `k get nodes` should return `(master + minions) = 15` available nodes. 6. Wait around for the cluster to fully come up and be available. `k get nodes` should return `(master + minions) = 15` available nodes.
7. (Optional) Create the Dashboard with `kubectl create -f https://rawgit.com/kubernetes/dashboard/master/src/deploy/kubernetes-dashboard.yaml` 7. (Optional) Create the Dashboard with `kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml`
8. Deploy the existing resource configuration to the new cluster. 8. Deploy the existing resource configuration to the new cluster.
9. Confirm that pods on the new cluster are able to access remote resources. 9. Confirm that pods on the new cluster are able to access remote resources.
- For AWS-hosted services, add the generated `nodes.cluster.example.com` security group to the resources that may need it (i.e. ElastiCache, RDS, etc). - For AWS-hosted services, add the generated `nodes.cluster.example.com` security group to the resources that may need it (i.e. ElastiCache, RDS, etc).

View File

@ -3,7 +3,7 @@
Kops uses the Kubernetes API machinery. It is well designed, and very powerful, but you have to Kops uses the Kubernetes API machinery. It is well designed, and very powerful, but you have to
jump through some hoops to use it. jump through some hoops to use it.
Recommended reading: [kubernetes API changes doc](https://github.com/kubernetes/kubernetes/blob/master/docs/devel/api_changes.md) Recommended reading: [kubernetes API changes doc](https://github.com/kubernetes/community/blob/master/contributors/devel/api_changes.md)
The kops APIs live in [pkg/apis/kops](https://github.com/kubernetes/kops/tree/master/pkg/apis/kops), both in The kops APIs live in [pkg/apis/kops](https://github.com/kubernetes/kops/tree/master/pkg/apis/kops), both in
that directory directly (the unversioned API) and in the versioned subdirectories (`v1alpha1`, `v1alpha2`). that directory directly (the unversioned API) and in the versioned subdirectories (`v1alpha1`, `v1alpha2`).

View File

@ -19,9 +19,10 @@ package main
import ( import (
"flag" "flag"
"fmt" "fmt"
"k8s.io/kops/util/pkg/vfs"
"os" "os"
"strings" "strings"
"k8s.io/kops/util/pkg/vfs"
) )
// registryBase is the base path where state files are kept (the state store) // registryBase is the base path where state files are kept (the state store)

View File

@ -19,6 +19,7 @@ package main
import ( import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
api "k8s.io/kops/pkg/apis/kops" api "k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/client/simple/vfsclientset" "k8s.io/kops/pkg/client/simple/vfsclientset"
"k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi"

View File

@ -18,6 +18,7 @@ package federation
import ( import (
"fmt" "fmt"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
k8sapiv1 "k8s.io/api/core/v1" k8sapiv1 "k8s.io/api/core/v1"

View File

@ -18,6 +18,7 @@ package federation
import ( import (
"fmt" "fmt"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"

View File

@ -18,6 +18,7 @@ package federation
import ( import (
"fmt" "fmt"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"

View File

@ -18,6 +18,7 @@ package kubernetestarget
import ( import (
"fmt" "fmt"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
kopsapi "k8s.io/kops/pkg/apis/kops" kopsapi "k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/client/simple" "k8s.io/kops/pkg/client/simple"

View File

@ -18,6 +18,7 @@ package tasks
import ( import (
"fmt" "fmt"
"k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/kops/federation/targets/kubernetestarget" "k8s.io/kops/federation/targets/kubernetestarget"
"k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi"

View File

@ -18,11 +18,12 @@ package distros
import ( import (
"fmt" "fmt"
"github.com/golang/glog"
"io/ioutil" "io/ioutil"
"os" "os"
"path" "path"
"strings" "strings"
"github.com/golang/glog"
) )
// FindDistribution identifies the distribution on which we are running // FindDistribution identifies the distribution on which we are running

View File

@ -17,11 +17,12 @@ limitations under the License.
package model package model
import ( import (
"path"
"testing"
"k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/flagbuilder" "k8s.io/kops/pkg/flagbuilder"
"k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi"
"path"
"testing"
) )
func TestDockerBuilder_Simple(t *testing.T) { func TestDockerBuilder_Simple(t *testing.T) {

View File

@ -33,7 +33,7 @@ type KubectlBuilder struct {
var _ fi.ModelBuilder = &KubectlBuilder{} var _ fi.ModelBuilder = &KubectlBuilder{}
// Build is responsible for mananging the kubectl on the nodes // Build is responsible for managing the kubectl on the nodes
func (b *KubectlBuilder) Build(c *fi.ModelBuilderContext) error { func (b *KubectlBuilder) Build(c *fi.ModelBuilderContext) error {
if !b.IsMaster { if !b.IsMaster {
return nil return nil

View File

@ -25,6 +25,7 @@ import (
"testing" "testing"
"fmt" "fmt"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/kops/nodeup/pkg/distros" "k8s.io/kops/nodeup/pkg/distros"
"k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/apis/kops"

View File

@ -18,9 +18,10 @@ package model
import ( import (
"fmt" "fmt"
"path/filepath"
"k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/nodeup/nodetasks" "k8s.io/kops/upup/pkg/fi/nodeup/nodetasks"
"path/filepath"
) )
// NetworkBuilder writes CNI assets // NetworkBuilder writes CNI assets

View File

@ -18,13 +18,14 @@ package kops
import ( import (
"fmt" "fmt"
"net/url"
"github.com/blang/semver" "github.com/blang/semver"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kops/pkg/apis/kops/util" "k8s.io/kops/pkg/apis/kops/util"
"k8s.io/kops/util/pkg/vfs" "k8s.io/kops/util/pkg/vfs"
"net/url"
) )
var DefaultChannelBase = "https://raw.githubusercontent.com/kubernetes/kops/master/channels/" var DefaultChannelBase = "https://raw.githubusercontent.com/kubernetes/kops/master/channels/"

View File

@ -18,6 +18,7 @@ package model
import ( import (
"fmt" "fmt"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/apis/kops"
) )

View File

@ -17,9 +17,10 @@ limitations under the License.
package model package model
import ( import (
"k8s.io/kops/pkg/apis/kops"
"reflect" "reflect"
"testing" "testing"
"k8s.io/kops/pkg/apis/kops"
) )
// Test_FindSubnet tests FindSubnet // Test_FindSubnet tests FindSubnet

View File

@ -18,6 +18,7 @@ package registry
import ( import (
"fmt" "fmt"
api "k8s.io/kops/pkg/apis/kops" api "k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/client/simple" "k8s.io/kops/pkg/client/simple"
) )

View File

@ -18,6 +18,7 @@ package registry
import ( import (
"fmt" "fmt"
"k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/validation/field"
api "k8s.io/kops/pkg/apis/kops" api "k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/util/pkg/vfs" "k8s.io/kops/util/pkg/vfs"

View File

@ -17,8 +17,9 @@ limitations under the License.
package kops package kops
import ( import (
"github.com/blang/semver"
"testing" "testing"
"github.com/blang/semver"
) )
// Test_SemverOrdering is a test of semver ordering, but highlights the case that trips everyone one: // Test_SemverOrdering is a test of semver ordering, but highlights the case that trips everyone one:

View File

@ -17,8 +17,9 @@ limitations under the License.
package util package util
import ( import (
"k8s.io/api/core/v1"
"strings" "strings"
"k8s.io/api/core/v1"
) )
func GetNodeRole(node *v1.Node) string { func GetNodeRole(node *v1.Node) string {

View File

@ -18,11 +18,12 @@ package v1alpha1
import ( import (
"fmt" "fmt"
"k8s.io/apimachinery/pkg/conversion"
"k8s.io/kops/pkg/apis/kops"
"reflect" "reflect"
"sort" "sort"
"strings" "strings"
"k8s.io/apimachinery/pkg/conversion"
"k8s.io/kops/pkg/apis/kops"
) )
func Convert_v1alpha1_BastionSpec_To_kops_BastionSpec(in *BastionSpec, out *kops.BastionSpec, s conversion.Scope) error { func Convert_v1alpha1_BastionSpec_To_kops_BastionSpec(in *BastionSpec, out *kops.BastionSpec, s conversion.Scope) error {

View File

@ -17,9 +17,10 @@ limitations under the License.
package validation package validation
import ( import (
"k8s.io/apimachinery/pkg/util/validation/field"
"net" "net"
"net/url" "net/url"
"k8s.io/apimachinery/pkg/util/validation/field"
) )
// isSubnet checks if child is a subnet of parent // isSubnet checks if child is a subnet of parent

View File

@ -18,6 +18,7 @@ package validation
import ( import (
"fmt" "fmt"
"k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/apis/kops/util" "k8s.io/kops/pkg/apis/kops/util"

View File

@ -17,10 +17,11 @@ limitations under the License.
package validation package validation
import ( import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kops/pkg/apis/kops"
"strings" "strings"
"testing" "testing"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kops/pkg/apis/kops"
) )
func TestDefaultTaintsEnforcedBefore160(t *testing.T) { func TestDefaultTaintsEnforcedBefore160(t *testing.T) {

View File

@ -18,6 +18,7 @@ package apiserver
import ( import (
"fmt" "fmt"
"k8s.io/apimachinery/pkg/apimachinery/announced" "k8s.io/apimachinery/pkg/apimachinery/announced"
"k8s.io/apimachinery/pkg/apimachinery/registered" "k8s.io/apimachinery/pkg/apimachinery/registered"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

View File

@ -17,8 +17,9 @@ limitations under the License.
package assets package assets
import ( import (
"k8s.io/kops/pkg/apis/kops"
"testing" "testing"
"k8s.io/kops/pkg/apis/kops"
) )
func TestRemap_File(t *testing.T) { func TestRemap_File(t *testing.T) {

View File

@ -18,6 +18,10 @@ package vfsclientset
import ( import (
"fmt" "fmt"
"os"
"strings"
"time"
"github.com/golang/glog" "github.com/golang/glog"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
@ -28,9 +32,6 @@ import (
"k8s.io/kops/pkg/apis/kops/v1alpha1" "k8s.io/kops/pkg/apis/kops/v1alpha1"
"k8s.io/kops/pkg/apis/kops/validation" "k8s.io/kops/pkg/apis/kops/validation"
"k8s.io/kops/util/pkg/vfs" "k8s.io/kops/util/pkg/vfs"
"os"
"strings"
"time"
) )
type ClusterVFS struct { type ClusterVFS struct {

View File

@ -19,6 +19,11 @@ package vfsclientset
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"os"
"reflect"
"sort"
"time"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -30,10 +35,6 @@ import (
"k8s.io/kops/pkg/apis/kops/v1alpha2" "k8s.io/kops/pkg/apis/kops/v1alpha2"
"k8s.io/kops/pkg/kopscodecs" "k8s.io/kops/pkg/kopscodecs"
"k8s.io/kops/util/pkg/vfs" "k8s.io/kops/util/pkg/vfs"
"os"
"reflect"
"sort"
"time"
) )
var StoreVersion = v1alpha2.SchemeGroupVersion var StoreVersion = v1alpha2.SchemeGroupVersion

View File

@ -18,6 +18,7 @@ package vfsclientset
import ( import (
"fmt" "fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"

View File

@ -19,6 +19,7 @@ package vfsclientset
// These imports are the API groups the client will support. // These imports are the API groups the client will support.
import ( import (
"fmt" "fmt"
"k8s.io/kops/pkg/kopscodecs" "k8s.io/kops/pkg/kopscodecs"
) )

View File

@ -18,6 +18,7 @@ package vfsclientset
import ( import (
"fmt" "fmt"
"github.com/golang/glog" "github.com/golang/glog"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"

View File

@ -18,8 +18,9 @@ package vfsclientset
import ( import (
"fmt" "fmt"
"k8s.io/kops/util/pkg/vfs"
"os" "os"
"k8s.io/kops/util/pkg/vfs"
) )
func listChildNames(vfsPath vfs.Path) ([]string, error) { func listChildNames(vfsPath vfs.Path) ([]string, error) {

View File

@ -17,8 +17,9 @@ limitations under the License.
package diff package diff
import ( import (
"github.com/sergi/go-diff/diffmatchpatch"
"testing" "testing"
"github.com/sergi/go-diff/diffmatchpatch"
) )
func Test_Diff_1(t *testing.T) { func Test_Diff_1(t *testing.T) {

View File

@ -18,6 +18,7 @@ package edit
import ( import (
"bytes" "bytes"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/kops/pkg/diff" "k8s.io/kops/pkg/diff"
"k8s.io/kops/pkg/kopscodecs" "k8s.io/kops/pkg/kopscodecs"

View File

@ -17,9 +17,10 @@ limitations under the License.
package featureflag package featureflag
import ( import (
"github.com/golang/glog"
"os" "os"
"testing" "testing"
"github.com/golang/glog"
) )
func TestFlagToFalse(t *testing.T) { func TestFlagToFalse(t *testing.T) {

View File

@ -29,7 +29,7 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
) )
// BuildFlags returns a space seperated list arguments // BuildFlags returns a space separated list arguments
// @deprecated: please use BuildFlagsList // @deprecated: please use BuildFlagsList
func BuildFlags(options interface{}) (string, error) { func BuildFlags(options interface{}) (string, error) {
flags, err := BuildFlagsList(options) flags, err := BuildFlagsList(options)

View File

@ -17,10 +17,11 @@ limitations under the License.
package formatter package formatter
import ( import (
"strings"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/apis/kops/model" "k8s.io/kops/pkg/apis/kops/model"
"strings"
) )
// InstanceGroupRenderFunction is a render function for an InstanceGroup // InstanceGroupRenderFunction is a render function for an InstanceGroup
@ -38,7 +39,7 @@ func RenderInstanceGroupZones(cluster *kops.Cluster) InstanceGroupRenderFunction
return func(ig *kops.InstanceGroup) string { return func(ig *kops.InstanceGroup) string {
zones, err := model.FindZonesForInstanceGroup(cluster, ig) zones, err := model.FindZonesForInstanceGroup(cluster, ig)
if err != nil { if err != nil {
glog.Warningf("error fetch zones for instancegroup: %v", err) glog.Warningf("error fetching zones for instancegroup: %v", err)
return "" return ""
} }
return strings.Join(zones, ",") return strings.Join(zones, ",")

View File

@ -17,8 +17,9 @@ limitations under the License.
package formatter package formatter
import ( import (
"k8s.io/kops/pkg/apis/kops"
"testing" "testing"
"k8s.io/kops/pkg/apis/kops"
) )
func TestRenderInstanceGroupZones(t *testing.T) { func TestRenderInstanceGroupZones(t *testing.T) {

View File

@ -19,6 +19,8 @@ package k8scodecs
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"os"
"github.com/golang/glog" "github.com/golang/glog"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/apimachinery/announced" "k8s.io/apimachinery/pkg/apimachinery/announced"
@ -27,7 +29,6 @@ import (
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/apimachinery/pkg/runtime/serializer"
"os"
) )
var Scheme = runtime.NewScheme() var Scheme = runtime.NewScheme()

View File

@ -17,14 +17,15 @@ limitations under the License.
package k8scodecs package k8scodecs
import ( import (
"strings"
"testing"
"time"
"github.com/MakeNowJust/heredoc" "github.com/MakeNowJust/heredoc"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/kops/pkg/diff" "k8s.io/kops/pkg/diff"
"strings"
"testing"
"time"
) )
// An arbitrary timestamp for testing // An arbitrary timestamp for testing

View File

@ -19,6 +19,8 @@ package kopscodecs
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"os"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/apimachinery/pkg/apimachinery/announced" "k8s.io/apimachinery/pkg/apimachinery/announced"
"k8s.io/apimachinery/pkg/apimachinery/registered" "k8s.io/apimachinery/pkg/apimachinery/registered"
@ -29,7 +31,6 @@ import (
"k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/apis/kops/install" "k8s.io/kops/pkg/apis/kops/install"
"k8s.io/kops/pkg/apis/kops/v1alpha2" "k8s.io/kops/pkg/apis/kops/v1alpha2"
"os"
) )
var Scheme = runtime.NewScheme() var Scheme = runtime.NewScheme()
@ -44,12 +45,12 @@ func init() {
install.Install(GroupFactoryRegistry, Registry, Scheme) install.Install(GroupFactoryRegistry, Registry, Scheme)
} }
func encoder(gv runtime.GroupVersioner) runtime.Encoder { func encoder(gv runtime.GroupVersioner, mediaType string) runtime.Encoder {
yaml, ok := runtime.SerializerInfoForMediaType(Codecs.SupportedMediaTypes(), "application/yaml") e, ok := runtime.SerializerInfoForMediaType(Codecs.SupportedMediaTypes(), mediaType)
if !ok { if !ok {
glog.Fatalf("no YAML serializer registered") glog.Fatalf("no %s serializer registered", mediaType)
} }
return Codecs.EncoderForVersion(yaml.Serializer, gv) return Codecs.EncoderForVersion(e.Serializer, gv)
} }
func decoder() runtime.Decoder { func decoder() runtime.Decoder {
@ -67,7 +68,22 @@ func ToVersionedYaml(obj runtime.Object) ([]byte, error) {
// ToVersionedYamlWithVersion encodes the object to YAML, in a specified API version // ToVersionedYamlWithVersion encodes the object to YAML, in a specified API version
func ToVersionedYamlWithVersion(obj runtime.Object, version runtime.GroupVersioner) ([]byte, error) { func ToVersionedYamlWithVersion(obj runtime.Object, version runtime.GroupVersioner) ([]byte, error) {
var w bytes.Buffer var w bytes.Buffer
err := encoder(version).Encode(obj, &w) err := encoder(version, "application/yaml").Encode(obj, &w)
if err != nil {
return nil, fmt.Errorf("error encoding %T: %v", obj, err)
}
return w.Bytes(), nil
}
// ToVersionedJSON encodes the object to JSON
func ToVersionedJSON(obj runtime.Object) ([]byte, error) {
return ToVersionedJSONWithVersion(obj, v1alpha2.SchemeGroupVersion)
}
// ToVersionedJSONWithVersion encodes the object to JSON, in a specified API version
func ToVersionedJSONWithVersion(obj runtime.Object, version runtime.GroupVersioner) ([]byte, error) {
var w bytes.Buffer
err := encoder(version, "application/json").Encode(obj, &w)
if err != nil { if err != nil {
return nil, fmt.Errorf("error encoding %T: %v", obj, err) return nil, fmt.Errorf("error encoding %T: %v", obj, err)
} }

View File

@ -17,14 +17,15 @@ limitations under the License.
package kopscodecs package kopscodecs
import ( import (
"strings"
"testing"
"time"
"github.com/MakeNowJust/heredoc" "github.com/MakeNowJust/heredoc"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/kops/pkg/apis/kops/v1alpha2" "k8s.io/kops/pkg/apis/kops/v1alpha2"
"k8s.io/kops/pkg/diff" "k8s.io/kops/pkg/diff"
"strings"
"testing"
"time"
) )
// An arbitrary timestamp for testing // An arbitrary timestamp for testing

View File

@ -18,11 +18,12 @@ package kubeconfig
import ( import (
"fmt" "fmt"
"sort"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/dns" "k8s.io/kops/pkg/dns"
"k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi"
"sort"
) )
func BuildKubecfg(cluster *kops.Cluster, keyStore fi.Keystore, secretStore fi.SecretStore, status kops.StatusStore) (*KubeconfigBuilder, error) { func BuildKubecfg(cluster *kops.Cluster, keyStore fi.Keystore, secretStore fi.SecretStore, status kops.StatusStore) (*KubeconfigBuilder, error) {

View File

@ -18,8 +18,9 @@ package kubemanifest
import ( import (
"fmt" "fmt"
"github.com/golang/glog"
"strings" "strings"
"github.com/golang/glog"
) )
type ImageRemapFunction func(image string) (string, error) type ImageRemapFunction func(image string) (string, error)

View File

@ -19,6 +19,7 @@ package kubemanifest
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"github.com/ghodss/yaml" "github.com/ghodss/yaml"
"github.com/golang/glog" "github.com/golang/glog"
) )

View File

@ -18,8 +18,9 @@ package kubemanifest
import ( import (
"fmt" "fmt"
"github.com/golang/glog"
"strings" "strings"
"github.com/golang/glog"
) )
type visitorBase struct { type visitorBase struct {

View File

@ -17,11 +17,12 @@ limitations under the License.
package awsmodel package awsmodel
import ( import (
"testing"
"k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/model" "k8s.io/kops/pkg/model"
"k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/cloudup/awstasks" "k8s.io/kops/upup/pkg/fi/cloudup/awstasks"
"testing"
) )
func buildMinimalCluster() *kops.Cluster { func buildMinimalCluster() *kops.Cluster {

View File

@ -17,11 +17,12 @@ limitations under the License.
package components package components
import ( import (
"testing"
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
api "k8s.io/kops/pkg/apis/kops" api "k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/assets" "k8s.io/kops/pkg/assets"
"testing"
"time"
) )
type ClusterParams struct { type ClusterParams struct {

View File

@ -18,6 +18,7 @@ package components
import ( import (
"fmt" "fmt"
"k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/loader" "k8s.io/kops/upup/pkg/fi/loader"

Some files were not shown because too many files have changed in this diff Show More