From 43180a9bccf6db60938750c0fe6fa3f9999bebfc Mon Sep 17 00:00:00 2001 From: Rohan Kumar Date: Thu, 1 Feb 2024 18:05:18 +0530 Subject: [PATCH] feat (extensions) : Add DSL for Open Virtual Networking `k8s.ovn.org` API group resources Add client module to provide DSL for resources in `k8s.ovn.org` API group Signed-off-by: Rohan Kumar --- CHANGELOG.md | 2 +- .../open-virtual-networking/client/pom.xml | 112 +++++++++++++++++ .../DefaultOpenVirtualNetworkingClient.java | 49 ++++++++ .../GenericOpenVirtualNetworkingClient.java | 27 ++++ ...NamespacedOpenVirtualNetworkingClient.java | 20 +++ .../client/OpenVirtualNetworkingClient.java | 28 +++++ ...OpenVirtualNetworkingExtensionAdapter.java | 41 ++++++ ...V1OpenVirtualNetworkingAPIGroupClient.java | 65 ++++++++++ .../V1OpenVirtualNetworkingAPIGroupDSL.java | 91 ++++++++++++++ ...bernetes.client.extension.ExtensionAdapter | 17 +++ .../OpenVirtualNetworkingClientAdaptTest.java | 82 ++++++++++++ .../org.mockito.plugins.MockMaker | 1 + extensions/open-virtual-networking/pom.xml | 2 + .../open-virtual-networking/tests/pom.xml | 76 +++++++++++ .../io/fabric8/ovn/client/mock/AdaptTest.java | 49 ++++++++ .../AdminPolicyBasedExternalRouteTest.java | 118 ++++++++++++++++++ .../ovn/client/mock/EgressFirewallTest.java | 118 ++++++++++++++++++ .../fabric8/ovn/client/mock/EgressIPTest.java | 106 ++++++++++++++++ .../ovn/client/mock/EgressQoSTest.java | 105 ++++++++++++++++ .../ovn/client/mock/EgressServiceTest.java | 101 +++++++++++++++ pom.xml | 5 + 21 files changed, 1214 insertions(+), 1 deletion(-) create mode 100644 extensions/open-virtual-networking/client/pom.xml create mode 100644 extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/DefaultOpenVirtualNetworkingClient.java create mode 100644 extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/GenericOpenVirtualNetworkingClient.java create mode 100644 extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/NamespacedOpenVirtualNetworkingClient.java create mode 100644 extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/OpenVirtualNetworkingClient.java create mode 100644 extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/OpenVirtualNetworkingExtensionAdapter.java create mode 100644 extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/V1OpenVirtualNetworkingAPIGroupClient.java create mode 100644 extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/dsl/V1OpenVirtualNetworkingAPIGroupDSL.java create mode 100644 extensions/open-virtual-networking/client/src/main/resources/META-INF/services/io.fabric8.kubernetes.client.extension.ExtensionAdapter create mode 100644 extensions/open-virtual-networking/client/src/test/java/io/fabric8/ovn/client/OpenVirtualNetworkingClientAdaptTest.java create mode 100644 extensions/open-virtual-networking/client/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker create mode 100644 extensions/open-virtual-networking/tests/pom.xml create mode 100644 extensions/open-virtual-networking/tests/src/test/java/io/fabric8/ovn/client/mock/AdaptTest.java create mode 100644 extensions/open-virtual-networking/tests/src/test/java/io/fabric8/ovn/client/mock/AdminPolicyBasedExternalRouteTest.java create mode 100644 extensions/open-virtual-networking/tests/src/test/java/io/fabric8/ovn/client/mock/EgressFirewallTest.java create mode 100644 extensions/open-virtual-networking/tests/src/test/java/io/fabric8/ovn/client/mock/EgressIPTest.java create mode 100644 extensions/open-virtual-networking/tests/src/test/java/io/fabric8/ovn/client/mock/EgressQoSTest.java create mode 100644 extensions/open-virtual-networking/tests/src/test/java/io/fabric8/ovn/client/mock/EgressServiceTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 64458670d4d..ac2460ae022 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ #### Dependency Upgrade #### New Features -* Fix #5636: Add model for Kubernetes Open Virtual Networking `k8s.ovn.org/v1` +* Fix #5636: Add new extension `open-virtual-networking` to manage resources in `k8s.ovn.org/v1` API group. #### _**Note**_: Breaking changes diff --git a/extensions/open-virtual-networking/client/pom.xml b/extensions/open-virtual-networking/client/pom.xml new file mode 100644 index 00000000000..942cd1f3c50 --- /dev/null +++ b/extensions/open-virtual-networking/client/pom.xml @@ -0,0 +1,112 @@ + + + + 4.0.0 + + io.fabric8 + kubernetes-client-project + 6.11-SNAPSHOT + ../../../pom.xml + + + open-virtual-networking-client + + + false + + osgi.extender; + filter:="(osgi.extender=osgi.serviceloader.registrar)" + + + osgi.serviceloader; + osgi.serviceloader=io.fabric8.kubernetes.client.extension.ExtensionAdapter + + + io.fabric8.kubernetes.api.builder, + !io.fabric8.ovn.client.*, + * + + + io.fabric8.ovn.client.* + + + ${osgi.include.resources.default}, + /META-INF/services/io.fabric8.kubernetes.client.extension.ExtensionAdapter=target/classes/META-INF/services/io.fabric8.kubernetes.client.extension.ExtensionAdapter + + + + + + io.fabric8 + open-virtual-networking-model-v1 + + + + io.fabric8 + kubernetes-client-api + + + io.sundr + * + + + + + + io.fabric8 + kubernetes-client + runtime + + + + io.sundr + builder-annotations + + + io.sundr + transform-annotations + + + org.projectlombok + lombok + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.junit.jupiter + junit-jupiter-params + test + + + org.mockito + mockito-core + test + + + org.assertj + assertj-core + test + + + diff --git a/extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/DefaultOpenVirtualNetworkingClient.java b/extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/DefaultOpenVirtualNetworkingClient.java new file mode 100644 index 00000000000..68f94f03cb4 --- /dev/null +++ b/extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/DefaultOpenVirtualNetworkingClient.java @@ -0,0 +1,49 @@ +/** + * Copyright (C) 2015 Red Hat, Inc. + * + * 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 io.fabric8.ovn.client; + +import io.fabric8.kubernetes.client.Client; +import io.fabric8.kubernetes.client.RequestConfig; +import io.fabric8.kubernetes.client.WithRequestCallable; +import io.fabric8.kubernetes.client.dsl.FunctionCallable; +import io.fabric8.kubernetes.client.extension.ExtensionRootClientAdapter; +import io.fabric8.ovn.client.dsl.V1OpenVirtualNetworkingAPIGroupDSL; + +public class DefaultOpenVirtualNetworkingClient extends ExtensionRootClientAdapter + implements NamespacedOpenVirtualNetworkingClient { + public DefaultOpenVirtualNetworkingClient() { + super(); + } + + public DefaultOpenVirtualNetworkingClient(Client client) { + super(client); + } + + @Override + public V1OpenVirtualNetworkingAPIGroupDSL v1() { + return adapt(V1OpenVirtualNetworkingAPIGroupClient.class); + } + + @Override + protected DefaultOpenVirtualNetworkingClient newInstance(Client client) { + return new DefaultOpenVirtualNetworkingClient(client); + } + + @Override + public FunctionCallable withRequestConfig(RequestConfig requestConfig) { + return new WithRequestCallable<>(this, requestConfig); + } +} diff --git a/extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/GenericOpenVirtualNetworkingClient.java b/extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/GenericOpenVirtualNetworkingClient.java new file mode 100644 index 00000000000..65dd80c6f57 --- /dev/null +++ b/extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/GenericOpenVirtualNetworkingClient.java @@ -0,0 +1,27 @@ +/** + * Copyright (C) 2015 Red Hat, Inc. + * + * 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 io.fabric8.ovn.client; + +import io.fabric8.kubernetes.client.Client; +import io.fabric8.kubernetes.client.dsl.AnyNamespaceable; +import io.fabric8.kubernetes.client.dsl.Namespaceable; +import io.fabric8.kubernetes.client.dsl.RequestConfigurable; + +public interface GenericOpenVirtualNetworkingClient extends Client, OpenVirtualNetworkingClient, + Namespaceable, + AnyNamespaceable, + RequestConfigurable { +} diff --git a/extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/NamespacedOpenVirtualNetworkingClient.java b/extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/NamespacedOpenVirtualNetworkingClient.java new file mode 100644 index 00000000000..37d5f4b6b3f --- /dev/null +++ b/extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/NamespacedOpenVirtualNetworkingClient.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2015 Red Hat, Inc. + * + * 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 io.fabric8.ovn.client; + +public interface NamespacedOpenVirtualNetworkingClient extends OpenVirtualNetworkingClient, + GenericOpenVirtualNetworkingClient { +} diff --git a/extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/OpenVirtualNetworkingClient.java b/extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/OpenVirtualNetworkingClient.java new file mode 100644 index 00000000000..55e7457a210 --- /dev/null +++ b/extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/OpenVirtualNetworkingClient.java @@ -0,0 +1,28 @@ +/** + * Copyright (C) 2015 Red Hat, Inc. + * + * 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 io.fabric8.ovn.client; + +import io.fabric8.kubernetes.client.Client; +import io.fabric8.ovn.client.dsl.V1OpenVirtualNetworkingAPIGroupDSL; + +public interface OpenVirtualNetworkingClient extends Client { + /** + * DSL entrypoint for entrypoint for k8s.ovn.org/v1 resources + * + * @return {@link V1OpenVirtualNetworkingAPIGroupDSL} + */ + V1OpenVirtualNetworkingAPIGroupDSL v1(); +} diff --git a/extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/OpenVirtualNetworkingExtensionAdapter.java b/extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/OpenVirtualNetworkingExtensionAdapter.java new file mode 100644 index 00000000000..cb51fda7a94 --- /dev/null +++ b/extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/OpenVirtualNetworkingExtensionAdapter.java @@ -0,0 +1,41 @@ +/** + * Copyright (C) 2015 Red Hat, Inc. + * + * 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 io.fabric8.ovn.client; + +import io.fabric8.kubernetes.client.Client; +import io.fabric8.kubernetes.client.extension.ExtensionAdapter; +import io.fabric8.ovn.client.dsl.V1OpenVirtualNetworkingAPIGroupDSL; + +public class OpenVirtualNetworkingExtensionAdapter implements ExtensionAdapter { + + @Override + public Class getExtensionType() { + return OpenVirtualNetworkingClient.class; + } + + @Override + public OpenVirtualNetworkingClient adapt(Client client) { + if (client.hasApiGroup("k8s.ovn.org", false)) { + return new DefaultOpenVirtualNetworkingClient(client); + } + return null; + } + + @Override + public void registerClients(ClientFactory factory) { + factory.register(V1OpenVirtualNetworkingAPIGroupDSL.class, new V1OpenVirtualNetworkingAPIGroupClient()); + } +} diff --git a/extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/V1OpenVirtualNetworkingAPIGroupClient.java b/extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/V1OpenVirtualNetworkingAPIGroupClient.java new file mode 100644 index 00000000000..a6f60d560a8 --- /dev/null +++ b/extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/V1OpenVirtualNetworkingAPIGroupClient.java @@ -0,0 +1,65 @@ +/** + * Copyright (C) 2015 Red Hat, Inc. + * + * 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 io.fabric8.ovn.client; + +import io.fabric8.kubernetes.api.model.ovn.v1.AdminPolicyBasedExternalRoute; +import io.fabric8.kubernetes.api.model.ovn.v1.AdminPolicyBasedExternalRouteList; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressFirewall; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressFirewallList; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressIP; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressIPList; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressQoS; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressQoSList; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressService; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressServiceList; +import io.fabric8.kubernetes.client.dsl.MixedOperation; +import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation; +import io.fabric8.kubernetes.client.dsl.Resource; +import io.fabric8.kubernetes.client.extension.ClientAdapter; +import io.fabric8.ovn.client.dsl.V1OpenVirtualNetworkingAPIGroupDSL; + +public class V1OpenVirtualNetworkingAPIGroupClient extends ClientAdapter + implements V1OpenVirtualNetworkingAPIGroupDSL { + @Override + public NonNamespaceOperation> egressIps() { + return resources(EgressIP.class, EgressIPList.class); + } + + @Override + public NonNamespaceOperation> adminPolicyBasedExternalRoutes() { + return resources(AdminPolicyBasedExternalRoute.class, AdminPolicyBasedExternalRouteList.class); + } + + @Override + public MixedOperation> egressFirewalls() { + return resources(EgressFirewall.class, EgressFirewallList.class); + } + + @Override + public MixedOperation> egressQoses() { + return resources(EgressQoS.class, EgressQoSList.class); + } + + @Override + public MixedOperation> egressServices() { + return resources(EgressService.class, EgressServiceList.class); + } + + @Override + public V1OpenVirtualNetworkingAPIGroupClient newInstance() { + return new V1OpenVirtualNetworkingAPIGroupClient(); + } +} diff --git a/extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/dsl/V1OpenVirtualNetworkingAPIGroupDSL.java b/extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/dsl/V1OpenVirtualNetworkingAPIGroupDSL.java new file mode 100644 index 00000000000..76666592399 --- /dev/null +++ b/extensions/open-virtual-networking/client/src/main/java/io/fabric8/ovn/client/dsl/V1OpenVirtualNetworkingAPIGroupDSL.java @@ -0,0 +1,91 @@ +/** + * Copyright (C) 2015 Red Hat, Inc. + * + * 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 io.fabric8.ovn.client.dsl; + +import io.fabric8.kubernetes.api.model.ovn.v1.AdminPolicyBasedExternalRoute; +import io.fabric8.kubernetes.api.model.ovn.v1.AdminPolicyBasedExternalRouteList; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressFirewall; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressFirewallList; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressIP; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressIPList; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressQoS; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressQoSList; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressService; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressServiceList; +import io.fabric8.kubernetes.client.Client; +import io.fabric8.kubernetes.client.dsl.MixedOperation; +import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation; +import io.fabric8.kubernetes.client.dsl.Resource; + +public interface V1OpenVirtualNetworkingAPIGroupDSL extends Client { + /** + * API entrypoint for k8s.ovn.org/v1 EgressIP. + * EgressIP is a CRD allowing the user to define a fixed + * source IP for all egress traffic originating from any pods which + * match the EgressIP resource according to its spec definition. + * + * @return {@link NonNamespaceOperation} for EgressIP + */ + NonNamespaceOperation> egressIps(); + + /** + * API entrypoint for k8s.ovn.org/v1 AdminPolicyBasedExternalRoute. + * AdminPolicyBasedExternalRoute is a CRD allowing the cluster administrators to configure policies for external gateway IPs + * to be applied to all the pods contained in selected namespaces. + * Egress traffic from the pods that belong to the selected namespaces to outside the cluster is routed through these external + * gateway IPs. + * + * @return {@link NonNamespaceOperation} for AdminPolicBasedExternalRoute + */ + NonNamespaceOperation> adminPolicyBasedExternalRoutes(); + + /** + * API entrypoint for k8s.ovn.org/v1 EgressFirewall. + * EgressFirewall describes the current egress firewall for a Namespace. + * Traffic from a pod to an IP address outside the cluster will be checked against + * each EgressFirewallRule in the pod's namespace's EgressFirewall, in + * order. If no rule matches (or no EgressFirewall is present) then the traffic + * will be allowed by default. + * + * @return {@link MixedOperation} for EgressFirewall + */ + MixedOperation> egressFirewalls(); + + /** + * API entrypoint for k8s.ovn.org/v1 EgressQoS. + * EgressQoS is a CRD that allows the user to define a DSCP value + * for pods egress traffic on its namespace to specified CIDRs. + * Traffic from these pods will be checked against each EgressQoSRule in + * the namespace's EgressQoS, and if there is a match the traffic is marked + * with the relevant DSCP value. + * + * @return {@link MixedOperation} for EgressQoS + */ + MixedOperation> egressQoses(); + + /** + * API entrypoint for k8s.ovn.org/v1 EgressService. + * EgressService is a CRD that allows the user to request that the source + * IP of egress packets originating from all the pods that are endpoints + * of the corresponding LoadBalancer Service would be its ingress IP. + * In addition, it allows the user to request that egress packets originating from + * all the pods that are endpoints of the LoadBalancer service would use a different + * network than the main one. + * + * @return {@link MixedOperation} for EgressService + */ + MixedOperation> egressServices(); +} diff --git a/extensions/open-virtual-networking/client/src/main/resources/META-INF/services/io.fabric8.kubernetes.client.extension.ExtensionAdapter b/extensions/open-virtual-networking/client/src/main/resources/META-INF/services/io.fabric8.kubernetes.client.extension.ExtensionAdapter new file mode 100644 index 00000000000..36f8186f284 --- /dev/null +++ b/extensions/open-virtual-networking/client/src/main/resources/META-INF/services/io.fabric8.kubernetes.client.extension.ExtensionAdapter @@ -0,0 +1,17 @@ +# +# Copyright (C) 2018 Red Hat inc. +# +# 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. +# + +io.fabric8.ovn.client.OpenVirtualNetworkingExtensionAdapter diff --git a/extensions/open-virtual-networking/client/src/test/java/io/fabric8/ovn/client/OpenVirtualNetworkingClientAdaptTest.java b/extensions/open-virtual-networking/client/src/test/java/io/fabric8/ovn/client/OpenVirtualNetworkingClientAdaptTest.java new file mode 100644 index 00000000000..40b418fb00c --- /dev/null +++ b/extensions/open-virtual-networking/client/src/test/java/io/fabric8/ovn/client/OpenVirtualNetworkingClientAdaptTest.java @@ -0,0 +1,82 @@ +/** + * Copyright (C) 2015 Red Hat, Inc. + * + * 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 io.fabric8.ovn.client; + +import io.fabric8.kubernetes.api.model.APIGroup; +import io.fabric8.kubernetes.api.model.APIGroupBuilder; +import io.fabric8.kubernetes.api.model.APIGroupList; +import io.fabric8.kubernetes.api.model.APIGroupListBuilder; +import io.fabric8.kubernetes.client.Config; +import io.fabric8.kubernetes.client.ConfigBuilder; +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.dsl.internal.OperationSupport; +import io.fabric8.kubernetes.client.http.HttpClient; +import io.fabric8.kubernetes.client.impl.KubernetesClientImpl; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.MockedConstruction; +import org.mockito.Mockito; + +import java.util.Optional; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mockConstruction; +import static org.mockito.Mockito.when; + +class OpenVirtualNetworkingClientAdaptTest { + private KubernetesClient kubernetesClient; + + @BeforeEach + public void setUp() { + HttpClient mockClient = Mockito.mock(HttpClient.class, Mockito.RETURNS_DEEP_STUBS); + Config config = new ConfigBuilder().withMasterUrl("https://localhost:8443/").build(); + kubernetesClient = new KubernetesClientImpl(mockClient, config); + } + + @AfterEach + void tearDown() { + kubernetesClient.close(); + kubernetesClient = null; + } + + @ParameterizedTest + @MethodSource("getInputData") + void isSupported_withGivenApiGroup_shouldValidateSupport(String apiGroupName, boolean expectedResult) { + try (MockedConstruction ignored = mockConstruction(OperationSupport.class, (mock, ctx) -> { + givenApiGroupsCallReturns(mock, new APIGroupBuilder().withName(apiGroupName).build()); + })) { + assertThat(Optional.ofNullable(kubernetesClient.adapt(OpenVirtualNetworkingClient.class)).isPresent()) + .isEqualTo(expectedResult); + } + } + + private static Stream getInputData() { + return Stream.of( + Arguments.of("k8s.ovn.org", true), + Arguments.of("unknown-apigroup.io", false)); + } + + private void givenApiGroupsCallReturns(OperationSupport operationSupport, APIGroup apiGroup) { + when(operationSupport.restCall(APIGroupList.class, "/apis")) + .thenReturn(new APIGroupListBuilder() + .addToGroups(apiGroup) + .build()); + } +} diff --git a/extensions/open-virtual-networking/client/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/extensions/open-virtual-networking/client/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 00000000000..1f0955d450f --- /dev/null +++ b/extensions/open-virtual-networking/client/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline diff --git a/extensions/open-virtual-networking/pom.xml b/extensions/open-virtual-networking/pom.xml index fa0bd3b49e1..7dd0f899967 100644 --- a/extensions/open-virtual-networking/pom.xml +++ b/extensions/open-virtual-networking/pom.xml @@ -35,6 +35,8 @@ model-v1 + client + tests diff --git a/extensions/open-virtual-networking/tests/pom.xml b/extensions/open-virtual-networking/tests/pom.xml new file mode 100644 index 00000000000..831238b4219 --- /dev/null +++ b/extensions/open-virtual-networking/tests/pom.xml @@ -0,0 +1,76 @@ + + + + 4.0.0 + + io.fabric8 + kubernetes-client-project + 6.11-SNAPSHOT + ../../../pom.xml + + open-virtual-networking-tests + jar + Fabric8 :: Open Virtual Networking :: Tests + + + + io.fabric8 + open-virtual-networking-client + + + + io.fabric8 + kubernetes-server-mock + test + + + + io.fabric8 + mockwebserver + test + + + + org.junit.jupiter + junit-jupiter-engine + test + + + + org.junit.jupiter + junit-jupiter-params + test + + + + org.slf4j + slf4j-simple + ${slf4j.version} + test + + + + org.assertj + assertj-core + test + + + diff --git a/extensions/open-virtual-networking/tests/src/test/java/io/fabric8/ovn/client/mock/AdaptTest.java b/extensions/open-virtual-networking/tests/src/test/java/io/fabric8/ovn/client/mock/AdaptTest.java new file mode 100644 index 00000000000..cf479893e43 --- /dev/null +++ b/extensions/open-virtual-networking/tests/src/test/java/io/fabric8/ovn/client/mock/AdaptTest.java @@ -0,0 +1,49 @@ +/** + * Copyright (C) 2015 Red Hat, Inc. + * + * 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 io.fabric8.ovn.client.mock; + +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; +import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer; +import io.fabric8.ovn.client.OpenVirtualNetworkingClient; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import java.util.Optional; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; + +@EnableKubernetesMockClient +class AdaptTest { + private KubernetesClient client; + private KubernetesMockServer server; + + @ParameterizedTest(name = "when server does not support {0}, then adapt = {1}") + @CsvSource(value = { + "example.k8s.io,true", + "k8s.ovn.org,false" + }) + void shouldAdaptOnlyWhenOvnApiGroupSupported(String unsupportedApiGroup, boolean expectedResult) { + // Given + server.setUnsupported(unsupportedApiGroup); + + // When + OpenVirtualNetworkingClient ovnClient = client.adapt(OpenVirtualNetworkingClient.class); + + // Then + assertThat(Optional.ofNullable(ovnClient).isPresent()).isEqualTo(expectedResult); + } +} diff --git a/extensions/open-virtual-networking/tests/src/test/java/io/fabric8/ovn/client/mock/AdminPolicyBasedExternalRouteTest.java b/extensions/open-virtual-networking/tests/src/test/java/io/fabric8/ovn/client/mock/AdminPolicyBasedExternalRouteTest.java new file mode 100644 index 00000000000..23cb7c0e3d9 --- /dev/null +++ b/extensions/open-virtual-networking/tests/src/test/java/io/fabric8/ovn/client/mock/AdminPolicyBasedExternalRouteTest.java @@ -0,0 +1,118 @@ +/** + * Copyright (C) 2015 Red Hat, Inc. + * + * 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 io.fabric8.ovn.client.mock; + +import io.fabric8.kubernetes.api.model.ovn.v1.AdminPolicyBasedExternalRoute; +import io.fabric8.kubernetes.api.model.ovn.v1.AdminPolicyBasedExternalRouteBuilder; +import io.fabric8.kubernetes.api.model.ovn.v1.AdminPolicyBasedExternalRouteList; +import io.fabric8.kubernetes.api.model.ovn.v1.AdminPolicyBasedExternalRouteListBuilder; +import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; +import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer; +import io.fabric8.ovn.client.OpenVirtualNetworkingClient; +import org.junit.jupiter.api.Test; + +import java.net.HttpURLConnection; +import java.util.Collections; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; + +@EnableKubernetesMockClient +class AdminPolicyBasedExternalRouteTest { + private OpenVirtualNetworkingClient ovnClient; + private KubernetesMockServer server; + + @Test + void get() { + // Given + server.expect().get().withPath("/apis/k8s.ovn.org/v1/adminpolicybasedexternalroutes/test-get") + .andReturn(HttpURLConnection.HTTP_OK, createNewAdminPolicyBasedExternalRoute("test-get")) + .once(); + + // When + AdminPolicyBasedExternalRoute adminPolicyBasedExternalRoute = ovnClient.v1() + .adminPolicyBasedExternalRoutes().withName("test-get").get(); + + // Then + assertThat(adminPolicyBasedExternalRoute) + .isNotNull() + .hasFieldOrPropertyWithValue("metadata.name", "test-get"); + } + + @Test + void list() { + // Given + server.expect().get().withPath("/apis/k8s.ovn.org/v1/adminpolicybasedexternalroutes") + .andReturn(HttpURLConnection.HTTP_OK, new AdminPolicyBasedExternalRouteListBuilder() + .addToItems(createNewAdminPolicyBasedExternalRoute("test-list")) + .build()) + .once(); + + // When + AdminPolicyBasedExternalRouteList adminPolicyBasedExternalRouteList = ovnClient.v1() + .adminPolicyBasedExternalRoutes().list(); + + // Then + assertThat(adminPolicyBasedExternalRouteList).isNotNull(); + assertThat(adminPolicyBasedExternalRouteList.getItems()).hasSize(1); + assertThat(adminPolicyBasedExternalRouteList.getItems().get(0)) + .hasFieldOrPropertyWithValue("metadata.name", "test-list"); + } + + @Test + void delete() { + // Given + server.expect().delete().withPath("/apis/k8s.ovn.org/v1/adminpolicybasedexternalroutes/test-adminpolicybasedexternalroute") + .andReturn(HttpURLConnection.HTTP_OK, createNewAdminPolicyBasedExternalRoute("test-adminpolicybasedexternalroute")) + .once(); + + // When + boolean isDeleted = ovnClient.v1().adminPolicyBasedExternalRoutes() + .withName("test-adminpolicybasedexternalroute").delete().size() == 1; + + // Then + assertThat(isDeleted).isTrue(); + } + + private AdminPolicyBasedExternalRoute createNewAdminPolicyBasedExternalRoute(String name) { + return new AdminPolicyBasedExternalRouteBuilder() + .withNewMetadata() + .withName(name) + .endMetadata() + .withNewSpec() + .withNewFrom() + .withNewNamespaceSelector() + .withMatchLabels(Collections.singletonMap("multiple_gws", "true")) + .endNamespaceSelector() + .endFrom() + .withNewNextHops() + .addNewStatic() + .withIp("172.18.0.2") + .withBfdEnabled(true) + .endStatic() + .addNewDynamic() + .withBfdEnabled(true) + .withNewNamespaceSelector() + .withMatchLabels(Collections.singletonMap("gateway", "true")) + .endNamespaceSelector() + .withNewPodSelector() + .withMatchLabels(Collections.singletonMap("external-gateway", "true")) + .endPodSelector() + .endDynamic() + .endNextHops() + .endSpec() + .build(); + } +} diff --git a/extensions/open-virtual-networking/tests/src/test/java/io/fabric8/ovn/client/mock/EgressFirewallTest.java b/extensions/open-virtual-networking/tests/src/test/java/io/fabric8/ovn/client/mock/EgressFirewallTest.java new file mode 100644 index 00000000000..dc532de1439 --- /dev/null +++ b/extensions/open-virtual-networking/tests/src/test/java/io/fabric8/ovn/client/mock/EgressFirewallTest.java @@ -0,0 +1,118 @@ +/** + * Copyright (C) 2015 Red Hat, Inc. + * + * 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 io.fabric8.ovn.client.mock; + +import io.fabric8.kubernetes.api.model.ovn.v1.EgressFirewall; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressFirewallBuilder; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressFirewallList; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressFirewallListBuilder; +import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; +import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer; +import io.fabric8.ovn.client.OpenVirtualNetworkingClient; +import org.junit.jupiter.api.Test; + +import java.net.HttpURLConnection; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; + +@EnableKubernetesMockClient +class EgressFirewallTest { + private OpenVirtualNetworkingClient ovnClient; + private KubernetesMockServer server; + + @Test + void get() { + // Given + server.expect().get().withPath("/apis/k8s.ovn.org/v1/namespaces/default/egressfirewalls/test-get") + .andReturn(HttpURLConnection.HTTP_OK, createNewEgressFirewall("test-get")) + .once(); + + // When + EgressFirewall egressFirewall = ovnClient.v1().egressFirewalls().inNamespace("default") + .withName("test-get").get(); + + // Then + assertThat(egressFirewall) + .isNotNull() + .hasFieldOrPropertyWithValue("metadata.name", "test-get"); + } + + @Test + void list() { + // Given + server.expect().get().withPath("/apis/k8s.ovn.org/v1/namespaces/default/egressfirewalls") + .andReturn(HttpURLConnection.HTTP_OK, new EgressFirewallListBuilder() + .addToItems(createNewEgressFirewall("test-list")) + .build()) + .once(); + + // When + EgressFirewallList egressFirewallList = ovnClient.v1().egressFirewalls().inNamespace("default").list(); + + // Then + assertThat(egressFirewallList).isNotNull(); + assertThat(egressFirewallList.getItems()).hasSize(1); + assertThat(egressFirewallList.getItems().get(0)) + .hasFieldOrPropertyWithValue("metadata.name", "test-list"); + } + + @Test + void delete() { + // Given + server.expect().delete().withPath("/apis/k8s.ovn.org/v1/namespaces/default/egressfirewalls/default") + .andReturn(HttpURLConnection.HTTP_OK, createNewEgressFirewall("default")) + .once(); + + // When + boolean isDeleted = ovnClient.v1().egressFirewalls().inNamespace("default").withName("default") + .delete().size() == 1; + + // Then + assertThat(isDeleted).isTrue(); + } + + private EgressFirewall createNewEgressFirewall(String name) { + return new EgressFirewallBuilder() + .withNewMetadata() + .withName(name) + .endMetadata() + .withNewSpec() + .addNewEgress() + .withType("Allow") + .withNewTo() + .withDnsName("www.openvswitch.org") + .endTo() + .endEgress() + .addNewEgress() + .withType("Allow") + .withNewTo() + .withCidrSelector("1.2.3.0/24") + .endTo() + .addNewPort() + .withProtocol("UDP") + .withPort(55) + .endPort() + .endEgress() + .addNewEgress() + .withType("Deny") + .withNewTo() + .withCidrSelector("0.0.0.0/0") + .endTo() + .endEgress() + .endSpec() + .build(); + } +} diff --git a/extensions/open-virtual-networking/tests/src/test/java/io/fabric8/ovn/client/mock/EgressIPTest.java b/extensions/open-virtual-networking/tests/src/test/java/io/fabric8/ovn/client/mock/EgressIPTest.java new file mode 100644 index 00000000000..0812adc7a3a --- /dev/null +++ b/extensions/open-virtual-networking/tests/src/test/java/io/fabric8/ovn/client/mock/EgressIPTest.java @@ -0,0 +1,106 @@ +/** + * Copyright (C) 2015 Red Hat, Inc. + * + * 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 io.fabric8.ovn.client.mock; + +import io.fabric8.kubernetes.api.model.ovn.v1.EgressIP; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressIPBuilder; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressIPList; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressIPListBuilder; +import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; +import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer; +import io.fabric8.ovn.client.OpenVirtualNetworkingClient; +import org.junit.jupiter.api.Test; + +import java.net.HttpURLConnection; +import java.util.Collections; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; + +@EnableKubernetesMockClient +class EgressIPTest { + private OpenVirtualNetworkingClient ovnClient; + private KubernetesMockServer server; + + @Test + void get() { + // Given + server.expect().get().withPath("/apis/k8s.ovn.org/v1/egressips/test-get") + .andReturn(HttpURLConnection.HTTP_OK, createNewEgressIP("test-get")) + .once(); + + // When + EgressIP egressIP = ovnClient.v1().egressIps().withName("test-get").get(); + + // Then + assertThat(egressIP) + .isNotNull() + .hasFieldOrPropertyWithValue("metadata.name", "test-get"); + } + + @Test + void list() { + // Given + server.expect().get().withPath("/apis/k8s.ovn.org/v1/egressips") + .andReturn(HttpURLConnection.HTTP_OK, new EgressIPListBuilder() + .addToItems(createNewEgressIP("test-list")) + .build()) + .once(); + + // When + EgressIPList egressIPList = ovnClient.v1().egressIps().list(); + + // Then + assertThat(egressIPList).isNotNull(); + assertThat(egressIPList.getItems()).hasSize(1); + assertThat(egressIPList.getItems().get(0)) + .hasFieldOrPropertyWithValue("metadata.name", "test-list"); + } + + @Test + void delete() { + // Given + server.expect().delete().withPath("/apis/k8s.ovn.org/v1/egressips/egressip-prod") + .andReturn(HttpURLConnection.HTTP_OK, createNewEgressIP("egressip-prod")) + .once(); + + // When + boolean isDeleted = ovnClient.v1().egressIps().withName("egressip-prod").delete().size() == 1; + + // Then + assertThat(isDeleted).isTrue(); + } + + private EgressIP createNewEgressIP(String name) { + return new EgressIPBuilder() + .withNewMetadata() + .withName(name) + .endMetadata() + .withNewSpec() + .addToEgressIPs("172.18.0.33", "172.18.0.44") + .withNewNamespaceSelector() + .addNewMatchExpression() + .withKey("environment") + .withOperator("NotIn") + .withValues("development") + .endMatchExpression() + .endNamespaceSelector() + .withNewPodSelector() + .withMatchLabels(Collections.singletonMap("app", "web")) + .endPodSelector() + .endSpec() + .build(); + } +} diff --git a/extensions/open-virtual-networking/tests/src/test/java/io/fabric8/ovn/client/mock/EgressQoSTest.java b/extensions/open-virtual-networking/tests/src/test/java/io/fabric8/ovn/client/mock/EgressQoSTest.java new file mode 100644 index 00000000000..47a4aac4a84 --- /dev/null +++ b/extensions/open-virtual-networking/tests/src/test/java/io/fabric8/ovn/client/mock/EgressQoSTest.java @@ -0,0 +1,105 @@ +/** + * Copyright (C) 2015 Red Hat, Inc. + * + * 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 io.fabric8.ovn.client.mock; + +import io.fabric8.kubernetes.api.model.ovn.v1.EgressQoS; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressQoSBuilder; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressQoSList; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressQoSListBuilder; +import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; +import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer; +import io.fabric8.ovn.client.OpenVirtualNetworkingClient; +import org.junit.jupiter.api.Test; + +import java.net.HttpURLConnection; +import java.util.Collections; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; + +@EnableKubernetesMockClient +class EgressQoSTest { + private OpenVirtualNetworkingClient ovnClient; + private KubernetesMockServer server; + + @Test + void get() { + // Given + server.expect().get().withPath("/apis/k8s.ovn.org/v1/namespaces/default/egressqoses/test-get") + .andReturn(HttpURLConnection.HTTP_OK, createNewEgressQoS("test-get")) + .once(); + + // When + EgressQoS egressQoS = ovnClient.v1().egressQoses().inNamespace("default").withName("test-get").get(); + + // Then + assertThat(egressQoS) + .isNotNull() + .hasFieldOrPropertyWithValue("metadata.name", "test-get"); + } + + @Test + void list() { + // Given + server.expect().get().withPath("/apis/k8s.ovn.org/v1/namespaces/default/egressqoses") + .andReturn(HttpURLConnection.HTTP_OK, new EgressQoSListBuilder() + .addToItems(createNewEgressQoS("test-list")) + .build()) + .once(); + + // When + EgressQoSList egressQoSList = ovnClient.v1().egressQoses().inNamespace("default").list(); + + // Then + assertThat(egressQoSList).isNotNull(); + assertThat(egressQoSList.getItems()).hasSize(1); + assertThat(egressQoSList.getItems().get(0)) + .hasFieldOrPropertyWithValue("metadata.name", "test-list"); + } + + @Test + void delete() { + // Given + server.expect().delete().withPath("/apis/k8s.ovn.org/v1/namespaces/default/egressqoses/default") + .andReturn(HttpURLConnection.HTTP_OK, createNewEgressQoS("default")) + .once(); + + // When + boolean isDeleted = ovnClient.v1().egressQoses().inNamespace("default").withName("default").delete() + .size() == 1; + + // Then + assertThat(isDeleted).isTrue(); + } + + private EgressQoS createNewEgressQoS(String name) { + return new EgressQoSBuilder() + .withNewMetadata() + .withName(name) + .endMetadata() + .withNewSpec() + .addNewEgress() + .withDscp(48) + .withNewPodSelector() + .withMatchLabels(Collections.singletonMap("app", "updated-example")) + .endPodSelector() + .endEgress() + .addNewEgress() + .withDscp(28) + .endEgress() + .endSpec() + .build(); + } +} diff --git a/extensions/open-virtual-networking/tests/src/test/java/io/fabric8/ovn/client/mock/EgressServiceTest.java b/extensions/open-virtual-networking/tests/src/test/java/io/fabric8/ovn/client/mock/EgressServiceTest.java new file mode 100644 index 00000000000..8dfbef43d60 --- /dev/null +++ b/extensions/open-virtual-networking/tests/src/test/java/io/fabric8/ovn/client/mock/EgressServiceTest.java @@ -0,0 +1,101 @@ +/** + * Copyright (C) 2015 Red Hat, Inc. + * + * 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 io.fabric8.ovn.client.mock; + +import io.fabric8.kubernetes.api.model.ovn.v1.EgressService; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressServiceBuilder; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressServiceList; +import io.fabric8.kubernetes.api.model.ovn.v1.EgressServiceListBuilder; +import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; +import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer; +import io.fabric8.ovn.client.OpenVirtualNetworkingClient; +import org.junit.jupiter.api.Test; + +import java.net.HttpURLConnection; +import java.util.Collections; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; + +@EnableKubernetesMockClient +class EgressServiceTest { + private OpenVirtualNetworkingClient ovnClient; + private KubernetesMockServer server; + + @Test + void get() { + // Given + server.expect().get().withPath("/apis/k8s.ovn.org/v1/namespaces/default/egressservices/test-get") + .andReturn(HttpURLConnection.HTTP_OK, createNewEgressService("test-get")) + .once(); + + // When + EgressService egressService = ovnClient.v1().egressServices().inNamespace("default") + .withName("test-get").get(); + + // Then + assertThat(egressService) + .isNotNull() + .hasFieldOrPropertyWithValue("metadata.name", "test-get"); + } + + @Test + void list() { + // Given + server.expect().get().withPath("/apis/k8s.ovn.org/v1/namespaces/default/egressservices") + .andReturn(HttpURLConnection.HTTP_OK, new EgressServiceListBuilder() + .addToItems(createNewEgressService("test-list")) + .build()) + .once(); + + // When + EgressServiceList egressServiceList = ovnClient.v1().egressServices().inNamespace("default").list(); + + // Then + assertThat(egressServiceList).isNotNull(); + assertThat(egressServiceList.getItems()).hasSize(1); + assertThat(egressServiceList.getItems().get(0)) + .hasFieldOrPropertyWithValue("metadata.name", "test-list"); + } + + @Test + void delete() { + // Given + server.expect().delete().withPath("/apis/k8s.ovn.org/v1/namespaces/default/egressservices/default") + .andReturn(HttpURLConnection.HTTP_OK, createNewEgressService("default")) + .once(); + + // When + boolean isDeleted = ovnClient.v1().egressServices().inNamespace("default").withName("default").delete() + .size() == 1; + + // Then + assertThat(isDeleted).isTrue(); + } + + private EgressService createNewEgressService(String name) { + return new EgressServiceBuilder() + .withNewMetadata() + .withName(name) + .endMetadata() + .withNewSpec() + .withSourceIPBy("LoadBalancerIP") + .withNewNodeSelector() + .withMatchLabels(Collections.singletonMap("node-role.kubernetes.io/worker", "")) + .endNodeSelector() + .endSpec() + .build(); + } +} diff --git a/pom.xml b/pom.xml index b1dfaff651c..6b46de382f5 100644 --- a/pom.xml +++ b/pom.xml @@ -626,6 +626,11 @@ open-virtual-networking-model-v1 ${project.version} + + io.fabric8 + open-virtual-networking-client + ${project.version} + io.fabric8