2.52.0 • Published 24 days ago

apigeelint v2.52.0

Weekly downloads
1,923
License
MIT
Repository
github
Last release
24 days ago

apigeelint

Apache 2.0 Node Test LastCommit CommitActivity Downloads Node.js Package

Static code analysis for Apigee proxy and sharedflow bundles to encourage API developers to use best practices and avoid anti-patterns.

This utility is intended to capture the best practices knowledge from across Apigee including our Global Support Center team, Customer Success, Engineering, and our product team in a tool that will help developers create more scalable, performant, and stable API bundles using the Apigee DSL.

Status

At this point, we are focused on plugin execution and modelling the various lintable assets including Bundles, Proxies, SharedFlows, Targets, Flows, Steps, and Policies.

Plugins that test these abstractions are being developed concurrently.

Reporters (the means to report out results), Ingesters (bundle loaders) are to be developed with Filesystem being the only supported means of loading a bundle and all reporting now going to console.

Installation

You can install apigeellint using npm. But, there is a minimum version of npm required.

  1. First verify the version of npm:

    npm --version

    If the version is 8.3.0 or later, then proceed to step 2. If the version is less than 8.3.0, then update:

    npm install npm@8.3.0 -g

    Alternatively, you may choose to get the latest npm:

    npm install npm@latest -g
  2. Then install apigeelint:

    npm install -g apigeelint

Usage

Help

apigeelint -h
Usage: apigeelint [options]

Options:
  -V, --version                           output the version number
  -s, --path <path>                       Path of the proxies
  -f, --formatter [value]                 Specify formatters (default: json.js)
  -w, --write [value]                     file path to write results
  -e, --excluded [value]                  The comma separated list of tests to exclude (default: none)
  -x, --externalPluginsDirectory [value]  Relative or full path to an external plugins directory
  -q, --quiet                             do not emit the report to stdout. (can use --write option to write to file)
  --list                                  do not execute, instead list the available plugins and formatters
  --maxWarnings [value]                   Number of warnings to trigger nonzero exit code (default: -1)
  --profile [value]                       Either apigee or apigeex (default: apigee)
  -h, --help                              output usage information

Example:

apigeelint -s sampleProxy/apiproxy -f table.js

Where -s points to the apiProxy source directory and -f is the output formatter desired.

Possible formatters are: "json.js" (the default), "stylish.js", "compact.js", "codeframe.js", "codeclimate.js", "html.js", "table.js", "unix.js", "visualstudio.js", "checkstyle.js", "jslint-xml.js", "junit.js" and "tap.js".

More Examples

Using External Plugins:

apigeelint -x ./externalPlugins -s path/to/your/apiproxy -f table.js

Where -x points to the directory containing externally developed plugins.

You could, for example, create your own plugin for naming conventions, and exclude the builtin plugin that enforces naming conventions (PO007) with the -e option:

apigeelint -x ./externalPlugins -e PO007 -s path/to/your/apiproxy -f table.js

This would effectively override the built-in naming conventions that apigeelint checks.

Excluding plugins

You can, of course, exclude plugins without providing a replacement implementation:

apigeelint -s path/to/your/apiproxy -f table.js -e PO007,ST003

The above would exclude the policy naming convention check (PO007), and would also not check for conditions on an ExtractVariables with a JSONPayload (ST003), if for some reason you wanted to do that.

Writing output to a file

apigeelint -s sampleProxy/apiproxy -f table.js -w existing-outputdir --quiet

The -w option can point to an existing directory, in which case the output will be emitted to a file named apigeelint.out in that directory, in whatever format you specify with -f. An existing file by that name will be overwritten. If the -w option is not a directory, it is treated as the name of a file, and output is written there.

If you do not also specify --quiet the report will go to both stdout and to the specified filesystem destination.

Listing plugins

List plugins and formatters, with or without --externalPluginsDirectory.

apigeelint --list
apigeelint --list -x ./externalPlugins

# or

apigeelint --list --externalPluginsDirectory ./externalPlugins

Selecting a profile

Apigee X/hybrid is very similar to Apigee Edge, but there are differences in the supported policy types, and some of the supported configuration options. For example, policies like GraphQL, the AssertCondition, or the Integration policy step types are available only in X/hybrid.

As a result of these differences, a proxy that is valid in Apigee Edge might not work in Apigee X, and vice versa. Apigeelint uses the --profile option to allow the user to configure which target environment is intended: Edge (--profile apigee) or X/hybrid (--profile apigeex). The default is apigee.

# lint a proxy that will be used in Apigee X/hybrid
apigeelint -f table.js --profile apigeex -s path/to/your/apiproxy

# lint a proxy that will be used in Apigee Edge
apigeelint -f table.js --profile apigee -s path/to/your/apiproxy

As an example, if you lint a proxy that uses the GraphQL policy type, and you specify the apigee profile, the PO028 plugin will issue an error, telling you that the GraphQL policy is not available in the apigee profile. If you lint the same proxy with the apigeex profile, apigeelint will not generate an error.

The selection of a profile affects other checks, too. For example, the Google Authentication feature is available only in X/hybrid.

Pipeline lint job integration

GitLab CI/CD

On GitLab CI/CD, on your .gitlab-ci.yml you can use codequality report artifact to get a report supported by GitLab. Once the CI/CD has been completed, a new tab appears in your Pipeline named "Code Quality". This new tab lets you easily view the information from the apigeelint job, with the associated severity level and lines affected. A widget with the same information appears during merge requests.

apigeelint:
  stage: lint
  image: node:12-alpine
  before_script:
    - npm install -g apigeelint
  script:
    - apigeelint -f codeclimate.js > apigeelint-results.json
  artifacts:
    reports:
      codequality:
        - "${CI_PROJECT_DIR}/apigeelint-results.json"

Does this tool just lint or does it also check style?

This tool does both traditional linting (looking for problematic patterns) and style checking (enforcement of conventions). You can use it for both.

Tests

The test directory includes scripts to exercise a subset of rules. Overall linting can be tested with:

apigeelint -s ./test/fixtures/resources/sampleProxy/24Solver/apiproxy/

This sample exhibits many bad practices and as such generates numerous errors and warnings in output.

In a development installation, the equivalent to the command above is:

node ./cli.js  -s ./test/fixtures/resources/sampleProxy/24Solver/apiproxy/

Contributing

We welcome pull requests for bug fixes and new features. In lieu of a formal style guide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code.

Run the unit tests like this:

npm run test

or, run a subset of tests like this:

./node_modules/mocha/bin/mocha --grep PO033

You can also contribute by reporting issues, asking for new features.

Rules

The list of rules is a work in progress. We expect it to increase over time. As product features change (new policies, deprecated policies, etc), we will change rules as well.

This is the current list:

LinterStatusCodeNameDescription
Bundle    
 :white_check_mark:BN001Bundle folder structure correctness.Bundles have a clear structure. This plugin ignores some files, like .DS_store and any file ending in ~.
 :white_medium_square:BN002Extraneous files.Ensure each folder contains appropriate resources in the bundle.
 :white_check_mark:BN003Cache CoherenceA bundle that includes cache reads should include cache writes with the same keys.
 :white_medium_square:BN004Unused variables.Within a bundle variables created should be used in conditions, resource callouts, or policies.
 :white_check_mark:BN005Unattached policies.Unattached policies are dead code and should be removed from production bundles.
 :white_check_mark:BN006Bundle size - policies.Large bundles are a symptom of poor design. A high number of policies is predictive of an oversized bundle.
 :white_check_mark:BN007Bundle size - resource callouts.Large bundles are a symptom of poor design. A high number of resource callouts is indicative of underutilizing out of the box Apigee policies.
 :white_medium_square:BN008IgnoreUnresolvedVariables and FaultRulesUse of IgnoreUnresolvedVariables without the use of FaultRules may lead to unexpected errors.
 :white_check_mark:BN009Statistics Collector - duplicate policiesWarn on duplicate policies when no conditions are present or conditions are duplicates.
 :white_check_mark:BN010Missing policiesIssue an error if a referenced policy is not present in the bundle.
 :white_check_mark:BN011Check each XML file for well-formedness.
 :white_check_mark:BN012unreferrenced Target EndpointsCheck that each TargetEndpoint can be reached.
 :white_check_mark:BN013Unreferenced resources.Warn for resources that not referenced in any policy. Unreferenced resources are dead code.
Proxy Definition    
 :white_check_mark:PD001RouteRules to TargetsRouteRules should map to defined Targets.
 :white_check_mark:PD002Unreachable Route Rules - defaultsOnly one RouteRule should be present without a condition.
 :white_check_mark:PD003Unreachable Route RulesRouteRule without a condition should be last.
 :white_check_mark:PD004ProxyEndpoint nameProxyEndpoint name should match basename of filename.
 :white_check_mark:PD005VirtualHostProxyEndpoint should have one HTTPProxyConnection, and in the case of profile=apigeex, no VirtualHost.
Target Definition    
 :white_check_mark:TD001Mgmt Server as TargetDiscourage calls to the Management Server from a Proxy via target.
 :white_check_mark:TD002Use Target ServersEncourage the use of target servers.
 :white_check_mark:TD003TargetEndpoint nameTargetEndpoint name should match basename of filename.
 :white_check_mark:TD004TargetEndpoint SSLInfoTargetEndpoint HTTPTargetConnection should enable TLS/SSL.
 :white_check_mark:TD005TargetEndpoint SSLInfo referencesTargetEndpoint SSLInfo should use references for KeyStore and TrustStore.
Flow    
 :white_check_mark:FL001Unconditional FlowsOnly one unconditional flow will get executed. Error if more than one was detected.
Step    
 :white_check_mark:ST001Empty StepEmpty steps clutter the bundle.
 :white_check_mark:ST002Step Structureeach Step should have at most one Name element, one Condition element, no others.
 :white_check_mark:ST003Extract Variables Step with JSONPayloadA check for message content should be performed before policy execution.
 :white_check_mark:ST004Extract Variables Step with XMLPayloadA check for message content should be performed before policy execution.
 :white_check_mark:ST005Extract Variables Step with FormParamA check for message content should be performed before policy execution.
 :white_check_mark:ST006JSON Threat Protection StepA check for message content should be performed before policy execution.
 :white_check_mark:ST007XML Threat Protection StepA check for message content should be performed before policy execution.
Policy    
 :white_check_mark:PO006Policy Name & filename agreementPolicy name attribute should coincide with the policy filename.
 :white_check_mark:PO007Policy Naming Conventions - type indicationIt is recommended that the policy name use a prefix or follow a pattern that indicates the policy type.
 :white_check_mark:PO008Policy DisplayName & DisplayName agreementCheck that the policy filename matches the display name of the policy.
 :white_medium_square:PO009Service Callout Target - Mgmt ServerTargeting management server may result in higher than expected latency; use with caution.
 :white_medium_square:PO010Service Callout Target - Target ServerEncourage use of target servers.
 :white_medium_square:PO011Service Callout Target - Dynamic URLsError on dynamic URLs in target server URL tag.
 :white_check_mark:PO012AssignMessage/AssignToWarn on unnecessary AssignTo in AssignMessage when createNew is false and no destination variable.
 :white_check_mark:PO013Resource Call Out - JavascriptJSHint, ESLint.
 :white_medium_square:PO014Resource Call Out - JavaPMD, Checkstyle.
 :white_medium_square:PO015Resource Call Out - PythonPylint.
 :white_medium_square:PO016Statistics Collector - duplicate variablesWarn on duplicate variables.
 :white_medium_square:PO017Misconfigured - FaultRules/Fault Rule in PolicyFaultRules are configured in ProxyEndpoints and TargetEndpoints.
 :white_check_mark:PO018Regex Lookahead/Lookbehind are Expensive - Threat Protection PolicyRegular expressions that include lookahead or lookbehind perform slowly on large payloads and are typically not required.
 :white_check_mark:PO019Reserved words as variables - ServiceCallout RequestUsing "request" as the name of a Request may cause unexpected side effects.
 :white_check_mark:PO020Reserved words as variables - ServiceCallout ResponseUsing "response" as the name of a Response may cause unexpected side effects.
 :white_medium_square:PO021Statistics Collector - reserved variablesWarn on insertion of duplicate variables.
 :white_check_mark:PO022Nondistributed QuotaWhen using nondistributed quota the number of allowed calls is influenced by the number of Message Processors (MPs) deployed. This may lead to higher than expected transactions for a given quota as MPs now autoscale.
 :white_check_mark:PO023Quota Policy ReuseWhen the same Quota policy is used more than once you must ensure that the conditions of execution are mutually exclusive or that you intend for a call to count more than once per message processed.
 :white_check_mark:PO024Cache Error ResponsesBy default the ResponseCache policy will cache non 200 responses. Either create a condition or use policy configuration options to exclude non 200 responses.
 :white_check_mark:PO025EsLint ErrorsRuns EsLint on all policy resources.
 :white_check_mark:PO026AssignVariable UsageWith AssignMessage/AssignVariable, check various usage issues. Example: The Name element must be present. The Ref element, if any, should not be surrounded in curlies. And so on.
 :white_check_mark:PO027HMAC UsageWith HMAC, check that the SecretKey is present and that a ref= attribute refers to a private variable.
 :white_check_mark:PO028Policy Availability in profileCheck for policies available in particular profiles.
 :white_check_mark:PO029Known policy typeCheck that all policies are of a known type.
 :white_check_mark:PO030ExpirySettingsExpirySettings should use exactly one child element, no deprecated elements.
 :white_check_mark:PO031AssignMessage content-typeWhen assigning to Payload, you should also assign content-type, exactly once.
 :white_check_mark:PO032CORS policy hygieneIn a CORS policy, wildcard origins should generate a warning. And other hygiene checks.
 :white_check_mark:PO033ExtractVariables policy hygieneIn an ExtractVariables policy, check variable types and other hygiene.
 :white_check_mark:PO034AssignMessage policy hygieneIn an AssignMessage policy, check element placement and other hygiene.
FaultRules    
 :white_check_mark:FR001No Condition on FaultRuleUse Condition elements on FaultRules, unless it is the fallback rule.
 :white_check_mark:FR002DefaultFaultRule StructureDefaultFaultRule should have only supported child elements, at most one AlwaysEnforce element, and at most one Condition element.
 :white_check_mark:FR003single FaultRuleWhen a single FaultRule is present, consider using a DefaultFaultRule.
Conditional    
 :white_check_mark:CC001Literals in ConditionalsWarn on literals in any conditional statement.
 :white_medium_square:CC002Null Blank ChecksBlank checks should also check for null conditions. (to be reviewed)
 :white_check_mark:CC003Long condition statementConditions should not be long.
 :white_check_mark:CC004Overly complex conditionCondition complexity should be limited to fix number of variables and conjunctions.
 :white_check_mark:CC005unterminated strings in ConditionStrings within a Condition element must be properly wrapped by double quotes.
 :white_check_mark:CC006Detect logical absurditiesConditions should not have internal logic conflicts - warn when these are detected.
 :white_check_mark:CC007Check validity of expression syntaxCondition expressions should use valid syntax. No single quotes, no extraneous or unmatched parens, etc.
Endpoints    
 :white_check_mark:EP001CORS Policy attachmentCheck for multiple CORS policies, or attachment to Target Endpoint.
 :white_check_mark:EP002Misplaced ElementsCheck for commonly misplaced configuration elements in Proxy and Target Endpoints.
Features    
 :white_check_mark:FE001Use of Authentication elementCheck for the Authentication element in policies or in Target Endpoints.
Deprecation    
 :white_check_mark:DC001ConcurrentRateLimit Policy DeprecationCheck usage of deprecated policy ConcurrentRateLimit.
 :white_check_mark:DC002OAuth V1 Policies DeprecationCheck usage of deprecated OAuth V1 policies.

From an implementation perspective, the focus is on plugin support and flexibility over performance. Compute is cheap.

Release Notes

Release v2.31.0

Condition checks around policies

In release v2.31.0, the plugins PO001, PO002, PO003, PO004, and PO005 have been converted to ST006, ST007, ST003, ST004, and ST005, respectively. These plugins move from the "Policy" category to the "Step" category because the plugin analyzes the attachment of the policy in a Step element, rather than the policy itself. Also these plugins will now generate warnings, rather than errors.

If previously you excluded PO003 via the --excluded option, you must now exclude ST003, and so on.

Sharedflows

Starting with release v2.31.0, using apigeelint against Sharedflows will generate a correct report. Previously the report on a sharedflow was truncated and omitted some warnings and errors.

Support

If you find issues, file a ticket here on Github. Keep in mind that there is no service level agreement (SLA) for responses to these issues. Assume all responses are on an ad-hoc, volunteer basis.

If you simply have questions, we recommend asking on the Apigee forum on GoogleCloudCommunity.com. Apigee experts regularly check that forum.

Apigee customers should use formal support channels for Apigee product related concerns.

License and Copyright

This material is Copyright (c) 2018-2024 Google LLC. and is licensed under the Apache 2.0 License.

Disclaimer

This tool is open-source software. It is not an officially supported Google product. It is not a part of Apigee, or any other officially supported Google Product.

2.52.0

24 days ago

2.51.0

28 days ago

2.50.0

2 months ago

2.49.0

2 months ago

2.48.0

2 months ago

2.48.1

2 months ago

2.47.0

4 months ago

2.46.1

4 months ago

2.46.3

4 months ago

2.46.2

4 months ago

2.46.0

5 months ago

2.45.0

5 months ago

2.43.0

8 months ago

2.41.0

8 months ago

2.42.0

8 months ago

2.44.0

7 months ago

2.40.0

9 months ago

2.39.0

1 year ago

2.38.0

1 year ago

2.36.0

1 year ago

2.35.0

1 year ago

2.37.0

1 year ago

2.34.0

1 year ago

2.32.1

2 years ago

2.33.0

2 years ago

2.29.0

2 years ago

2.25.0

2 years ago

2.27.0

2 years ago

2.32.0

2 years ago

2.30.0

2 years ago

2.22.0

2 years ago

2.28.0

2 years ago

2.24.0

2 years ago

2.26.0

2 years ago

2.31.0

2 years ago

2.23.0

2 years ago

2.21.4

2 years ago

2.21.3

2 years ago

2.21.2

2 years ago

2.11.0

2 years ago

2.19.0

2 years ago

2.17.0

2 years ago

2.15.0

2 years ago

2.13.0

2 years ago

2.20.0

2 years ago

2.12.0

2 years ago

2.18.0

2 years ago

2.16.0

2 years ago

2.14.0

2 years ago

2.21.0

2 years ago

2.21.1

2 years ago

2.10.0

3 years ago

2.9.0

3 years ago

2.8.0

3 years ago

2.7.0

3 years ago

2.6.0

3 years ago

2.5.1

3 years ago

2.5.0

3 years ago

2.3.0

3 years ago

2.2.0

3 years ago

2.1.2

3 years ago

2.1.1

4 years ago

2.1.0

4 years ago

2.0.0

4 years ago

1.0.0

4 years ago

0.5.2

4 years ago

0.5.1

4 years ago

0.5.0

4 years ago

0.4.9

4 years ago

0.4.8

4 years ago

0.4.7

4 years ago

0.4.6

4 years ago

0.4.5

4 years ago

0.4.4

4 years ago

0.4.3

4 years ago

0.4.2

4 years ago

0.4.1

4 years ago

0.4.0

4 years ago

0.3.0

5 years ago

0.2.8

5 years ago

0.2.7

5 years ago

0.2.6

5 years ago

0.2.5

6 years ago

0.2.4

6 years ago

0.2.3

6 years ago

0.2.2

6 years ago

0.2.1

6 years ago

0.2.0

6 years ago

0.1.8

7 years ago

0.1.7

7 years ago

0.1.6

7 years ago

0.1.5

7 years ago

0.1.4

7 years ago

0.1.3

7 years ago

0.1.2

7 years ago

0.1.1

7 years ago

0.1.0

7 years ago