Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(kubernetes-client-api): Add support for v1.APIVersions in KubernetesClient #6089

Merged
merged 1 commit into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* Fix #6052: Removed dependency on no longer maintained com.github.mifmif:generex

#### New Features
* Fix #6066: Add support for `v1.APIVersions` in KubernetesClient

#### _**Note**_: Breaking changes
* Check detailed migration documentation for breaking changes in [7.0.0](./doc/MIGRATION-v7.md)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import io.fabric8.kubernetes.api.model.APIGroup;
import io.fabric8.kubernetes.api.model.APIGroupList;
import io.fabric8.kubernetes.api.model.APIResourceList;
import io.fabric8.kubernetes.api.model.APIVersions;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.KubernetesResource;
import io.fabric8.kubernetes.api.model.KubernetesResourceList;
Expand Down Expand Up @@ -108,6 +109,15 @@ public interface Client extends Closeable {
@Override
void close();

/**
* Get the available APIversions. APIVersions lists the versions that are available,
* to allow clients to discover the API at /api, which is the root path of the
* legacy v1 API.
*
* @return the {@link APIVersions} object
*/
APIVersions getAPIVersions();

/**
* Returns the api groups. This does not include the core/legacy v1 apiVersion.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import io.fabric8.kubernetes.api.model.APIGroup;
import io.fabric8.kubernetes.api.model.APIGroupList;
import io.fabric8.kubernetes.api.model.APIResourceList;
import io.fabric8.kubernetes.api.model.APIVersions;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.KubernetesResource;
import io.fabric8.kubernetes.api.model.KubernetesResourceList;
Expand Down Expand Up @@ -117,6 +118,11 @@ public APIGroupList getApiGroups() {
return client.getApiGroups();
}

@Override
public APIVersions getAPIVersions() {
return client.getAPIVersions();
}

@Override
public APIGroup getApiGroup(String name) {
return client.getApiGroup(name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import io.fabric8.kubernetes.api.model.APIGroup;
import io.fabric8.kubernetes.api.model.APIGroupList;
import io.fabric8.kubernetes.api.model.APIResourceList;
import io.fabric8.kubernetes.api.model.APIVersions;
import io.fabric8.kubernetes.api.model.GenericKubernetesResource;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.KubernetesResource;
Expand Down Expand Up @@ -79,6 +80,7 @@ public void onClose(Executor executor) {
};

public static final String APIS = "/apis";
private static final String API = "/api";

private URL masterUrl;
private String apiVersion;
Expand Down Expand Up @@ -297,6 +299,11 @@ public APIGroup getApiGroup(String name) {
return getOperationSupport().restCall(APIGroup.class, APIS, name);
}

@Override
public APIVersions getAPIVersions() {
return getOperationSupport().restCall(APIVersions.class, API);
}

private OperationSupport getOperationSupport() {
if (operationSupport == null) {
this.operationSupport = new OperationSupport(this);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* 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.kubernetes.client.impl;

import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.ConfigBuilder;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.http.HttpClient;
import io.fabric8.kubernetes.client.http.HttpRequest;
import io.fabric8.kubernetes.client.http.TestHttpResponse;
import io.fabric8.kubernetes.client.utils.KubernetesSerialization;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

class APIVersionsTest {
private HttpClient mockClient;
private KubernetesClient kubernetesClient;
private List<HttpRequest.Builder> builders;

@BeforeEach
public void setUp() throws IOException {
builders = new ArrayList<>();
this.mockClient = Mockito.mock(HttpClient.class, Mockito.RETURNS_DEEP_STUBS);
Config config = new ConfigBuilder().withMasterUrl("https://localhost:8443/").build();
when(mockClient.sendAsync(any(), Mockito.eq(byte[].class)))
.thenReturn(CompletableFuture.completedFuture(TestHttpResponse.from(200,
"{\"kind\":\"Pod\", \"apiVersion\":\"v1\"}")));
kubernetesClient = new KubernetesClientImpl(mockClient, config, () -> Runnable::run,
new KubernetesSerialization());
Mockito.when(mockClient.newHttpRequestBuilder()).thenAnswer(answer -> {
HttpRequest.Builder result = Mockito.mock(HttpRequest.Builder.class, Mockito.RETURNS_SELF);
builders.add(result);
return result;
});
}

@AfterEach
void tearDown() {
kubernetesClient.close();
kubernetesClient = null;
}

@Test
void getApiVersions() {
// When
kubernetesClient.getAPIVersions();
// Then
verify(mockClient).sendAsync(any(), any());
ArgumentCaptor<String> stringCaptor = ArgumentCaptor.forClass(String.class);
verify(builders.get(0)).uri(stringCaptor.capture());
assertThat(stringCaptor.getValue())
.isEqualTo("https://localhost:8443/api");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* 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.kubernetes;

import io.fabric8.kubernetes.api.model.APIVersions;
import io.fabric8.kubernetes.api.model.ServerAddressByClientCIDR;
import io.fabric8.kubernetes.client.KubernetesClient;
import org.assertj.core.api.InstanceOfAssertFactories;
import org.junit.jupiter.api.Test;

import java.util.Collections;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

class APIVersionsIT {
KubernetesClient client;

@Test
void testApiVersions() {
// Given + When
APIVersions apiVersions = client.getAPIVersions();
// Then
assertThat(apiVersions)
.isNotNull()
.hasFieldOrPropertyWithValue("versions", Collections.singletonList("v1"))
.extracting(APIVersions::getServerAddressByClientCIDRs)
.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()));
}
}
Loading