├── .dockerignore ├── .gitignore ├── Dockerfile ├── authorization.yml ├── deploy.yml ├── pom.xml ├── skaffold.yaml └── src └── main ├── java └── ch │ └── frankel │ └── kubernetes │ └── extend │ ├── Sidecar.java │ └── SidecarWatcher.java └── resources └── META-INF └── native-image └── ch.frankel.blog └── jvm-operator ├── jni-config.json ├── native-image.properties ├── proxy-config.json ├── reflect-config.json └── resource-config.json /.dockerignore: -------------------------------------------------------------------------------- 1 | ** 2 | !src/** 3 | !pom.xml 4 | !dependencies/** 5 | !config/* -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .idea 3 | target 4 | .java-version 5 | dependency-reduced-pom.xml 6 | 7 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # docker build -t jvm-operator:2.5 . 2 | 3 | ARG VERSION=2.5 4 | 5 | FROM maven:3-adoptopenjdk-11 as build 6 | WORKDIR /app 7 | COPY pom.xml . 8 | RUN mvn -B dependency:resolve-plugins dependency:resolve 9 | COPY . . 10 | RUN mvn package 11 | 12 | FROM ghcr.io/graalvm/graalvm-ce:21.2.0 as native 13 | ARG VERSION 14 | COPY --from=build /app/target/jvm-operator-$VERSION.jar /var/jvm-operator-$VERSION.jar 15 | WORKDIR /opt/graalvm 16 | RUN gu install native-image \ 17 | && native-image -jar /var/jvm-operator-$VERSION.jar \ 18 | && mv jvm-operator-$VERSION /opt/jvm-operator-$VERSION 19 | 20 | FROM scratch 21 | ARG VERSION 22 | WORKDIR /home 23 | COPY --from=native /opt/jvm-operator-$VERSION operator 24 | ENTRYPOINT ["./operator"] 25 | -------------------------------------------------------------------------------- /authorization.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: jvmoperator 5 | --- 6 | apiVersion: rbac.authorization.k8s.io/v1 7 | kind: ClusterRole 8 | metadata: 9 | namespace: jvmoperator 10 | name: operator-example 11 | rules: 12 | - apiGroups: 13 | - "" 14 | resources: 15 | - pods 16 | verbs: 17 | - list 18 | - watch 19 | - create 20 | - delete 21 | --- 22 | apiVersion: v1 23 | kind: ServiceAccount 24 | metadata: 25 | name: operator-service 26 | --- 27 | kind: ClusterRoleBinding 28 | apiVersion: rbac.authorization.k8s.io/v1 29 | metadata: 30 | name: operator-example 31 | subjects: 32 | - kind: ServiceAccount 33 | name: operator-service 34 | namespace: jvmoperator 35 | roleRef: 36 | kind: ClusterRole 37 | name: operator-example 38 | apiGroup: rbac.authorization.k8s.io -------------------------------------------------------------------------------- /deploy.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: jvmoperator 5 | --- 6 | apiVersion: v1 7 | kind: Pod 8 | metadata: 9 | namespace: jvmoperator 10 | name: custom-operator 11 | spec: 12 | serviceAccountName: operator-service 13 | containers: 14 | - name: custom-operator 15 | image: jvm-operator:2.5 16 | imagePullPolicy: Never 17 | env: 18 | - name: KUBERNETES_AUTH_TRYKUBECONFIG 19 | value: "false" -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | blog.frankel.ch 7 | jvm-operator 8 | 2.5 9 | 10 | 11 11 | ${java.version} 12 | ${java.version} 13 | UTF-8 14 | 15 | 16 | 17 | 18 | org.apache.maven.plugins 19 | maven-shade-plugin 20 | 3.2.4 21 | 22 | 23 | package 24 | 25 | shade 26 | 27 | 28 | 29 | 30 | ch.frankel.kubernetes.extend.Sidecar 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | *:* 39 | 40 | module-info.class 41 | manifest.vm 42 | META-INF/MANIFEST.MF 43 | META-INF/jandex.idx 44 | 45 | 46 | 47 | *:* 48 | 49 | schema/kube-validation-schema.json 50 | schema/kube-schema.json 51 | schema/validation-schema.json 52 | META-INF/LICENSE.md 53 | META-INF/NOTICE.md 54 | 55 | 56 | 57 | *:kubernetes-model-admissionregistration 58 | 59 | schema/kube-validation-schema.json 60 | schema/kube-schema.json 61 | schema/validation-schema.json 62 | 63 | 64 | 65 | *:jakarta.activation-api 66 | 67 | META-INF/LICENSE.md 68 | META-INF/NOTICE.md 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | io.fabric8 81 | kubernetes-client 82 | 5.5.0 83 | 84 | 85 | org.slf4j 86 | slf4j-simple 87 | 1.7.31 88 | runtime 89 | 90 | 91 | -------------------------------------------------------------------------------- /skaffold.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skaffold/v2beta4 2 | kind: Config 3 | build: 4 | tagPolicy: 5 | gitCommit: {} 6 | artifacts: 7 | - image: jvm-operator 8 | context: . 9 | local: {} 10 | deploy: 11 | kubectl: 12 | manifests: 13 | - authorization.yml 14 | - deploy.yml -------------------------------------------------------------------------------- /src/main/java/ch/frankel/kubernetes/extend/Sidecar.java: -------------------------------------------------------------------------------- 1 | package ch.frankel.kubernetes.extend; 2 | 3 | import io.fabric8.kubernetes.client.DefaultKubernetesClient; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | public class Sidecar { 8 | 9 | private static final Logger LOGGER = LoggerFactory.getLogger(Sidecar.class); 10 | 11 | public static void main(String[] args) { 12 | LOGGER.info("*** JVM Operator v2.5 ***"); 13 | var client = new DefaultKubernetesClient(); 14 | client.pods().inNamespace(SidecarWatcher.NAMESPACE) 15 | .watch(new SidecarWatcher(client)); 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/java/ch/frankel/kubernetes/extend/SidecarWatcher.java: -------------------------------------------------------------------------------- 1 | package ch.frankel.kubernetes.extend; 2 | 3 | import io.fabric8.kubernetes.api.model.Pod; 4 | import io.fabric8.kubernetes.api.model.PodBuilder; 5 | import io.fabric8.kubernetes.client.KubernetesClient; 6 | import io.fabric8.kubernetes.client.Watcher; 7 | import io.fabric8.kubernetes.client.WatcherException; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import java.util.HashMap; 12 | import java.util.Optional; 13 | 14 | public class SidecarWatcher implements Watcher { 15 | 16 | private static final Logger LOGGER = LoggerFactory.getLogger(SidecarWatcher.class); 17 | private static final String SIDECAR_IMAGE_NAME = "hazelcast/hazelcast:5.0-BETA-1-slim"; 18 | private static final String SIDECAR_POD_NAME = "hazelcast"; 19 | public static final String NAMESPACE = "jvmoperator"; 20 | 21 | private final KubernetesClient client; 22 | 23 | public SidecarWatcher(KubernetesClient client) { 24 | this.client = client; 25 | } 26 | 27 | public void eventReceived(Action action, Pod pod) { 28 | switch (action) { 29 | case ADDED: 30 | var namespace = pod.getMetadata().getNamespace(); 31 | if (NAMESPACE.equals(namespace) && !isSidecar(pod)) { 32 | if (!alreadyHasSidecar(pod)) { 33 | createSidecar(pod); 34 | } else { 35 | LOGGER.info("Sidecar already existing for pod {}", pod.getMetadata().getName()); 36 | } 37 | } 38 | break; 39 | case DELETED: 40 | if (isAssignedSidecar(pod)) { 41 | pod.getMetadata().setResourceVersion(null); 42 | client.pods().inNamespace(NAMESPACE).create(pod); 43 | } 44 | break; 45 | default: 46 | // NOTHING TO DO 47 | } 48 | } 49 | 50 | @Override 51 | public void onClose(WatcherException cause) { 52 | // NOTHING TO DO 53 | } 54 | 55 | private boolean isSidecar(Pod pod) { 56 | var labels = Optional.ofNullable(pod.getMetadata().getLabels()); 57 | return "true".equals(labels 58 | .orElse(new HashMap<>()) 59 | .getOrDefault("sidecar", "false")); 60 | } 61 | 62 | private void createSidecar(Pod pod) { 63 | var podName = pod.getMetadata().getName(); 64 | var name = SIDECAR_POD_NAME + "-" + podName; 65 | client.pods().inNamespace(NAMESPACE).create( 66 | new PodBuilder() 67 | .withApiVersion("v1") 68 | .withKind("Pod") 69 | .withNewMetadata() 70 | .withName(name) 71 | .withNamespace(pod.getMetadata().getNamespace()) 72 | .addNewOwnerReference() 73 | .withApiVersion("v1") 74 | .withKind("Pod") 75 | .withName(podName) 76 | .withUid(pod.getMetadata().getUid()) 77 | .endOwnerReference() 78 | .addToLabels("sidecar", "true") 79 | .endMetadata() 80 | .withNewSpec() 81 | .addNewContainer() 82 | .withName(name) 83 | .withImage(SIDECAR_IMAGE_NAME) 84 | .endContainer() 85 | .endSpec() 86 | .build()); 87 | } 88 | 89 | private boolean alreadyHasSidecar(Pod pod) { 90 | return client.pods().inNamespace(NAMESPACE).list() 91 | .getItems() 92 | .stream() 93 | .anyMatch(it -> it.getMetadata().getName().equals(SIDECAR_POD_NAME + "-" + pod.getMetadata().getName())); 94 | } 95 | 96 | private boolean isAssignedSidecar(Pod pod) { 97 | var metadata = pod.getMetadata(); 98 | return metadata.getName().startsWith(SIDECAR_POD_NAME + "-") 99 | && metadata.getOwnerReferences().stream() 100 | .anyMatch(it -> "Pod".equals(it.getKind()) && "v1".equals(it.getApiVersion())); 101 | } 102 | } -------------------------------------------------------------------------------- /src/main/resources/META-INF/native-image/ch.frankel.blog/jvm-operator/jni-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name":"java.lang.ClassLoader", 4 | "methods":[{"name":"getPlatformClassLoader","parameterTypes":[] }] 5 | }, 6 | { 7 | "name":"java.lang.NoSuchMethodError" 8 | } 9 | ] 10 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/native-image/ch.frankel.blog/jvm-operator/native-image.properties: -------------------------------------------------------------------------------- 1 | Args= -J-Xmx3072m \ 2 | --static \ 3 | --allow-incomplete-classpath \ 4 | --no-fallback \ 5 | --no-server \ 6 | -H:EnableURLProtocols=https \ 7 | -H:ConfigurationFileDirectories=/var/config \ 8 | --initialize-at-build-time=okhttp3.internal.Util,okio.ByteString,okio.Util -------------------------------------------------------------------------------- /src/main/resources/META-INF/native-image/ch.frankel.blog/jvm-operator/proxy-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | ] 3 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/native-image/ch.frankel.blog/jvm-operator/reflect-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name":"byte[]" 4 | }, 5 | { 6 | "name":"com.fasterxml.jackson.databind.deser.Deserializers[]" 7 | }, 8 | { 9 | "name":"com.fasterxml.jackson.databind.deser.KeyDeserializers[]" 10 | }, 11 | { 12 | "name":"com.fasterxml.jackson.databind.deser.ValueInstantiators[]" 13 | }, 14 | { 15 | "name":"com.fasterxml.jackson.databind.ext.Java7HandlersImpl", 16 | "methods":[{"name":"","parameterTypes":[] }] 17 | }, 18 | { 19 | "name":"com.fasterxml.jackson.databind.ext.Java7SupportImpl", 20 | "methods":[{"name":"","parameterTypes":[] }] 21 | }, 22 | { 23 | "name":"com.fasterxml.jackson.databind.ser.Serializers[]" 24 | }, 25 | { 26 | "name":"com.sun.crypto.provider.AESCipher$General", 27 | "methods":[{"name":"","parameterTypes":[] }] 28 | }, 29 | { 30 | "name":"com.sun.crypto.provider.DHParameters", 31 | "methods":[{"name":"","parameterTypes":[] }] 32 | }, 33 | { 34 | "name":"com.sun.crypto.provider.TlsKeyMaterialGenerator", 35 | "methods":[{"name":"","parameterTypes":[] }] 36 | }, 37 | { 38 | "name":"com.sun.crypto.provider.TlsMasterSecretGenerator", 39 | "methods":[{"name":"","parameterTypes":[] }] 40 | }, 41 | { 42 | "name":"com.sun.crypto.provider.TlsPrfGenerator$V12", 43 | "methods":[{"name":"","parameterTypes":[] }] 44 | }, 45 | { 46 | "name":"io.fabric8.kubernetes.api.model.AWSElasticBlockStoreVolumeSource", 47 | "allDeclaredFields":true, 48 | "allDeclaredMethods":true, 49 | "allDeclaredConstructors":true 50 | }, 51 | { 52 | "name":"io.fabric8.kubernetes.api.model.Affinity", 53 | "allDeclaredFields":true, 54 | "allDeclaredMethods":true, 55 | "allDeclaredConstructors":true 56 | }, 57 | { 58 | "name":"io.fabric8.kubernetes.api.model.AzureDiskVolumeSource", 59 | "allDeclaredFields":true, 60 | "allDeclaredMethods":true, 61 | "allDeclaredConstructors":true 62 | }, 63 | { 64 | "name":"io.fabric8.kubernetes.api.model.AzureFileVolumeSource", 65 | "allDeclaredFields":true, 66 | "allDeclaredMethods":true, 67 | "allDeclaredConstructors":true 68 | }, 69 | { 70 | "name":"io.fabric8.kubernetes.api.model.CSIVolumeSource", 71 | "allDeclaredFields":true, 72 | "allDeclaredMethods":true, 73 | "allDeclaredConstructors":true 74 | }, 75 | { 76 | "name":"io.fabric8.kubernetes.api.model.Capabilities", 77 | "allDeclaredFields":true, 78 | "allDeclaredMethods":true, 79 | "allDeclaredConstructors":true 80 | }, 81 | { 82 | "name":"io.fabric8.kubernetes.api.model.CephFSVolumeSource", 83 | "allDeclaredFields":true, 84 | "allDeclaredMethods":true, 85 | "allDeclaredConstructors":true 86 | }, 87 | { 88 | "name":"io.fabric8.kubernetes.api.model.CinderVolumeSource", 89 | "allDeclaredFields":true, 90 | "allDeclaredMethods":true, 91 | "allDeclaredConstructors":true 92 | }, 93 | { 94 | "name":"io.fabric8.kubernetes.api.model.ConfigMapEnvSource", 95 | "allDeclaredFields":true, 96 | "allDeclaredMethods":true, 97 | "allDeclaredConstructors":true 98 | }, 99 | { 100 | "name":"io.fabric8.kubernetes.api.model.ConfigMapKeySelector", 101 | "allDeclaredFields":true, 102 | "allDeclaredMethods":true, 103 | "allDeclaredConstructors":true 104 | }, 105 | { 106 | "name":"io.fabric8.kubernetes.api.model.ConfigMapProjection", 107 | "allDeclaredFields":true, 108 | "allDeclaredMethods":true, 109 | "allDeclaredConstructors":true 110 | }, 111 | { 112 | "name":"io.fabric8.kubernetes.api.model.ConfigMapVolumeSource", 113 | "allDeclaredFields":true, 114 | "allDeclaredMethods":true, 115 | "allDeclaredConstructors":true 116 | }, 117 | { 118 | "name":"io.fabric8.kubernetes.api.model.Container", 119 | "allDeclaredFields":true, 120 | "allDeclaredMethods":true, 121 | "allDeclaredConstructors":true 122 | }, 123 | { 124 | "name":"io.fabric8.kubernetes.api.model.ContainerPort", 125 | "allDeclaredFields":true, 126 | "allDeclaredMethods":true, 127 | "allDeclaredConstructors":true 128 | }, 129 | { 130 | "name":"io.fabric8.kubernetes.api.model.ContainerState", 131 | "allDeclaredFields":true, 132 | "allDeclaredMethods":true, 133 | "allDeclaredConstructors":true 134 | }, 135 | { 136 | "name":"io.fabric8.kubernetes.api.model.ContainerStateRunning", 137 | "allDeclaredFields":true, 138 | "allDeclaredMethods":true, 139 | "allDeclaredConstructors":true 140 | }, 141 | { 142 | "name":"io.fabric8.kubernetes.api.model.ContainerStateTerminated", 143 | "allDeclaredFields":true, 144 | "allDeclaredMethods":true, 145 | "allDeclaredConstructors":true 146 | }, 147 | { 148 | "name":"io.fabric8.kubernetes.api.model.ContainerStateWaiting", 149 | "allDeclaredFields":true, 150 | "allDeclaredMethods":true, 151 | "allDeclaredConstructors":true 152 | }, 153 | { 154 | "name":"io.fabric8.kubernetes.api.model.ContainerStatus", 155 | "allDeclaredFields":true, 156 | "allDeclaredMethods":true, 157 | "allDeclaredConstructors":true 158 | }, 159 | { 160 | "name":"io.fabric8.kubernetes.api.model.DownwardAPIProjection", 161 | "allDeclaredFields":true, 162 | "allDeclaredMethods":true, 163 | "allDeclaredConstructors":true 164 | }, 165 | { 166 | "name":"io.fabric8.kubernetes.api.model.DownwardAPIVolumeFile", 167 | "allDeclaredFields":true, 168 | "allDeclaredMethods":true, 169 | "allDeclaredConstructors":true 170 | }, 171 | { 172 | "name":"io.fabric8.kubernetes.api.model.DownwardAPIVolumeSource", 173 | "allDeclaredFields":true, 174 | "allDeclaredMethods":true, 175 | "allDeclaredConstructors":true 176 | }, 177 | { 178 | "name":"io.fabric8.kubernetes.api.model.EmptyDirVolumeSource", 179 | "allDeclaredFields":true, 180 | "allDeclaredMethods":true, 181 | "allDeclaredConstructors":true 182 | }, 183 | { 184 | "name":"io.fabric8.kubernetes.api.model.EnvFromSource", 185 | "allDeclaredFields":true, 186 | "allDeclaredMethods":true, 187 | "allDeclaredConstructors":true 188 | }, 189 | { 190 | "name":"io.fabric8.kubernetes.api.model.EnvVar", 191 | "allDeclaredFields":true, 192 | "allDeclaredMethods":true, 193 | "allDeclaredConstructors":true 194 | }, 195 | { 196 | "name":"io.fabric8.kubernetes.api.model.EnvVarSource", 197 | "allDeclaredFields":true, 198 | "allDeclaredMethods":true, 199 | "allDeclaredConstructors":true 200 | }, 201 | { 202 | "name":"io.fabric8.kubernetes.api.model.EphemeralContainer", 203 | "allDeclaredFields":true, 204 | "allDeclaredMethods":true, 205 | "allDeclaredConstructors":true 206 | }, 207 | { 208 | "name":"io.fabric8.kubernetes.api.model.EphemeralVolumeSource", 209 | "allDeclaredFields":true, 210 | "allDeclaredMethods":true, 211 | "allDeclaredConstructors":true 212 | }, 213 | { 214 | "name":"io.fabric8.kubernetes.api.model.ExecAction", 215 | "allDeclaredFields":true, 216 | "allDeclaredMethods":true, 217 | "allDeclaredConstructors":true 218 | }, 219 | { 220 | "name":"io.fabric8.kubernetes.api.model.FCVolumeSource", 221 | "allDeclaredFields":true, 222 | "allDeclaredMethods":true, 223 | "allDeclaredConstructors":true 224 | }, 225 | { 226 | "name":"io.fabric8.kubernetes.api.model.FieldsV1", 227 | "allDeclaredFields":true, 228 | "allDeclaredMethods":true, 229 | "allDeclaredConstructors":true 230 | }, 231 | { 232 | "name":"io.fabric8.kubernetes.api.model.FlexVolumeSource", 233 | "allDeclaredFields":true, 234 | "allDeclaredMethods":true, 235 | "allDeclaredConstructors":true 236 | }, 237 | { 238 | "name":"io.fabric8.kubernetes.api.model.FlockerVolumeSource", 239 | "allDeclaredFields":true, 240 | "allDeclaredMethods":true, 241 | "allDeclaredConstructors":true 242 | }, 243 | { 244 | "name":"io.fabric8.kubernetes.api.model.GCEPersistentDiskVolumeSource", 245 | "allDeclaredFields":true, 246 | "allDeclaredMethods":true, 247 | "allDeclaredConstructors":true 248 | }, 249 | { 250 | "name":"io.fabric8.kubernetes.api.model.GitRepoVolumeSource", 251 | "allDeclaredFields":true, 252 | "allDeclaredMethods":true, 253 | "allDeclaredConstructors":true 254 | }, 255 | { 256 | "name":"io.fabric8.kubernetes.api.model.GlusterfsVolumeSource", 257 | "allDeclaredFields":true, 258 | "allDeclaredMethods":true, 259 | "allDeclaredConstructors":true 260 | }, 261 | { 262 | "name":"io.fabric8.kubernetes.api.model.HTTPGetAction", 263 | "allDeclaredFields":true, 264 | "allDeclaredMethods":true, 265 | "allDeclaredConstructors":true 266 | }, 267 | { 268 | "name":"io.fabric8.kubernetes.api.model.HTTPHeader", 269 | "allDeclaredFields":true, 270 | "allDeclaredMethods":true, 271 | "allDeclaredConstructors":true 272 | }, 273 | { 274 | "name":"io.fabric8.kubernetes.api.model.Handler", 275 | "allDeclaredFields":true, 276 | "allDeclaredMethods":true, 277 | "allDeclaredConstructors":true 278 | }, 279 | { 280 | "name":"io.fabric8.kubernetes.api.model.HasMetadata", 281 | "allDeclaredMethods":true 282 | }, 283 | { 284 | "name":"io.fabric8.kubernetes.api.model.HostAlias", 285 | "allDeclaredFields":true, 286 | "allDeclaredMethods":true, 287 | "allDeclaredConstructors":true 288 | }, 289 | { 290 | "name":"io.fabric8.kubernetes.api.model.HostPathVolumeSource", 291 | "allDeclaredFields":true, 292 | "allDeclaredMethods":true, 293 | "allDeclaredConstructors":true 294 | }, 295 | { 296 | "name":"io.fabric8.kubernetes.api.model.ISCSIVolumeSource", 297 | "allDeclaredFields":true, 298 | "allDeclaredMethods":true, 299 | "allDeclaredConstructors":true 300 | }, 301 | { 302 | "name":"io.fabric8.kubernetes.api.model.IntOrString$Deserializer", 303 | "methods":[{"name":"","parameterTypes":[] }] 304 | }, 305 | { 306 | "name":"io.fabric8.kubernetes.api.model.KeyToPath", 307 | "allDeclaredFields":true, 308 | "allDeclaredMethods":true, 309 | "allDeclaredConstructors":true 310 | }, 311 | { 312 | "name":"io.fabric8.kubernetes.api.model.KubernetesResource", 313 | "allDeclaredMethods":true 314 | }, 315 | { 316 | "name":"io.fabric8.kubernetes.api.model.KubernetesResourceList", 317 | "allDeclaredMethods":true 318 | }, 319 | { 320 | "name":"io.fabric8.kubernetes.api.model.LabelSelector", 321 | "allDeclaredFields":true, 322 | "allDeclaredMethods":true, 323 | "allDeclaredConstructors":true 324 | }, 325 | { 326 | "name":"io.fabric8.kubernetes.api.model.LabelSelectorRequirement", 327 | "allDeclaredFields":true, 328 | "allDeclaredMethods":true, 329 | "allDeclaredConstructors":true 330 | }, 331 | { 332 | "name":"io.fabric8.kubernetes.api.model.Lifecycle", 333 | "allDeclaredFields":true, 334 | "allDeclaredMethods":true, 335 | "allDeclaredConstructors":true 336 | }, 337 | { 338 | "name":"io.fabric8.kubernetes.api.model.ListMeta", 339 | "allDeclaredFields":true, 340 | "allDeclaredMethods":true, 341 | "allDeclaredConstructors":true 342 | }, 343 | { 344 | "name":"io.fabric8.kubernetes.api.model.LocalObjectReference", 345 | "allDeclaredFields":true, 346 | "allDeclaredMethods":true, 347 | "allDeclaredConstructors":true 348 | }, 349 | { 350 | "name":"io.fabric8.kubernetes.api.model.ManagedFieldsEntry", 351 | "allDeclaredFields":true, 352 | "allDeclaredMethods":true, 353 | "allDeclaredConstructors":true 354 | }, 355 | { 356 | "name":"io.fabric8.kubernetes.api.model.NFSVolumeSource", 357 | "allDeclaredFields":true, 358 | "allDeclaredMethods":true, 359 | "allDeclaredConstructors":true 360 | }, 361 | { 362 | "name":"io.fabric8.kubernetes.api.model.Namespaced", 363 | "allDeclaredMethods":true 364 | }, 365 | { 366 | "name":"io.fabric8.kubernetes.api.model.NodeAffinity", 367 | "allDeclaredFields":true, 368 | "allDeclaredMethods":true, 369 | "allDeclaredConstructors":true 370 | }, 371 | { 372 | "name":"io.fabric8.kubernetes.api.model.NodeSelector", 373 | "allDeclaredFields":true, 374 | "allDeclaredMethods":true, 375 | "allDeclaredConstructors":true 376 | }, 377 | { 378 | "name":"io.fabric8.kubernetes.api.model.NodeSelectorRequirement", 379 | "allDeclaredFields":true, 380 | "allDeclaredMethods":true, 381 | "allDeclaredConstructors":true 382 | }, 383 | { 384 | "name":"io.fabric8.kubernetes.api.model.NodeSelectorTerm", 385 | "allDeclaredFields":true, 386 | "allDeclaredMethods":true, 387 | "allDeclaredConstructors":true 388 | }, 389 | { 390 | "name":"io.fabric8.kubernetes.api.model.ObjectFieldSelector", 391 | "allDeclaredFields":true, 392 | "allDeclaredMethods":true, 393 | "allDeclaredConstructors":true 394 | }, 395 | { 396 | "name":"io.fabric8.kubernetes.api.model.ObjectMeta", 397 | "allDeclaredFields":true, 398 | "allDeclaredMethods":true, 399 | "allDeclaredConstructors":true 400 | }, 401 | { 402 | "name":"io.fabric8.kubernetes.api.model.OwnerReference", 403 | "allDeclaredFields":true, 404 | "allDeclaredMethods":true, 405 | "allDeclaredConstructors":true 406 | }, 407 | { 408 | "name":"io.fabric8.kubernetes.api.model.PersistentVolumeClaimSpec", 409 | "allDeclaredFields":true, 410 | "allDeclaredMethods":true, 411 | "allDeclaredConstructors":true 412 | }, 413 | { 414 | "name":"io.fabric8.kubernetes.api.model.PersistentVolumeClaimTemplate", 415 | "allDeclaredFields":true, 416 | "allDeclaredMethods":true, 417 | "allDeclaredConstructors":true 418 | }, 419 | { 420 | "name":"io.fabric8.kubernetes.api.model.PersistentVolumeClaimVolumeSource", 421 | "allDeclaredFields":true, 422 | "allDeclaredMethods":true, 423 | "allDeclaredConstructors":true 424 | }, 425 | { 426 | "name":"io.fabric8.kubernetes.api.model.PhotonPersistentDiskVolumeSource", 427 | "allDeclaredFields":true, 428 | "allDeclaredMethods":true, 429 | "allDeclaredConstructors":true 430 | }, 431 | { 432 | "name":"io.fabric8.kubernetes.api.model.Pod", 433 | "allDeclaredFields":true, 434 | "allDeclaredMethods":true, 435 | "allDeclaredConstructors":true 436 | }, 437 | { 438 | "name":"io.fabric8.kubernetes.api.model.PodAffinity", 439 | "allDeclaredFields":true, 440 | "allDeclaredMethods":true, 441 | "allDeclaredConstructors":true 442 | }, 443 | { 444 | "name":"io.fabric8.kubernetes.api.model.PodAffinityTerm", 445 | "allDeclaredFields":true, 446 | "allDeclaredMethods":true, 447 | "allDeclaredConstructors":true 448 | }, 449 | { 450 | "name":"io.fabric8.kubernetes.api.model.PodAntiAffinity", 451 | "allDeclaredFields":true, 452 | "allDeclaredMethods":true, 453 | "allDeclaredConstructors":true 454 | }, 455 | { 456 | "name":"io.fabric8.kubernetes.api.model.PodCondition", 457 | "allDeclaredFields":true, 458 | "allDeclaredMethods":true, 459 | "allDeclaredConstructors":true 460 | }, 461 | { 462 | "name":"io.fabric8.kubernetes.api.model.PodDNSConfig", 463 | "allDeclaredFields":true, 464 | "allDeclaredMethods":true, 465 | "allDeclaredConstructors":true 466 | }, 467 | { 468 | "name":"io.fabric8.kubernetes.api.model.PodDNSConfigOption", 469 | "allDeclaredFields":true, 470 | "allDeclaredMethods":true, 471 | "allDeclaredConstructors":true 472 | }, 473 | { 474 | "name":"io.fabric8.kubernetes.api.model.PodIP", 475 | "allDeclaredFields":true, 476 | "allDeclaredMethods":true, 477 | "allDeclaredConstructors":true 478 | }, 479 | { 480 | "name":"io.fabric8.kubernetes.api.model.PodList", 481 | "allDeclaredFields":true, 482 | "allDeclaredMethods":true, 483 | "allDeclaredConstructors":true 484 | }, 485 | { 486 | "name":"io.fabric8.kubernetes.api.model.PodReadinessGate", 487 | "allDeclaredFields":true, 488 | "allDeclaredMethods":true, 489 | "allDeclaredConstructors":true 490 | }, 491 | { 492 | "name":"io.fabric8.kubernetes.api.model.PodSecurityContext", 493 | "allDeclaredFields":true, 494 | "allDeclaredMethods":true, 495 | "allDeclaredConstructors":true 496 | }, 497 | { 498 | "name":"io.fabric8.kubernetes.api.model.PodSpec", 499 | "allDeclaredFields":true, 500 | "allDeclaredMethods":true, 501 | "allDeclaredConstructors":true 502 | }, 503 | { 504 | "name":"io.fabric8.kubernetes.api.model.PodStatus", 505 | "allDeclaredFields":true, 506 | "allDeclaredMethods":true, 507 | "allDeclaredConstructors":true 508 | }, 509 | { 510 | "name":"io.fabric8.kubernetes.api.model.PortworxVolumeSource", 511 | "allDeclaredFields":true, 512 | "allDeclaredMethods":true, 513 | "allDeclaredConstructors":true 514 | }, 515 | { 516 | "name":"io.fabric8.kubernetes.api.model.PreferredSchedulingTerm", 517 | "allDeclaredFields":true, 518 | "allDeclaredMethods":true, 519 | "allDeclaredConstructors":true 520 | }, 521 | { 522 | "name":"io.fabric8.kubernetes.api.model.Probe", 523 | "allDeclaredFields":true, 524 | "allDeclaredMethods":true, 525 | "allDeclaredConstructors":true 526 | }, 527 | { 528 | "name":"io.fabric8.kubernetes.api.model.ProjectedVolumeSource", 529 | "allDeclaredFields":true, 530 | "allDeclaredMethods":true, 531 | "allDeclaredConstructors":true 532 | }, 533 | { 534 | "name":"io.fabric8.kubernetes.api.model.Quantity$Deserializer", 535 | "methods":[{"name":"","parameterTypes":[] }] 536 | }, 537 | { 538 | "name":"io.fabric8.kubernetes.api.model.QuobyteVolumeSource", 539 | "allDeclaredFields":true, 540 | "allDeclaredMethods":true, 541 | "allDeclaredConstructors":true 542 | }, 543 | { 544 | "name":"io.fabric8.kubernetes.api.model.RBDVolumeSource", 545 | "allDeclaredFields":true, 546 | "allDeclaredMethods":true, 547 | "allDeclaredConstructors":true 548 | }, 549 | { 550 | "name":"io.fabric8.kubernetes.api.model.ResourceFieldSelector", 551 | "allDeclaredFields":true, 552 | "allDeclaredMethods":true, 553 | "allDeclaredConstructors":true 554 | }, 555 | { 556 | "name":"io.fabric8.kubernetes.api.model.ResourceRequirements", 557 | "allDeclaredFields":true, 558 | "allDeclaredMethods":true, 559 | "allDeclaredConstructors":true 560 | }, 561 | { 562 | "name":"io.fabric8.kubernetes.api.model.SELinuxOptions", 563 | "allDeclaredFields":true, 564 | "allDeclaredMethods":true, 565 | "allDeclaredConstructors":true 566 | }, 567 | { 568 | "name":"io.fabric8.kubernetes.api.model.ScaleIOVolumeSource", 569 | "allDeclaredFields":true, 570 | "allDeclaredMethods":true, 571 | "allDeclaredConstructors":true 572 | }, 573 | { 574 | "name":"io.fabric8.kubernetes.api.model.SeccompProfile", 575 | "allDeclaredFields":true, 576 | "allDeclaredMethods":true, 577 | "allDeclaredConstructors":true 578 | }, 579 | { 580 | "name":"io.fabric8.kubernetes.api.model.SecretEnvSource", 581 | "allDeclaredFields":true, 582 | "allDeclaredMethods":true, 583 | "allDeclaredConstructors":true 584 | }, 585 | { 586 | "name":"io.fabric8.kubernetes.api.model.SecretKeySelector", 587 | "allDeclaredFields":true, 588 | "allDeclaredMethods":true, 589 | "allDeclaredConstructors":true 590 | }, 591 | { 592 | "name":"io.fabric8.kubernetes.api.model.SecretProjection", 593 | "allDeclaredFields":true, 594 | "allDeclaredMethods":true, 595 | "allDeclaredConstructors":true 596 | }, 597 | { 598 | "name":"io.fabric8.kubernetes.api.model.SecretVolumeSource", 599 | "allDeclaredFields":true, 600 | "allDeclaredMethods":true, 601 | "allDeclaredConstructors":true 602 | }, 603 | { 604 | "name":"io.fabric8.kubernetes.api.model.SecurityContext", 605 | "allDeclaredFields":true, 606 | "allDeclaredMethods":true, 607 | "allDeclaredConstructors":true 608 | }, 609 | { 610 | "name":"io.fabric8.kubernetes.api.model.ServiceAccountTokenProjection", 611 | "allDeclaredFields":true, 612 | "allDeclaredMethods":true, 613 | "allDeclaredConstructors":true 614 | }, 615 | { 616 | "name":"io.fabric8.kubernetes.api.model.StorageOSVolumeSource", 617 | "allDeclaredFields":true, 618 | "allDeclaredMethods":true, 619 | "allDeclaredConstructors":true 620 | }, 621 | { 622 | "name":"io.fabric8.kubernetes.api.model.Sysctl", 623 | "allDeclaredFields":true, 624 | "allDeclaredMethods":true, 625 | "allDeclaredConstructors":true 626 | }, 627 | { 628 | "name":"io.fabric8.kubernetes.api.model.TCPSocketAction", 629 | "allDeclaredFields":true, 630 | "allDeclaredMethods":true, 631 | "allDeclaredConstructors":true 632 | }, 633 | { 634 | "name":"io.fabric8.kubernetes.api.model.Toleration", 635 | "allDeclaredFields":true, 636 | "allDeclaredMethods":true, 637 | "allDeclaredConstructors":true 638 | }, 639 | { 640 | "name":"io.fabric8.kubernetes.api.model.TopologySpreadConstraint", 641 | "allDeclaredFields":true, 642 | "allDeclaredMethods":true, 643 | "allDeclaredConstructors":true 644 | }, 645 | { 646 | "name":"io.fabric8.kubernetes.api.model.TypedLocalObjectReference", 647 | "allDeclaredFields":true, 648 | "allDeclaredMethods":true, 649 | "allDeclaredConstructors":true 650 | }, 651 | { 652 | "name":"io.fabric8.kubernetes.api.model.Volume", 653 | "allDeclaredFields":true, 654 | "allDeclaredMethods":true, 655 | "allDeclaredConstructors":true 656 | }, 657 | { 658 | "name":"io.fabric8.kubernetes.api.model.VolumeDevice", 659 | "allDeclaredFields":true, 660 | "allDeclaredMethods":true, 661 | "allDeclaredConstructors":true 662 | }, 663 | { 664 | "name":"io.fabric8.kubernetes.api.model.VolumeMount", 665 | "allDeclaredFields":true, 666 | "allDeclaredMethods":true, 667 | "allDeclaredConstructors":true 668 | }, 669 | { 670 | "name":"io.fabric8.kubernetes.api.model.VolumeProjection", 671 | "allDeclaredFields":true, 672 | "allDeclaredMethods":true, 673 | "allDeclaredConstructors":true 674 | }, 675 | { 676 | "name":"io.fabric8.kubernetes.api.model.VsphereVirtualDiskVolumeSource", 677 | "allDeclaredFields":true, 678 | "allDeclaredMethods":true, 679 | "allDeclaredConstructors":true 680 | }, 681 | { 682 | "name":"io.fabric8.kubernetes.api.model.WatchEvent", 683 | "allDeclaredFields":true, 684 | "allDeclaredMethods":true, 685 | "allDeclaredConstructors":true 686 | }, 687 | { 688 | "name":"io.fabric8.kubernetes.api.model.WeightedPodAffinityTerm", 689 | "allDeclaredFields":true, 690 | "allDeclaredMethods":true, 691 | "allDeclaredConstructors":true 692 | }, 693 | { 694 | "name":"io.fabric8.kubernetes.api.model.WindowsSecurityContextOptions", 695 | "allDeclaredFields":true, 696 | "allDeclaredMethods":true, 697 | "allDeclaredConstructors":true 698 | }, 699 | { 700 | "name":"io.fabric8.kubernetes.internal.KubernetesDeserializer", 701 | "methods":[{"name":"","parameterTypes":[] }] 702 | }, 703 | { 704 | "name":"java.io.Serializable", 705 | "allDeclaredMethods":true 706 | }, 707 | { 708 | "name":"java.lang.String" 709 | }, 710 | { 711 | "name":"java.lang.String[]" 712 | }, 713 | { 714 | "name":"java.lang.Throwable", 715 | "methods":[{"name":"addSuppressed","parameterTypes":["java.lang.Throwable"] }] 716 | }, 717 | { 718 | "name":"java.security.AlgorithmParametersSpi" 719 | }, 720 | { 721 | "name":"java.security.KeyStoreSpi" 722 | }, 723 | { 724 | "name":"java.security.MessageDigestSpi" 725 | }, 726 | { 727 | "name":"java.security.SecureRandomParameters" 728 | }, 729 | { 730 | "name":"java.security.interfaces.RSAPrivateKey" 731 | }, 732 | { 733 | "name":"java.security.interfaces.RSAPublicKey" 734 | }, 735 | { 736 | "name":"java.util.Date" 737 | }, 738 | { 739 | "name":"javax.net.ssl.SSLParameters", 740 | "methods":[{"name":"setApplicationProtocols","parameterTypes":["java.lang.String[]"] }] 741 | }, 742 | { 743 | "name":"javax.net.ssl.SSLSocket", 744 | "methods":[{"name":"getApplicationProtocol","parameterTypes":[] }] 745 | }, 746 | { 747 | "name":"javax.security.auth.x500.X500Principal", 748 | "fields":[{"name":"thisX500Name"}], 749 | "methods":[{"name":"","parameterTypes":["sun.security.x509.X500Name"] }] 750 | }, 751 | { 752 | "name":"sun.security.pkcs.SignerInfo[]" 753 | }, 754 | { 755 | "name":"sun.security.provider.DSA$SHA224withDSA", 756 | "methods":[{"name":"","parameterTypes":[] }] 757 | }, 758 | { 759 | "name":"sun.security.provider.DSA$SHA256withDSA", 760 | "methods":[{"name":"","parameterTypes":[] }] 761 | }, 762 | { 763 | "name":"sun.security.provider.JavaKeyStore$DualFormatJKS", 764 | "methods":[{"name":"","parameterTypes":[] }] 765 | }, 766 | { 767 | "name":"sun.security.provider.JavaKeyStore$JKS", 768 | "methods":[{"name":"","parameterTypes":[] }] 769 | }, 770 | { 771 | "name":"sun.security.provider.NativePRNG", 772 | "methods":[{"name":"","parameterTypes":[] }] 773 | }, 774 | { 775 | "name":"sun.security.provider.SHA", 776 | "methods":[{"name":"","parameterTypes":[] }] 777 | }, 778 | { 779 | "name":"sun.security.provider.SHA2$SHA224", 780 | "methods":[{"name":"","parameterTypes":[] }] 781 | }, 782 | { 783 | "name":"sun.security.provider.SHA2$SHA256", 784 | "methods":[{"name":"","parameterTypes":[] }] 785 | }, 786 | { 787 | "name":"sun.security.provider.SHA5$SHA384", 788 | "methods":[{"name":"","parameterTypes":[] }] 789 | }, 790 | { 791 | "name":"sun.security.provider.SHA5$SHA512", 792 | "methods":[{"name":"","parameterTypes":[] }] 793 | }, 794 | { 795 | "name":"sun.security.provider.X509Factory", 796 | "methods":[{"name":"","parameterTypes":[] }] 797 | }, 798 | { 799 | "name":"sun.security.provider.certpath.PKIXCertPathValidator", 800 | "methods":[{"name":"","parameterTypes":[] }] 801 | }, 802 | { 803 | "name":"sun.security.rsa.RSAKeyFactory$Legacy", 804 | "methods":[{"name":"","parameterTypes":[] }] 805 | }, 806 | { 807 | "name":"sun.security.rsa.RSAPSSSignature", 808 | "methods":[{"name":"","parameterTypes":[] }] 809 | }, 810 | { 811 | "name":"sun.security.rsa.RSASignature$SHA224withRSA", 812 | "methods":[{"name":"","parameterTypes":[] }] 813 | }, 814 | { 815 | "name":"sun.security.rsa.RSASignature$SHA256withRSA", 816 | "methods":[{"name":"","parameterTypes":[] }] 817 | }, 818 | { 819 | "name":"sun.security.ssl.SSLContextImpl$TLS12Context", 820 | "methods":[{"name":"","parameterTypes":[] }] 821 | }, 822 | { 823 | "name":"sun.security.ssl.TrustManagerFactoryImpl$PKIXFactory", 824 | "methods":[{"name":"","parameterTypes":[] }] 825 | }, 826 | { 827 | "name":"sun.security.util.ObjectIdentifier" 828 | }, 829 | { 830 | "name":"sun.security.x509.AuthorityInfoAccessExtension", 831 | "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] 832 | }, 833 | { 834 | "name":"sun.security.x509.AuthorityKeyIdentifierExtension", 835 | "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] 836 | }, 837 | { 838 | "name":"sun.security.x509.BasicConstraintsExtension", 839 | "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] 840 | }, 841 | { 842 | "name":"sun.security.x509.CRLDistributionPointsExtension", 843 | "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] 844 | }, 845 | { 846 | "name":"sun.security.x509.CertificateExtensions" 847 | }, 848 | { 849 | "name":"sun.security.x509.CertificatePoliciesExtension", 850 | "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] 851 | }, 852 | { 853 | "name":"sun.security.x509.ExtendedKeyUsageExtension", 854 | "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] 855 | }, 856 | { 857 | "name":"sun.security.x509.IssuerAlternativeNameExtension", 858 | "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] 859 | }, 860 | { 861 | "name":"sun.security.x509.KeyUsageExtension", 862 | "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] 863 | }, 864 | { 865 | "name":"sun.security.x509.NetscapeCertTypeExtension", 866 | "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] 867 | }, 868 | { 869 | "name":"sun.security.x509.PrivateKeyUsageExtension", 870 | "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] 871 | }, 872 | { 873 | "name":"sun.security.x509.SubjectAlternativeNameExtension", 874 | "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] 875 | }, 876 | { 877 | "name":"sun.security.x509.SubjectKeyIdentifierExtension", 878 | "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] 879 | } 880 | ] 881 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/native-image/ch.frankel.blog/jvm-operator/resource-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "resources":{ 3 | "includes":[ 4 | {"pattern":"\\QMETA-INF/services/io.fabric8.kubernetes.api.KubernetesResourceMappingProvider\\E"}, 5 | {"pattern":"\\Qorg/slf4j/impl/StaticLoggerBinder.class\\E"} 6 | ]}, 7 | "bundles":[] 8 | } 9 | --------------------------------------------------------------------------------