Skip to content
This repository was archived by the owner on Aug 5, 2020. It is now read-only.

Commit 7d859f5

Browse files
authored
feature(data): add deployments, daemonsets to cluster data (#95)
* feature(data): add deployments, daemonsets to cluster data * test(data): basic clusterIDFromPersistentStorage.Get() coverage and installedDeisData.Get() test coverage scaffolding and TODO note * chore(swagger): image is a versionData property this was inadvertently duplicated as a property of version * chore(data): version annotation = component.deis.io/version see deis/charts#331
1 parent 31fe3bc commit 7d859f5

8 files changed

Lines changed: 202 additions & 52 deletions

File tree

api/swagger-spec/swagger.yml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -401,10 +401,10 @@ definitions:
401401
minLength: 1
402402
description:
403403
type: string
404+
type:
405+
type: string
404406
version:
405407
type: object
406-
required:
407-
- train
408408
properties:
409409
train:
410410
type: string
@@ -416,8 +416,8 @@ definitions:
416416
type: string
417417
minLength: 1
418418
data:
419-
$ref: "#/definitions/data"
420-
data:
419+
$ref: "#/definitions/versionData"
420+
versionData:
421421
type: object
422422
properties:
423423
description:
@@ -426,6 +426,8 @@ definitions:
426426
fixes:
427427
type: string
428428
minLength: 1
429+
image:
430+
type: string
429431
error:
430432
type: object
431433
required:

data/cluster_id_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package data
2+
3+
import (
4+
"sync"
5+
"testing"
6+
7+
"github.com/arschles/assert"
8+
"github.com/deis/kubeapp/api/secret"
9+
"github.com/deis/workflow-manager/k8s"
10+
"github.com/satori/go.uuid"
11+
"k8s.io/kubernetes/pkg/api"
12+
)
13+
14+
func TestClusterIDFromPersistentStorage(t *testing.T) {
15+
sec := api.Secret{}
16+
secretGetter := &secret.FakeGetter{
17+
Secret: &sec,
18+
}
19+
secretCreator := &secret.FakeCreator{
20+
CreateFunc: func(sec *api.Secret) (*api.Secret, error) {
21+
return sec, nil
22+
},
23+
}
24+
secrets := k8s.NewFakeKubeSecretGetterCreator(secretGetter, secretCreator)
25+
clusterID := clusterIDFromPersistentStorage{
26+
rwm: new(sync.RWMutex),
27+
cache: "",
28+
secretGetterCreator: secrets,
29+
}
30+
resp, err := clusterID.Get()
31+
assert.NoErr(t, err)
32+
// verify that the secret is a UUID
33+
_, err = uuid.FromString(resp)
34+
assert.NoErr(t, err)
35+
}

data/installed_data.go

Lines changed: 61 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ import (
77
"github.com/deis/workflow-manager/pkg/swagger/models"
88
)
99

10+
var (
11+
daemonSetType = "Daemon Set"
12+
deploymentType = "Deployment"
13+
rcType = "Replication Controller"
14+
)
15+
16+
const versionAnnotation = "component.deis.io/version"
17+
1018
// InstalledData is an interface for managing installed cluster metadata
1119
type InstalledData interface {
1220
// will have a Get method to retrieve installed data
@@ -25,19 +33,62 @@ func NewInstalledDeisData(ri *k8s.ResourceInterfaceNamespaced) InstalledData {
2533

2634
// Get method for InstalledDeisData
2735
func (g *installedDeisData) Get() ([]byte, error) {
28-
rcItems, err := k8s.GetReplicationControllers(g.k8sResources.ReplicationControllers())
36+
var cluster models.Cluster
37+
deployments, err := k8s.GetDeployments(g.k8sResources.Deployments())
2938
if err != nil {
3039
return nil, err
3140
}
32-
var cluster models.Cluster
33-
for _, rc := range rcItems {
34-
component := models.ComponentVersion{}
35-
component.Component = &models.Component{}
36-
component.Version = &models.Version{}
37-
component.Component.Name = rc.Name
38-
desc := rc.Annotations["chart.helm.sh/description"]
39-
component.Component.Description = &desc
40-
component.Version.Version = rc.Annotations["chart.helm.sh/version"]
41+
for _, deployment := range deployments {
42+
component := models.ComponentVersion{
43+
Component: &models.Component{
44+
Name: deployment.Name,
45+
Type: &deploymentType,
46+
},
47+
Version: &models.Version{
48+
Version: deployment.Annotations[versionAnnotation],
49+
Data: &models.VersionData{
50+
Image: &deployment.Spec.Template.Spec.Containers[0].Image,
51+
},
52+
},
53+
}
54+
cluster.Components = append(cluster.Components, &component)
55+
}
56+
daemonSets, err := k8s.GetDaemonSets(g.k8sResources.DaemonSets())
57+
if err != nil {
58+
return nil, err
59+
}
60+
for _, daemonSet := range daemonSets {
61+
component := models.ComponentVersion{
62+
Component: &models.Component{
63+
Name: daemonSet.Name,
64+
Type: &daemonSetType,
65+
},
66+
Version: &models.Version{
67+
Version: daemonSet.Annotations[versionAnnotation],
68+
Data: &models.VersionData{
69+
Image: &daemonSet.Spec.Template.Spec.Containers[0].Image,
70+
},
71+
},
72+
}
73+
cluster.Components = append(cluster.Components, &component)
74+
}
75+
replicationControllers, err := k8s.GetReplicationControllers(g.k8sResources.ReplicationControllers())
76+
if err != nil {
77+
return nil, err
78+
}
79+
for _, rc := range replicationControllers {
80+
component := models.ComponentVersion{
81+
Component: &models.Component{
82+
Name: rc.Name,
83+
Type: &rcType,
84+
},
85+
Version: &models.Version{
86+
Version: rc.Annotations[versionAnnotation],
87+
Data: &models.VersionData{
88+
Image: &rc.Spec.Template.Spec.Containers[0].Image,
89+
},
90+
},
91+
}
4192
cluster.Components = append(cluster.Components, &component)
4293
}
4394
js, err := json.Marshal(cluster)

data/installed_data_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package data
2+
3+
import (
4+
"testing"
5+
6+
"github.com/deis/workflow-manager/k8s"
7+
"k8s.io/kubernetes/pkg/api"
8+
"k8s.io/kubernetes/pkg/api/testapi"
9+
"k8s.io/kubernetes/pkg/apis/extensions"
10+
"k8s.io/kubernetes/pkg/client/unversioned/testclient/simple"
11+
)
12+
13+
const namespace = "deis"
14+
15+
func TestInstalledDeisData(t *testing.T) {
16+
client := getK8sClient(t)
17+
k := k8s.NewResourceInterfaceNamespaced(client, namespace)
18+
installedData := installedDeisData{
19+
k8sResources: k,
20+
}
21+
_, _ = installedData.Get()
22+
//TODO: we need to create a fake client interface that is a union of api+extension fake clients
23+
}
24+
25+
func getK8sClient(t *testing.T) *simple.Client {
26+
c := &simple.Client{
27+
Request: simple.Request{
28+
Method: "GET",
29+
Path: testapi.Extensions.ResourcePath("deployments", namespace, ""),
30+
},
31+
Response: simple.Response{StatusCode: 200,
32+
Body: &extensions.DeploymentList{
33+
Items: []extensions.Deployment{
34+
{
35+
ObjectMeta: api.ObjectMeta{
36+
Name: "deis-builder",
37+
},
38+
Spec: extensions.DeploymentSpec{
39+
Template: api.PodTemplateSpec{
40+
Spec: api.PodSpec{
41+
Containers: []api.Container{
42+
{
43+
Image: "container-image",
44+
},
45+
},
46+
},
47+
},
48+
},
49+
},
50+
},
51+
},
52+
},
53+
}
54+
return c.Setup(t)
55+
}

k8s/k8s.go

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func NewRunningK8sData(r *ResourceInterfaceNamespaced) RunningK8sData {
6363

6464
// DaemonSets method for runningK8sData
6565
func (rkd *runningK8sData) DaemonSets() ([]*models.K8sResource, error) {
66-
ds, err := getDaemonSets(rkd.daemonSetLister)
66+
ds, err := GetDaemonSets(rkd.daemonSetLister)
6767
if err != nil {
6868
return nil, err
6969
}
@@ -80,7 +80,7 @@ func (rkd *runningK8sData) DaemonSets() ([]*models.K8sResource, error) {
8080

8181
// Deployments method for runningK8sData
8282
func (rkd *runningK8sData) Deployments() ([]*models.K8sResource, error) {
83-
ds, err := getDeployments(rkd.deploymentLister)
83+
ds, err := GetDeployments(rkd.deploymentLister)
8484
if err != nil {
8585
return nil, err
8686
}
@@ -269,6 +269,30 @@ func GetServicesModels(k RunningK8sData) ([]*models.K8sResource, error) {
269269
return services, nil
270270
}
271271

272+
// GetDaemonSets is a helper function that returns a slice of
273+
// DaemonSet objects given a daemonset.Lister interface
274+
func GetDaemonSets(dLister daemonset.Lister) ([]extensions.DaemonSet, error) {
275+
ds, err := dLister.List(api.ListOptions{
276+
LabelSelector: labels.Everything(),
277+
})
278+
if err != nil {
279+
return nil, err
280+
}
281+
return ds.Items, nil
282+
}
283+
284+
// GetDeployments is a helper function that returns a slice of
285+
// Deployment objects given a deployment.Lister interface
286+
func GetDeployments(depsLister deployment.Lister) ([]extensions.Deployment, error) {
287+
deps, err := depsLister.List(api.ListOptions{
288+
LabelSelector: labels.Everything(),
289+
})
290+
if err != nil {
291+
return nil, err
292+
}
293+
return deps.Items, nil
294+
}
295+
272296
// GetReplicationControllers is a helper function that returns a slice of
273297
// ReplicationController objects given a rc.Lister interface
274298
func GetReplicationControllers(rcLister rc.Lister) ([]api.ReplicationController, error) {
@@ -305,30 +329,6 @@ func getPods(podLister pod.Lister) ([]api.Pod, error) {
305329
return pods.Items, nil
306330
}
307331

308-
// getDaemonSets is a helper function that returns a slice of
309-
// DaemonSet objects given a daemonset.Lister interface
310-
func getDaemonSets(dsLister daemonset.Lister) ([]extensions.DaemonSet, error) {
311-
daemonSets, err := dsLister.List(api.ListOptions{
312-
LabelSelector: labels.Everything(),
313-
})
314-
if err != nil {
315-
return []extensions.DaemonSet{}, err
316-
}
317-
return daemonSets.Items, nil
318-
}
319-
320-
// getDeployments is a helper function that returns a slice of
321-
// Deployment objects given a deployment.Lister interface
322-
func getDeployments(dLister deployment.Lister) ([]extensions.Deployment, error) {
323-
deployments, err := dLister.List(api.ListOptions{
324-
LabelSelector: labels.Everything(),
325-
})
326-
if err != nil {
327-
return []extensions.Deployment{}, err
328-
}
329-
return deployments.Items, nil
330-
}
331-
332332
// getEvents is a helper function that returns a slice of
333333
// Event objects given an event.Lister interface
334334
func getEvents(eLister event.Lister) ([]api.Event, error) {

pkg/swagger/models/component.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ type Component struct {
2626
Min Length: 1
2727
*/
2828
Name string `json:"name"`
29+
30+
/* type
31+
*/
32+
Type *string `json:"type,omitempty"`
2933
}
3034

3135
// Validate validates this component

pkg/swagger/models/version.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ type Version struct {
1919

2020
/* data
2121
*/
22-
Data *Data `json:"data,omitempty"`
22+
Data *VersionData `json:"data,omitempty"`
2323

2424
/* released
2525
@@ -29,10 +29,9 @@ type Version struct {
2929

3030
/* train
3131
32-
Required: true
3332
Min Length: 1
3433
*/
35-
Train string `json:"train"`
34+
Train string `json:"train,omitempty"`
3635

3736
/* version
3837
@@ -81,8 +80,8 @@ func (m *Version) validateReleased(formats strfmt.Registry) error {
8180

8281
func (m *Version) validateTrain(formats strfmt.Registry) error {
8382

84-
if err := validate.RequiredString("train", "body", string(m.Train)); err != nil {
85-
return err
83+
if swag.IsZero(m.Train) { // not required
84+
return nil
8685
}
8786

8887
if err := validate.MinLength("train", "body", string(m.Train), 1); err != nil {
Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ import (
1111
"github.com/go-swagger/go-swagger/httpkit/validate"
1212
)
1313

14-
/*Data data
14+
/*VersionData version data
1515
16-
swagger:model data
16+
swagger:model versionData
1717
*/
18-
type Data struct {
18+
type VersionData struct {
1919

2020
/* description
2121
@@ -28,10 +28,14 @@ type Data struct {
2828
Min Length: 1
2929
*/
3030
Fixes string `json:"fixes,omitempty"`
31+
32+
/* image
33+
*/
34+
Image *string `json:"image,omitempty"`
3135
}
3236

33-
// Validate validates this data
34-
func (m *Data) Validate(formats strfmt.Registry) error {
37+
// Validate validates this version data
38+
func (m *VersionData) Validate(formats strfmt.Registry) error {
3539
var res []error
3640

3741
if err := m.validateDescription(formats); err != nil {
@@ -50,7 +54,7 @@ func (m *Data) Validate(formats strfmt.Registry) error {
5054
return nil
5155
}
5256

53-
func (m *Data) validateDescription(formats strfmt.Registry) error {
57+
func (m *VersionData) validateDescription(formats strfmt.Registry) error {
5458

5559
if swag.IsZero(m.Description) { // not required
5660
return nil
@@ -63,7 +67,7 @@ func (m *Data) validateDescription(formats strfmt.Registry) error {
6367
return nil
6468
}
6569

66-
func (m *Data) validateFixes(formats strfmt.Registry) error {
70+
func (m *VersionData) validateFixes(formats strfmt.Registry) error {
6771

6872
if swag.IsZero(m.Fixes) { // not required
6973
return nil

0 commit comments

Comments
 (0)