replicationcontrollerlist.go 7.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// 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 main

import (
M
Marcin Maciaszczyk 已提交
18 19
	"log"

20
	"k8s.io/kubernetes/pkg/api"
21
	"k8s.io/kubernetes/pkg/api/unversioned"
22 23 24 25 26
	client "k8s.io/kubernetes/pkg/client/unversioned"
	"k8s.io/kubernetes/pkg/fields"
	"k8s.io/kubernetes/pkg/labels"
)

27 28 29
// Callback function in order to get the pod status errors
type GetPodsEventWarningsFunc func(pods []api.Pod) ([]PodEvent, error)

30 31 32 33
// ReplicationControllerList contains a list of Replication Controllers in the cluster.
type ReplicationControllerList struct {
	// Unordered list of Replication Controllers.
	ReplicationControllers []ReplicationController `json:"replicationControllers"`
34 35
}

36 37 38 39
// ReplicationController (aka. Replication Controller) plus zero or more Kubernetes services that
// target the Replication Controller.
type ReplicationController struct {
	// Name of the Replication Controller.
40 41
	Name string `json:"name"`

42
	// Namespace this Replication Controller is in.
43 44
	Namespace string `json:"namespace"`

45
	// Human readable description of this Replication Controller.
46 47
	Description string `json:"description"`

48
	// Label of this Replication Controller.
49 50
	Labels map[string]string `json:"labels"`

51
	// Aggregate information about pods belonging to this repolica set.
52
	Pods ReplicationControllerPodInfo `json:"pods"`
53

54
	// Container images of the Replication Controller.
55
	ContainerImages []string `json:"containerImages"`
56

57
	// Time the replication controller was created.
58
	CreationTime unversioned.Time `json:"creationTime"`
59

60
	// Internal endpoints of all Kubernetes services have the same label selector as this Replication Controller.
61
	InternalEndpoints []Endpoint `json:"internalEndpoints"`
62

63
	// External endpoints of all Kubernetes services have the same label selector as this Replication Controller.
64
	ExternalEndpoints []Endpoint `json:"externalEndpoints"`
65 66
}

67 68 69
// GetReplicationControllerList returns a list of all Replication Controllers in the cluster.
func GetReplicationControllerList(client *client.Client) (*ReplicationControllerList, error) {
	log.Printf("Getting list of all replication controllers in the cluster")
M
Marcin Maciaszczyk 已提交
70

71 72 73 74 75
	listEverything := unversioned.ListOptions{
		LabelSelector: unversioned.LabelSelector{labels.Everything()},
		FieldSelector: unversioned.FieldSelector{fields.Everything()},
	}

76
	replicationControllers, err := client.ReplicationControllers(api.NamespaceAll).List(listEverything)
77 78 79 80 81

	if err != nil {
		return nil, err
	}

82 83 84 85 86 87 88
	services, err := client.Services(api.NamespaceAll).List(listEverything)

	if err != nil {
		return nil, err
	}

	pods, err := client.Pods(api.NamespaceAll).List(listEverything)
89 90 91 92 93

	if err != nil {
		return nil, err
	}

94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
	// Anonymous callback function to get pods warnings.
	// Function fulfils GetPodsEventWarningsFunc type contract.
	// Based on list of api pods returns list of pod related warning events
	getPodsEventWarningsFn := func(pods []api.Pod) ([]PodEvent, error) {
		errors, err := GetPodsEventWarnings(client, pods)

		if err != nil {
			return nil, err
		}

		return errors, nil
	}

	result, err := getReplicationControllerList(replicationControllers.Items, services.Items, pods.Items, getPodsEventWarningsFn)

	if err != nil {
		return nil, err
	}

	return result, nil
114 115
}

116 117 118
// Returns a list of all Replication Controller model objects in the cluster, based on all Kubernetes
// Replication Controller and Service API objects.
// The function processes all Replication Controllers API objects and finds matching Services for them.
119 120 121
func getReplicationControllerList(replicationControllers []api.ReplicationController,
	services []api.Service, pods []api.Pod, getPodsEventWarningsFn GetPodsEventWarningsFunc) (
	*ReplicationControllerList, error) {
122

123
	replicationControllerList := &ReplicationControllerList{ReplicationControllers: make([]ReplicationController, 0)}
124

125
	for _, replicationController := range replicationControllers {
126
		var containerImages []string
127
		for _, container := range replicationController.Spec.Template.Spec.Containers {
128 129 130
			containerImages = append(containerImages, container.Image)
		}

131
		matchingServices := getMatchingServices(services, &replicationController)
132 133
		var internalEndpoints []Endpoint
		var externalEndpoints []Endpoint
134 135 136
		for _, service := range matchingServices {
			internalEndpoints = append(internalEndpoints,
				getInternalEndpoint(service.Name, service.Namespace, service.Spec.Ports))
137
			for _, externalIP := range service.Status.LoadBalancer.Ingress {
138
				externalEndpoints = append(externalEndpoints,
139
					getExternalEndpoint(externalIP, service.Spec.Ports))
140 141 142
			}
		}

143 144
		matchingPods := make([]api.Pod, 0)
		for _, pod := range pods {
145 146
			if pod.ObjectMeta.Namespace == replicationController.ObjectMeta.Namespace &&
				isLabelSelectorMatching(replicationController.Spec.Selector, pod.ObjectMeta.Labels) {
147 148 149
				matchingPods = append(matchingPods, pod)
			}
		}
150
		podInfo := getReplicationControllerPodInfo(&replicationController, matchingPods)
151 152 153 154 155 156 157
		podErrors, err := getPodsEventWarningsFn(matchingPods)

		if err != nil {
			return nil, err
		}

		podInfo.Warnings = podErrors
158

159 160 161 162 163
		replicationControllerList.ReplicationControllers = append(replicationControllerList.ReplicationControllers, ReplicationController{
			Name:              replicationController.ObjectMeta.Name,
			Namespace:         replicationController.ObjectMeta.Namespace,
			Description:       replicationController.Annotations[DescriptionAnnotationKey],
			Labels:            replicationController.ObjectMeta.Labels,
164
			Pods:              podInfo,
165
			ContainerImages:   containerImages,
166
			CreationTime:      replicationController.ObjectMeta.CreationTimestamp,
167 168
			InternalEndpoints: internalEndpoints,
			ExternalEndpoints: externalEndpoints,
169 170 171
		})
	}

172
	return replicationControllerList, nil
173 174
}

175
// Returns all services that target the same Pods (or subset) as the given Replication Controller.
176
func getMatchingServices(services []api.Service,
177
	replicationController *api.ReplicationController) []api.Service {
178 179 180

	var matchingServices []api.Service
	for _, service := range services {
181 182
		if service.ObjectMeta.Namespace == replicationController.ObjectMeta.Namespace &&
			isLabelSelectorMatching(service.Spec.Selector, replicationController.Spec.Selector) {
183

184 185 186 187 188 189 190
			matchingServices = append(matchingServices, service)
		}
	}
	return matchingServices
}

// Returns true when a Service with the given selector targets the same Pods (or subset) that
191
// a Replication Controller with the given selector.
192 193
func isLabelSelectorMatching(labelSelector map[string]string,
	testedObjectLabels map[string]string) bool {
194 195

	// If service has no selectors, then assume it targets different Pods.
196
	if len(labelSelector) == 0 {
197 198
		return false
	}
199 200
	for label, value := range labelSelector {
		if rsValue, ok := testedObjectLabels[label]; !ok || rsValue != value {
201 202 203 204
			return false
		}
	}
	return true
205
}