#!/bin/bash
set -oe pipefail

#
# pre-install:
# aws-cli, jq, python3
# python3 packages: boto3
#
# Usage
# ./init-d-account.sh mAccountProfile dAccountProfile pcaArn dev
#

mAccountProfile=$1
dAccountProfile=$2
pcaArn=$3
env=$4
o11yAccountId=$5
shift 5

region=us-west-2
mAccountId=$(aws sts get-caller-identity --query "Account" --profile=$mAccountProfile --output text --no-cli-pager)
dAccountId=$(aws sts get-caller-identity --query "Account" --profile=$dAccountProfile --output text --no-cli-pager)
echo "mAccountId=$mAccountId"
echo "dAccountId=$dAccountId"

function createRole() {
  local roleName=$1
  local trustPolicy=$2
  local policyArns=$3
  local roleList=$(aws iam list-roles \
    --query="Roles[?RoleName=='$roleName']" \
    --region=$region --profile=$dAccountProfile --no-cli-pager)
  if test $? -ne 0; then
    echo "failed to list roles"
    exit 1
  fi
  local hasCreated=$(echo "$roleList" | jq "length")
  if [[ $hasCreated == "0" ]]; then
    aws iam create-role --role-name=$roleName \
      --assume-role-policy-document="$trustPolicy" \
      --region=$region --profile=$dAccountProfile --no-cli-pager > /dev/null
    if test $? -ne 0; then
      echo "failed to create role $roleName"
      exit 1
    fi
    echo "created iam role $roleName"

    aws iam attach-role-policy --role-name=$roleName \
      --policy-arn="$policyArns" \
      --region=$region --profile=$dAccountProfile
    if test $? -ne 0; then
      echo "failed to set role policy $roleName"
      exit 1
    fi
    echo "added iam role policy $roleName"
  else
    echo "iam role $roleName has already created"
  fi
  
}

function createRoleWithPolicy() {
  local roleName=$1
  local trustPolicy=$2
  local policy=$3
  local roleList=$(aws iam list-roles \
    --query="Roles[?RoleName=='$roleName']" \
    --region=$region --profile=$dAccountProfile --no-cli-pager)
  if test $? -ne 0; then
    echo "failed to list roles"
    exit 1
  fi
  local hasCreated=$(echo "$roleList" | jq "length")
  if [[ $hasCreated == "0" ]]; then
    aws iam create-role --role-name=$roleName \
      --assume-role-policy-document="$trustPolicy" \
      --region=$region --profile=$dAccountProfile --no-cli-pager > /dev/null
    if test $? -ne 0; then
      echo "failed to create role $roleName"
      exit 1
    fi
    echo "created iam role $roleName"
  else
    echo "iam role $roleName has already created"
  fi
  aws iam put-role-policy --role-name=$roleName \
    --policy-name="$roleName-policy" --policy-document "$policy" \
    --region=$region --profile=$dAccountProfile --no-cli-pager
  if test $? -ne 0; then
    echo "failed to set role policy $roleName"
    exit 1
  fi
  echo "update iam role policy $roleName"
}

# create auto-deploy-cli role
trustPolicy=$(cat <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::$mAccountId:role/auto-deploy-cli",
                    "arn:aws:iam::$o11yAccountId:role/auto-deploy-cli"
                ]
            },
            "Action": "sts:AssumeRole"
        },
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "config.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
EOF
)
policy=$(cat <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "cloudformation:CreateStack",
                "cloudformation:DeleteStack",
                "cloudformation:UpdateStack",
                "cloudformation:DescribeStacks",
                "cloudformation:ListStacks",
                "cloudformation:DescribeStackEvents",
                "cloudformation:DescribeStackResource",
                "cloudformation:DescribeStackResources",
                "cloudformation:GetTemplate",
                "cloudformation:ValidateTemplate",
                "cloudformation:GetTemplateSummary",
                "cloudformation:TagResource",
                "cloudformation:UntagResource",
                "cloudformation:CreateChangeSet",
                "cloudformation:DescribeChangeSet",
                "cloudformation:ExecuteChangeSet",
                "cloudformation:DeleteChangeSet",
                "cloudformation:ListChangeSets",

                "iam:AttachRolePolicy",
                "iam:DeleteRolePolicy",
                "iam:DetachRolePolicy",
                "iam:GetRolePolicy",
                "iam:PutRolePolicy",
                "iam:CreatePolicy",
                "iam:DeletePolicy",
                "iam:CreateRole",
                "iam:DeleteRole",
                "iam:GetRole",
                "iam:TagRole",
                "iam:UntagRole",
                "iam:ListRolePolicies",
                "iam:ListAttachedRolePolicies",
                "iam:UpdateAssumeRolePolicy",
                "iam:CreateInstanceProfile",
                "iam:DeleteInstanceProfile",
                "iam:GetInstanceProfile",
                "iam:CreateOpenIDConnectProvider",
                "iam:DeleteOpenIDConnectProvider",
                "iam:GetOpenIDConnectProvider",
                "iam:ListOpenIDConnectProviders",
                "iam:TagOpenIDConnectProvider",
                "iam:UntagOpenIDConnectProvider",
                "iam:ListInstanceProfilesForRole",

                "ec2:DescribeAvailabilityZones"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "account:ListRegions",
                "account:DisableRegion",
                "account:EnableRegion",
                "account:GetRegionOptStatus",
                "ec2:DescribeRegions"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:PassRole",
                "s3:CreateBucket",
                "s3:PutBucketPolicy",
                "s3:PutBucketAcl",
                "s3:ListBucket",
                "s3:PutObject",
                "config:DeleteDeliveryChannel",
                "config:PutDeliveryChannel",
                "config:StartConfigurationRecorder",
                "config:StopConfigurationRecorder",
                "config:PutConfigurationRecorder",
                "config:DeleteConfigurationRecorder"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "securityhub:EnableSecurityHub",
                "securityhub:DisableSecurityHub",
                "securityhub:ListEnabledProductsForImport",
                "securityhub:GetFindings"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "guardduty:GetDetector",
                "guardduty:CreateDetector",
                "guardduty:DeleteDetector",
                "guardduty:ListDetectors",
                "guardduty:UpdateDetector",
                "guardduty:CreateThreatIntelSet",
                "guardduty:DeleteThreatIntelSet",
                "guardduty:ListThreatIntelSets",
                "guardduty:UpdateThreatIntelSet",
                "guardduty:CreateIPSet",
                "guardduty:DeleteIPSet",
                "guardduty:ListIPSets",
                "guardduty:UpdateIPSet",
                "guardduty:CreateMembers",
                "guardduty:DeleteMembers",
                "guardduty:ListMembers",
                "guardduty:InviteMembers",
                "guardduty:AcceptInvitation",
                "guardduty:GetFindings",
                "guardduty:ListFindings",
                "guardduty:UpdateFindingsFeedback",
                "iam:CreateServiceLinkedRole",
                "iam:GetRole"
            ],
            "Resource": "*"
        }
    ]
}
EOF
)
createRoleWithPolicy "auto-deploy-cli" "$trustPolicy" "$policy"
aws iam attach-role-policy --role-name "auto-deploy-cli" \
  --policy-arn "arn:aws:iam::aws:policy/service-role/AWS_ConfigRole" \
  --region=$region --profile=$dAccountProfile --no-cli-pager

# create full-manager-eks-role role
trustPolicy=$(cat <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "eks.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
EOF
)
createRole "full-manager-eks-role" "$trustPolicy" "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"

./share-pca.sh "pca" $pcaArn $mAccountProfile $dAccountProfile

