Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for User Links add through annotations for Pods and Services #2249

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions i18n/messages-en.xtb
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,7 @@
<translation id="3180983899887518304" key="MSG_POD_DETAIL_DETAIL_3" desc="Subtitle at the top of the container details.">Init Containers</translation>
<translation id="855512770998820017" key="MSG_POD_DETAIL_INFO_0" desc="Header in a detail view">Details</translation>
<translation id="1457675883548195036" key="MSG_POD_DETAIL_INFO_1" desc="Label \'Status\' for the pod status in details part (left) of the pod details view.">Status</translation>
<translation id="4777332816950119819" key="MSG_POD_DETAIL_INFO_2" desc="Subtitle \'User links\' at the top of the column about user links attached in resource objects annotations, (right) at the pod detail view.">User links</translation>
<translation id="694126564552626450" key="MSG_POD_DETAIL_INFO_3" desc="Subtitle \'Network\' at the top of the column about network connectivity (right) at the pod detail view.">Network</translation>
<translation id="7855013997463493128" key="MSG_POD_DETAIL_INFO_4" desc="Label \'Node\' for the node a pods is running on, appears in the connectivity part (right) of the pod details view.">Node</translation>
<translation id="7683783814970718475" key="MSG_POD_DETAIL_INFO_5" desc="Label \'IP\' for the pod internal IP, appears in the connectivity part (right) of the pod details view.">IP</translation>
Expand Down Expand Up @@ -822,6 +823,7 @@
<translation id="4993540105836483919" key="MSG_SERVICE_DETAIL_INFO_5" desc="Label \'Internal endpoints\' for the internal endpoints of the service, appears in the connectivity part (right) of the service details view.">Internal endpoints</translation>
<translation id="314633649096123526" key="MSG_SERVICE_DETAIL_INFO_6" desc="Label \'External endpoints\' for the external endpoints of the service, appears in the connectivity part (right) of the service details view.">External endpoints</translation>
<translation id="4558893031510551107" key="MSG_SERVICE_DETAIL_INFO_7" desc="Label \'Session Affinity\' for the service type in the details part (left) of the service details view.">Session Affinity</translation>
<translation id="7920121929307714546" key="MSG_SERVICE_DETAIL_INFO_8" desc="Subtitle \'User links\' at the top of the column about user links attached to resource objects annotations, (right) at the service detail view.">User links</translation>
<translation id="1726750954635562524" key="MSG_SERVICE_LIST_CARDLIST_0" desc="Label which appears above the list of such objects.">Services</translation>
<translation id="5124961947121108258" key="MSG_SERVICE_LIST_CARDLIST_1" desc="Label \'Name\' which appears as a column label in the table of services (service list view).">Name</translation>
<translation id="520133206236868567" key="MSG_SERVICE_LIST_CARDLIST_2" desc="Label \'Namespace\' which appears as a column label in the table of services (service list view).">Namespace</translation>
Expand Down
2 changes: 2 additions & 0 deletions i18n/messages-ja.xtb
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,7 @@
<translation id="3180983899887518304" key="MSG_POD_DETAIL_DETAIL_3" desc="Subtitle at the top of the container details.">初期コンテナ</translation>
<translation id="855512770998820017" key="MSG_POD_DETAIL_INFO_0" desc="Header in a detail view">詳細</translation>
<translation id="1457675883548195036" key="MSG_POD_DETAIL_INFO_1" desc="Label \'Status\' for the pod status in details part (left) of the pod details view.">状態</translation>
<translation id="4777332816950119819" key="MSG_POD_DETAIL_INFO_2" desc="Subtitle \'User links\' at the top of the column about user links attached in resource objects annotations, (right) at the pod detail view.">User links</translation>
<translation id="694126564552626450" key="MSG_POD_DETAIL_INFO_3" desc="Subtitle \'Network\' at the top of the column about network connectivity (right) at the pod detail view.">ネットワーク</translation>
<translation id="7855013997463493128" key="MSG_POD_DETAIL_INFO_4" desc="Label \'Node\' for the node a pods is running on, appears in the connectivity part (right) of the pod details view.">ノード</translation>
<translation id="7683783814970718475" key="MSG_POD_DETAIL_INFO_5" desc="Label \'IP\' for the pod internal IP, appears in the connectivity part (right) of the pod details view.">IP</translation>
Expand Down Expand Up @@ -856,6 +857,7 @@
<translation id="4993540105836483919" key="MSG_SERVICE_DETAIL_INFO_5" desc="Label \'Internal endpoints\' for the internal endpoints of the service, appears in the connectivity part (right) of the service details view.">内部エンドポイント</translation>
<translation id="314633649096123526" key="MSG_SERVICE_DETAIL_INFO_6" desc="Label \'External endpoints\' for the external endpoints of the service, appears in the connectivity part (right) of the service details view.">外部エンドポイント</translation>
<translation id="4558893031510551107" key="MSG_SERVICE_DETAIL_INFO_7" desc="Label \'Session Affinity\' for the service type in the details part (left) of the service details view.">Session Affinity</translation>
<translation id="7920121929307714546" key="MSG_SERVICE_DETAIL_INFO_8" desc="Subtitle \'User links\' at the top of the column about user links attached to resource objects annotations, (right) at the service detail view.">User links</translation>
<translation id="1726750954635562524" key="MSG_SERVICE_LIST_CARDLIST_0" desc="Label which appears above the list of such objects.">サービス</translation>
<translation id="5124961947121108258" key="MSG_SERVICE_LIST_CARDLIST_1" desc="Label \'Name\' which appears as a column label in the table of services (service list view).">名前</translation>
<translation id="520133206236868567" key="MSG_SERVICE_LIST_CARDLIST_2" desc="Label \'Namespace\' which appears as a column label in the table of services (service list view).">ネームスペース</translation>
Expand Down
2 changes: 2 additions & 0 deletions i18n/messages-zh.xtb
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,7 @@
<translation id="3180983899887518304" key="MSG_POD_DETAIL_DETAIL_3" desc="Subtitle at the top of the container details.">初始化容器</translation>
<translation id="855512770998820017" key="MSG_POD_DETAIL_INFO_0" desc="Header in a detail view">详情</translation>
<translation id="1457675883548195036" key="MSG_POD_DETAIL_INFO_1" desc="Label \'Status\' for the pod status in details part (left) of the pod details view.">状态</translation>
<translation id="4777332816950119819" key="MSG_POD_DETAIL_INFO_2" desc="Subtitle \'User links\' at the top of the column about user links attached in resource objects annotations, (right) at the pod detail view.">User links</translation>
<translation id="694126564552626450" key="MSG_POD_DETAIL_INFO_3" desc="Subtitle \'Network\' at the top of the column about network connectivity (right) at the pod detail view.">网络</translation>
<translation id="7855013997463493128" key="MSG_POD_DETAIL_INFO_4" desc="Label \'Node\' for the node a pods is running on, appears in the connectivity part (right) of the pod details view.">节点</translation>
<translation id="7683783814970718475" key="MSG_POD_DETAIL_INFO_5" desc="Label \'IP\' for the pod internal IP, appears in the connectivity part (right) of the pod details view.">IP</translation>
Expand Down Expand Up @@ -822,6 +823,7 @@
<translation id="4993540105836483919" key="MSG_SERVICE_DETAIL_INFO_5" desc="Label \'Internal endpoints\' for the internal endpoints of the service, appears in the connectivity part (right) of the service details view.">内部入口</translation>
<translation id="314633649096123526" key="MSG_SERVICE_DETAIL_INFO_6" desc="Label \'External endpoints\' for the external endpoints of the service, appears in the connectivity part (right) of the service details view.">外部入口</translation>
<translation id="4558893031510551107" key="MSG_SERVICE_DETAIL_INFO_7" desc="Label \'Session Affinity\' for the service type in the details part (left) of the service details view.">Session Affinity</translation>
<translation id="7920121929307714546" key="MSG_SERVICE_DETAIL_INFO_8" desc="Subtitle \'User links\' at the top of the column about user links attached to resource objects annotations, (right) at the service detail view.">User links</translation>
<translation id="1726750954635562524" key="MSG_SERVICE_LIST_CARDLIST_0" desc="Label which appears above the list of such objects.">服务</translation>
<translation id="5124961947121108258" key="MSG_SERVICE_LIST_CARDLIST_1" desc="Label \'Name\' which appears as a column label in the table of services (service list view).">名称</translation>
<translation id="520133206236868567" key="MSG_SERVICE_LIST_CARDLIST_2" desc="Label \'Namespace\' which appears as a column label in the table of services (service list view).">命名空间</translation>
Expand Down
20 changes: 17 additions & 3 deletions src/app/backend/handler/apihandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,10 @@ func CreateHTTPAPIHandler(iManager integration.IntegrationManager, cManager clie
apiV1Ws.GET("/service/{namespace}").
To(apiHandler.handleGetServiceList).
Writes(resourceService.ServiceList{}))
apiV1Ws.Route(
apiV1Ws.GET("/service/{namespace}/{service}/endpoint").
To(apiHandler.handleGetServiceEndpoints).
Writes(endpoint.EndpointList{}))
apiV1Ws.Route(
apiV1Ws.GET("/service/{namespace}/{service}").
To(apiHandler.handleGetServiceDetail).
Expand Down Expand Up @@ -750,12 +754,17 @@ func (apiHandler *APIHandler) handleGetServiceDetail(request *restful.Request, r
handleInternalError(response, err)
return
}

config, err := apiHandler.cManager.Config(nil)
if err != nil {
handleInternalError(response, err)
return
}
namespace := request.PathParameter("namespace")
name := request.PathParameter("service")
dataSelect := parseDataSelectPathParameter(request)
dataSelect.MetricQuery = dataselect.StandardMetrics
result, err := resourceService.GetServiceDetail(k8sClient, apiHandler.iManager.Metric().Client(), namespace, name, dataSelect)
result, err := resourceService.GetServiceDetail(k8sClient, apiHandler.iManager.Metric().Client(), namespace, name,
config.Host, dataSelect)
if err != nil {
handleInternalError(response, err)
return
Expand Down Expand Up @@ -1391,10 +1400,15 @@ func (apiHandler *APIHandler) handleGetPodDetail(request *restful.Request, respo
handleInternalError(response, err)
return
}
config, err := apiHandler.cManager.Config(nil)
if err != nil {
handleInternalError(response, err)
return
}

namespace := request.PathParameter("namespace")
name := request.PathParameter("pod")
result, err := pod.GetPodDetail(k8sClient, apiHandler.iManager.Metric().Client(), namespace, name)
result, err := pod.GetPodDetail(k8sClient, apiHandler.iManager.Metric().Client(), namespace, name, config.Host)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Were you able to test it not on a localhost?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure I understand the question... Are you asking if I was not able to test it on localhost?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant setup different than localhost, i.e. AWS, GCE etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested running master on a vagrant vm. Dashboard did generated correct links.

if err != nil {
handleInternalError(response, err)
return
Expand Down
19 changes: 16 additions & 3 deletions src/app/backend/resource/pod/detail.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/kubernetes/dashboard/src/app/backend/resource/common"
"github.com/kubernetes/dashboard/src/app/backend/resource/controller"
"github.com/kubernetes/dashboard/src/app/backend/resource/dataselect"
"github.com/kubernetes/dashboard/src/app/backend/userlinks"
"k8s.io/apimachinery/pkg/api/errors"
res "k8s.io/apimachinery/pkg/api/resource"
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -72,6 +73,9 @@ type PodDetail struct {
// Events is list of events associated with a pod.
EventList common.EventList `json:"eventList"`

// Array of composed userlinks that have been derived from pod annotation.
UserLinks []userlinks.UserLink `json:"userLinks"`

// List of non-critical errors, that occurred during resource retrieval.
Errors []error `json:"errors"`
}
Expand Down Expand Up @@ -110,7 +114,7 @@ type EnvVar struct {

// GetPodDetail returns the details (PodDetail) of a named Pod from a particular namespace.
// TODO(maciaszczykm): Owner reference should be used instead of created by annotation.
func GetPodDetail(client kubernetes.Interface, metricClient metricapi.MetricClient, namespace, name string) (*PodDetail, error) {
func GetPodDetail(client kubernetes.Interface, metricClient metricapi.MetricClient, namespace, name, host string) (*PodDetail, error) {
log.Printf("Getting details of %s pod in %s namespace", name, namespace)

channels := &common.ResourceChannels{
Expand Down Expand Up @@ -152,7 +156,14 @@ func GetPodDetail(client kubernetes.Interface, metricClient metricapi.MetricClie
return nil, criticalError
}

podDetail := toPodDetail(pod, metrics, configMapList, secretList, controller, eventList, nonCriticalErrors)
userLinks, err := userlinks.GetUserLinks(client, namespace, name, api.ResourceKindPod, host)
nonCriticalErrors, criticalError = errorHandler.AppendError(err, nonCriticalErrors)
if criticalError != nil {
return nil, criticalError
}

podDetail := toPodDetail(pod, metrics, configMapList, secretList, controller, eventList,
userLinks, nonCriticalErrors)
return &podDetail, nil
}

Expand Down Expand Up @@ -224,7 +235,8 @@ func extractContainerInfo(containerList []v1.Container, pod *v1.Pod, configMaps
}

func toPodDetail(pod *v1.Pod, metrics []metricapi.Metric, configMaps *v1.ConfigMapList, secrets *v1.SecretList,
controller controller.ResourceOwner, events *common.EventList, nonCriticalErrors []error) PodDetail {
controller controller.ResourceOwner, events *common.EventList, userLinks []userlinks.UserLink,
nonCriticalErrors []error) PodDetail {
return PodDetail{
ObjectMeta: api.NewObjectMeta(pod.ObjectMeta),
TypeMeta: api.NewTypeMeta(api.ResourceKindPod),
Expand All @@ -238,6 +250,7 @@ func toPodDetail(pod *v1.Pod, metrics []metricapi.Metric, configMaps *v1.ConfigM
Metrics: metrics,
Conditions: getPodConditions(*pod),
EventList: *events,
UserLinks: userLinks,
Errors: nonCriticalErrors,
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/app/backend/resource/pod/detail_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,20 @@ import (
"github.com/kubernetes/dashboard/src/app/backend/resource/common"
"github.com/kubernetes/dashboard/src/app/backend/resource/controller"
"github.com/kubernetes/dashboard/src/app/backend/resource/dataselect"
"github.com/kubernetes/dashboard/src/app/backend/userlinks"
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake"
"k8s.io/client-go/pkg/api/v1"
)

func TestGetPodDetail(t *testing.T) {
cases := []struct {
host string
pod *v1.PodList
expected *PodDetail
}{
{
host: "http://localhost:8080",
pod: &v1.PodList{Items: []v1.Pod{{
ObjectMeta: metaV1.ObjectMeta{
Name: "test-pod", Namespace: "test-namespace",
Expand All @@ -51,6 +54,7 @@ func TestGetPodDetail(t *testing.T) {
Containers: []Container{},
InitContainers: []Container{},
EventList: common.EventList{Events: []common.Event{}},
UserLinks: []userlinks.UserLink{},
Metrics: []metricapi.Metric{},
Errors: []error{},
},
Expand All @@ -61,7 +65,7 @@ func TestGetPodDetail(t *testing.T) {
fakeClient := fake.NewSimpleClientset(c.pod)

dataselect.DefaultDataSelectWithMetrics.MetricQuery = dataselect.NoMetrics
actual, err := GetPodDetail(fakeClient, nil, "test-namespace", "test-pod")
actual, err := GetPodDetail(fakeClient, nil, "test-namespace", "test-pod", c.host)

if err != nil {
t.Errorf("GetPodDetail(%#v) == \ngot err %#v", c.pod, err)
Expand Down
3 changes: 3 additions & 0 deletions src/app/backend/resource/service/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/kubernetes/dashboard/src/app/backend/resource/dataselect"
"github.com/kubernetes/dashboard/src/app/backend/resource/endpoint"
"github.com/kubernetes/dashboard/src/app/backend/resource/pod"
"github.com/kubernetes/dashboard/src/app/backend/userlinks"
"k8s.io/client-go/pkg/api/v1"
)

Expand All @@ -38,6 +39,7 @@ func ToService(service *v1.Service) Service {

// ToServiceDetail returns api service object based on kubernetes service object
func ToServiceDetail(service *v1.Service, events common.EventList, pods pod.PodList, endpointList endpoint.EndpointList,
userLinks []userlinks.UserLink,
nonCriticalErrors []error) ServiceDetail {
return ServiceDetail{
ObjectMeta: api.NewObjectMeta(service.ObjectMeta),
Expand All @@ -50,6 +52,7 @@ func ToServiceDetail(service *v1.Service, events common.EventList, pods pod.PodL
Type: service.Spec.Type,
EventList: events,
PodList: pods,
UserLink: userLinks,
SessionAffinity: service.Spec.SessionAffinity,
Errors: nonCriticalErrors,
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/backend/resource/service/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func TestToServiceDetail(t *testing.T) {
}

for _, c := range cases {
actual := ToServiceDetail(c.service, c.eventList, c.podList, c.endpointList, nil)
actual := ToServiceDetail(c.service, c.eventList, c.podList, c.endpointList, nil, nil)

if !reflect.DeepEqual(actual, c.expected) {
t.Errorf("ToServiceDetail(%#v) == \ngot %#v, \nexpected %#v", c.service, actual,
Expand Down
14 changes: 12 additions & 2 deletions src/app/backend/resource/service/detail.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/kubernetes/dashboard/src/app/backend/resource/dataselect"
"github.com/kubernetes/dashboard/src/app/backend/resource/endpoint"
"github.com/kubernetes/dashboard/src/app/backend/resource/pod"
"github.com/kubernetes/dashboard/src/app/backend/userlinks"
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sClient "k8s.io/client-go/kubernetes"
"k8s.io/client-go/pkg/api/v1"
Expand Down Expand Up @@ -61,6 +62,9 @@ type ServiceDetail struct {
// PodList represents list of pods targeted by same label selector as this service.
PodList pod.PodList `json:"podList"`

// Array of composed userlinks that have been derived from service annotation.
UserLink []userlinks.UserLink `json:"userLinks"`

// Show the value of the SessionAffinity of the Service.
SessionAffinity v1.ServiceAffinity `json:"sessionAffinity"`

Expand All @@ -69,7 +73,7 @@ type ServiceDetail struct {
}

// GetServiceDetail gets service details.
func GetServiceDetail(client k8sClient.Interface, metricClient metricapi.MetricClient, namespace, name string,
func GetServiceDetail(client k8sClient.Interface, metricClient metricapi.MetricClient, namespace, name, host string,
dsQuery *dataselect.DataSelectQuery) (*ServiceDetail, error) {

log.Printf("Getting details of %s service in %s namespace", name, namespace)
Expand All @@ -84,6 +88,12 @@ func GetServiceDetail(client k8sClient.Interface, metricClient metricapi.MetricC
return nil, criticalError
}

userLinks, err := userlinks.GetUserLinks(client, namespace, name, api.ResourceKindService, host)
nonCriticalErrors, criticalError = errors.AppendError(err, nonCriticalErrors)
if criticalError != nil {
return nil, criticalError
}

podList, err := GetServicePods(client, metricClient, namespace, name, dsQuery)
nonCriticalErrors, criticalError = errors.AppendError(err, nonCriticalErrors)
if criticalError != nil {
Expand All @@ -96,6 +106,6 @@ func GetServiceDetail(client k8sClient.Interface, metricClient metricapi.MetricC
return nil, criticalError
}

service := ToServiceDetail(serviceData, *eventList, *podList, *endpointList, nonCriticalErrors)
service := ToServiceDetail(serviceData, *eventList, *podList, *endpointList, userLinks, nonCriticalErrors)
return &service, nil
}
Loading