diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/DefaultKubernetesClient.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/DefaultKubernetesClient.java index 13e2fd7d0dc..3c783f1a26e 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/DefaultKubernetesClient.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/DefaultKubernetesClient.java @@ -54,6 +54,7 @@ import io.fabric8.kubernetes.client.dsl.internal.SecurityContextConstraintsOperationsImpl; import io.fabric8.kubernetes.client.dsl.internal.ServiceAccountOperationsImpl; import io.fabric8.kubernetes.client.dsl.internal.ServiceOperationsImpl; +import io.fabric8.kubernetes.client.dsl.internal.StorageClassOperationsImpl; import io.fabric8.kubernetes.client.utils.Serialization; import io.fabric8.openshift.api.model.DoneableSecurityContextConstraints; import io.fabric8.openshift.api.model.SecurityContextConstraints; @@ -217,6 +218,11 @@ public MixedOperation> storageClasses() { + return new StorageClassOperationsImpl(httpClient, getConfiguration()); + } + @Override public NonNamespaceOperation> customResourceDefinitions() { return new CustomResourceDefinitionOperationsImpl(httpClient, getConfiguration()); diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/KubernetesClient.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/KubernetesClient.java index 9a7c4f916b2..53df69ec60c 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/KubernetesClient.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/KubernetesClient.java @@ -103,4 +103,7 @@ public interface KubernetesClient extends Client { MixedOperation> configMaps(); MixedOperation> limitRanges(); + + MixedOperation> storageClasses(); + } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/StorageClassOperationsImpl.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/StorageClassOperationsImpl.java new file mode 100644 index 00000000000..aef6b5043e8 --- /dev/null +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/StorageClassOperationsImpl.java @@ -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. + */ +package io.fabric8.kubernetes.client.dsl.internal; + +import io.fabric8.kubernetes.api.model.DoneableStorageClass; +import io.fabric8.kubernetes.api.model.StorageClass; +import io.fabric8.kubernetes.api.model.StorageClassList; +import io.fabric8.kubernetes.client.Config; +import io.fabric8.kubernetes.client.dsl.Resource; +import io.fabric8.kubernetes.client.dsl.base.HasMetadataOperation; +import okhttp3.OkHttpClient; + +import java.util.Map; +import java.util.TreeMap; + +public class StorageClassOperationsImpl extends HasMetadataOperation> { + public StorageClassOperationsImpl(OkHttpClient client, Config config) { + this(client, config, null, null, null, true, null, null, false, -1, new TreeMap(), new TreeMap(), new TreeMap(), new TreeMap(), new TreeMap()); + } + + public StorageClassOperationsImpl(OkHttpClient client, Config config, String apiVersion, String namespace, String name, Boolean cascading, StorageClass item, String resourceVersion, Boolean reloadingFromServer, long gracePeriodSeconds, Map labels, Map labelsNot, Map labelsIn, Map labelsNotIn, Map fields) { + super(client, config, "storage.k8s.io", apiVersion, "storageclasses", namespace, name, cascading, item, resourceVersion, reloadingFromServer, gracePeriodSeconds, labels, labelsNot, labelsIn, labelsNotIn, fields); + } + + @Override + public boolean isResourceNamespaced() { + return false; + } +} diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/handlers/StorageClassHandler.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/handlers/StorageClassHandler.java new file mode 100644 index 00000000000..b6538466eaa --- /dev/null +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/handlers/StorageClassHandler.java @@ -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.handlers; + +import io.fabric8.kubernetes.api.model.StorageClass; +import io.fabric8.kubernetes.api.model.StorageClassBuilder; +import io.fabric8.kubernetes.client.Config; +import io.fabric8.kubernetes.client.ResourceHandler; +import io.fabric8.kubernetes.client.Watch; +import io.fabric8.kubernetes.client.Watcher; +import io.fabric8.kubernetes.client.dsl.internal.StorageClassOperationsImpl; +import okhttp3.OkHttpClient; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Service; + +import java.util.TreeMap; +import java.util.concurrent.TimeUnit; + +@Component +@Service +public class StorageClassHandler implements ResourceHandler { + @Override + public String getKind() { + return StorageClass.class.getSimpleName(); + } + + @Override + public StorageClass create(OkHttpClient client, Config config, String namespace, StorageClass item) { + return new StorageClassOperationsImpl(client, config, null, namespace, null, true, item, null, false, -1, new TreeMap(), new TreeMap(), new TreeMap(), new TreeMap(), new TreeMap()).create(); + } + + @Override + public StorageClass replace(OkHttpClient client, Config config, String namespace, StorageClass item) { + return new StorageClassOperationsImpl(client, config, null, namespace, null, true, item, null, true, -1, new TreeMap(), new TreeMap(), new TreeMap(), new TreeMap(), new TreeMap()).replace(item); + } + + @Override + public StorageClass reload(OkHttpClient client, Config config, String namespace, StorageClass item) { + return new StorageClassOperationsImpl(client, config, null, namespace, null, true, item, null, false, -1, new TreeMap(), new TreeMap(), new TreeMap(), new TreeMap(), new TreeMap()).fromServer().get(); + } + + @Override + public StorageClassBuilder edit(StorageClass item) { + return new StorageClassBuilder(item); + } + + @Override + public Boolean delete(OkHttpClient client, Config config, String namespace, StorageClass item) { + return new StorageClassOperationsImpl(client, config, null, namespace, null, true, item, null, false, -1, new TreeMap(), new TreeMap(), new TreeMap(), new TreeMap(), new TreeMap()).delete(item); + } + + @Override + public Watch watch(OkHttpClient client, Config config, String namespace, StorageClass item, Watcher watcher) { + return new StorageClassOperationsImpl(client, config, null, namespace, null, true, item, null, false, -1, new TreeMap(), new TreeMap(), new TreeMap(), new TreeMap(), new TreeMap()).watch(watcher); + } + + @Override + public Watch watch(OkHttpClient client, Config config, String namespace, StorageClass item, String resourceVersion, Watcher watcher) { + return new StorageClassOperationsImpl(client, config, null, namespace, null, true, item, null, false, -1, new TreeMap(), new TreeMap(), new TreeMap(), new TreeMap(), new TreeMap()).watch(resourceVersion, watcher); + } + + @Override + public StorageClass waitUntilReady(OkHttpClient client, Config config, String namespace, StorageClass item, long amount, TimeUnit timeUnit) throws InterruptedException { + return new StorageClassOperationsImpl(client, config, null, namespace, null, true, item, null, false, -1, new TreeMap(), new TreeMap(), new TreeMap(), new TreeMap(), new TreeMap()).waitUntilReady(amount, timeUnit); + } + +} diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/osgi/ManagedKubernetesClient.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/osgi/ManagedKubernetesClient.java index d55c030cbbb..78936cf33d8 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/osgi/ManagedKubernetesClient.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/osgi/ManagedKubernetesClient.java @@ -272,6 +272,10 @@ public MixedOperation> storageClasses() { + return delegate.storageClasses(); + } + @Override public RootPaths rootPaths() { return delegate.rootPaths(); diff --git a/kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/ListStorageClassExample.java b/kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/ListStorageClassExample.java new file mode 100644 index 00000000000..31f55abfa03 --- /dev/null +++ b/kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/ListStorageClassExample.java @@ -0,0 +1,48 @@ +/** + * 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.examples; + +import io.fabric8.kubernetes.api.model.*; +import io.fabric8.kubernetes.client.Config; +import io.fabric8.kubernetes.client.*; +import org.slf4j.*; + +public class ListStorageClassExample { + + private static final Logger logger = LoggerFactory.getLogger(ListStorageClassExample.class); + + public static void main(String[] args) { + + String master = "http://localhost:8080/"; + + if (args.length == 1) { + master = args[0]; + } + + io.fabric8.kubernetes.client.Config config = new io.fabric8.kubernetes.client.ConfigBuilder().withMasterUrl(master).build(); + + try (final KubernetesClient client = new DefaultKubernetesClient(config)) { + + StorageClassList storageClassList = client.storageClasses().list(); + + logger.info(storageClassList.toString()); + + } catch (KubernetesClientException e) { + logger.error(e.getMessage(), e); + } + + } +} diff --git a/kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/StorageClassExamples.java b/kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/StorageClassExamples.java new file mode 100644 index 00000000000..72053e42f4f --- /dev/null +++ b/kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/StorageClassExamples.java @@ -0,0 +1,97 @@ +/** + * 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.examples; + +import io.fabric8.kubernetes.api.model.ObjectMeta; +import io.fabric8.kubernetes.api.model.StorageClass; +import io.fabric8.kubernetes.api.model.StorageClassBuilder; +import io.fabric8.kubernetes.api.model.StorageClassList; +import io.fabric8.kubernetes.client.DefaultKubernetesClient; +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.KubernetesClientException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class StorageClassExamples { + + private static final Logger logger = LoggerFactory.getLogger(StorageClassExamples.class); + + public static void main(String[] args) { + + String master = "http://localhost:8080/"; + + if (args.length == 1) { + master = args[0]; + } + + io.fabric8.kubernetes.client.Config config = new io.fabric8.kubernetes.client.ConfigBuilder().withMasterUrl(master).build(); + + try (final KubernetesClient client = new DefaultKubernetesClient(config)) { + + //list all storage classes + StorageClassList storageClassList = client.storageClasses().list(); + logger.info("List of storage classes: {}", storageClassList.toString()); + + //create new storage class + + String name = UUID.randomUUID().toString(); + ObjectMeta metadata = new ObjectMeta(); + metadata.setName(name); + + Map parameters = new HashMap<>(); + parameters.put("resturl", "http://192.168.10.100:8080"); + parameters.put("restuser", ""); + parameters.put("secretNamespace", ""); + parameters.put("secretName", ""); + parameters.put("key", "value1"); + + StorageClass storageClass = new StorageClassBuilder().withApiVersion("storage.k8s.io/v1") + .withKind("StorageClass") + .withMetadata(metadata) + .withParameters(parameters) + .withProvisioner("k8s.io/minikube-hostpath") + .build(); + + storageClass = client.storageClasses().create(storageClass); + logger.info("Newly created storage class details: {}", storageClass.toString()); + + //list all storage classes + storageClassList = client.storageClasses().list(); + logger.info("List of storage classes: {}", storageClassList.toString()); + + //update storage class. add label + storageClass = client.storageClasses().withName(name).edit().editMetadata().addToLabels("testLabel", "testLabelValue").endMetadata().done(); + + //list all storage classes + storageClassList = client.storageClasses().list(); + logger.info("List of storage classes: {}", storageClassList.toString()); + + + //delete storage class + boolean isDeleteSuccessful = client.storageClasses().delete(storageClass); + logger.info("Storage Class resource successfully deleted: {}", isDeleteSuccessful); + + + } catch (KubernetesClientException e) { + logger.error(e.getMessage(), e); + } + + } +} diff --git a/kubernetes-itests/src/test/java/io/fabric8/kubernetes/StorageClassIT.java b/kubernetes-itests/src/test/java/io/fabric8/kubernetes/StorageClassIT.java new file mode 100644 index 00000000000..df92a1b4b78 --- /dev/null +++ b/kubernetes-itests/src/test/java/io/fabric8/kubernetes/StorageClassIT.java @@ -0,0 +1,102 @@ +/** + * 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.ObjectMeta; +import io.fabric8.kubernetes.api.model.StorageClass; +import io.fabric8.kubernetes.api.model.StorageClassBuilder; +import io.fabric8.kubernetes.api.model.StorageClassList; +import io.fabric8.kubernetes.client.KubernetesClient; +import static junit.framework.TestCase.assertNotNull; +import org.arquillian.cube.kubernetes.api.Session; +import org.arquillian.cube.kubernetes.impl.requirement.RequiresKubernetes; +import org.arquillian.cube.requirement.ArquillianConditionalRunner; +import org.jboss.arquillian.test.api.ArquillianResource; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +@RunWith(ArquillianConditionalRunner.class) +@RequiresKubernetes +public class StorageClassIT { + @ArquillianResource + KubernetesClient client; + + @ArquillianResource + Session session; + + private StorageClass storageClass; + + private String name = UUID.randomUUID().toString(); + + + @Before + public void init() { + ObjectMeta metadata = new ObjectMeta(); + metadata.setName(name); + + Map parameters = new HashMap<>(); + parameters.put("key", "value1"); + + storageClass = new StorageClassBuilder().withApiVersion("storage.k8s.io/v1") + .withKind("StorageClass") + .withMetadata(metadata) + .withParameters(parameters) + .withProvisioner("k8s.io/minikube-hostpath") + .build(); + + client.storageClasses().createOrReplace(storageClass); + } + + @Test + public void load() { + StorageClass storageClassLoaded = client.storageClasses().load(getClass().getResourceAsStream("/test-storageclass.yml")).get(); + assertNotNull(storageClassLoaded); + assertEquals("gluster-vol-default", storageClassLoaded.getMetadata().getName()); + } + + @Test + public void get() { + storageClass = client.storageClasses().withName(name).get(); + assertNotNull(storageClass); + } + + @Test + public void list() { + StorageClassList storageClassList = client.storageClasses().list(); + assertNotNull(storageClassList); + assertTrue(storageClassList.getItems().size() > 1); + } + + @Test + public void update() { + storageClass = client.storageClasses().withName(name).edit().editMetadata().addToLabels("testLabel", "testLabelValue").endMetadata().done(); + assertNotNull(storageClass); + assertEquals("testLabelValue", storageClass.getMetadata().getLabels().get("testLabel")); + } + + @Test + public void delete() { + assertTrue(client.storageClasses().delete(storageClass)); + } + +} diff --git a/kubernetes-itests/src/test/resources/test-storageclass.yml b/kubernetes-itests/src/test/resources/test-storageclass.yml new file mode 100644 index 00000000000..29f756300c1 --- /dev/null +++ b/kubernetes-itests/src/test/resources/test-storageclass.yml @@ -0,0 +1,26 @@ +# +# 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. +# + +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: gluster-vol-default +provisioner: kubernetes.io/glusterfs +parameters: + resturl: "http://192.168.10.100:8080" + restuser: "" + secretNamespace: "" + secretName: "" diff --git a/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/StorageSpaceCrudTest.java b/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/StorageSpaceCrudTest.java new file mode 100644 index 00000000000..0a83f0e5d4a --- /dev/null +++ b/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/StorageSpaceCrudTest.java @@ -0,0 +1,92 @@ +/** + * 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.mock; + +import io.fabric8.kubernetes.api.model.ObjectMeta; +import io.fabric8.kubernetes.api.model.Pod; +import io.fabric8.kubernetes.api.model.PodBuilder; +import io.fabric8.kubernetes.api.model.PodList; +import io.fabric8.kubernetes.api.model.StorageClass; +import io.fabric8.kubernetes.api.model.StorageClassBuilder; +import io.fabric8.kubernetes.api.model.StorageClassList; +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.server.mock.KubernetesServer; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import org.junit.Rule; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + + +public class StorageSpaceCrudTest { + + private static final Logger logger = LoggerFactory.getLogger(StorageSpaceCrudTest.class); + + @Rule + public KubernetesServer server = new KubernetesServer(true, true); + + @Test + public void testCrud() { + KubernetesClient client = server.getClient(); + + final String name = "test"; + ObjectMeta metadata = new ObjectMeta(); + metadata.setName(name); + + Map parameters = new HashMap<>(); + parameters.put("key", "value"); + + StorageClass storageClass = new StorageClassBuilder().withApiVersion("storage.k8s.io/v1") + .withKind("StorageClass") + .withMetadata(metadata) + .withParameters(parameters) + .withProvisioner("kubernetes.io/aws-ebs") + .build(); + + //test create + storageClass = client.storageClasses().create(storageClass); + assertNotNull(storageClass); + assertEquals(name, storageClass.getMetadata().getName()); + + //test get + StorageClassList storageClassList = client.storageClasses().list(); + logger.info(storageClassList.toString()); + assertNotNull(storageClassList); + assertEquals(1, storageClassList.getItems().size()); + assertEquals("kubernetes.io/aws-ebs", storageClassList.getItems().get(0).getProvisioner()); + assertEquals("value", storageClassList.getItems().get(0).getParameters().get("key")); + assertEquals(0, storageClassList.getItems().get(0).getMetadata().getLabels().size()); + + //test update + storageClass = client.storageClasses().withName(name).edit().editOrNewMetadata().addToLabels("key1", "value1").endMetadata().done(); + logger.info("Updated Storage Class: {} ", storageClass.toString()); + assertNotNull(storageClass); + assertEquals(1, storageClass.getMetadata().getLabels().size()); + + //test delete + boolean result = client.storageClasses().delete(storageClass); + assertEquals(true, result); + StorageClassList storageClassList2 = client.storageClasses().list(); + assertEquals(0, storageClassList2.getItems().size()); + + } +} diff --git a/openshift-client/src/main/java/io/fabric8/openshift/client/DefaultOpenShiftClient.java b/openshift-client/src/main/java/io/fabric8/openshift/client/DefaultOpenShiftClient.java index bf10ff373f6..ac88a23e5ea 100644 --- a/openshift-client/src/main/java/io/fabric8/openshift/client/DefaultOpenShiftClient.java +++ b/openshift-client/src/main/java/io/fabric8/openshift/client/DefaultOpenShiftClient.java @@ -387,6 +387,11 @@ public MixedOperation> storageClasses() { + return delegate.storageClasses(); + } + @Override public NamespacedOpenShiftClient inNamespace(String namespace) { OpenShiftConfig updated = new OpenShiftConfigBuilder(new OpenShiftConfig(getConfiguration())) diff --git a/openshift-client/src/main/java/io/fabric8/openshift/client/osgi/ManagedOpenShiftClient.java b/openshift-client/src/main/java/io/fabric8/openshift/client/osgi/ManagedOpenShiftClient.java index d5a6351c2b6..d6b8bc21ed1 100644 --- a/openshift-client/src/main/java/io/fabric8/openshift/client/osgi/ManagedOpenShiftClient.java +++ b/openshift-client/src/main/java/io/fabric8/openshift/client/osgi/ManagedOpenShiftClient.java @@ -436,6 +436,11 @@ public MixedOperation> storageClasses() { + return delegate.storageClasses(); + } + @Override public MixedOperation> services() { return delegate.services();