-
Notifications
You must be signed in to change notification settings - Fork 172
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
23 changed files
with
549 additions
and
7 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
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
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
File renamed without changes.
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
File renamed without changes.
File renamed without changes.
File renamed without changes.
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,144 @@ | ||
//go:unit | ||
|
||
package ciliumutil | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
|
||
"github.com/sirupsen/logrus" | ||
|
||
v2 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2" | ||
ciliumv2 "github.com/cilium/cilium/pkg/k8s/client/clientset/versioned/typed/cilium.io/v2" | ||
"github.com/cilium/cilium/pkg/k8s/resource" | ||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/apimachinery/pkg/types" | ||
"k8s.io/apimachinery/pkg/watch" | ||
) | ||
|
||
// ensure all interfaces are implemented | ||
var _ ciliumv2.CiliumEndpointInterface = &MockEndpointClient{} | ||
|
||
type MockEndpointClient struct { | ||
l logrus.FieldLogger | ||
namespace string | ||
ciliumEndpoints *MockResource[*v2.CiliumEndpoint] | ||
watchers []watch.Interface | ||
} | ||
|
||
func NewMockEndpointClient(l logrus.FieldLogger, namespace string, ciliumEndpoints *MockResource[*v2.CiliumEndpoint]) *MockEndpointClient { | ||
return &MockEndpointClient{ | ||
l: l, | ||
namespace: namespace, | ||
ciliumEndpoints: ciliumEndpoints, | ||
watchers: make([]watch.Interface, 0), | ||
} | ||
} | ||
|
||
func (m *MockEndpointClient) Create(ctx context.Context, ciliumEndpoint *v2.CiliumEndpoint, opts v1.CreateOptions) (*v2.CiliumEndpoint, error) { | ||
m.l.Info("MockEndpointClient.Create() called") | ||
_, ok, err := m.ciliumEndpoints.GetByKey(resource.NewKey(ciliumEndpoint)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if ok { | ||
return nil, ErrAlreadyExists | ||
} | ||
|
||
m.ciliumEndpoints.Upsert(ciliumEndpoint) | ||
return ciliumEndpoint, nil | ||
} | ||
|
||
func (m *MockEndpointClient) Update(ctx context.Context, ciliumEndpoint *v2.CiliumEndpoint, opts v1.UpdateOptions) (*v2.CiliumEndpoint, error) { | ||
m.l.Info("MockEndpointClient.Update() called") | ||
m.ciliumEndpoints.cache[resource.NewKey(ciliumEndpoint)] = ciliumEndpoint | ||
return ciliumEndpoint, nil | ||
} | ||
|
||
func (m *MockEndpointClient) UpdateStatus(ctx context.Context, ciliumEndpoint *v2.CiliumEndpoint, opts v1.UpdateOptions) (*v2.CiliumEndpoint, error) { | ||
m.l.Warn("MockEndpointClient.UpdateStatus() called but this returns nil because it's not implemented") | ||
return nil, ErrNotImplemented | ||
} | ||
|
||
func (m *MockEndpointClient) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { | ||
m.l.Info("MockEndpointClient.Delete() called") | ||
_, ok, err := m.ciliumEndpoints.GetByKey(resource.Key{Name: name, Namespace: m.namespace}) | ||
if err != nil { | ||
return err | ||
} | ||
if !ok { | ||
return ErrNotFound{} | ||
} | ||
m.ciliumEndpoints.Delete(resource.Key{Name: name, Namespace: m.namespace}) | ||
return nil | ||
} | ||
|
||
func (m *MockEndpointClient) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { | ||
m.l.Warn("MockEndpointClient.DeleteCollection() called but this is not implemented") | ||
return ErrNotImplemented | ||
} | ||
|
||
func (m *MockEndpointClient) Get(ctx context.Context, name string, opts v1.GetOptions) (*v2.CiliumEndpoint, error) { | ||
m.l.Info("MockEndpointClient.Get() called") | ||
item, _, err := m.ciliumEndpoints.GetByKey(resource.Key{Name: name, Namespace: m.namespace}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return item, nil | ||
} | ||
|
||
func (m *MockEndpointClient) List(ctx context.Context, opts v1.ListOptions) (*v2.CiliumEndpointList, error) { | ||
m.l.Info("MockEndpointClient.List() called") | ||
|
||
items := make([]v2.CiliumEndpoint, len(m.ciliumEndpoints.cache)) | ||
for _, cep := range m.ciliumEndpoints.cache { | ||
items = append(items, *cep) | ||
} | ||
|
||
return &v2.CiliumEndpointList{Items: items}, nil | ||
} | ||
|
||
func (m *MockEndpointClient) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { | ||
m.l.Warn("MockEndpointClient.Watch() called but this returns a fake watch because it's not implemented") | ||
|
||
// not sure if watching is important for us | ||
w := watch.NewFake() | ||
m.watchers = append(m.watchers, w) | ||
return w, nil | ||
} | ||
|
||
func (m *MockEndpointClient) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v2.CiliumEndpoint, err error) { | ||
key := resource.Key{Name: name, Namespace: m.namespace} | ||
cep, ok, err := m.ciliumEndpoints.GetByKey(key) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if !ok { | ||
return nil, ErrNotFound{} | ||
} | ||
|
||
var replaceCEPStatus []JSONPatch | ||
err = json.Unmarshal(data, &replaceCEPStatus) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
cep.Status = replaceCEPStatus[0].Value | ||
m.ciliumEndpoints.Upsert(cep) | ||
cep, ok, err = m.ciliumEndpoints.GetByKey(key) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if !ok { | ||
return nil, ErrNotFound{} | ||
} | ||
|
||
return cep, nil | ||
} | ||
|
||
type JSONPatch struct { | ||
OP string `json:"op,omitempty"` | ||
Path string `json:"path,omitempty"` | ||
Value v2.EndpointStatus `json:"value"` | ||
} |
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,26 @@ | ||
//go:unit | ||
|
||
package ciliumutil | ||
|
||
import ( | ||
"github.com/pkg/errors" | ||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
) | ||
|
||
var ( | ||
ErrAlreadyExists = errors.New("already exists") | ||
ErrNotImplemented = errors.New("not implemented") | ||
) | ||
|
||
type ErrNotFound struct{} | ||
|
||
func (e ErrNotFound) Error() string { | ||
return "not found on API server" | ||
} | ||
|
||
func (e ErrNotFound) Status() v1.Status { | ||
return v1.Status{ | ||
Reason: v1.StatusReasonNotFound, | ||
Code: 404, | ||
} | ||
} |
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,14 @@ | ||
package ciliumutil | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
|
||
apierrors "k8s.io/apimachinery/pkg/api/errors" | ||
) | ||
|
||
func TestErrNotFound(t *testing.T) { | ||
err := ErrNotFound{} | ||
require.True(t, apierrors.IsNotFound(err)) | ||
} |
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,120 @@ | ||
//go:unit | ||
|
||
package ciliumutil | ||
|
||
import ( | ||
"context" | ||
|
||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/apimachinery/pkg/types" | ||
"k8s.io/apimachinery/pkg/watch" | ||
|
||
"github.com/sirupsen/logrus" | ||
|
||
v2 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2" | ||
ciliumv2 "github.com/cilium/cilium/pkg/k8s/client/clientset/versioned/typed/cilium.io/v2" | ||
) | ||
|
||
// ensure all interfaces are implemented | ||
var _ ciliumv2.CiliumIdentityInterface = &MockIdentityClient{} | ||
|
||
// MockIdentityClient is a mock implementation of ciliumv2.CiliumIdentityInterface. | ||
// We only implement what's needed. These methods are used by: | ||
// - CRDBackend within the Allocator within the IdentityManager | ||
// - identitygc cell | ||
type MockIdentityClient struct { | ||
l logrus.FieldLogger | ||
// identities maps identity name to identity | ||
// namespace is irrelevant since identity names must be globally unique numbers | ||
identities map[string]*v2.CiliumIdentity | ||
watchers []watch.Interface | ||
} | ||
|
||
func NewMockIdentityClient(l logrus.FieldLogger) *MockIdentityClient { | ||
return &MockIdentityClient{ | ||
l: l, | ||
identities: make(map[string]*v2.CiliumIdentity), | ||
watchers: make([]watch.Interface, 0), | ||
} | ||
} | ||
|
||
func (m *MockIdentityClient) GetIdentities() map[string]*v2.CiliumIdentity { | ||
return m.identities | ||
} | ||
|
||
func (m *MockIdentityClient) Create(ctx context.Context, ciliumIdentity *v2.CiliumIdentity, opts v1.CreateOptions) (*v2.CiliumIdentity, error) { | ||
m.l.Info("MockIdentityClient.Create() called") | ||
if _, ok := m.identities[ciliumIdentity.Name]; ok { | ||
return nil, ErrAlreadyExists | ||
} | ||
|
||
m.identities[ciliumIdentity.Name] = ciliumIdentity | ||
return ciliumIdentity, nil | ||
} | ||
|
||
func (m *MockIdentityClient) Update(ctx context.Context, ciliumIdentity *v2.CiliumIdentity, opts v1.UpdateOptions) (*v2.CiliumIdentity, error) { | ||
m.l.Info("MockIdentityClient.Update() called") | ||
|
||
if _, ok := m.identities[ciliumIdentity.Name]; ok { | ||
m.l.Info("MockIdentityClient.Update() found existing identity") | ||
} else { | ||
m.l.Info("MockIdentityClient.Update() did not find existing identity") | ||
} | ||
|
||
m.identities[ciliumIdentity.Name] = ciliumIdentity | ||
return ciliumIdentity, nil | ||
} | ||
|
||
func (m *MockIdentityClient) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { | ||
m.l.Info("MockIdentityClient.Delete() called") | ||
|
||
if _, ok := m.identities[name]; ok { | ||
m.l.Info("MockIdentityClient.Delete() found existing identity") | ||
} else { | ||
m.l.Info("MockIdentityClient.Delete() did not find existing identity") | ||
} | ||
|
||
delete(m.identities, name) | ||
return nil | ||
} | ||
|
||
func (m *MockIdentityClient) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { | ||
m.l.Warn("MockIdentityClient.DeleteCollection() called but this is not implemented") | ||
return ErrNotImplemented | ||
} | ||
|
||
func (m *MockIdentityClient) Get(ctx context.Context, name string, opts v1.GetOptions) (*v2.CiliumIdentity, error) { | ||
m.l.Info("MockIdentityClient.Get() called") | ||
|
||
if identity, ok := m.identities[name]; ok { | ||
m.l.Info("MockIdentityClient.Get() found existing identity") | ||
return identity, nil | ||
} | ||
|
||
return nil, ErrNotFound{} | ||
} | ||
|
||
func (m *MockIdentityClient) List(ctx context.Context, opts v1.ListOptions) (*v2.CiliumIdentityList, error) { | ||
m.l.Info("MockIdentityClient.List() called") | ||
|
||
items := make([]v2.CiliumIdentity, len(m.identities)) | ||
for _, identity := range m.identities { | ||
items = append(items, *identity) | ||
} | ||
|
||
return &v2.CiliumIdentityList{Items: items}, nil | ||
} | ||
|
||
func (m *MockIdentityClient) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { | ||
m.l.Warn("MockIdentityClient.Watch() called but this returns a fake watch because it's not implemented") | ||
|
||
// not sure if watching is important for us | ||
w := watch.NewFake() | ||
m.watchers = append(m.watchers, w) | ||
return w, nil | ||
} | ||
|
||
func (m *MockIdentityClient) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v2.CiliumIdentity, err error) { | ||
m.l.Warn("MockIdentityClient.Patch() called but this returns nil because it's not implemented") | ||
return nil, ErrNotImplemented | ||
} |
Oops, something went wrong.