提交 68397fbe 编写于 作者: P Piotr Bryk 提交者: Sebastian Florek

Add config map backend (list and details) (#1012)

上级 d21d6b96
......@@ -34,6 +34,7 @@ import (
"github.com/kubernetes/dashboard/src/app/backend/resource/petset"
"github.com/kubernetes/dashboard/src/app/backend/resource/pod"
"github.com/kubernetes/dashboard/src/app/backend/resource/replicaset"
"github.com/kubernetes/dashboard/src/app/backend/resource/configmap"
. "github.com/kubernetes/dashboard/src/app/backend/resource/replicationcontroller"
. "github.com/kubernetes/dashboard/src/app/backend/resource/secret"
resourceService "github.com/kubernetes/dashboard/src/app/backend/resource/service"
......@@ -274,6 +275,19 @@ func CreateHttpApiHandler(client *client.Client, heapsterClient HeapsterClient,
Reads(ImagePullSecretSpec{}).
Writes(Secret{}))
apiV1Ws.Route(
apiV1Ws.GET("/configmap").
To(apiHandler.handleGetConfigMaps).
Writes(configmap.ConfigMapList{}))
apiV1Ws.Route(
apiV1Ws.GET("/configmap/{namespace}").
To(apiHandler.handleGetConfigMaps).
Writes(configmap.ConfigMapList{}))
apiV1Ws.Route(
apiV1Ws.GET("/configmap/{namespace}/{configmap}").
To(apiHandler.handleGetConfigMapDetail).
Writes(configmap.ConfigMapDetail{}))
apiV1Ws.Route(
apiV1Ws.GET("/service").
To(apiHandler.handleGetServiceList).
......@@ -786,6 +800,28 @@ func (apiHandler *ApiHandler) handleGetSecrets(request *restful.Request, respons
response.WriteHeaderAndEntity(http.StatusOK, result)
}
func (apiHandler *ApiHandler) handleGetConfigMaps(request *restful.Request, response *restful.Response) {
namespace := parseNamespacePathParameter(request)
result, err := configmap.GetConfigMapList(apiHandler.client, namespace)
if err != nil {
handleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
func (apiHandler *ApiHandler) handleGetConfigMapDetail(request *restful.Request, response *restful.Response) {
namespace := request.PathParameter("namespace")
service := request.PathParameter("configmap")
result, err := configmap.GetConfigMapDetail(apiHandler.client, namespace, service)
if err != nil {
handleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusCreated, result)
}
// Handles log API call.
func (apiHandler *ApiHandler) handleLogs(request *restful.Request, response *restful.Response) {
namespace := request.PathParameter("namespace")
......
......@@ -40,31 +40,34 @@ type ResourceChannels struct {
ReplicationControllerList ReplicationControllerListChannel
// List and error channels to Replica Sets.
ReplicaSetList ReplicaSetListChannel
ReplicaSetList ReplicaSetListChannel
// List and error channels to Deployments.
DeploymentList DeploymentListChannel
DeploymentList DeploymentListChannel
// List and error channels to Daemon Sets.
DaemonSetList DaemonSetListChannel
DaemonSetList DaemonSetListChannel
// List and error channels to Jobs.
JobList JobListChannel
JobList JobListChannel
// List and error channels to Services.
ServiceList ServiceListChannel
ServiceList ServiceListChannel
// List and error channels to Pods.
PodList PodListChannel
PodList PodListChannel
// List and error channels to Events.
EventList EventListChannel
EventList EventListChannel
// List and error channels to Nodes.
NodeList NodeListChannel
NodeList NodeListChannel
// List and error channels to PetSets.
PetSetList PetSetListChannel
PetSetList PetSetListChannel
// List and error channels to PetSets.
ConfigMapList ConfigMapListChannel
}
// ServiceListChannel is a list and error channels to Services.
......@@ -76,7 +79,7 @@ type ServiceListChannel struct {
// GetServiceListChannel returns a pair of channels to a Service list and errors that both
// must be read numReads times.
func GetServiceListChannel(client client.ServicesNamespacer,
nsQuery *NamespaceQuery, numReads int) ServiceListChannel {
nsQuery *NamespaceQuery, numReads int) ServiceListChannel {
channel := ServiceListChannel{
List: make(chan *api.ServiceList, numReads),
......@@ -134,13 +137,13 @@ type EventListChannel struct {
// GetEventListChannel returns a pair of channels to an Event list and errors that both must be read
// numReads times.
func GetEventListChannel(client client.EventNamespacer,
nsQuery *NamespaceQuery, numReads int) EventListChannel {
nsQuery *NamespaceQuery, numReads int) EventListChannel {
return GetEventListChannelWithOptions(client, nsQuery, listEverything, numReads)
}
// GetEventListChannelWithOptions is GetEventListChannel plus list options.
func GetEventListChannelWithOptions(client client.EventNamespacer,
nsQuery *NamespaceQuery, options api.ListOptions, numReads int) EventListChannel {
nsQuery *NamespaceQuery, options api.ListOptions, numReads int) EventListChannel {
channel := EventListChannel{
List: make(chan *api.EventList, numReads),
Error: make(chan error, numReads),
......@@ -173,13 +176,13 @@ type PodListChannel struct {
// GetPodListChannel returns a pair of channels to a Pod list and errors that both must be read
// numReads times.
func GetPodListChannel(client client.PodsNamespacer,
nsQuery *NamespaceQuery, numReads int) PodListChannel {
nsQuery *NamespaceQuery, numReads int) PodListChannel {
return GetPodListChannelWithOptions(client, nsQuery, listEverything, numReads)
}
// GetPodListChannelWithOptions is GetPodListChannel plus listing options.
func GetPodListChannelWithOptions(client client.PodsNamespacer, nsQuery *NamespaceQuery,
options api.ListOptions, numReads int) PodListChannel {
options api.ListOptions, numReads int) PodListChannel {
channel := PodListChannel{
List: make(chan *api.PodList, numReads),
......@@ -214,7 +217,7 @@ type ReplicationControllerListChannel struct {
// Replication Controller list and errors that both must be read
// numReads times.
func GetReplicationControllerListChannel(client client.ReplicationControllersNamespacer,
nsQuery *NamespaceQuery, numReads int) ReplicationControllerListChannel {
nsQuery *NamespaceQuery, numReads int) ReplicationControllerListChannel {
channel := ReplicationControllerListChannel{
List: make(chan *api.ReplicationControllerList, numReads),
......@@ -248,7 +251,7 @@ type DeploymentListChannel struct {
// GetDeploymentListChannel returns a pair of channels to a Deployment list and errors
// that both must be read numReads times.
func GetDeploymentListChannel(client client.DeploymentsNamespacer,
nsQuery *NamespaceQuery, numReads int) DeploymentListChannel {
nsQuery *NamespaceQuery, numReads int) DeploymentListChannel {
channel := DeploymentListChannel{
List: make(chan *extensions.DeploymentList, numReads),
......@@ -282,14 +285,14 @@ type ReplicaSetListChannel struct {
// GetReplicaSetListChannel returns a pair of channels to a ReplicaSet list and
// errors that both must be read numReads times.
func GetReplicaSetListChannel(client client.ReplicaSetsNamespacer,
nsQuery *NamespaceQuery, numReads int) ReplicaSetListChannel {
nsQuery *NamespaceQuery, numReads int) ReplicaSetListChannel {
return GetReplicaSetListChannelWithOptions(client, nsQuery, listEverything, numReads)
}
// GetReplicaSetListChannelWithOptions returns a pair of channels to a ReplicaSet list filtered
// by provided options and errors that both must be read numReads times.
func GetReplicaSetListChannelWithOptions(client client.ReplicaSetsNamespacer,
nsQuery *NamespaceQuery, options api.ListOptions, numReads int) ReplicaSetListChannel {
nsQuery *NamespaceQuery, options api.ListOptions, numReads int) ReplicaSetListChannel {
channel := ReplicaSetListChannel{
List: make(chan *extensions.ReplicaSetList, numReads),
Error: make(chan error, numReads),
......@@ -322,7 +325,7 @@ type DaemonSetListChannel struct {
// GetDaemonSetListChannel returns a pair of channels to a DaemonSet list and errors that
// both must be read numReads times.
func GetDaemonSetListChannel(client client.DaemonSetsNamespacer,
nsQuery *NamespaceQuery, numReads int) DaemonSetListChannel {
nsQuery *NamespaceQuery, numReads int) DaemonSetListChannel {
channel := DaemonSetListChannel{
List: make(chan *extensions.DaemonSetList, numReads),
Error: make(chan error, numReads),
......@@ -355,7 +358,7 @@ type JobListChannel struct {
// GetJobListChannel returns a pair of channels to a Job list and errors that
// both must be read numReads times.
func GetJobListChannel(client client.JobsNamespacer,
nsQuery *NamespaceQuery, numReads int) JobListChannel {
nsQuery *NamespaceQuery, numReads int) JobListChannel {
channel := JobListChannel{
List: make(chan *batch.JobList, numReads),
Error: make(chan error, numReads),
......@@ -388,7 +391,7 @@ type PetSetListChannel struct {
// GetPetSetListChannel returns a pair of channels to a PetSet list and errors that
// both must be read numReads times.
func GetPetSetListChannel(client client.PetSetNamespacer,
nsQuery *NamespaceQuery, numReads int) PetSetListChannel {
nsQuery *NamespaceQuery, numReads int) PetSetListChannel {
channel := PetSetListChannel{
List: make(chan *apps.PetSetList, numReads),
Error: make(chan error, numReads),
......@@ -412,6 +415,39 @@ func GetPetSetListChannel(client client.PetSetNamespacer,
return channel
}
// ConfigMapListChannel is a list and error channels to ConfigMaps.
type ConfigMapListChannel struct {
List chan *api.ConfigMapList
Error chan error
}
// GetConfigMapListChannel returns a pair of channels to a ConfigMap list and errors that
// both must be read numReads times.
func GetConfigMapListChannel(client client.ConfigMapsNamespacer, nsQuery *NamespaceQuery, numReads int) ConfigMapListChannel {
channel := ConfigMapListChannel{
List: make(chan *api.ConfigMapList, numReads),
Error: make(chan error, numReads),
}
go func() {
list, err := client.ConfigMaps(nsQuery.ToRequestParam()).List(listEverything)
var filteredItems []api.ConfigMap
for _, item := range list.Items {
if nsQuery.Matches(item.ObjectMeta.Namespace) {
filteredItems = append(filteredItems, item)
}
}
list.Items = filteredItems
for i := 0; i < numReads; i++ {
channel.List <- list
channel.Error <- err
}
}()
return channel
}
var listEverything api.ListOptions = api.ListOptions{
LabelSelector: labels.Everything(),
FieldSelector: fields.Everything(),
......
......@@ -106,6 +106,7 @@ const (
ResourceKindPetSet = "petset"
ResourceKindNode = "node"
ResourceKindSecret = "secret"
ResourceKindConfigMap = "configmap"
)
// ClientType represents type of client that is used to perform generic operations on resources.
......@@ -142,6 +143,7 @@ var kindToAPIMapping = map[string]struct {
ResourceKindJob: {"jobs", ClientTypeBatchClient},
ResourceKindNode: {"nodes", ClientTypeDefault},
ResourceKindSecret: {"secrets", ClientTypeDefault},
ResourceKindConfigMap: {"configmaps", ClientTypeDefault},
}
// IsSelectorMatching returns true when an object with the given
......
// Copyright 2015 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 configmap
import (
"log"
"github.com/kubernetes/dashboard/src/app/backend/resource/common"
client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/api"
)
// ConfigMapDetail API resource provides mechanisms to inject containers with configuration data while keeping
// containers agnostic of Kubernetes
type ConfigMapDetail struct {
ObjectMeta common.ObjectMeta `json:"objectMeta"`
TypeMeta common.TypeMeta `json:"typeMeta"`
// Data contains the configuration data.
// Each key must be a valid DNS_SUBDOMAIN with an optional leading dot.
Data map[string]string `json:"data,omitempty"`
}
// GetConfigMapDetail returns returns detailed information about a config map
func GetConfigMapDetail(client *client.Client, namespace, name string) (*ConfigMapDetail, error) {
log.Printf("Getting details of %s config map in %s namespace", name, namespace)
rawConfigMap, err := client.ConfigMaps(namespace).Get(name)
if err != nil {
return nil, err
}
return getConfigMapDetail(rawConfigMap), nil
}
func getConfigMapDetail(rawConfigMap *api.ConfigMap) *ConfigMapDetail {
return &ConfigMapDetail{
ObjectMeta: common.NewObjectMeta(rawConfigMap.ObjectMeta),
TypeMeta: common.NewTypeMeta(common.ResourceKindConfigMap),
Data: rawConfigMap.Data,
}
}
// Copyright 2015 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 configmap
import (
"log"
"github.com/kubernetes/dashboard/src/app/backend/resource/common"
"k8s.io/kubernetes/pkg/api"
client "k8s.io/kubernetes/pkg/client/unversioned"
)
// ConfigMapList contains a list of Config Maps in the cluster.
type ConfigMapList struct {
ListMeta common.ListMeta `json:"listMeta"`
// Unordered list of Config Maps
Items []ConfigMap `json:"items"`
}
// ConfigMap API resource provides mechanisms to inject containers with configuration data while keeping
// containers agnostic of Kubernetes
type ConfigMap struct {
ObjectMeta common.ObjectMeta `json:"objectMeta"`
TypeMeta common.TypeMeta `json:"typeMeta"`
// No additional info in the list object.
}
// GetConfigMapList returns a list of all ConfigMaps in the cluster.
func GetConfigMapList(client *client.Client, nsQuery *common.NamespaceQuery) (*ConfigMapList, error) {
log.Printf("Getting list config maps in the namespace %s", nsQuery.ToRequestParam())
channels := &common.ResourceChannels{
ConfigMapList: common.GetConfigMapListChannel(client, nsQuery, 1),
}
return GetConfigMapListFromChannels(channels)
}
// GetConfigMapListFromChannels returns a list of all Config Maps in the cluster
// reading required resource list once from the channels.
func GetConfigMapListFromChannels(channels *common.ResourceChannels) (
*ConfigMapList, error) {
configMaps := <-channels.ConfigMapList.List
if err := <-channels.ConfigMapList.Error; err != nil {
return nil, err
}
result := getConfigMapList(configMaps.Items)
return result, nil
}
func getConfigMapList(configMaps []api.ConfigMap) *ConfigMapList {
result := &ConfigMapList{
Items: make([]ConfigMap, 0),
ListMeta: common.ListMeta{TotalItems: len(configMaps)},
}
for _, item := range configMaps {
result.Items = append(result.Items,
ConfigMap{
ObjectMeta: common.NewObjectMeta(item.ObjectMeta),
TypeMeta: common.NewTypeMeta(common.ResourceKindConfigMap),
})
}
return result
}
// Copyright 2015 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 configmap
import (
"reflect"
"testing"
"k8s.io/kubernetes/pkg/api"
"github.com/kubernetes/dashboard/src/app/backend/resource/common"
)
func TestGetConfigMapList(t *testing.T) {
cases := []struct {
configMaps []api.ConfigMap
expected *ConfigMapList
}{
{nil, &ConfigMapList{Items: []ConfigMap{}}},
{
[]api.ConfigMap{
{Data: map[string]string{"app": "my-name"}, ObjectMeta: api.ObjectMeta{Name: "foo"}},
},
&ConfigMapList{
ListMeta:common.ListMeta{TotalItems:1},
Items: []ConfigMap{{
TypeMeta: common.TypeMeta{Kind: "configmap"},
ObjectMeta: common.ObjectMeta{Name: "foo"},
}},
},
},
}
for _, c := range cases {
actual := getConfigMapList(c.configMaps)
if !reflect.DeepEqual(actual, c.expected) {
t.Errorf("getConfigMapList(%#v) == \n%#v\nexpected \n%#v\n",
c.configMaps, actual, c.expected)
}
}
}
// Copyright 2015 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 configmap
import (
"reflect"
"testing"
"k8s.io/kubernetes/pkg/api"
"github.com/kubernetes/dashboard/src/app/backend/resource/common"
)
func TestGetConfigMapDetail(t *testing.T) {
cases := []struct {
configMaps *api.ConfigMap
expected *ConfigMapDetail
}{
{
&api.ConfigMap{
Data: map[string]string{"app": "my-name"}, ObjectMeta: api.ObjectMeta{Name: "foo"},
},
&ConfigMapDetail{
TypeMeta: common.TypeMeta{Kind: "configmap"},
ObjectMeta: common.ObjectMeta{Name: "foo"},
Data: map[string]string{"app": "my-name"},
},
},
}
for _, c := range cases {
actual := getConfigMapDetail(c.configMaps)
if !reflect.DeepEqual(actual, c.expected) {
t.Errorf("getConfigMapDetail(%#v) == \n%#v\nexpected \n%#v\n",
c.configMaps, actual, c.expected)
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册