Skip to content

Commit

Permalink
KIALI-402 use LabelsMatch algo to match deployments in service details
Browse files Browse the repository at this point in the history
Some changes are necessary for that, such as passing []Deployment instead of DeploymentsList in the k8s temporary model
  • Loading branch information
jotak committed Apr 13, 2018
1 parent 7b6bd83 commit 6604f12
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 76 deletions.
31 changes: 23 additions & 8 deletions kubernetes/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ package kubernetes

import (
"fmt"
"net"
"os"

kialiConfig "github.com/kiali/kiali/config"
"k8s.io/api/apps/v1beta1"
"k8s.io/api/core/v1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer"
kube "k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"net"
"os"
)

const (
Expand Down Expand Up @@ -123,7 +126,24 @@ func NewClient() (*IstioClient, error) {
return &client, nil
}

func LabelsMatch(serviceLabels, filterLabels map[string]string) bool {
// FilterDeploymentsForService returns a subpart of deployments list where labels match the ones of the given service
func FilterDeploymentsForService(s *v1.Service, deployments *v1beta1.DeploymentList) *[]v1beta1.Deployment {
if s == nil || deployments == nil {
return nil
}
depls := make([]v1beta1.Deployment, len(deployments.Items))
i := 0
for _, depl := range deployments.Items {
if labelsMatch(depl.ObjectMeta.Labels, s.Spec.Selector) {
depls[i] = depl
i++
}
}
shrinked := depls[:i]
return &shrinked
}

func labelsMatch(serviceLabels, filterLabels map[string]string) bool {
labelMatch := true

for key, value := range filterLabels {
Expand All @@ -135,8 +155,3 @@ func LabelsMatch(serviceLabels, filterLabels map[string]string) bool {

return labelMatch
}

func GetLabeledListOptions(labelSelector string) *meta_v1.ListOptions {
return &meta_v1.ListOptions{
LabelSelector: labelSelector}
}
16 changes: 6 additions & 10 deletions kubernetes/client_test.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
package kubernetes

import (
"testing"
// func TestGetList(t *testing.T) {
// assert := assert.New(t)

"github.com/stretchr/testify/assert"
)
// listOptions := GetLabeledListOptions("app=helloworld")

func TestGetList(t *testing.T) {
assert := assert.New(t)
// assert.Equal(listOptions.LabelSelector, "app=helloworld")
// }

listOptions := GetLabeledListOptions("app=helloworld")

assert.Equal(listOptions.LabelSelector, "app=helloworld")
}
// TODO: add LabelsMatch tests
14 changes: 2 additions & 12 deletions kubernetes/kubernetes_service.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
package kubernetes

import (
"strings"

"k8s.io/api/apps/v1beta1"
autoscalingV1 "k8s.io/api/autoscaling/v1"
"k8s.io/api/core/v1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/kiali/kiali/config"
)

const (
Expand Down Expand Up @@ -108,7 +103,7 @@ func (in *IstioClient) GetServiceDetails(namespace string, serviceName string) (
}()

go func() {
deployments, err := in.k8s.AppsV1beta1().Deployments(namespace).List(*getDeploymentFilterListOptions(serviceName))
deployments, err := in.k8s.AppsV1beta1().Deployments(namespace).List(emptyListOptions)
deploymentsChan <- deploymentsResponse{deployments: deployments, err: err}
}()

Expand All @@ -135,7 +130,7 @@ func (in *IstioClient) GetServiceDetails(namespace string, serviceName string) (
if deploymentsResponse.err != nil {
return nil, deploymentsResponse.err
}
serviceDetails.Deployments = deploymentsResponse.deployments
serviceDetails.Deployments = FilterDeploymentsForService(serviceDetails.Service, deploymentsResponse.deployments)

autoscalersResponse := <-autoscalersChan
if autoscalersResponse.err != nil {
Expand Down Expand Up @@ -170,11 +165,6 @@ func getDeploymentNames(deployments *v1beta1.DeploymentList) []string {
return deploymentNames
}

func getDeploymentFilterListOptions(serviceName string) *meta_v1.ListOptions {
filterLabelName := config.Get().ServiceFilterLabelName
return GetLabeledListOptions(strings.Join([]string{filterLabelName, serviceName}, "="))
}

func (in *IstioClient) getServiceList(namespaceName string, servicesChan chan servicesResponse) {
services, err := in.k8s.CoreV1().Services(namespaceName).List(emptyListOptions)
servicesChan <- servicesResponse{services: services, err: err}
Expand Down
2 changes: 1 addition & 1 deletion kubernetes/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ type ServiceList struct {
type ServiceDetails struct {
Service *v1.Service `json:"service"`
Endpoints *v1.Endpoints `json:"endpoints"`
Deployments *v1beta1.DeploymentList `json:"deployments"`
Deployments *[]v1beta1.Deployment `json:"deployments"`
Autoscalers *autoscalingV1.HorizontalPodAutoscalerList `json:"autoscalers"`
}

Expand Down
10 changes: 5 additions & 5 deletions services/business/health.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func (in *HealthService) GetServiceHealth(namespace, service string) models.Heal
// Pod status
details, _ := in.k8s.GetServiceDetails(namespace, service)
if details != nil {
health.DeploymentStatuses = castDeploymentsStatuses(details.Deployments.Items)
health.DeploymentStatuses = castDeploymentsStatuses(details.Deployments)
}

// Envoy health
Expand All @@ -30,17 +30,17 @@ func (in *HealthService) GetServiceHealth(namespace, service string) models.Heal
return health
}

func (in *HealthService) getServiceHealthFromDeployments(namespace, service string, deployments []v1beta1.Deployment) models.Health {
func (in *HealthService) getServiceHealthFromDeployments(namespace, service string, deployments *[]v1beta1.Deployment) models.Health {
statuses := castDeploymentsStatuses(deployments)
healthy, total, _ := in.prom.GetServiceHealth(namespace, service)
return models.Health{
Envoy: models.EnvoyHealth{Healthy: healthy, Total: total},
DeploymentStatuses: statuses}
}

func castDeploymentsStatuses(deployments []v1beta1.Deployment) []models.DeploymentStatus {
statuses := make([]models.DeploymentStatus, len(deployments))
for i, deployment := range deployments {
func castDeploymentsStatuses(deployments *[]v1beta1.Deployment) []models.DeploymentStatus {
statuses := make([]models.DeploymentStatus, len(*deployments))
for i, deployment := range *deployments {
statuses[i] = models.DeploymentStatus{
Name: deployment.Name,
Replicas: deployment.Status.Replicas,
Expand Down
22 changes: 5 additions & 17 deletions services/business/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,27 +38,15 @@ func (in *SvcService) buildServiceList(namespace models.Namespace, sl *kubernete
services := make([]models.ServiceOverview, len(sl.Services.Items))

for i, item := range sl.Services.Items {
depls := getDeploymentsMatchingService(&item, sl.Deployments)
depls := kubernetes.FilterDeploymentsForService(&item, sl.Deployments)
services[i] = in.castServiceOverview(&item, depls)
}
processRequestCounters(services, requestCounters)

return &models.ServiceList{Namespace: namespace, Services: services}
}

func getDeploymentsMatchingService(s *v1.Service, deployments *v1beta1.DeploymentList) []v1beta1.Deployment {
depls := make([]v1beta1.Deployment, len(deployments.Items))
i := 0
for _, depl := range deployments.Items {
if kubernetes.LabelsMatch(depl.ObjectMeta.Labels, s.Spec.Selector) {
depls[i] = depl
i++
}
}
return depls[:i]
}

func (in *SvcService) castServiceOverview(s *v1.Service, deployments []v1beta1.Deployment) models.ServiceOverview {
func (in *SvcService) castServiceOverview(s *v1.Service, deployments *[]v1beta1.Deployment) models.ServiceOverview {
hasSideCar := hasIstioSideCar(deployments)
health := in.health.getServiceHealthFromDeployments(s.Namespace, s.Name, deployments)
return models.ServiceOverview{
Expand All @@ -67,8 +55,8 @@ func (in *SvcService) castServiceOverview(s *v1.Service, deployments []v1beta1.D
Health: health}
}

func hasIstioSideCar(deployments []v1beta1.Deployment) bool {
for _, deployment := range deployments {
func hasIstioSideCar(deployments *[]v1beta1.Deployment) bool {
for _, deployment := range *deployments {
if deployment.Spec.Template.Annotations != nil {
if _, exists := deployment.Spec.Template.Annotations[config.Get().Products.Istio.IstioSidecarAnnotation]; exists {
return true
Expand Down Expand Up @@ -133,7 +121,7 @@ func (in *SvcService) GetService(namespace, service string) (*models.Service, er
return nil, err
}

health := in.health.getServiceHealthFromDeployments(namespace, service, serviceDetails.Deployments.Items)
health := in.health.getServiceHealthFromDeployments(namespace, service, serviceDetails.Deployments)

s := models.Service{
Namespace: models.Namespace{Name: namespace},
Expand Down
4 changes: 2 additions & 2 deletions services/models/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ type Deployment struct {
Autoscaler Autoscaler `json:"autoscaler"`
}

func (deployments *Deployments) Parse(ds *v1beta1.DeploymentList) {
func (deployments *Deployments) Parse(ds *[]v1beta1.Deployment) {
if ds == nil {
return
}

for _, deployment := range ds.Items {
for _, deployment := range *ds {
casted := Deployment{}
casted.Parse(&deployment)
*deployments = append(*deployments, &casted)
Expand Down
41 changes: 20 additions & 21 deletions services/models/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,26 +183,25 @@ func fakeServiceDetails() *kubernetes.ServiceDetails {

t1, _ := time.Parse(time.RFC822Z, "08 Mar 18 17:44 +0300")
t2, _ := time.Parse(time.RFC822Z, "08 Mar 18 17:45 +0300")
deployments := &v1beta1.DeploymentList{
Items: []v1beta1.Deployment{
v1beta1.Deployment{
ObjectMeta: meta_v1.ObjectMeta{
Name: "reviews-v1",
CreationTimestamp: meta_v1.NewTime(t1),
Labels: map[string]string{"apps": "reviews", "version": "v1"}},
Status: v1beta1.DeploymentStatus{
Replicas: 3,
AvailableReplicas: 1,
UnavailableReplicas: 2}},
v1beta1.Deployment{
ObjectMeta: meta_v1.ObjectMeta{
Name: "reviews-v2",
CreationTimestamp: meta_v1.NewTime(t2),
Labels: map[string]string{"apps": "reviews", "version": "v2"}},
Status: v1beta1.DeploymentStatus{
Replicas: 3,
AvailableReplicas: 3,
UnavailableReplicas: 0}}}}
deployments := []v1beta1.Deployment{
v1beta1.Deployment{
ObjectMeta: meta_v1.ObjectMeta{
Name: "reviews-v1",
CreationTimestamp: meta_v1.NewTime(t1),
Labels: map[string]string{"apps": "reviews", "version": "v1"}},
Status: v1beta1.DeploymentStatus{
Replicas: 3,
AvailableReplicas: 1,
UnavailableReplicas: 2}},
v1beta1.Deployment{
ObjectMeta: meta_v1.ObjectMeta{
Name: "reviews-v2",
CreationTimestamp: meta_v1.NewTime(t2),
Labels: map[string]string{"apps": "reviews", "version": "v2"}},
Status: v1beta1.DeploymentStatus{
Replicas: 3,
AvailableReplicas: 3,
UnavailableReplicas: 0}}}

autoscalers := &autoscalingV1.HorizontalPodAutoscalerList{
Items: []autoscalingV1.HorizontalPodAutoscaler{
Expand Down Expand Up @@ -239,7 +238,7 @@ func fakeServiceDetails() *kubernetes.ServiceDetails {
DesiredReplicas: 2,
CurrentCPUUtilizationPercentage: &[]int32{30}[0]}}}}

return &kubernetes.ServiceDetails{service, endpoints, deployments, autoscalers}
return &kubernetes.ServiceDetails{service, endpoints, &deployments, autoscalers}
}

func fakeIstioDetails() *kubernetes.IstioDetails {
Expand Down

0 comments on commit 6604f12

Please sign in to comment.