# ###################################
##       Rule Specification        ##
#####################################
# 
# Rule Identifier:
#   rds_cluster_default_admin_check
# 
# Description:
#   This control checks whether an Amazon Relational Database Service (RDS) database (DB) cluster has changed the administrator username from its default value.
# 
# Reports on:
#   AWS::RDS::DBCluster
# 
# Evaluates:
#   AWS CloudFormation, AWS CloudFormation hook
# 
# Rule Parameters:
#   None
# 
# Scenarios:
#   Scenario: 1
#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
#       And: The input document does not contain any RDS DB cluster resources
#      Then: SKIP
#   Scenario: 2
#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
#       And: The input document contains an RDS DB cluster resource
#       And: 'MasterUsername' has not been provided
#      Then: SKIP
#   Scenario: 3
#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
#       And: The input document contains an RDS DB cluster resource
#       And: 'MasterUsername' has been provided and it is set to 'admin' or 'postgres'
#      Then: FAIL
#   Scenario: 4
#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
#       And: The input document contains an RDS DB cluster resource
#       And: 'MasterUsername' has been provided and is not set to 'admin' or 'postgres'
#      Then: PASS

#
# Constants
#
let RDS_DB_CLUSTER_TYPE = "AWS::RDS::DBCluster"
let DISALLOWED_MASTER_USERNAMES = ["admin", "postgres"]
let INPUT_DOCUMENT = this

#
# Assignments
#
let db_clusters = Resources.*[ Type == %RDS_DB_CLUSTER_TYPE ]

#
# Primary Rules
#
rule rds_cluster_default_admin_check when is_cfn_template(%INPUT_DOCUMENT)
                                          %db_clusters not empty {
    check(%db_clusters.Properties)
        <<
        [CT.RDS.PR.21]: Require an Amazon RDS DB cluster to have a unique administrator username
        [FIX]: Set 'MasterUsername' to a value other than 'admin' or 'postgres'.
        >>
}

rule rds_cluster_default_admin_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_CLUSTER_TYPE) {
    check(%INPUT_DOCUMENT.%RDS_DB_CLUSTER_TYPE.resourceProperties)
        <<
        [CT.RDS.PR.21]: Require an Amazon RDS DB cluster to have a unique administrator username
        [FIX]: Set 'MasterUsername' to a value other than 'admin' or 'postgres'.
        >>
}

rule check(db_cluster) {
    %db_cluster [
        # scenario 2
        filter_master_username_provided(this)
    ] {
        # scenario 3 and 4
        MasterUsername not in %DISALLOWED_MASTER_USERNAMES
    }
}

#
# Utility Rules
#
rule filter_master_username_provided(dbcluster_properties) {
    %dbcluster_properties{
        MasterUsername exists
    }
}

rule is_cfn_template(doc) {
    %doc {
        AWSTemplateFormatVersion exists  or
        Resources exists
    }
}

rule is_cfn_hook(doc, RESOURCE_TYPE) {
    %doc.%RESOURCE_TYPE.resourceProperties exists

}
