Commit 7bff03fb authored by bgrant0607's avatar bgrant0607

Merge pull request #2878 from smarterclayton/enable_v1beta3

Enable v1beta3 API via --runtime_config=api/v1beta3 flag
parents 812e8346 7fd887df
...@@ -82,6 +82,7 @@ var ( ...@@ -82,6 +82,7 @@ var (
allowPrivileged = flag.Bool("allow_privileged", false, "If true, allow privileged containers.") allowPrivileged = flag.Bool("allow_privileged", false, "If true, allow privileged containers.")
portalNet util.IPNet // TODO: make this a list portalNet util.IPNet // TODO: make this a list
enableLogsSupport = flag.Bool("enable_logs_support", true, "Enables server endpoint for log collection") enableLogsSupport = flag.Bool("enable_logs_support", true, "Enables server endpoint for log collection")
runtimeConfig util.ConfigurationMap
kubeletConfig = client.KubeletConfig{ kubeletConfig = client.KubeletConfig{
Port: 10250, Port: 10250,
EnableHttps: false, EnableHttps: false,
...@@ -89,10 +90,13 @@ var ( ...@@ -89,10 +90,13 @@ var (
) )
func init() { func init() {
runtimeConfig = make(util.ConfigurationMap)
flag.Var(&address, "address", "The IP address on to serve on (set to 0.0.0.0 for all interfaces)") flag.Var(&address, "address", "The IP address on to serve on (set to 0.0.0.0 for all interfaces)")
flag.Var(&etcdServerList, "etcd_servers", "List of etcd servers to watch (http://ip:port), comma separated. Mutually exclusive with -etcd_config") flag.Var(&etcdServerList, "etcd_servers", "List of etcd servers to watch (http://ip:port), comma separated. Mutually exclusive with -etcd_config")
flag.Var(&corsAllowedOriginList, "cors_allowed_origins", "List of allowed origins for CORS, comma separated. An allowed origin can be a regular expression to support subdomain matching. If this list is empty CORS will not be enabled.") flag.Var(&corsAllowedOriginList, "cors_allowed_origins", "List of allowed origins for CORS, comma separated. An allowed origin can be a regular expression to support subdomain matching. If this list is empty CORS will not be enabled.")
flag.Var(&portalNet, "portal_net", "A CIDR notation IP range from which to assign portal IPs. This must not overlap with any IP ranges assigned to nodes for pods.") flag.Var(&portalNet, "portal_net", "A CIDR notation IP range from which to assign portal IPs. This must not overlap with any IP ranges assigned to nodes for pods.")
flag.Var(&runtimeConfig, "runtime_config", "A set of key=value pairs that describe runtime configuration that may be passed to the apiserver.")
client.BindKubeletClientConfigFlags(flag.CommandLine, &kubeletConfig) client.BindKubeletClientConfigFlags(flag.CommandLine, &kubeletConfig)
} }
...@@ -140,6 +144,8 @@ func main() { ...@@ -140,6 +144,8 @@ func main() {
glog.Fatalf("Failure to start kubelet client: %v", err) glog.Fatalf("Failure to start kubelet client: %v", err)
} }
_, v1beta3 := runtimeConfig["api/v1beta3"]
// TODO: expose same flags as client.BindClientConfigFlags but for a server // TODO: expose same flags as client.BindClientConfigFlags but for a server
clientConfig := &client.Config{ clientConfig := &client.Config{
Host: net.JoinHostPort(address.String(), strconv.Itoa(int(*port))), Host: net.JoinHostPort(address.String(), strconv.Itoa(int(*port))),
...@@ -189,6 +195,7 @@ func main() { ...@@ -189,6 +195,7 @@ func main() {
Authenticator: authenticator, Authenticator: authenticator,
Authorizer: authorizer, Authorizer: authorizer,
AdmissionControl: admissionController, AdmissionControl: admissionController,
EnableV1Beta3: v1beta3,
} }
m := master.New(config) m := master.New(config)
......
...@@ -92,6 +92,7 @@ sudo "${GO_OUT}/kube-apiserver" \ ...@@ -92,6 +92,7 @@ sudo "${GO_OUT}/kube-apiserver" \
-v=${LOG_LEVEL} \ -v=${LOG_LEVEL} \
--address="${API_HOST}" \ --address="${API_HOST}" \
--port="${API_PORT}" \ --port="${API_PORT}" \
--runtime_config=api/v1beta3 \
--etcd_servers="http://127.0.0.1:4001" \ --etcd_servers="http://127.0.0.1:4001" \
--portal_net="10.0.0.0/24" \ --portal_net="10.0.0.0/24" \
--cors_allowed_origins="${API_CORS_ALLOWED_ORIGINS}" >"${APISERVER_LOG}" 2>&1 & --cors_allowed_origins="${API_CORS_ALLOWED_ORIGINS}" >"${APISERVER_LOG}" 2>&1 &
......
...@@ -74,6 +74,7 @@ kube::log::status "Starting kube-apiserver" ...@@ -74,6 +74,7 @@ kube::log::status "Starting kube-apiserver"
--etcd_servers="http://${ETCD_HOST}:${ETCD_PORT}" \ --etcd_servers="http://${ETCD_HOST}:${ETCD_PORT}" \
--public_address_override="127.0.0.1" \ --public_address_override="127.0.0.1" \
--kubelet_port=${KUBELET_PORT} \ --kubelet_port=${KUBELET_PORT} \
--runtime_config=api/v1beta3 \
--portal_net="10.0.0.0/24" 1>&2 & --portal_net="10.0.0.0/24" 1>&2 &
APISERVER_PID=$! APISERVER_PID=$!
...@@ -87,6 +88,7 @@ kube::log::status "Starting CONTROLLER-MANAGER" ...@@ -87,6 +88,7 @@ kube::log::status "Starting CONTROLLER-MANAGER"
CTLRMGR_PID=$! CTLRMGR_PID=$!
kube::util::wait_for_url "http://127.0.0.1:${CTLRMGR_PORT}/healthz" "controller-manager: " kube::util::wait_for_url "http://127.0.0.1:${CTLRMGR_PORT}/healthz" "controller-manager: "
kube::util::wait_for_url "http://127.0.0.1:${API_PORT}/api/v1beta1/minions/127.0.0.1" "apiserver(minions): " 0.2 25
kube_cmd=( kube_cmd=(
"${KUBE_OUTPUT_HOSTBIN}/kubectl" "${KUBE_OUTPUT_HOSTBIN}/kubectl"
...@@ -94,6 +96,7 @@ kube_cmd=( ...@@ -94,6 +96,7 @@ kube_cmd=(
kube_api_versions=( kube_api_versions=(
v1beta1 v1beta1
v1beta2 v1beta2
v1beta3
) )
for version in "${kube_api_versions[@]}"; do for version in "${kube_api_versions[@]}"; do
kube_flags=( kube_flags=(
...@@ -102,7 +105,7 @@ for version in "${kube_api_versions[@]}"; do ...@@ -102,7 +105,7 @@ for version in "${kube_api_versions[@]}"; do
--api-version="${version}" --api-version="${version}"
) )
kube::log::status "Testing kubectl(pods)" kube::log::status "Testing kubectl(${version}:pods)"
"${kube_cmd[@]}" get pods "${kube_flags[@]}" "${kube_cmd[@]}" get pods "${kube_flags[@]}"
"${kube_cmd[@]}" create -f examples/guestbook/redis-master.json "${kube_flags[@]}" "${kube_cmd[@]}" create -f examples/guestbook/redis-master.json "${kube_flags[@]}"
"${kube_cmd[@]}" get pods "${kube_flags[@]}" "${kube_cmd[@]}" get pods "${kube_flags[@]}"
...@@ -110,34 +113,36 @@ for version in "${kube_api_versions[@]}"; do ...@@ -110,34 +113,36 @@ for version in "${kube_api_versions[@]}"; do
[[ "$("${kube_cmd[@]}" get pod redis-master -o template --output-version=v1beta1 -t '{{ .id }}' "${kube_flags[@]}")" == "redis-master" ]] [[ "$("${kube_cmd[@]}" get pod redis-master -o template --output-version=v1beta1 -t '{{ .id }}' "${kube_flags[@]}")" == "redis-master" ]]
output_pod=$("${kube_cmd[@]}" get pod redis-master -o json --output-version=v1beta1 "${kube_flags[@]}") output_pod=$("${kube_cmd[@]}" get pod redis-master -o json --output-version=v1beta1 "${kube_flags[@]}")
"${kube_cmd[@]}" delete pod redis-master "${kube_flags[@]}" "${kube_cmd[@]}" delete pod redis-master "${kube_flags[@]}"
before="$("${kube_cmd[@]}" get pods -o template -t '{{ len .items }}' "${kube_flags[@]}")" before="$("${kube_cmd[@]}" get pods -o template -t "{{ len .items }}" "${kube_flags[@]}")"
echo $output_pod | "${kube_cmd[@]}" create -f - "${kube_flags[@]}" echo $output_pod | "${kube_cmd[@]}" create -f - "${kube_flags[@]}"
after="$("${kube_cmd[@]}" get pods -o template -t '{{ len .items }}' "${kube_flags[@]}")" after="$("${kube_cmd[@]}" get pods -o template -t "{{ len .items }}" "${kube_flags[@]}")"
[[ "$((${after} - ${before}))" -eq 1 ]] [[ "$((${after} - ${before}))" -eq 1 ]]
"${kube_cmd[@]}" get pods -o yaml "${kube_flags[@]}" | grep -q "id: redis-master" "${kube_cmd[@]}" get pods -o yaml --output-version=v1beta1 "${kube_flags[@]}" | grep -q "id: redis-master"
"${kube_cmd[@]}" describe pod redis-master "${kube_flags[@]}" | grep -q 'Name:.*redis-master' "${kube_cmd[@]}" describe pod redis-master "${kube_flags[@]}" | grep -q 'Name:.*redis-master'
"${kube_cmd[@]}" delete -f examples/guestbook/redis-master.json "${kube_flags[@]}" "${kube_cmd[@]}" delete -f examples/guestbook/redis-master.json "${kube_flags[@]}"
kube::log::status "Testing kubectl(services)" kube::log::status "Testing kubectl(${version}:services)"
"${kube_cmd[@]}" get services "${kube_flags[@]}" "${kube_cmd[@]}" get services "${kube_flags[@]}"
"${kube_cmd[@]}" create -f examples/guestbook/frontend-service.json "${kube_flags[@]}" "${kube_cmd[@]}" create -f examples/guestbook/frontend-service.json "${kube_flags[@]}"
"${kube_cmd[@]}" get services "${kube_flags[@]}" "${kube_cmd[@]}" get services "${kube_flags[@]}"
"${kube_cmd[@]}" delete service frontend "${kube_flags[@]}" "${kube_cmd[@]}" delete service frontend "${kube_flags[@]}"
kube::log::status "Testing kubectl(replicationcontrollers)" kube::log::status "Testing kubectl(${version}:replicationcontrollers)"
"${kube_cmd[@]}" get replicationcontrollers "${kube_flags[@]}" "${kube_cmd[@]}" get replicationcontrollers "${kube_flags[@]}"
"${kube_cmd[@]}" create -f examples/guestbook/frontend-controller.json "${kube_flags[@]}" "${kube_cmd[@]}" create -f examples/guestbook/frontend-controller.json "${kube_flags[@]}"
"${kube_cmd[@]}" get replicationcontrollers "${kube_flags[@]}" "${kube_cmd[@]}" get replicationcontrollers "${kube_flags[@]}"
"${kube_cmd[@]}" describe replicationcontroller frontendController "${kube_flags[@]}" | grep -q 'Replicas:.*3 desired' "${kube_cmd[@]}" describe replicationcontroller frontendController "${kube_flags[@]}" | grep -q 'Replicas:.*3 desired'
"${kube_cmd[@]}" delete rc frontendController "${kube_flags[@]}" "${kube_cmd[@]}" delete rc frontendController "${kube_flags[@]}"
kube::log::status "Testing kubectl(minions)" kube::log::status "Testing kubectl(${version}:nodes)"
"${kube_cmd[@]}" get minions "${kube_flags[@]}"
"${kube_cmd[@]}" get minions 127.0.0.1 "${kube_flags[@]}"
kube::log::status "Testing kubectl(nodes)"
"${kube_cmd[@]}" get nodes "${kube_flags[@]}" "${kube_cmd[@]}" get nodes "${kube_flags[@]}"
"${kube_cmd[@]}" describe nodes 127.0.0.1 "${kube_flags[@]}" "${kube_cmd[@]}" describe nodes 127.0.0.1 "${kube_flags[@]}"
if [[ "${version}" != "v1beta3" ]]; then
kube::log::status "Testing kubectl(${version}:minions)"
"${kube_cmd[@]}" get minions "${kube_flags[@]}"
"${kube_cmd[@]}" get minions 127.0.0.1 "${kube_flags[@]}"
fi
done done
kube::log::status "TEST PASSED" kube::log::status "TEST PASSED"
...@@ -24,6 +24,7 @@ import ( ...@@ -24,6 +24,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
) )
...@@ -38,7 +39,7 @@ const OldestVersion = "v1beta1" ...@@ -38,7 +39,7 @@ const OldestVersion = "v1beta1"
// may be assumed to be least feature rich to most feature rich, and clients may // may be assumed to be least feature rich to most feature rich, and clients may
// choose to prefer the latter items in the list over the former items when presented // choose to prefer the latter items in the list over the former items when presented
// with a set of versions to choose. // with a set of versions to choose.
var Versions = []string{"v1beta1", "v1beta2"} var Versions = []string{"v1beta1", "v1beta2", "v1beta3"}
// Codec is the default codec for serializing output that should use // Codec is the default codec for serializing output that should use
// the latest supported version. Use this Codec when writing to // the latest supported version. Use this Codec when writing to
...@@ -80,6 +81,12 @@ func InterfacesFor(version string) (*meta.VersionInterfaces, error) { ...@@ -80,6 +81,12 @@ func InterfacesFor(version string) (*meta.VersionInterfaces, error) {
ObjectConvertor: api.Scheme, ObjectConvertor: api.Scheme,
MetadataAccessor: accessor, MetadataAccessor: accessor,
}, nil }, nil
case "v1beta3":
return &meta.VersionInterfaces{
Codec: v1beta3.Codec,
ObjectConvertor: api.Scheme,
MetadataAccessor: accessor,
}, nil
default: default:
return nil, fmt.Errorf("unsupported storage version: %s (valid: %s)", version, strings.Join(Versions, ", ")) return nil, fmt.Errorf("unsupported storage version: %s (valid: %s)", version, strings.Join(Versions, ", "))
} }
...@@ -96,7 +103,7 @@ func init() { ...@@ -96,7 +103,7 @@ func init() {
return interfaces, true return interfaces, true
}, },
) )
mapper.Add(api.Scheme, true, Versions...) mapper.Add(api.Scheme, true, "v1beta1", "v1beta2")
// TODO: when v1beta3 is added it will not use mixed case. mapper.Add(api.Scheme, false, "v1beta3")
RESTMapper = mapper RESTMapper = mapper
} }
...@@ -103,6 +103,7 @@ type Request struct { ...@@ -103,6 +103,7 @@ type Request struct {
// structural elements of the request that are part of the Kubernetes API conventions // structural elements of the request that are part of the Kubernetes API conventions
namespace string namespace string
namespaceSet bool
resource string resource string
resourceName string resourceName string
selector labels.Selector selector labels.Selector
...@@ -190,10 +191,11 @@ func (r *Request) Namespace(namespace string) *Request { ...@@ -190,10 +191,11 @@ func (r *Request) Namespace(namespace string) *Request {
if r.err != nil { if r.err != nil {
return r return r
} }
if len(r.namespace) != 0 { if r.namespaceSet {
r.err = fmt.Errorf("namespace already set to %q, cannot change to %q", r.namespace, namespace) r.err = fmt.Errorf("namespace already set to %q, cannot change to %q", r.namespace, namespace)
return r return r
} }
r.namespaceSet = true
r.namespace = namespace r.namespace = namespace
return r return r
} }
...@@ -330,7 +332,7 @@ func (r *Request) Poller(poller PollFunc) *Request { ...@@ -330,7 +332,7 @@ func (r *Request) Poller(poller PollFunc) *Request {
func (r *Request) finalURL() string { func (r *Request) finalURL() string {
p := r.path p := r.path
if !r.namespaceInQuery { if r.namespaceSet && !r.namespaceInQuery && len(r.namespace) > 0 {
p = path.Join(p, "ns", r.namespace) p = path.Join(p, "ns", r.namespace)
} }
if len(r.resource) != 0 { if len(r.resource) != 0 {
...@@ -353,7 +355,7 @@ func (r *Request) finalURL() string { ...@@ -353,7 +355,7 @@ func (r *Request) finalURL() string {
query.Add(key, value) query.Add(key, value)
} }
if r.namespaceInQuery && len(r.namespace) > 0 { if r.namespaceSet && r.namespaceInQuery && len(r.namespace) > 0 {
query.Add("namespace", r.namespace) query.Add("namespace", r.namespace)
} }
......
...@@ -86,6 +86,11 @@ func TestRequestAbsPathPreservesTrailingSlash(t *testing.T) { ...@@ -86,6 +86,11 @@ func TestRequestAbsPathPreservesTrailingSlash(t *testing.T) {
if s := r.finalURL(); s != "/foo/" { if s := r.finalURL(); s != "/foo/" {
t.Errorf("trailing slash should be preserved: %s", s) t.Errorf("trailing slash should be preserved: %s", s)
} }
r = (&Request{baseURL: &url.URL{}}).AbsPath("/foo/")
if s := r.finalURL(); s != "/foo/" {
t.Errorf("trailing slash should be preserved: %s", s)
}
} }
func TestRequestAbsPathJoins(t *testing.T) { func TestRequestAbsPathJoins(t *testing.T) {
......
...@@ -27,6 +27,7 @@ import ( ...@@ -27,6 +27,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
) )
...@@ -40,7 +41,8 @@ func TestSetsCodec(t *testing.T) { ...@@ -40,7 +41,8 @@ func TestSetsCodec(t *testing.T) {
"v1beta1": {false, "/api/v1beta1/", v1beta1.Codec}, "v1beta1": {false, "/api/v1beta1/", v1beta1.Codec},
"": {false, "/api/v1beta1/", v1beta1.Codec}, "": {false, "/api/v1beta1/", v1beta1.Codec},
"v1beta2": {false, "/api/v1beta2/", v1beta2.Codec}, "v1beta2": {false, "/api/v1beta2/", v1beta2.Codec},
"v1beta3": {true, "", nil}, "v1beta3": {false, "/api/v1beta3/", v1beta3.Codec},
"v1beta4": {true, "", nil},
} }
for version, expected := range testCases { for version, expected := range testCases {
client, err := New(&Config{Host: "127.0.0.1", Version: version}) client, err := New(&Config{Host: "127.0.0.1", Version: version})
......
...@@ -457,6 +457,10 @@ func (c *Converter) defaultConvert(sv, dv reflect.Value, scope *scope) error { ...@@ -457,6 +457,10 @@ func (c *Converter) defaultConvert(sv, dv reflect.Value, scope *scope) error {
} }
dkv := reflect.New(dt.Elem()).Elem() dkv := reflect.New(dt.Elem()).Elem()
scope.setKeys(sk.Interface(), dk.Interface()) scope.setKeys(sk.Interface(), dk.Interface())
// TODO: sv.MapIndex(sk) may return a value with CanAddr() == false,
// because a map[string]struct{} does not allow a pointer reference.
// Calling a custom conversion function defined for the map value
// will panic. Example is PodInfo map[string]ContainerStatus.
if err := c.convert(sv.MapIndex(sk), dkv, scope); err != nil { if err := c.convert(sv.MapIndex(sk), dkv, scope); err != nil {
return err return err
} }
......
...@@ -21,9 +21,13 @@ import ( ...@@ -21,9 +21,13 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"reflect" "reflect"
"strings"
"testing" "testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
) )
// Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get. // Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get.
...@@ -50,3 +54,31 @@ func TestGetUnknownSchemaObject(t *testing.T) { ...@@ -50,3 +54,31 @@ func TestGetUnknownSchemaObject(t *testing.T) {
t.Errorf("unexpected output: %s", buf.String()) t.Errorf("unexpected output: %s", buf.String())
} }
} }
// Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get.
func TestGetSchemaObject(t *testing.T) {
f, tf, _ := NewTestFactory()
f.Mapper = latest.RESTMapper
f.Typer = api.Scheme
codec := latest.Codec
tf.Printer = &testPrinter{}
tf.Client = &client.FakeRESTClient{
Codec: codec,
Resp: &http.Response{StatusCode: 200, Body: objBody(codec, &api.ReplicationController{ObjectMeta: api.ObjectMeta{Name: "foo"}})},
}
buf := bytes.NewBuffer([]byte{})
cmd := f.NewCmdGet(buf)
cmd.Flags().String("api-version", "v1beta3", "")
cmd.Flags().String("namespace", "test", "")
cmd.Run(cmd, []string{"replicationcontrollers", "foo"})
expected := &api.ReplicationController{ObjectMeta: api.ObjectMeta{Name: "foo"}, Spec: api.ReplicationControllerSpec{Template: &api.PodTemplateSpec{}}}
actual := tf.Printer.(*testPrinter).Obj
if !reflect.DeepEqual(expected, actual) {
t.Errorf("unexpected object: %s", util.ObjectGoPrintDiff(expected, actual))
}
if !strings.Contains(buf.String(), "\"foo\"") {
t.Errorf("unexpected output: %s", buf.String())
}
}
...@@ -33,6 +33,7 @@ import ( ...@@ -33,6 +33,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3"
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
"github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authenticator" "github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authenticator"
"github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authorizer" "github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authorizer"
...@@ -72,6 +73,7 @@ type Config struct { ...@@ -72,6 +73,7 @@ type Config struct {
EnableLogsSupport bool EnableLogsSupport bool
EnableUISupport bool EnableUISupport bool
EnableSwaggerSupport bool EnableSwaggerSupport bool
EnableV1Beta3 bool
APIPrefix string APIPrefix string
CorsAllowedOriginList util.StringList CorsAllowedOriginList util.StringList
Authenticator authenticator.Request Authenticator authenticator.Request
...@@ -122,6 +124,7 @@ type Master struct { ...@@ -122,6 +124,7 @@ type Master struct {
authorizer authorizer.Authorizer authorizer authorizer.Authorizer
admissionControl admission.Interface admissionControl admission.Interface
masterCount int masterCount int
v1beta3 bool
readOnlyServer string readOnlyServer string
readWriteServer string readWriteServer string
...@@ -252,6 +255,7 @@ func New(c *Config) *Master { ...@@ -252,6 +255,7 @@ func New(c *Config) *Master {
authenticator: c.Authenticator, authenticator: c.Authenticator,
authorizer: c.Authorizer, authorizer: c.Authorizer,
admissionControl: c.AdmissionControl, admissionControl: c.AdmissionControl,
v1beta3: c.EnableV1Beta3,
masterCount: c.MasterCount, masterCount: c.MasterCount,
readOnlyServer: net.JoinHostPort(c.PublicAddress, strconv.Itoa(int(c.ReadOnlyPort))), readOnlyServer: net.JoinHostPort(c.PublicAddress, strconv.Itoa(int(c.ReadOnlyPort))),
...@@ -353,11 +357,16 @@ func (m *Master) init(c *Config) { ...@@ -353,11 +357,16 @@ func (m *Master) init(c *Config) {
"bindings": binding.NewREST(m.bindingRegistry), "bindings": binding.NewREST(m.bindingRegistry),
} }
versionHandler := apiserver.APIVersionHandler("v1beta1", "v1beta2")
apiserver.NewAPIGroupVersion(m.API_v1beta1()).InstallREST(m.handlerContainer, c.APIPrefix, "v1beta1") apiserver.NewAPIGroupVersion(m.API_v1beta1()).InstallREST(m.handlerContainer, c.APIPrefix, "v1beta1")
apiserver.NewAPIGroupVersion(m.API_v1beta2()).InstallREST(m.handlerContainer, c.APIPrefix, "v1beta2") apiserver.NewAPIGroupVersion(m.API_v1beta2()).InstallREST(m.handlerContainer, c.APIPrefix, "v1beta2")
if c.EnableV1Beta3 {
apiserver.NewAPIGroupVersion(m.API_v1beta3()).InstallREST(m.handlerContainer, c.APIPrefix, "v1beta3")
versionHandler = apiserver.APIVersionHandler("v1beta1", "v1beta2", "v1beta3")
}
// TODO: InstallREST should register each version automatically // TODO: InstallREST should register each version automatically
versionHandler := apiserver.APIVersionHandler("v1beta1", "v1beta2")
m.rootWebService.Route(m.rootWebService.GET(c.APIPrefix).To(versionHandler)) m.rootWebService.Route(m.rootWebService.GET(c.APIPrefix).To(versionHandler))
apiserver.InstallSupport(m.handlerContainer, m.rootWebService) apiserver.InstallSupport(m.handlerContainer, m.rootWebService)
...@@ -482,3 +491,15 @@ func (m *Master) API_v1beta2() (map[string]apiserver.RESTStorage, runtime.Codec, ...@@ -482,3 +491,15 @@ func (m *Master) API_v1beta2() (map[string]apiserver.RESTStorage, runtime.Codec,
} }
return storage, v1beta2.Codec, "/api/v1beta2", latest.SelfLinker, m.admissionControl return storage, v1beta2.Codec, "/api/v1beta2", latest.SelfLinker, m.admissionControl
} }
// API_v1beta3 returns the resources and codec for API version v1beta3.
func (m *Master) API_v1beta3() (map[string]apiserver.RESTStorage, runtime.Codec, string, runtime.SelfLinker, admission.Interface) {
storage := make(map[string]apiserver.RESTStorage)
for k, v := range m.storage {
if k == "minions" {
continue
}
storage[strings.ToLower(k)] = v
}
return storage, v1beta3.Codec, "/api/v1beta3", latest.SelfLinker, m.admissionControl
}
/*
Copyright 2014 Google Inc. All rights reserved.
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 util
import (
"fmt"
"sort"
"strings"
)
type ConfigurationMap map[string]string
func (m *ConfigurationMap) String() string {
pairs := []string{}
for k, v := range *m {
pairs = append(pairs, fmt.Sprintf("%s=%s", k, v))
}
sort.Strings(pairs)
return strings.Join(pairs, ",")
}
func (m *ConfigurationMap) Set(value string) error {
for _, s := range strings.Split(value, ",") {
if len(s) == 0 {
continue
}
arr := strings.SplitN(s, "=", 2)
if len(arr) == 2 {
(*m)[arr[0]] = arr[1]
} else {
(*m)[arr[0]] = ""
}
}
return nil
}
func (*ConfigurationMap) Type() string {
return "mapStringString"
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment