kafka-ops / julie

A solution to help you build automation and gitops in your Apache Kafka deployments. The Kafka gitops!

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Exception when having Julie manage principles with Confluent Cloud and existing serviceAccount

pjalbert27 opened this issue · comments

Hi

This is related to #438
When having Julie manage principals with Confluent Cloud, we get an message error
java.io.IOException: Translation of principal User:dev_myAccount failed, please review your system configuration

This serviceAccount dev_myAccount (sa-xxxx) exists on our confluent cloud

To Reproduce
Steps to reproduce the behavior:

projects: 
  context: dev
  - name: eda
    topics:
      - name: testing_acl
        config:
          replication.factor: 3
          num.partitions: 1
        consumers: 
          - principal: "User:dev_myAccount"
        producers:
          - principal: "User:dev_myAccount"

Include the following ccloud config in the connection properties file:

bootstrap.servers="xxxxxxx.confluent.cloud:9092"
security.protocol=SASL_SSL
sasl.jaas.config="org.apache.kafka.common.security.plain.PlainLoginModule required username=\"xxxxx\" password=\"xxxxxx\";"
ssl.endpoint.identification.algorithm=https
sasl.mechanism=PLAIN
topology.topic.prefix.separator=_
# Confluent Cloud Schema Registry
schema.registry.basic.auth.user.info="xxxxx:xxxxx"
schema.registry.url="https://xxxxx.confluent.cloud"
basic.auth.credentials.source=USER_INFO
ccloud.environment=env-xxxxx
ccloud.cluster.api.key=xxxxx
ccloud.cluster.api.secret="xxxxx"
ccloud.cloud.api.key=xxxxx
ccloud.cloud.api.secret=xxxxx
topology.builder.ccloud.kafka.cluster.id=lkc-xxxxx
ccloud.cluster.url="https://xxxxx.confluent.cloud:443"
topology.builder.access.control.class = com.purbon.kafka.topology.roles.CCloudAclsProvider
julie.enable.principal.management=false

Run Julie with the above topology file.
Version
Julie : 4.1.2
Java : 17,0

Expected behavior
The expected behavior is for the ACL to be created for the resource id associated with the dev_myAccount account and for the service account name to be dev_myAccount.

a/
Regarding request #438 it should work, may be i am doing something wrong ? I tried to set directly the dev_myAccount whithout the User: but raise an exception too
java.lang.IllegalArgumentException: No enum constant com.purbon.kafka.topology.model.users.ConfluentCloudPrincipal.PrincipalType.dev_myAccount

b/
I take a look on code and build a specific version trying to understand what was the problem. In file CCloudUtils.java we search for the specified service account but unfortunatly the service account we are searching for is User:dev_myAccount against a list of service account without User:

   /** CCloudUtils.java - line 40 */ 
    long numericServiceAccountId = serviceAccountIdByNameMap.getOrDefault(binding.getPrincipal(), SERVICE_ACCOUNT_NOT_FOUND);

I try with "updating" list with User: in key as follow (nota bene : i am not a skilled java developer)

   /** CCloudUtils.java */ 
    Map<String, Long> newMap = new HashMap<String, Long>();
    for (Map.Entry<String, Long> entry : serviceAccountIdByNameMap.entrySet()) {
      if (entry.getKey().contains("User:")) newMap.put(entry.getKey(), entry.getValue());
      else newMap.put("User:" + entry.getKey(), entry.getValue());
    }
    ConfluentCloudPrincipal principal = ConfluentCloudPrincipal.fromString(binding.getPrincipal());
    long numericServiceAccountId = newMap.getOrDefault(binding.getPrincipal(), SERVICE_ACCOUNT_NOT_FOUND);

Then after building this specific version, it succeed in creating what i expected to and acl are ok
With the old cclou cli (ccloud kafka acl list)

User:359475 | sa-xxxxxx | ALLOW | WRITE | TOPIC | dev_eda_testing_acl | LITERAL
User:359475 | sa-xxxxxx | ALLOW | DESCRIBE | TOPIC | dev_eda_testing_acl | LITERAL
User:359475 | sa-xxxxxx | ALLOW | READ | TOPIC | dev_eda_testing_acl | LITERAL

With the new confluent cli (confluent kafka acl list)

User:sa-xxxxxx | ALLOW | WRITE | TOPIC | dev_eda_testing_acl | LITERAL
User:sa-xxxxxx | ALLOW | DESCRIBE | TOPIC | dev_eda_testing_acl | LITERAL
User:sa-xxxxxx | ALLOW | READ | TOPIC | dev_eda_testing_acl | LITERAL

Thank you

Hi,
thanks for reporting this situation, I think the core situation here is that:

  • Per convention JulieOps expects users to be in the form of User:XXXX or Group:XXX. This is because with JulieOps these principals are going to be later used for Acls, outside of Confluent Cloud, this pattern is important in order to define things by group.
commented

Hi @purbon,

I noticed a different behaviour between CCloudAclsProvider.java#L84 and CCloudUtils.java#L39 inside translateIfNecessary method.

In fact, in CCloudAclsProvider.java#L84 we have a String[] fields = principal.split(":") before lookupServiceAccountId.get(fields[1]) contrary to CCloudUtils.java#L39 where we have juste serviceAccountIdByNameMap.getOrDefault(binding.getPrincipal(), ...) without split(":")

On the other hand, at line CCloudUtils.java#L38, we have ConfluentCloudPrincipal principal = ConfluentCloudPrincipal.fromString(binding.getPrincipal());. This method return a POJO contains a value of principalType and serviceAccountName after applying a principalString.split(COLON_AS_SEPARATOR) inside fromString method.

So I think, instead of using serviceAccountIdByNameMap.getOrDefault(**binding.getPrincipal()**, ...) we have to use serviceAccountIdByNameMap.getOrDefault(**principal.getServiceAccountName()**, ...)

I think this can fix issue reported by @pjalbert27.

Thanks.

Hi,
thanks both for reporting this, I have created #485 that would amend this problem, so hopefully will not come back. Feel free to reopen this issue, or just comment here, in case this problem reappears, that hopefully will not.