AWS-EKS

The AWS EKS integration allows for the management and operation of Amazon Elastic Kubernetes Service (EKS) clusters.

Cloud Services · AWS - EKS

Details

IDAWS-EKS
ProviderAmazon
CategoryCloud Services
From Version6.9.0
Docker Imagedemisto/boto3py3:1.0.0.10221838
Supported ModulesAgentix XSIAM

README

The AWS EKS integration allows for the management and operation of Amazon Elastic Kubernetes Service (EKS) clusters.
This integration was integrated and tested with version 1.29 of AWS-EKS.

Configure AWS-EKS in Cortex

Parameter Description Required
AWS Default Region AWS Default Region True
Access Key   True
Secret Key   True
Timeout The time in seconds till a timeout exception is reached. You can specify just the read timeout (for example 60) or also the connect timeout followed after a comma (for example 60,10). If a connect timeout is not specified, a default of 10 seconds will be used. False
Retries The maximum number of retry attempts when connection or throttling errors are encountered. Set to 0 to disable retries. The default value is 5 and the limit is 10. Note: Increasing the number of retries will increase the execution time. False
Trust any certificate (not secure) Trust any certificate (not secure) False
Use system proxy settings Use system proxy settings False

Commands

You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.

aws-eks-list-clusters


Lists the Amazon EKS clusters in your Amazon Web Services account in the specified Amazon Web Services Region.

Base Command

aws-eks-list-clusters

Input

Argument Name Description Required
limit The maximum number of clusters to return. Default is 50. Optional
next_token The nextToken value returned from a previous paginated request, where maxResults was used and the results exceeded the value of that parameter. Optional
region The AWS Region. If not specified, the configured region will be used. Possible values are: us-east-1, us-east-2, us-west-1, us-west-2, ca-central-1, eu-west-1, eu-central-1, eu-west-2, ap-northeast-1, ap-northeast-2, ap-southeast-1, ap-southeast-2, ap-south-1, sa-east-1, eu-north-1, eu-west-3. Optional

Context Output

Path Type Description
AWS.EKS.Cluster.ClustersNames List A list of all of the clusters for your account in the specified Amazon Web Services Region.
AWS.EKS.Cluster.NextToken List The nextToken value returned from a previous paginated request, where maxResults was used and the results exceeded the value of that parameter.

Command example


#### Context Example

```json
{
    "AWS": {
        "EKS": {
            "Cluster": {
                "ClustersNames": [
                    "cluster_name1",
                    "cluster_name2"
                ],
                "NextToken": null
            }
        }
    }
}

Human Readable Output

The list of clusters

Clusters Names
cluster_name1
cluster_name2

aws-eks-update-cluster-config


Updates an Amazon EKS cluster configuration. Only one type of update is allowed. Potentially harmful: once the authentication mode is updated to ‘API’ it is irreversible.

Base Command

aws-eks-update-cluster-config

Input

Argument Name Description Required
cluster_name The name of the Amazon EKS cluster to update. Required
resources_vpc_config A JSON representation of the VPC configuration used by the cluster control plane. An example: “{‘subnetIds’: [‘string’], ‘securityGroupIds’: [‘string’], ‘endpointPublicAccess’: True, ‘endpointPrivateAccess’: True, ‘publicAccessCidrs’: [‘string’]}”. Optional
logging A JSON representation of the logging configuration for the cluster. An example: “{‘clusterLogging’: [{‘types’: [‘api’, ‘audit’, ‘authenticator’, ‘controllerManager’, ‘scheduler’], ‘enabled’: true}]}”. Optional
authentication_mode Whether to update the authentication mode to ‘API_AND_CONFIG_MAP’ or not. Possible values are: true, false. Optional
region The AWS Region. If not specified, the configured region will be used. Possible values are: us-east-1, us-east-2, us-west-1, us-west-2, ca-central-1, eu-west-1, eu-central-1, eu-west-2, ap-northeast-1, ap-northeast-2, ap-southeast-1, ap-southeast-2, ap-south-1, sa-east-1, eu-north-1, eu-west-3. Optional

Context Output

Path Type Description
AWS.EKS.UpdateCluster.clusterName String The name of the cluster.
AWS.EKS.UpdateCluster.id Integer The ID of the update.
AWS.EKS.UpdateCluster.status String The status of the update.
AWS.EKS.UpdateCluster.type String The type of the update.
AWS.EKS.UpdateCluster.params Object The parameters of the update.
AWS.EKS.UpdateCluster.createdAt String The creation date of the object.
AWS.EKS.UpdateCluster.errors Object Any errors associated with a failed update.

Command example

!aws-eks-update-cluster-config cluster_name=CLUSTER_NAME logging="{'clusterLogging': [{'types': ['api', 'authenticator', 'audit'], 'enabled': false}]}"

Context Example

{
    "AWS": {
        "EKS": {
            "UpdateCluster": {
                "createdAt": "2024-02-26 09:38:11.578000+00:00",
                "errors": [],
                "id": "11111111-1111-1111-1111-111111111111",
                "name": "CLUSTER_NAME",
                "params": [
                    {
                        "type": "ClusterLogging",
                        "value": "{\"clusterLogging\":[{\"types\":[\"api\",\"audit\",\"authenticator\"],\"enabled\":false}]}"
                    }
                ],
                "status": "InProgress",
                "type": "LoggingUpdate"
            }
        }
    }
}

Human Readable Output

Updated Cluster Config Information

Cluster Name ID Status Type Params
CLUSTER_NAME 11111111-1111-1111-1111-111111111111 InProgress LoggingUpdate {‘type’: ‘ClusterLogging’, ‘value’: ‘{“clusterLogging”:[{“types”:[“api”,”audit”,”authenticator”],”enabled”:false}]}’}

aws-eks-describe-cluster


Describes an Amazon EKS cluster.

Base Command

aws-eks-describe-cluster

Input

Argument Name Description Required
cluster_name The name of the cluster to describe. Required
region The AWS Region. If not specified, the configured region will be used. Possible values are: us-east-1, us-east-2, us-west-1, us-west-2, ca-central-1, eu-west-1, eu-central-1, eu-west-2, ap-northeast-1, ap-northeast-2, ap-southeast-1, ap-southeast-2, ap-south-1, sa-east-1, eu-north-1, eu-west-3. Optional

Context Output

Path Type Description
AWS.EKS.DescribeCluster.name String The name of your cluster.
AWS.EKS.DescribeCluster.arn String The Amazon Resource Name (ARN) of the cluster.
AWS.EKS.DescribeCluster.createdAt String The creation date of the object.
AWS.EKS.DescribeCluster.version String The Kubernetes server version for the cluster.
AWS.EKS.DescribeCluster.endpoint String The endpoint for your Kubernetes API server.
AWS.EKS.DescribeCluster.roleArn String The Amazon Resource Name (ARN) of the IAM role that provides permissions for the Kubernetes control plane to make calls to Amazon Web Services API operations on your behalf.
AWS.EKS.DescribeCluster.resourcesVpcConfig.subnetIds List The subnets associated with your cluster.
AWS.EKS.DescribeCluster.resourcesVpcConfig.securityGroupIds List The security groups associated with the cross-account elastic network interfaces that are used to allow communication between your nodes and the Kubernetes control plane.
AWS.EKS.DescribeCluster.resourcesVpcConfig.clusterSecurityGroupId String The cluster security group that was created by Amazon EKS for the cluster. Managed node groups use this security group for control-plane-to-data-plane communication.
AWS.EKS.DescribeCluster.resourcesVpcConfig.vpcId String The VPC associated with your cluster.
AWS.EKS.DescribeCluster.resourcesVpcConfig.endpointPublicAccess Boolean Whether the public API server endpoint is enabled.
AWS.EKS.DescribeCluster.resourcesVpcConfig.endpointPrivateAccess Boolean This parameter indicates whether the Amazon EKS private API server endpoint is enabled.
AWS.EKS.DescribeCluster.resourcesVpcConfig.publicAccessCidrs List The CIDR blocks that are allowed access to your cluster’s public Kubernetes API server endpoint.
AWS.EKS.DescribeCluster.kubernetesNetworkConfig.serviceIpv4Cidr String The CIDR block that Kubernetes Pod and Service object IP addresses are assigned from.
AWS.EKS.DescribeCluster.kubernetesNetworkConfig.serviceIpv6Cidr String The CIDR block that Kubernetes Pod and Service IP addresses are assigned from if you created a 1.21 or later cluster with version 1.10.1 or later of the Amazon VPC CNI add-on and specified ipv6 for ipFamily when you created the cluster.
AWS.EKS.DescribeCluster.kubernetesNetworkConfig.ipFamily String The IP family used to assign Kubernetes Pod and Service objects IP addresses.
AWS.EKS.DescribeCluster.logging.clusterLogging Object The cluster control plane logging configuration for your cluster.
AWS.EKS.DescribeCluster.identity Object The identity provider information for the cluster.
AWS.EKS.DescribeCluster.status String The current status of the cluster.
AWS.EKS.DescribeCluster.certificateAuthority.data String The Base64-encoded certificate data required to communicate with your cluster.
AWS.EKS.DescribeCluster.clientRequestToken String A unique, case-sensitive identifier that you provide to ensure the idempotency of the request.
AWS.EKS.DescribeCluster.platformVersion String The platform version of your Amazon EKS cluster.
AWS.EKS.DescribeCluster.tags Object A dictionary containing metadata for categorization and organization.
AWS.EKS.DescribeCluster.encryptionConfig.resources List Specifies the resources to be encrypted. The only supported value is secrets.
AWS.EKS.DescribeCluster.encryptionConfig.provider Object Key Management Service (KMS) key.
AWS.EKS.DescribeCluster.connectorConfig.activationId String A unique ID associated with the cluster for registration purposes.
AWS.EKS.DescribeCluster.connectorConfig.activationCode String A unique code associated with the cluster for registration purposes.
AWS.EKS.DescribeCluster.connectorConfig.activationExpiry String The expiration time of the connected cluster.
AWS.EKS.DescribeCluster.connectorConfig.provider String The cluster’s cloud service provider.
AWS.EKS.DescribeCluster.connectorConfig.roleArn String The Amazon Resource Name (ARN) of the role to communicate with services from the connected Kubernetes cluster.
AWS.EKS.DescribeCluster.id String The ID of your local Amazon EKS cluster on an Amazon Web Services Outpost.
AWS.EKS.DescribeCluster.health.issues List An object representing the health issues of your local Amazon EKS cluster on an Amazon Web Services Outpost.
AWS.EKS.DescribeCluster.outpostConfig.outpostArns Object An object representing the configuration of your local Amazon EKS cluster on an Amazon Web Services Outpost.
AWS.EKS.DescribeCluster.outpostConfig.controlPlaneInstanceType String The Amazon EC2 instance type used for the control plane.
AWS.EKS.DescribeCluster.outpostConfig.controlPlanePlacement Object An object representing the placement configuration for all the control plane instances of your local Amazon EKS cluster on an Amazon Web Services Outpost.
AWS.EKS.DescribeCluster.accessConfig.bootstrapClusterCreatorAdminPermissions Boolean Specifies whether or not the cluster creator IAM principal was set as a cluster admin access entry during cluster creation time.
AWS.EKS.DescribeCluster.accessConfig.authenticationMode String The current authentication mode of the cluster.

Command example

!aws-eks-describe-cluster cluster_name=CLUSTER_NAME

Context Example

{
    "AWS": {
        "EKS": {
            "DescribeCluster": {
                "accessConfig": {
                    "authenticationMode": "API_AND_CONFIG_MAP"
                },
                "arn": "arn",
                "certificateAuthority": {
                    "data": "data_key"
                },
                "createdAt": "2024-02-26 09:38:11.578000+00:00",
                "endpoint": "endpoint",
                "health": {
                    "issues": []
                },
                "identity": {
                    "oidc": {
                        "issuer": "issuer"
                    }
                },
                "kubernetesNetworkConfig": {
                    "ipFamily": "ipv4",
                    "serviceIpv4Cidr": "11.111.1.1/11"
                },
                "logging": {
                    "clusterLogging": [
                        {
                            "enabled": true,
                            "types": [
                                "api",
                                "audit",
                                "authenticator",
                                "controllerManager",
                                "scheduler"
                            ]
                        }
                    ]
                },
                "name": "CLUSTER_NAME",
                "platformVersion": "eks.1",
                "resourcesVpcConfig": {
                    "clusterSecurityGroupId": "sg-id",
                    "endpointPrivateAccess": true,
                    "endpointPublicAccess": true,
                    "publicAccessCidrs": [
                        "111.111.111.111/11"
                    ],
                    "securityGroupIds": [
                        "sg-id"
                    ],
                    "subnetIds": [
                        "subnet-id"
                    ],
                    "vpcId": "vpc-id"
                },
                "roleArn": "roleArn",
                "status": "ACTIVE",
                "tags": {},
                "version": "1.29"
            }
        }
    }
}

Human Readable Output

Describe Cluster Information

Cluster Name Status ARN Created At Version
roleArn ACTIVE roleArn 2024-02-26 09:38:11.578000+00:00 1.29

aws-eks-create-access-entry


Creates an access entry.

Base Command

aws-eks-create-access-entry

Input

Argument Name Description Required
cluster_name The name of the cluster for which to create an access entry. Required
principal_arn ARN of the IAM principal for the AccessEntry. Required
kubernetes_groups A comma-separated list of names for Kubernetes groups in RoleBindings or ClusterRoleBindings. Optional
tags A dictionary containing metadata for categorization and organization. Each tag consists of a key and an optional value. Optional
client_request_token Unique identifier for idempotency. Optional
username Username for Kubernetes authentication. Optional
type The type of access entry to create. Possible values are: Standard, FARGATE_LINUX, EC2_LINUX, EC2_WINDOWS. Default is Standard. Optional
region The AWS Region. If not specified, the configured region will be used. Possible values are: us-east-1, us-east-2, us-west-1, us-west-2, ca-central-1, eu-west-1, eu-central-1, eu-west-2, ap-northeast-1, ap-northeast-2, ap-southeast-1, ap-southeast-2, ap-south-1, sa-east-1, eu-north-1, eu-west-3. Optional

Context Output

Path Type Description
AWS.EKS.CreateAccessEntry.clusterName String The name of the cluster.
AWS.EKS.CreateAccessEntry.principalArn String The ARN of the IAM principal for the access entry.
AWS.EKS.CreateAccessEntry.kubernetesGroups String A list of names that you’ve specified in a Kubernetes RoleBinding or ClusterRoleBinding object so that Kubernetes authorizes the principalARN access to cluster objects.
AWS.EKS.CreateAccessEntry.accessEntryArn String The ARN of the access entry.
AWS.EKS.CreateAccessEntry.createdAt String The creation date of the object.
AWS.EKS.CreateAccessEntry.modifiedAt String The date and time for the last modification to the object.
AWS.EKS.CreateAccessEntry.tags Object A dictionary containing metadata for categorization and organization.
AWS.EKS.CreateAccessEntry.username String The name of a user that can authenticate to the cluster.
AWS.EKS.CreateAccessEntry.type String The type of the access entry.

Command example

!aws-eks-create-access-entry cluster_name=CLUSTER_NAME principal_arn=principal_arn

Context Example

{
    "AWS": {
        "EKS": {
            "CreateAccessEntry": {
                "ResponseMetadata": {
                    "clusterName": "clusterName",
                    "principalArn": "principalArn",
                    "kubernetesGroups": [
                        "kubernetesGroups"
                    ],
                    "accessEntryArn": "accessEntryArn",
                    "createdAt": "2024-02-26 09:38:11.578000+00:00",
                    "modifiedAt": "2024-02-26 09:38:11.578000+00:00",
                    "tags": {
                        "string": "string"
                    },
                    "username": "username",
                    "type": "STANDARD"
                }
            }
        }
    }
}

Human Readable Output

The newly created access entry

Cluster Name Principal Arn Username Type Created At
clusterName principalArn username STANDARD 2024-02-26 09:38:11.578000+00:00

aws-eks-associate-access-policy


Associates an access policy and its scope to an access entry.

Base Command

aws-eks-associate-access-policy

Input

Argument Name Description Required
cluster_name The name of the cluster for which to create an access entry. Required
principal_arn The Amazon Resource Name (ARN) of the IAM user or role for the AccessEntry that you’re associating the access policy to. Required
policy_arn The ARN of the AccessPolicy that you’re associating. Required
type The scope type of an access policy. Possible values are: cluster, namespace. Required
namespaces A comma-separated list of Kubernetes namespaces that an access policy is scoped to. A value is required if you specified namespace for type. Optional
region The AWS Region. If not specified, the configured region will be used. Possible values are: us-east-1, us-east-2, us-west-1, us-west-2, ca-central-1, eu-west-1, eu-central-1, eu-west-2, ap-northeast-1, ap-northeast-2, ap-southeast-1, ap-southeast-2, ap-south-1, sa-east-1, eu-north-1, eu-west-3. Optional

Context Output

Path Type Description
AWS.EKS.AssociatedAccessPolicy.clusterName String The name of your cluster.
AWS.EKS.AssociatedAccessPolicy.principalArn String The ARN of the IAM principal for the AccessEntry.
AWS.EKS.AssociatedAccessPolicy.policyArn String The ARN of the AccessPolicy.
AWS.EKS.AssociatedAccessPolicy.accessScope.type String The scope type of an access policy.
AWS.EKS.AssociatedAccessPolicy.accessScope.namespaces String A Kubernetes namespace that an access policy is scoped to.
AWS.EKS.AssociatedAccessPolicy.associatedAt String The date and time the AccessPolicy was associated with an AccessEntry.
AWS.EKS.AssociatedAccessPolicy.modifiedAt String The date and time for the last modification to the object.

Command example

!aws-eks-associate-access-policy cluster_name=CLUSTER_NAME principal_arn=principal_arn type=cluster

Context Example

{
    "AWS": {
        "EKS": {
            "AssociatedAccessPolicy": {
                "associatedAccessPolicy": {
                    "accessScope": {
                        "namespaces": [],
                        "type": "cluster"
                    },
                    "associatedAt": "2024-02-26 09:38:11.578000+00:00",
                    "modifiedAt": "2024-02-26 09:38:11.578000+00:00",
                    "policyArn": "policyArn"
                },
                "clusterName": "CLUSTER_NAME",
                "principalArn": "principalArn"
            }
        }
    }
}

Human Readable Output

The access policy was associated to the access entry successfully

Cluster Name Principal Arn Policy Arn associate At
clusterName principalArn username 2024-02-26 09:38:11.578000+00:00

aws-eks-update-access-entry


Updates an access entry.

Base Command

aws-eks-update-access-entry

Input

Argument Name Description Required
cluster_name The name of the cluster. Required
principal_arn ARN of the IAM principal for the AccessEntry. Required
kubernetes_groups A comma-separated list of names for Kubernetes groups in RoleBindings or ClusterRoleBindings. Optional
client_request_token Unique identifier for idempotency. Optional
username Username for Kubernetes authentication. Optional
region The AWS Region. If not specified, the configured region will be used. Possible values are: us-east-1, us-east-2, us-west-1, us-west-2, ca-central-1, eu-west-1, eu-central-1, eu-west-2, ap-northeast-1, ap-northeast-2, ap-southeast-1, ap-southeast-2, ap-south-1, sa-east-1, eu-north-1, eu-west-3. Optional

Context Output

Path Type Description
AWS.EKS.UpdateAccessEntry.clusterName String The name of your cluster.
AWS.EKS.UpdateAccessEntry.principalArn String The ARN of the IAM principal for the access entry.
AWS.EKS.UpdateAccessEntry.kubernetesGroups List A list of names that you’ve specified in a Kubernetes RoleBinding or ClusterRoleBinding object so that Kubernetes authorizes the principalARN access to cluster objects.
AWS.EKS.UpdateAccessEntry.accessEntryArn String The ARN of the access entry.
AWS.EKS.UpdateAccessEntry.createdAt String The creation date of the object.
AWS.EKS.UpdateAccessEntry.modifiedAt String The date and time for the last modification to the object.
AWS.EKS.UpdateAccessEntry.tags Object Metadata that assists with categorization and organization. Each tag consists of a key and an optional value.
AWS.EKS.UpdateAccessEntry.username String The name of a user that can authenticate to your cluster.
AWS.EKS.UpdateAccessEntry.type String The type of the access entry.

Command example

!aws-eks-update-access-entry cluster_name=CLUSTER_NAME principal_arn=principal_arn

Context Example

{
    "AWS": {
        "EKS": {
            "UpdateAccessEntry": {
                "accessEntryArn": "accessEntryArn",
                "clusterName": "CLUSTER_NAME",
                "createdAt": "2024-02-26 09:38:11.578000+00:00",
                "kubernetesGroups": [],
                "modifiedAt": "2024-02-26 09:38:11.578000+00:00",
                "principalArn": "principalArn",
                "tags": {},
                "type": "STANDARD",
                "username": "username"
            }
        }
    }
}

Human Readable Output

The updated access entry

Cluster Name Principal Arn Username Type Modified At
CLUSTER_NAME principal_arn username STANDARD 2024-02-26 09:38:11.578000+00:00

Configuration parameters

  • defaultRegion — AWS Default Region (required)
  • credentials — Access Key (required)
  • timeout — Timeout
  • retries — Retries
  • sts_regional_endpoint — AWS STS Regional Endpoints
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (6)

  • aws-eks-associate-access-policy

    Associates an access policy and its scope to an access entry.

  • aws-eks-create-access-entry

    Creates an access entry.

  • aws-eks-describe-cluster

    Describes an Amazon EKS cluster.

  • aws-eks-list-clusters

    Lists the Amazon EKS clusters in your Amazon Web Services account in the specified Amazon Web Services Region.

  • aws-eks-update-access-entry

    Updates an access entry.

  • aws-eks-update-cluster-config

    Updates an Amazon EKS cluster configuration. Only one type of update is allowed. Potentially harmful: once the authentication mode is updated to 'API' it is irreversible.

import json

import demistomock as demisto  # noqa: F401
import urllib3
from AWSApiModule import *  # noqa: E402
from CommonServerPython import *  # noqa: F401

from CommonServerUserPython import *  # noqa

# Disable insecure warnings
urllib3.disable_warnings()


""" CONSTANTS """

DATE_FORMAT = "%Y-%m-%dT%H:%M:%SZ"  # ISO8601 format with UTC, default in XSOAR

""" HELPER FUNCTIONS """


def validate_args(resources_vpc_config: dict, logging_arg: dict, authentication_mode: bool):
    """
    Check that exactly one argument is passed, and if not raise a value error
    Args:
        resources_vpc_config: An object representing the VPC configuration to use for an Amazon EKS cluster.
        logging_arg: The cluster control plane logging configuration.
        authentication_mode: The desired authentication mode for the cluster.

    Returns:
        A Command Results object
    """
    arr = [resources_vpc_config, logging_arg, authentication_mode]
    arg_num = sum(bool(arg) for arg in arr)  # counts the number of non-empty args.
    if arg_num != 1:
        raise ValueError(
            "Please provide exactly one of the following arguments: resources_vpc_config, logging or authentication_mode."
        )


def config_aws_session(args: dict, aws_client: AWSClient):
    """
    Configures an AWS session for the EKS service,
    Used in all the commands.

    Args:
        args (dict): A dictionary containing the configuration parameters for the session.
                     - 'region' (str): The AWS region.

        aws_client (AWSClient): The AWS client used to configure the session.

    Returns:
        AWS session (boto3 client): The configured AWS session.
    """
    return aws_client.aws_session(service="eks", region=args.get("region"))


""" COMMAND FUNCTIONS """


def list_clusters_command(aws_client, args: dict) -> CommandResults:
    """
    Lists the Amazon EKS clusters in the Amazon Web Services account in the specified Amazon Web Services Region.
    Args:
        aws_client (boto3 client): The configured AWS session.
        args: command arguments

    Returns:
        A Command Results object
    """
    limit = arg_to_number(args.get("limit")) or 50
    next_token = args.get("next_token", "")
    list_clusters = []
    flag = True  # Do we want to enter the while loop? -> in the first time, yes. After that only if next_token!=None & limit>0
    while limit > 0 and flag:
        if limit > 100:
            response = aws_client.list_clusters(maxResults=100, nextToken=next_token)
            limit -= 100
        else:
            response = aws_client.list_clusters(maxResults=limit, nextToken=next_token)
            limit = 0
        list_clusters.extend(response.get("clusters", []))
        next_token = response.get("nextToken")
        flag = bool(next_token)

    md_table = {
        "Clusters Names": list_clusters,
    }

    outputs = {"ClustersNames": list_clusters, "NextToken": next_token}

    if list_clusters:
        readable_output = tableToMarkdown(
            name="The list of clusters",
            t=md_table,
            removeNull=True,
        )
    else:
        readable_output = "No clusters found."

    return CommandResults(
        readable_output=readable_output,
        outputs_prefix="AWS.EKS.Cluster",
        outputs=outputs,
        raw_response=outputs,
    )


def update_cluster_config_command(aws_client, args: dict) -> CommandResults:
    """
    Updates an Amazon EKS cluster configuration.
    Args:
        aws_client(boto3 client): The configured AWS session.
        args: command arguments

    Returns:
        A Command Results object
    """
    cluster_name = args.get("cluster_name")
    resources_vpc_config = args.get("resources_vpc_config", "").replace("'", '"')
    logging_arg = args.get("logging", "").replace("'", '"')
    resources_vpc_config = json.loads(resources_vpc_config) if resources_vpc_config else {}
    logging_arg = json.loads(logging_arg) if logging_arg else {}
    authentication_mode = argToBoolean(args.get("authentication_mode", False))

    validate_args(resources_vpc_config, logging_arg, authentication_mode)

    access_config = {"authenticationMode": "API_AND_CONFIG_MAP"} if authentication_mode else {}

    try:
        if resources_vpc_config:
            response = aws_client.update_cluster_config(name=cluster_name, resourcesVpcConfig=resources_vpc_config)
        elif logging_arg:
            response = aws_client.update_cluster_config(
                name=cluster_name,
                logging=logging_arg,
            )
        else:  # access_config
            response = aws_client.update_cluster_config(name=cluster_name, accessConfig=access_config)

        response_data = response.get("update", {})
        response_data["clusterName"] = cluster_name
        response_data["createdAt"] = datetime_to_string(response_data.get("createdAt"))

        headers = ["clusterName", "id", "status", "type", "params"]
        readable_output = tableToMarkdown(
            name="Updated Cluster Config Information",
            t=response_data,
            removeNull=True,
            headers=headers,
            headerTransform=pascalToSpace,
        )
        return CommandResults(
            readable_output=readable_output,
            outputs_prefix="AWS.EKS.UpdateCluster",
            outputs=response_data,
            raw_response=response_data,
            outputs_key_field="id",
        )
    except Exception as e:
        if "No changes needed" in str(e):
            return CommandResults(readable_output="No changes needed for the required update.")
        else:
            raise e


def describe_cluster_command(aws_client, args: dict) -> CommandResults:
    """
    Describes an Amazon EKS cluster.
    Args:
        aws_client(boto3 client): The configured AWS session.
        args: command arguments

    Returns:
        A Command Results object
    """
    cluster_name = args.get("cluster_name")

    response = aws_client.describe_cluster(name=cluster_name)
    response_data = response.get("cluster", {})
    response_data["createdAt"] = datetime_to_string(response_data.get("createdAt"))
    if response_data.get("connectorConfig", {}).get("activationExpiry"):
        response_data.get("connectorConfig", {})["activationExpiry"] = datetime_to_string(
            response_data.get("connectorConfig", {}).get("activationExpiry")
        )

    headers = ["name", "id", "status", "arn", "createdAt", "version"]
    readable_output = tableToMarkdown(
        name="Describe Cluster Information", t=response_data, removeNull=True, headers=headers, headerTransform=pascalToSpace
    )
    return CommandResults(
        readable_output=readable_output,
        outputs_prefix="AWS.EKS.DescribeCluster",
        outputs=response_data,
        raw_response=response_data,
        outputs_key_field="name",
    )


def create_access_entry_command(aws_client, args: dict) -> CommandResults:
    """
    Creates an access entry.
    Args:
        aws_client(boto3 client): The configured AWS session.
        args: command arguments

    Returns:
        A Command Results object
    """
    cluster_name = args.get("cluster_name")
    principal_arn = args.get("principal_arn")
    kubernetes_groups = argToList(args.get("kubernetes_groups"))
    tags = args.get("tags", "").replace("'", '"')
    tags = json.loads(tags) if tags else {}
    client_request_token = args.get("client_request_token", "")
    username = args.get("username", "")
    type_arg = args.get("type", "").upper()

    try:
        if username:
            response = aws_client.create_access_entry(
                clusterName=cluster_name,
                principalArn=principal_arn,
                kubernetesGroups=kubernetes_groups,
                tags=tags,
                clientRequestToken=client_request_token,
                username=username,
                type=type_arg,
            ).get("accessEntry")
        else:
            response = aws_client.create_access_entry(
                clusterName=cluster_name,
                principalArn=principal_arn,
                kubernetesGroups=kubernetes_groups,
                tags=tags,
                clientRequestToken=client_request_token,
                type=type_arg,
            ).get("accessEntry")

        response["createdAt"] = datetime_to_string(response.get("createdAt"))
        response["modifiedAt"] = datetime_to_string(response.get("modifiedAt"))

        headers = ["clusterName", "principalArn", "username", "type", "createdAt"]
        readable_output = tableToMarkdown(
            name="The newly created access entry", t=response, removeNull=True, headers=headers, headerTransform=pascalToSpace
        )

        return CommandResults(
            readable_output=readable_output,
            outputs_prefix="AWS.EKS.CreateAccessEntry",
            outputs=response,
            raw_response=response,
            outputs_key_field="ClusterName",
        )
    except Exception as e:
        if "already in use" in str(e):
            return CommandResults(readable_output="The specified access entry resource is already in use on this cluster.")
        else:
            raise e


def associate_access_policy_command(aws_client, args: dict) -> CommandResults:
    """
    Associates an access policy and its scope to an access entry.
    Args:
        aws_client(boto3 client): The configured AWS session.
        args: command arguments

    Returns:
        A Command Results object
    """
    cluster_name = args.get("cluster_name")
    principal_arn = args.get("principal_arn")
    policy_arn = args.get("policy_arn")
    type_arg = args.get("type")
    namespaces = argToList(args.get("namespaces"))
    if type_arg and type_arg == "namespace" and not namespaces:
        raise Exception(f"When the {type_arg=}, you must enter a namespace.")

    access_scope = {"type": type_arg, "namespaces": namespaces}

    response = aws_client.associate_access_policy(
        clusterName=cluster_name, principalArn=principal_arn, policyArn=policy_arn, accessScope=access_scope
    )
    response_data = response.get("associatedAccessPolicy", {})
    response_data["clusterName"] = response.get("clusterName")
    response_data["principalArn"] = response.get("principalArn")

    response_data["associatedAt"] = datetime_to_string(response_data.get("associatedAt"))
    response_data["modifiedAt"] = datetime_to_string(response_data.get("modifiedAt"))

    headers = ["clusterName", "principalArn", "policyArn", "associatedAt"]
    readable_output = tableToMarkdown(
        name="The access policy was associated to the access entry successfully.",
        t=response_data,
        removeNull=True,
        headers=headers,
        headerTransform=pascalToSpace,
    )

    return CommandResults(
        readable_output=readable_output,
        outputs_prefix="AWS.EKS.AssociatedAccessPolicy",
        outputs=response_data,
        raw_response=response_data,
        outputs_key_field="clusterName",
    )


def update_access_entry_command(aws_client, args: dict) -> CommandResults:
    """
    Updates an access entry.
    Args:
        aws_client(boto3 client): The configured AWS session.
        args: command arguments

    Returns:
        A Command Results object
    """
    cluster_name = args.get("cluster_name")
    principal_arn = args.get("principal_arn")
    kubernetes_groups = argToList(args.get("kubernetes_groups"))
    client_request_token = args.get("client_request_token", "")
    username = args.get("username")

    if username:
        response = aws_client.update_access_entry(
            clusterName=cluster_name,
            principalArn=principal_arn,
            kubernetesGroups=kubernetes_groups,
            clientRequestToken=client_request_token,
            username=username,
        ).get("accessEntry", {})
    else:
        response = aws_client.update_access_entry(
            clusterName=cluster_name,
            principalArn=principal_arn,
            kubernetesGroups=kubernetes_groups,
            clientRequestToken=client_request_token,
        ).get("accessEntry", {})

    response["createdAt"] = datetime_to_string(response.get("createdAt"))
    response["modifiedAt"] = datetime_to_string(response.get("modifiedAt"))

    headers = ["clusterName", "principalArn", "username", "type", "modifiedAt"]
    readable_output = tableToMarkdown(
        name="The updated access entry", t=response, removeNull=True, headers=headers, headerTransform=pascalToSpace
    )

    return CommandResults(
        readable_output=readable_output,
        outputs_prefix="AWS.EKS.UpdateAccessEntry",
        outputs=response,
        raw_response=response,
        outputs_key_field="ClusterName",
    )


def test_module(aws_client) -> str:
    """Tests API connectivity and authentication'

    Returning 'ok' indicates that the integration works like it is supposed to.
    Connection to the service is successful.
    Raises exceptions if something goes wrong.

    :type aws_client(boto3 client): The configured AWS session.
    :param AWSClient: client to use

    :return: 'ok' if test passed, anything else will fail the test.
    :rtype: ``str``
    """

    message: str = ""
    try:
        aws_client.list_clusters(maxResults=1)
        message = "ok"
    except DemistoException as e:
        if "Forbidden" in str(e) or "Authorization" in str(e):
            message = "Authorization Error: make sure API Key is correctly set"
        else:
            raise e
    return message


""" MAIN FUNCTION """


def main():  # pragma: no cover
    params = demisto.params()
    aws_default_region = params.get("defaultRegion")
    aws_access_key_id = params.get("credentials", {}).get("identifier")
    aws_secret_access_key = params.get("credentials", {}).get("password")
    verify_certificate = not demisto.params().get("insecure", False)
    timeout = params.get("timeout")
    retries = params.get("retries") or 5

    demisto.debug(f"Command being called is {demisto.command()}")
    try:
        validate_params(aws_default_region, "", "", aws_access_key_id, aws_secret_access_key)

        aws_client = AWSClient(
            aws_default_region,
            None,
            None,
            None,
            None,
            aws_access_key_id,
            aws_secret_access_key,
            verify_certificate,
            timeout,
            retries,
        )

        args = demisto.args()

        aws_client = config_aws_session(args, aws_client)

        if demisto.command() == "test-module":
            # This is the call made when pressing the integration Test button.
            return_results(test_module(aws_client))

        elif demisto.command() == "aws-eks-list-clusters":
            return_results(list_clusters_command(aws_client, args))

        elif demisto.command() == "aws-eks-update-cluster-config":
            return_results(update_cluster_config_command(aws_client, args))

        elif demisto.command() == "aws-eks-describe-cluster":
            return_results(describe_cluster_command(aws_client, args))

        elif demisto.command() == "aws-eks-create-access-entry":
            return_results(create_access_entry_command(aws_client, args))

        elif demisto.command() == "aws-eks-associate-access-policy":
            return_results(associate_access_policy_command(aws_client, args))

        elif demisto.command() == "aws-eks-update-access-entry":
            return_results(update_access_entry_command(aws_client, args))

        else:
            return_error(f"The command {demisto.command()} isn't implemented")

    # Log exceptions and return errors
    except Exception as e:
        return_error(f"Failed to execute {demisto.command()} command.\nError:\n{e!s}")


""" ENTRY POINT """


if __name__ in ("__main__", "__builtin__", "builtins"):
    main()