-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor available hosts and vm migration code
- Loading branch information
1 parent
e296203
commit c7c7eea
Showing
12 changed files
with
382 additions
and
347 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
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
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
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,147 @@ | ||
/* | ||
Copyright 2023. | ||
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 service | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/smartxworks/cloudtower-go-sdk/v2/models" | ||
"k8s.io/apimachinery/pkg/util/sets" | ||
) | ||
|
||
// Hosts is a set of hosts. | ||
type Hosts map[string]*models.Host | ||
|
||
// NewHosts creates a Hosts. from a list of values. | ||
func NewHosts(hosts ...*models.Host) Hosts { | ||
ss := make(Hosts, len(hosts)) | ||
ss.Insert(hosts...) | ||
return ss | ||
} | ||
|
||
// NewHostsFromList creates a Hosts from the given host slice. | ||
func NewHostsFromList(hosts []*models.Host) Hosts { | ||
ss := make(Hosts, len(hosts)) | ||
for i := range hosts { | ||
ss.Insert(hosts[i]) | ||
} | ||
return ss | ||
} | ||
|
||
func (s Hosts) Insert(hosts ...*models.Host) { | ||
for i := range hosts { | ||
if hosts[i] != nil { | ||
h := hosts[i] | ||
s[*h.ID] = h | ||
} | ||
} | ||
} | ||
|
||
func (s Hosts) Contains(hostID string) bool { | ||
_, ok := s[hostID] | ||
return ok | ||
} | ||
|
||
// Len returns the size of the set. | ||
func (s Hosts) Len() int { | ||
return len(s) | ||
} | ||
|
||
func (s Hosts) IsEmpty() bool { | ||
return len(s) == 0 | ||
} | ||
|
||
func (s Hosts) String() string { | ||
str := "" | ||
for _, host := range s { | ||
str += fmt.Sprintf("{id: %s,name: %s},", GetTowerString(host.ID), GetTowerString(host.Name)) | ||
} | ||
|
||
return fmt.Sprintf("[%s]", str) | ||
} | ||
|
||
// Available returns a Hosts with available hosts. | ||
func (s Hosts) Available(memory int64) Hosts { | ||
return s.Filter(func(h *models.Host) bool { | ||
ok, _ := IsAvailableHost(h, memory) | ||
return ok | ||
}) | ||
} | ||
|
||
// Get returns a Host of the specified host. | ||
func (s Hosts) Get(hostID string) *models.Host { | ||
if host, ok := s[hostID]; ok { | ||
return host | ||
} | ||
return nil | ||
} | ||
|
||
// Find returns a Hosts of the specified hosts. | ||
func (s Hosts) Find(targetHosts sets.Set[string]) Hosts { | ||
return s.Filter(func(h *models.Host) bool { | ||
return targetHosts.Has(*h.ID) | ||
}) | ||
} | ||
|
||
// UnsortedList returns the slice with contents in random order. | ||
func (s Hosts) UnsortedList() []*models.Host { | ||
res := make([]*models.Host, 0, len(s)) | ||
for _, value := range s { | ||
res = append(res, value) | ||
} | ||
return res | ||
} | ||
|
||
// Difference returns a copy without hosts that are in the given collection. | ||
func (s Hosts) Difference(hosts Hosts) Hosts { | ||
return s.Filter(func(h *models.Host) bool { | ||
_, found := hosts[*h.ID] | ||
return !found | ||
}) | ||
} | ||
|
||
// newFilteredHostCollection creates a Hosts from a filtered list of values. | ||
func newFilteredHostCollection(filter Func, hosts ...*models.Host) Hosts { | ||
ss := make(Hosts, len(hosts)) | ||
for i := range hosts { | ||
h := hosts[i] | ||
if filter(h) { | ||
ss.Insert(h) | ||
} | ||
} | ||
return ss | ||
} | ||
|
||
// Filter returns a Hosts containing only the Hosts that match all of the given HostFilters. | ||
func (s Hosts) Filter(filters ...Func) Hosts { | ||
return newFilteredHostCollection(And(filters...), s.UnsortedList()...) | ||
} | ||
|
||
// Func is the functon definition for a filter. | ||
type Func func(host *models.Host) bool | ||
|
||
// And returns a filter that returns true if all of the given filters returns true. | ||
func And(filters ...Func) Func { | ||
return func(host *models.Host) bool { | ||
for _, f := range filters { | ||
if !f(host) { | ||
return false | ||
} | ||
} | ||
return true | ||
} | ||
} |
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,69 @@ | ||
/* | ||
Copyright 2023. | ||
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 service | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/onsi/gomega" | ||
"github.com/smartxworks/cloudtower-go-sdk/v2/models" | ||
"k8s.io/apimachinery/pkg/util/sets" | ||
"k8s.io/utils/pointer" | ||
) | ||
|
||
func TestHostCollection(t *testing.T) { | ||
g := gomega.NewGomegaWithT(t) | ||
|
||
t.Run("Find", func(t *testing.T) { | ||
host1 := &models.Host{ID: TowerString("1"), Name: TowerString("host1")} | ||
host2 := &models.Host{ID: TowerString("2"), Name: TowerString("host2")} | ||
|
||
hosts := NewHosts() | ||
g.Expect(hosts.Find(sets.Set[string]{}.Insert(*host1.ID)).Len()).To(gomega.Equal(0)) | ||
|
||
hosts = NewHostsFromList([]*models.Host{host1, host2}) | ||
g.Expect(hosts.Get(*host1.ID)).To(gomega.Equal(host1)) | ||
g.Expect(hosts.Get(*TowerString("404"))).To(gomega.BeNil()) | ||
g.Expect(hosts.Find(sets.Set[string]{}.Insert(*host1.ID)).Contains(*host1.ID)).To(gomega.BeTrue()) | ||
g.Expect(hosts.Find(sets.Set[string]{}.Insert(*host1.ID)).Len()).To(gomega.Equal(1)) | ||
}) | ||
|
||
t.Run("Available", func(t *testing.T) { | ||
host1 := &models.Host{ID: TowerString("1"), Name: TowerString("host1"), AllocatableMemoryBytes: pointer.Int64(1), Status: models.NewHostStatus(models.HostStatusCONNECTEDHEALTHY)} | ||
host2 := &models.Host{ID: TowerString("2"), Name: TowerString("host2"), AllocatableMemoryBytes: pointer.Int64(2), Status: models.NewHostStatus(models.HostStatusCONNECTEDHEALTHY)} | ||
|
||
hosts := NewHosts() | ||
g.Expect(hosts.Available(0).Len()).To(gomega.Equal(0)) | ||
|
||
hosts = NewHostsFromList([]*models.Host{host1, host2}) | ||
availableHosts := hosts.Available(2) | ||
g.Expect(availableHosts.Len()).To(gomega.Equal(1)) | ||
g.Expect(availableHosts.Contains(*host2.ID)).To(gomega.BeTrue()) | ||
}) | ||
|
||
t.Run("Difference", func(t *testing.T) { | ||
host1 := &models.Host{ID: TowerString("1"), Name: TowerString("host1")} | ||
host2 := &models.Host{ID: TowerString("2"), Name: TowerString("host2")} | ||
|
||
g.Expect(NewHosts().Difference(NewHosts()).Len()).To(gomega.Equal(0)) | ||
g.Expect(NewHosts().Difference(NewHosts(host1)).Len()).To(gomega.Equal(0)) | ||
g.Expect(NewHosts(host1).Difference(NewHosts(host1)).Len()).To(gomega.Equal(0)) | ||
g.Expect(NewHosts(host1).Difference(NewHosts()).Contains(*host1.ID)).To(gomega.BeTrue()) | ||
g.Expect(NewHosts(host1).Difference(NewHosts(host2)).Contains(*host1.ID)).To(gomega.BeTrue()) | ||
g.Expect(NewHosts(host1, host2).Difference(NewHosts(host2)).Contains(*host1.ID)).To(gomega.BeTrue()) | ||
}) | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.