This repository has been archived by the owner on Nov 1, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Polyfill container fields filter from v10 to v6
- Loading branch information
Showing
12 changed files
with
355 additions
and
160 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
package v6 | ||
|
||
import ( | ||
"github.com/pkg/errors" | ||
"github.com/weaveworks/flux/image" | ||
"github.com/weaveworks/flux/registry" | ||
"github.com/weaveworks/flux/update" | ||
) | ||
|
||
// Container describes an individual container including current image info and | ||
// available images. | ||
type Container struct { | ||
Name string `json:",omitempty"` | ||
Current image.Info `json:",omitempty"` | ||
LatestFiltered image.Info `json:",omitempty"` | ||
|
||
// All available images (ignoring tag filters) | ||
Available []image.Info `json:",omitempty"` | ||
AvailableError string `json:",omitempty"` | ||
AvailableImagesCount int `json:",omitempty"` | ||
NewAvailableImagesCount int `json:",omitempty"` | ||
|
||
// Filtered available images (matching tag filters) | ||
FilteredImagesCount int `json:",omitempty"` | ||
NewFilteredImagesCount int `json:",omitempty"` | ||
} | ||
|
||
// NewContainer creates a Container given a list of images and the current image | ||
func NewContainer(name string, images update.ImageInfos, currentImage image.Info, tagPattern string, fields []string) (Container, error) { | ||
// All images | ||
imagesCount := len(images) | ||
imagesErr := "" | ||
if images == nil { | ||
imagesErr = registry.ErrNoImageData.Error() | ||
} | ||
var newImages []image.Info | ||
for _, img := range images { | ||
if img.CreatedAt.After(currentImage.CreatedAt) { | ||
newImages = append(newImages, img) | ||
} | ||
} | ||
newImagesCount := len(newImages) | ||
|
||
// Filtered images | ||
filteredImages := images.Filter(tagPattern) | ||
filteredImagesCount := len(filteredImages) | ||
var newFilteredImages []image.Info | ||
for _, img := range filteredImages { | ||
if img.CreatedAt.After(currentImage.CreatedAt) { | ||
newFilteredImages = append(newFilteredImages, img) | ||
} | ||
} | ||
newFilteredImagesCount := len(newFilteredImages) | ||
latestFiltered, _ := filteredImages.Latest() | ||
|
||
container := Container{ | ||
Name: name, | ||
Current: currentImage, | ||
LatestFiltered: latestFiltered, | ||
|
||
Available: images, | ||
AvailableError: imagesErr, | ||
AvailableImagesCount: imagesCount, | ||
NewAvailableImagesCount: newImagesCount, | ||
FilteredImagesCount: filteredImagesCount, | ||
NewFilteredImagesCount: newFilteredImagesCount, | ||
} | ||
return filterContainerFields(container, fields) | ||
} | ||
|
||
// filterContainerFields returns a new container with only the fields specified. If not fields are specified, | ||
// a list of default fields is used. | ||
func filterContainerFields(container Container, fields []string) (Container, error) { | ||
// Default fields | ||
if len(fields) == 0 { | ||
fields = []string{ | ||
"Name", | ||
"Current", | ||
"LatestFiltered", | ||
"Available", | ||
"AvailableError", | ||
"AvailableImagesCount", | ||
"NewAvailableImagesCount", | ||
"FilteredImagesCount", | ||
"NewFilteredImagesCount", | ||
} | ||
} | ||
|
||
var c Container | ||
for _, field := range fields { | ||
switch field { | ||
case "Name": | ||
c.Name = container.Name | ||
case "Current": | ||
c.Current = container.Current | ||
case "LatestFiltered": | ||
c.LatestFiltered = container.LatestFiltered | ||
case "Available": | ||
c.Available = container.Available | ||
case "AvailableError": | ||
c.AvailableError = container.AvailableError | ||
case "AvailableImagesCount": | ||
c.AvailableImagesCount = container.AvailableImagesCount | ||
case "NewAvailableImagesCount": | ||
c.NewAvailableImagesCount = container.NewAvailableImagesCount | ||
case "FilteredImagesCount": | ||
c.FilteredImagesCount = container.FilteredImagesCount | ||
case "NewFilteredImagesCount": | ||
c.NewFilteredImagesCount = container.NewFilteredImagesCount | ||
default: | ||
return c, errors.Errorf("%s is an invalid field", field) | ||
} | ||
} | ||
return c, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
package v6 | ||
|
||
import ( | ||
"reflect" | ||
"testing" | ||
|
||
"github.com/weaveworks/flux/image" | ||
"github.com/weaveworks/flux/update" | ||
) | ||
|
||
func TestNewContainer(t *testing.T) { | ||
|
||
testImage := image.Info{ImageID: "test"} | ||
|
||
type args struct { | ||
name string | ||
images update.ImageInfos | ||
currentImage image.Info | ||
tagPattern string | ||
fields []string | ||
} | ||
tests := []struct { | ||
name string | ||
args args | ||
want Container | ||
wantErr bool | ||
}{ | ||
{ | ||
name: "Simple", | ||
args: args{ | ||
name: "container1", | ||
images: update.ImageInfos{testImage}, | ||
currentImage: testImage, | ||
tagPattern: "*", | ||
}, | ||
want: Container{ | ||
Name: "container1", | ||
Current: testImage, | ||
LatestFiltered: testImage, | ||
Available: []image.Info{testImage}, | ||
AvailableImagesCount: 1, | ||
NewAvailableImagesCount: 0, | ||
FilteredImagesCount: 1, | ||
NewFilteredImagesCount: 0, | ||
}, | ||
wantErr: false, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
got, err := NewContainer(tt.args.name, tt.args.images, tt.args.currentImage, tt.args.tagPattern, tt.args.fields) | ||
if (err != nil) != tt.wantErr { | ||
t.Errorf("NewContainer() error = %v, wantErr %v", err, tt.wantErr) | ||
return | ||
} | ||
if !reflect.DeepEqual(got, tt.want) { | ||
t.Errorf("NewContainer() = %v, want %v", got, tt.want) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestFilterContainerFields(t *testing.T) { | ||
testContainer := Container{ | ||
Name: "test", | ||
Current: image.Info{ImageID: "123"}, | ||
LatestFiltered: image.Info{ImageID: "123"}, | ||
Available: []image.Info{{ImageID: "123"}}, | ||
AvailableError: "test", | ||
AvailableImagesCount: 1, | ||
NewAvailableImagesCount: 2, | ||
FilteredImagesCount: 3, | ||
NewFilteredImagesCount: 4, | ||
} | ||
|
||
type args struct { | ||
container Container | ||
fields []string | ||
} | ||
tests := []struct { | ||
name string | ||
args args | ||
want Container | ||
wantErr bool | ||
}{ | ||
{ | ||
name: "Default fields", | ||
args: args{ | ||
container: testContainer, | ||
}, | ||
want: testContainer, | ||
wantErr: false, | ||
}, | ||
{ | ||
name: "Filter", | ||
args: args{ | ||
container: testContainer, | ||
fields: []string{"Name", "Available", "NewAvailableImagesCount", "NewFilteredImagesCount"}, | ||
}, | ||
want: Container{ | ||
Name: "test", | ||
Available: []image.Info{{ImageID: "123"}}, | ||
NewAvailableImagesCount: 2, | ||
NewFilteredImagesCount: 4, | ||
}, | ||
wantErr: false, | ||
}, | ||
{ | ||
name: "Invalid field", | ||
args: args{ | ||
container: testContainer, | ||
fields: []string{"Invalid"}, | ||
}, | ||
want: Container{}, | ||
wantErr: true, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
got, err := filterContainerFields(tt.args.container, tt.args.fields) | ||
if (err != nil) != tt.wantErr { | ||
t.Errorf("FilterContainerFields() error = %v, wantErr %v", err, tt.wantErr) | ||
return | ||
} | ||
if !reflect.DeepEqual(got, tt.want) { | ||
t.Errorf("FilterContainerFields() = %v, want %v", got, tt.want) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.