diff --git a/.github/workflows/e2e-crc-okd-tests.yml b/.github/workflows/e2e-crc-okd-tests.yml new file mode 100644 index 00000000000..bb1c796442a --- /dev/null +++ b/.github/workflows/e2e-crc-okd-tests.yml @@ -0,0 +1,96 @@ +# +# 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. +# + +name: E2E CRC-OKD Tests + +on: + workflow_dispatch: + pull_request: + paths: + - .github/workflows/e2e-crc-okd-tests.yml + schedule: + - cron: '0 4 * * *' # Every day at 4am + +concurrency: + group: single-instance-for-crc-okd-cluster + cancel-in-progress: true + +env: + IT_MODULE: kubernetes-itests + MAVEN_ARGS: -B -C -V -ntp -Dhttp.keepAlive=false -e + SHELL: /bin/bash + +jobs: + e2e: + name: CRC ${{ matrix.crc }} / OKD ${{ matrix.okd }} + runs-on: ubuntu-24.04 + if: github.repository == 'fabric8io/kubernetes-client' + strategy: + fail-fast: false + matrix: + # There is some problem with latest version of crc configured with okd preset. I + # wasn't able to run tests successfully on latest version of crc. See linked issue: + # https://github.com/crc-org/crc/issues/4382 + # TODO: Update CRC version to latest when aforementioned issue gets resolved + # https://github.com/fabric8io/kubernetes-client/issues/6415 + okd: [ v4.14.0 ] + crc: [ 2.32.0 ] + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Java 11 + uses: actions/setup-java@v4 + with: + java-version: '11' + distribution: 'temurin' + - name: Install required virtualization software + run: | + sudo apt-get update + sudo apt install qemu-kvm libvirt-daemon libvirt-daemon-system + # This package may not be present depending on Ubuntu version + sudo apt install virtiofsd || true + sudo adduser $USER libvirt + sudo adduser $USER kvm + sudo usermod -a -G libvirt $USER + - name: Remove unwanted stuff to free up disk image + run: | + sudo rm -rf /usr/share/dotnet + sudo rm -rf /usr/local/lib/android + sudo rm -rf /opt/ghc + sudo rm -rf "/usr/local/share/boost" + sudo rm -rf /opt/hostedtoolcache/CodeQL + + sudo docker image prune --all --force + + sudo swapoff -a + sudo rm -f /mnt/swapfile + - name: Download CRC + run: | + wget https://developers.redhat.com/content-gateway/file/pub/openshift-v4/clients/crc/${{ matrix.crc }}/crc-linux-amd64.tar.xz + tar -xJf crc-linux-amd64.tar.xz + sudo cp crc-linux-${{ matrix.crc }}-amd64/crc /usr/local/bin/crc + - name: Set the crc config + run: | + crc config set preset okd + crc config set network-mode user + - name: Setup CRC + run: sudo -su $USER crc setup + - name: Start CRC + run: sudo -su $USER crc start + - name: Install Kubernetes Client + run: make quickly + - name: Install and Run Integration Tests + run: ./mvnw ${MAVEN_ARGS} -Pitests -pl $IT_MODULE verify diff --git a/kubernetes-itests/src/test/java/io/fabric8/kubernetes/APIVersionsIT.java b/kubernetes-itests/src/test/java/io/fabric8/kubernetes/APIVersionsIT.java index da719ee11f9..0b411b43de6 100644 --- a/kubernetes-itests/src/test/java/io/fabric8/kubernetes/APIVersionsIT.java +++ b/kubernetes-itests/src/test/java/io/fabric8/kubernetes/APIVersionsIT.java @@ -40,7 +40,8 @@ void testApiVersions() { .asInstanceOf(InstanceOfAssertFactories.list(ServerAddressByClientCIDR.class)) .singleElement() .hasFieldOrPropertyWithValue("clientCIDR", "0.0.0.0/0") - .hasFieldOrPropertyWithValue("serverAddress", - String.format("%s:%d", client.getMasterUrl().getHost(), client.getMasterUrl().getPort())); + .extracting("serverAddress") + .asString() + .isNotBlank(); } } diff --git a/kubernetes-itests/src/test/java/io/fabric8/kubernetes/PluralizeIT.java b/kubernetes-itests/src/test/java/io/fabric8/kubernetes/PluralizeIT.java index 45d5a98931f..0135be16e1f 100644 --- a/kubernetes-itests/src/test/java/io/fabric8/kubernetes/PluralizeIT.java +++ b/kubernetes-itests/src/test/java/io/fabric8/kubernetes/PluralizeIT.java @@ -29,6 +29,7 @@ import org.junit.jupiter.params.provider.MethodSource; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Locale; import java.util.stream.Stream; @@ -39,6 +40,10 @@ @RequireK8sVersionAtLeast(majorVersion = 1, minorVersion = 16) class PluralizeIT { + // This might be a mistake in OpenShift Aggregated Discovery API, + // The resource kind is ResourceAccessReview, and it's singularName is set as localresourceaccessreview + private static final String[] EXCEPTIONAL_SINGULAR_NAME = new String[] { "localresourceaccessreview" }; + @DisplayName("toPlural, should return argument's plural") @ParameterizedTest(name = "{index} {0}: ''{1}'' plural is ''{2}''") @MethodSource("toPluralInput") @@ -66,7 +71,9 @@ static Stream toPluralInput() { .map(ar -> arguments( ar.getKind(), // So far singularName field is always blank, we fall back to lower-cased kind - Utils.isNullOrEmpty(ar.getSingularName()) ? ar.getKind().toLowerCase(Locale.ROOT) : ar.getSingularName(), + Utils.isNullOrEmpty(ar.getSingularName()) || Arrays.asList(EXCEPTIONAL_SINGULAR_NAME).contains(ar.getSingularName()) + ? ar.getKind().toLowerCase(Locale.ROOT) + : ar.getSingularName(), ar.getName())); } } diff --git a/kubernetes-itests/src/test/java/io/fabric8/openshift/ServiceToURLIT.java b/kubernetes-itests/src/test/java/io/fabric8/openshift/ServiceToURLIT.java index 02e066fef89..dd05e07e6ec 100644 --- a/kubernetes-itests/src/test/java/io/fabric8/openshift/ServiceToURLIT.java +++ b/kubernetes-itests/src/test/java/io/fabric8/openshift/ServiceToURLIT.java @@ -20,7 +20,7 @@ import io.fabric8.kubernetes.api.model.IntOrString; import io.fabric8.kubernetes.api.model.Service; import io.fabric8.kubernetes.api.model.ServiceBuilder; -import io.fabric8.kubernetes.api.model.extensions.Ingress; +import io.fabric8.kubernetes.client.dsl.NonDeletingOperation; import io.fabric8.openshift.api.model.Route; import io.fabric8.openshift.api.model.RouteBuilder; import io.fabric8.openshift.client.OpenShiftClient; @@ -75,8 +75,8 @@ public void init() { .endStatus() .build(); - client.services().createOrReplace(svc1); - client.services().createOrReplace(svc2); + client.services().resource(svc1).createOr(NonDeletingOperation::update); + client.services().resource(svc2).createOr(NonDeletingOperation::update); } @Test @@ -86,29 +86,39 @@ void getURL() { assertNotNull(url); // Testing Ingress Impl - Ingress ingress = client.extensions().ingresses().load(getClass().getResourceAsStream("/test-ingress-extensions.yml")) - .item(); - client.extensions().ingresses().create(ingress); + if (client.supports(io.fabric8.kubernetes.api.model.extensions.Ingress.class)) { + io.fabric8.kubernetes.api.model.extensions.Ingress ingress = client.extensions().ingresses() + .load(getClass().getResourceAsStream("/test-ingress-extensions.yml")) + .item(); + client.extensions().ingresses().resource(ingress).create(); + } else if (client.supports(io.fabric8.kubernetes.api.model.networking.v1.Ingress.class)) { + io.fabric8.kubernetes.api.model.networking.v1.Ingress ingress = client.network().v1().ingresses() + .load(getClass().getResourceAsStream("/service-to-url-it-network-v1-ingress.yml")) + .item(); + client.network().v1().ingresses().resource(ingress).create(); + } url = client.services().withName("svc2").getURL("80"); assertNotNull(url); // Testing OpenShift Route Impl - Service svc3 = client.services().create(new ServiceBuilder() + Service svc3 = client.services().resource(new ServiceBuilder() .withNewMetadata().withName("svc3").endMetadata() .withNewSpec() .addNewPort().withName("80").withProtocol("TCP").withPort(80).endPort() .endSpec() - .build()); + .build()) + .create(); OpenShiftClient openshiftClient = client.adapt(OpenShiftClient.class); - openshiftClient.routes().create(new RouteBuilder() + openshiftClient.routes().resource(new RouteBuilder() .withNewMetadata().withName(svc3.getMetadata().getName()).endMetadata() .withNewSpec() .withHost("www.example.com") .withNewTo().withName(svc3.getMetadata().getName()).withKind("Service").endTo() .endSpec() - .build()); + .build()) + .create(); url = client.services().withName("svc3").getURL("80"); assertNotNull(url); diff --git a/kubernetes-itests/src/test/resources/service-to-url-it-network-v1-ingress.yml b/kubernetes-itests/src/test/resources/service-to-url-it-network-v1-ingress.yml new file mode 100644 index 00000000000..9a5ad7d88b1 --- /dev/null +++ b/kubernetes-itests/src/test/resources/service-to-url-it-network-v1-ingress.yml @@ -0,0 +1,42 @@ +# +# 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. +# + +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: test-multiple-paths + annotations: + nginx.ingress.kubernetes.io/rewrite-target: / +spec: + ingressClassName: nginx-example + rules: + - host: foo.bar.com + http: + paths: + - path: /foo + pathType: Prefix + backend: + service: + name: svc2 + port: + number: 80 + - path: /bar + pathType: Prefix + backend: + service: + name: s2 + port: + number: 80