snowdrop / istio-java-api

A Java API to generate Istio descriptors, inspired by Fabric8's kubernetes-model.
Apache License 2.0
112 stars 33 forks source link

Error occurs when Istio Auth is enabled #2

Closed geoand closed 6 years ago

geoand commented 6 years ago

I was testing whether or not the demo Spring Boot Istio application works correctly when Istio Auth is enabled. Unfortunately I encountered the following issue when deploying the application using mvn clean package fabric8:deploy -Pistio-openshift.

org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal io.fabric8:fabric8-maven-plugin:3.5.33:resource (default) on project greeting-service: Execution default of goal io.fabric8:fabric8-maven-plugin:3.5.33:resource failed: Couldn't parse Istio Mesh configuration
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:212)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
        at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106)
        at org.apache.maven.cli.MavenCli.execute(MavenCli.java:863)
        at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:288)
        at org.apache.maven.cli.MavenCli.main(MavenCli.java:199)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
Caused by: org.apache.maven.plugin.PluginExecutionException: Execution default of goal io.fabric8:fabric8-maven-plugin:3.5.33:resource failed: Couldn't parse Istio Mesh configuration
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:145)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:207)
        ... 20 more
Caused by: java.lang.IllegalArgumentException: Couldn't parse Istio Mesh configuration
        at me.snowdrop.cloud.fabric8.IstioEnricher.fetchConfigMap(IstioEnricher.java:232)
        at me.snowdrop.cloud.fabric8.IstioEnricher.addMissingResources(IstioEnricher.java:89)
        at io.fabric8.maven.plugin.enricher.EnricherManager$1.apply(EnricherManager.java:114)
        at io.fabric8.maven.plugin.enricher.EnricherManager$1.apply(EnricherManager.java:111)
        at io.fabric8.maven.plugin.enricher.EnricherManager.loop(EnricherManager.java:214)
        at io.fabric8.maven.plugin.enricher.EnricherManager.createDefaultResources(EnricherManager.java:111)
        at io.fabric8.maven.plugin.enricher.EnricherManager.createDefaultResources(EnricherManager.java:106)
        at io.fabric8.maven.plugin.mojo.build.ResourceMojo.generateAppResources(ResourceMojo.java:544)
        at io.fabric8.maven.plugin.mojo.build.ResourceMojo.generateResources(ResourceMojo.java:456)
        at io.fabric8.maven.plugin.mojo.build.ResourceMojo.executeInternal(ResourceMojo.java:264)
        at io.fabric8.maven.plugin.mojo.AbstractFabric8Mojo.execute(AbstractFabric8Mojo.java:74)
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
        ... 21 more
Caused by: com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not construct instance of java.lang.Integer from String value ("MUTUAL_TLS"): not a valid Integer value
 at [Source: java.io.StringReader@a99c42c; line: 2, column: 13] (through reference chain: me.snowdrop.istio.api.model.v1.mesh.MeshConfig["authPolicy"])
        at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:74)
        at com.fasterxml.jackson.databind.DeserializationContext.weirdStringException(DeserializationContext.java:1022)
        at com.fasterxml.jackson.databind.deser.std.StdDeserializer._parseInteger(StdDeserializer.java:444)
        at com.fasterxml.jackson.databind.deser.std.NumberDeserializers$IntegerDeserializer.deserialize(NumberDeserializers.java:315)
        at com.fasterxml.jackson.databind.deser.std.NumberDeserializers$IntegerDeserializer.deserialize(NumberDeserializers.java:293)
        at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:490)
        at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:95)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:260)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:125)
        at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3807)
        at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2797)
        at me.snowdrop.cloud.fabric8.IstioEnricher.fetchConfigMap(IstioEnricher.java:228)
        ... 32 more

It seems that there is a mismatch between the Java model specified for the MeshConfig object and the actual data being used in Openshift.

When Auth is enabled, the ConfigMap that holds the Mesh configuration in Openshift looks something like the following:

apiVersion: v1
data:
  mesh: |-
    # Uncomment the following line to enable mutual TLS between proxies
    authPolicy: MUTUAL_TLS
    #
    # Edit this list to avoid using mTLS to connect to these services.
    # Typically, these are control services (e.g kubernetes API server) that don't have Istio sidecar
    # to transparently terminate mTLS authentication.
    mtlsExcludedServices: ["kubernetes.default.svc.cluster.local"]
    ...

Note that when Auth is not enabled, the line authPolicy: MUTUAL_TLS is commented out, which is why there is no mapping exception occurring in that case.

Furthermore, this seems to be the AuthenticationPolicy type definition in istio/api.

I am guessing that the Java model assumes the Golang enum would end up in the ConfigMap as an Integer, when it actually ends up as a String.

cmoulliard commented 6 years ago

json reports this error as it parses text while the model has been defined as integer

Model

@JsonInclude(Include.NON_EMPTY)
@JsonPropertyOrder({"apiVersion", "kind", "metadata", "accessLogFile", "authPolicy", "connectTimeout", "defaultConfig", "disablePolicyChecks", "egressProxyAddress", "enableTracing", "ingressClass", "ingressControllerMode", "ingressService", "mixerAddress", "mtlsExcludedServices", "proxyHttpPort", "proxyListenPort", "rdsRefreshDelay"})
public class MeshConfig {
    @JsonProperty("accessLogFile")
    @JsonPropertyDescription("")
    private String accessLogFile;
    @JsonProperty("authPolicy")
    @JsonPropertyDescription("")
    private Integer authPolicy;

Istio config protobuf maps auth mode to an integer value

const (
    // Do not encrypt Envoy to Envoy traffic.
    AuthenticationPolicy_NONE AuthenticationPolicy = 0
    // Envoy to Envoy traffic is wrapped into mutual TLS connections.
    AuthenticationPolicy_MUTUAL_TLS AuthenticationPolicy = 1
    // Use the policy defined by the parent scope. Should not be used for mesh
    // policy.
    AuthenticationPolicy_INHERIT AuthenticationPolicy = 1000
)

var AuthenticationPolicy_name = map[int32]string{
    0:    "NONE",
    1:    "MUTUAL_TLS",
    1000: "INHERIT",
}
var AuthenticationPolicy_value = map[string]int32{
    "NONE":       0,
    "MUTUAL_TLS": 1,
    "INHERIT":    1000,
}