3 D\PV@sdZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl m Z yddlmZWn ek rddlmZYnXejdZddZGdd d eZd d Zd d ZGdddejZGdddeZGdddeZGdddeeeeZdS)a Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. N) __version__)PathcfnlintcCsntj}|jtj|r&tjtjn tjtjtjd}|j|xtjD]}tj |qNWtj |dS)z Setup Loggingz4%(asctime)s - %(name)s - %(levelname)s - %(message)sN) logging StreamHandlersetLevelDEBUGLOGGERINFO Formatter setFormatterhandlers removeHandler addHandler)Z debug_loggingchZ log_formatterhandlerrh/private/var/folders/pf/wv4htv3x0qs2c2mp0dnn0kchsvlck3/T/pip-install-emcbgzcf/cfn-lint/cfnlint/config.pyconfigure_logging$s     rc@sNeZdZdZiZdddZddZddZd d Zd d Z d dZ ddZ dS)ConfigFileArgsz^ Config File arguments. Parses .cfnlintrc in the Home and Project folder. Nc Csbd|_d|_i|_ttjjd|_|jj}t j ||_ WdQRX|sP|j n||_ |j dS)Nz"data/CfnLintCli/config/schema.json) !_ConfigFileArgs__user_config_file$_ConfigFileArgs__project_config_file file_argsr__file__parentjoinpathZdefault_schema_fileopenjsonloadZdefault_schemaschema)selfrfrrr__init__=s zConfigFileArgs.__init__cCsd}tjr$ttjjdj||_ntjj||_tj j||_ d}d}|j |jrht j d|j}|j |j rt j d|j }||fS)aLooks up for user and project level config Returns ------- Tuple (Path, Path) Tuple with both configs and whether they were found Example ------- > user_config, project_config = self._find_config() z .cfnlintrc~zFound User CFNLINTRCzFound Project level CFNLINTRC)sixPY34rospath expanduserrrhomecwdr _has_filer debug)r Zconfig_file_nameZuser_config_pathZproject_config_pathrrr _find_configHs     zConfigFileArgs._find_configcCs t|jS)zConfirm whether file exists Parameters ---------- filename : str Path to a file Returns ------- Boolean )ris_file)r filenamerrrr,gs zConfigFileArgs._has_filecCstjd|j\}}|j|}tjd|j||j|j|}tjd|j||jtjdtjd|tjdtjd|tjd|j|||_dS) zLoad configuration file and expose as a dictionary Returns ------- Dict CFLINTRC configuration z.Looking for CFLINTRC before attempting to loadzValidating User CFNLINTRCzValidating Project CFNLINTRCzUser configuration loaded asz%szProject configuration loaded aszMerging configurations...N)r r-r. _read_configvalidate_configr merge_configr)r user_configproject_configrrrrts           zConfigFileArgs.loadcCs<tjdtjd|tjd|tj||tjddS)a^Validate configuration against schema Parameters ---------- config : dict CFNLINTRC configuration schema : dict JSONSchema to validate against Raises ------- jsonschema.exceptions.ValidationError Returned when cfnlintrc doesn't match schema provided z1Validating CFNLINTRC config with given JSONSchemazSchema used: %szConfig used: %szCFNLINTRC looks valid!N)r r- jsonschemavalidate)r configrrrrr2s    zConfigFileArgs.validate_configcCsxd|D]\}||krt||trDt||trD|j||||q||||<tjd|||qWx |D]}||krl||||<qlW|S)aMerge project and user configuration into a single dictionary Creates a new configuration with both configuration merged it favours project level over user configuration if keys are duplicated NOTE ---- It takes any number of nested dicts It overrides lists found in user_config with project_config Parameters ---------- user_config : Dict User configuration (~/.cfnlintrc) found at user's home directory project_config : Dict Project configuration (.cfnlintrc) found at current directory Returns ------- Dict Merged configuration z:Overriding User's key %s with Project's specific value %s.) isinstancedictr3r r-)r r4r5keyrrrr3s   zConfigFileArgs.merge_configcCs>t|}d}|j|r2tjdtjjjt|}|s:i}|S)zParse given YAML configuration Returns ------- Dict Parsed YAML configuration as dictionary NzParsing CFNLINTRC) rr,r r-rdecodeZcfn_yamlrstr)r r8Zconfig_templaterrrr1s  zConfigFileArgs._read_config)N) __name__ __module__ __qualname____doc__rr"r.r,rr2r3r1rrrrr6s  %rcCs |jdS)z Split a comma separated string ,)split)stringrrrcomma_separated_argsrEcCs&t||ddkrt|||t||S)N)getattrsetattr) namespacenamevaluerrr _ensure_values rKcs4eZdZdZd fdd ZddZd dd ZZS) RuleConfigurationActionz Override the default Action NFc s(tt|j||||||||| | d dS)N) option_stringsdestnargsconstdefaulttypechoicesrequiredhelpmetavar)superrLr") r rMrNrOrPrQrRrSrTrUrV) __class__rrr"s z RuleConfigurationAction.__init__cCsxt|}i}xf|D]^}|jdd}|jddjdd}|jddjdd}||krdi||<||||<qW|S)z! Parse the config rule structure :r=)rErC)r rDconfigsresultsr8Zrule_id config_name config_valuerrr_parse_rule_configurations z1RuleConfigurationAction._parse_rule_configurationc Cstjt||ji}ytx`|D]X}|j|}xH|jD]<\}} ||krhx*| jD]\} } | ||| <qNWq4| ||<q4WqWt||j|Wn$tk r|j|jYnXdS)N) copyrKrNr`itemsrG Exception print_helpexit) r parserrHvalues option_stringrbrJZ new_valueZv_kZv_vsZs_kZs_vrrr__call__s  z RuleConfigurationAction.__call__)NNNNNFNN)N)r>r?r@rAr"r`ri __classcell__rr)rXrrLs  rLc@s$eZdZdZiZddZddZdS)CliArgsz Base Args classcCs |j|_|jj|\|_}dS)N) create_parserrfZparse_known_argscli_args)r rm_rrrr"s zCliArgs.__init__c CsGdddtj}Gdddtj}|dd}|jdd||jd }|jd }|jd d d dd|jddd dddgdd|jddddd|jddddgdd|jddd dd|jd!d"d#d$d%d&gd'|jd(d)d*d+dd,d-|jd.d/d0dgtdd1d2|jd3d4d5dgtdd6d2|jd7d8d9dgtdd:d2|jd;dd2|jd?d@dAdd|jdBdCdDditdEdF|jdGdHdIdJdK|jdLdMdNdOdPjt dQdR|jdSdTdUdd|jdVtj dd|jdWtj dd|S)Xz3Do first round of parsing parameters to set optionsc@seZdZdZddZdS)z-CliArgs.create_parser..ArgumentParserz9 Override Argument Parser so we can control the exit codecSs&|jtj|jdd|j|fdS)N z%s: error: %s )rdsysstderrreprog)r messagerrrerror"s z3CliArgs.create_parser..ArgumentParser.errorN)r>r?r@rArtrrrrArgumentParser sruc@seZdZdZdddZdS)z+CliArgs.create_parser..ExtendActionzJSupport argument types that are lists and can be specified multiple times.NcSs\t||j}|dkrgn|}x,|D]$}t|tr<|j|q"|j|q"Wt||j|dS)N)rFrNr9listextendappendrG)r rfrHrgrhrbrJrrrri(s    z4CliArgs.create_parser..ExtendAction.__call__)N)r>r?r@rArirrrr ExtendAction&sryzCloudFormation Linter) descriptionactionrwZStandardzAdvanced / Debugging templatesTEMPLATE*z(The CloudFormation template to be linted)rVrOrUz-tz --template template_alt+)rVrNrUrOrQr{z-bz--ignore-bad-templatez!Ignore failures with Bad template store_true)rUr{z--ignore-templatesignore_templateszIgnore templates)rNrUrOrQr{z-dz--debugzEnable debug loggingz-fz--formatz Output FormatquietZ parseabler)rUrSz-lz --list-rules listrulesFzlist all the rules)rNrQr{rUz-rz --regionsregionsz%list the regions to validate against.)rNrOrQrRr{rUz-az--append-rules append_ruleszRspecify one or more rules directories using one or more --append-rules arguments. z-iz--ignore-checks ignore_checksz3only check rules whose id do not match these valuesz-cz--include-checksinclude_checksz)include rules whose id match these valuesz-ez--include-experimentalzInclude experimental rulesz-xz--configure-ruleconfigure_ruleszVProvide configuration for a rule. Format RuleId:key=value. Example: E3012:strict=false)rNrOrQr{rUz-oz--override-spec override_specz=A CloudFormation Spec override file that allows customization)rNrUz-vz --versionzVersion of cfn-lintversionz%(prog)s {version})r)rUr{rz-uz--update-specszUpdate the CloudFormation Specsz--update-documentationz--update-iam-policies) argparseruActionregisteradd_argument_group add_argumentrErLformatrZSUPPRESS)r ruryrfstandardZadvancedrrrrls|         zCliArgs.create_parserN)r>r?r@rArmr"rlrrrrrksrkc@s2eZdZdZddZddZddZeeeZdS) TemplateArgsz Per Template Args cCs|j|dS)N)set_template_args)r template_argsrrrr"szTemplateArgs.__init__cCs|jS)z Get Template Args)_template_args)r rrrget_template_argsszTemplateArgs.get_template_argscCsi}t|tr|jdijdijdi}t|trx|jD]\}}|dkrdt|trd||d<|dkr~t|tr~||d<|dkrt|tr||d<|dkrt|tjr||d<|dkrt|tr||d<|d krt|tr||d <|d krBt|trB||d <qBW||_d S) z Set Template ArgsZMetadatazcfn-lintr8rrrrignore_bad_templaterrN) r9r:getrbrvr% string_typesboolr)r templatedefaultsr\r^r_rrrrs6          zTemplateArgs.set_template_argsN) r>r?r@rAr"rrpropertyrrrrrrs  rc@seZdZdZddZddZeddZedd Zed d Z ed d Z eddZ eddZ eddZ eddZddZeddZeddZeddZeddZed d!Zed"d#Zed$d%Zd&S)' ConfigMixInz Mixin for the Configs cCs2tj||t|jjtj|tj|idS)N)rkr"rrmr-rr)r rmrrrr"s   zConfigMixIn.__init__cCsHt|j|}|jj|}|jj|}|r,|S|r8|r8|S|rD|rD|S|S)z Get Argument value )rFrmrrr)r Zarg_nameZ is_templateZis_config_fileZ cli_valueZtemplate_valueZ file_valuerrr_get_argument_values   zConfigMixIn._get_argument_valuecCs|jdddS)z ignore_checks rT)r)r rrrrszConfigMixIn.ignore_checkscCs|jdddS)z include_checks rT)r)r rrrrszConfigMixIn.include_checkscCs|jdddS)z include_experimental include_experimentalT)r)r rrrrsz ConfigMixIn.include_experimentalcCs|jddd}|sdgS|S)z regions rTz us-east-1)r)r r]rrrrszConfigMixIn.regionscCs|jdddS)z ignore_bad_template rT)r)r rrrrszConfigMixIn.ignore_bad_templatecCs|jdddS)z debug r-F)r)r rrrr-szConfigMixIn.debugcCs|jdddS)z format rFT)r)r rrrrszConfigMixIn.formatc Cs|jddd}|jddd}|r&|}n|r0|}ndSt|tjrF|g}g}|j}xh|D]`}tjd krvtj|dd}n tj|}|s||kr|j|qXx|D]}||kr|j|qWqXW|S) z templates r|FTrN) recursive)rr) rr9r%r_ignore_templatesrp version_infoglobrx) r Ztemplates_argsZtemplate_alt_args filenames all_filenamesrr0 add_filenamesZ add_filenamerrrr|s,      zConfigMixIn.templatescCs|jddd}|r|}ngSt|tjr.|g}g}xJ|D]B}tjdkrVtj|dd}n tj|}|sp|j|q8|j|q8W|S)z templates rFTrr)r)rr) rr9r%rrprrrxrw)r Zignore_template_argsrrr0rrrrrs     zConfigMixIn._ignore_templatescCs|jdddS)z append_rules rFT)r)r rrrr6szConfigMixIn.append_rulescCs|jdddS)z override_spec rFT)r)r rrrr;szConfigMixIn.override_speccCs|jdddS)z update_specs update_specsF)r)r rrrr@szConfigMixIn.update_specscCs|jdddS)z update_specs update_documentationF)r)r rrrrEsz ConfigMixIn.update_documentationcCs|jdddS)z update_iam_policies update_iam_policiesF)r)r rrrrJszConfigMixIn.update_iam_policiescCs|jdddS)z listrules rF)r)r rrrrOszConfigMixIn.listrulescCs|jdddS)z Configure rules rT)r)r rrrrTszConfigMixIn.configure_rulesN)r>r?r@rAr"rrrrrrrr-rr|rrrrrrrrrrrrrs&        &      r)rArprrrrr'rar%r6Zcfnlint.decode.cfn_yamlrZcfnlint.versionrZpathlibr ImportErrorZpathlib2 getLoggerr robjectrrErKrrLrkrrrrrrs2  '/s,