2018-05-22 21:43:36 +02:00
|
|
|
// Copyright 2016-2018, Pulumi Corporation.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
Add basic analyzer support
This change introduces the basic requirements for analyzers, as per
pulumi/coconut#119. In particular, an analyzer can implement either,
or both, of the RPC methods, Analyze and AnalyzeResource. The former
is meant to check an overall deployment (e.g., to ensure it has been
signed off on) and the latter is to check individual resources (e.g.,
to ensure properties of them are correct, such as checking style,
security, etc. rules). These run simultaneous to overall checking.
Analyzers are loaded as plugins just like providers are. The difference
is mainly in their naming ("analyzer-" prefix, rather than "resource-"),
and the RPC methods that they support.
This isn't 100% functional since we need a way to specify at the CLI
that a particular analyzer should be run, in addition to a way of
recording which analyzers certain projects should use in their manifests.
2017-03-11 08:49:17 +01:00
|
|
|
|
Overhaul resources, planning, and environments
This change, part of pulumi/lumi#90, overhauls quite a bit of the
core resource, planning, environments, and related areas.
The biggest amount of movement comes from the splitting of pkg/resource
into multiple sub-packages. This results in:
- pkg/resource: just the core resource data structures.
- pkg/resource/deployment: all planning and deployment logic.
- pkg/resource/environment: all environment, configuration, and
serialized checkpoint structures and logic.
- pkg/resource/plugin: all dynamically loaded analyzer and
provider logic, including the actual loading and RPC mechanisms.
This also splits the resource abstraction up. We now have:
- resource.Resource: a shared interface.
- resource.Object: a resource that is connected to a live object
that will periodically observe mutations due to ongoing
evaluation of computations. Snapshots of its state may be
taken; however, this is purely a "pre-planning" abstraction.
- resource.State: a snapshot of a resource's state that is frozen.
In other words, it is no longer connected to a live object.
This is what will store provider outputs (ID and properties),
and is what may be serialized into a deployment record.
The branch is in a half-baked state as of this change; more changes
are to come...
2017-06-09 01:37:40 +02:00
|
|
|
package plugin
|
Add basic analyzer support
This change introduces the basic requirements for analyzers, as per
pulumi/coconut#119. In particular, an analyzer can implement either,
or both, of the RPC methods, Analyze and AnalyzeResource. The former
is meant to check an overall deployment (e.g., to ensure it has been
signed off on) and the latter is to check individual resources (e.g.,
to ensure properties of them are correct, such as checking style,
security, etc. rules). These run simultaneous to overall checking.
Analyzers are loaded as plugins just like providers are. The difference
is mainly in their naming ("analyzer-" prefix, rather than "resource-"),
and the RPC methods that they support.
This isn't 100% functional since we need a way to specify at the CLI
that a particular analyzer should be run, in addition to a way of
recording which analyzers certain projects should use in their manifests.
2017-03-11 08:49:17 +01:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
|
2018-02-06 18:57:32 +01:00
|
|
|
"github.com/blang/semver"
|
2017-12-01 22:50:32 +01:00
|
|
|
pbempty "github.com/golang/protobuf/ptypes/empty"
|
2019-07-26 01:17:06 +02:00
|
|
|
"github.com/pkg/errors"
|
2019-06-11 00:20:44 +02:00
|
|
|
"github.com/pulumi/pulumi/pkg/apitype"
|
2017-09-22 04:18:21 +02:00
|
|
|
"github.com/pulumi/pulumi/pkg/resource"
|
|
|
|
"github.com/pulumi/pulumi/pkg/tokens"
|
2018-02-06 16:20:04 +01:00
|
|
|
"github.com/pulumi/pulumi/pkg/util/contract"
|
2018-05-16 00:28:00 +02:00
|
|
|
"github.com/pulumi/pulumi/pkg/util/logging"
|
2018-03-29 02:07:35 +02:00
|
|
|
"github.com/pulumi/pulumi/pkg/util/rpcutil/rpcerror"
|
2018-02-06 16:20:04 +01:00
|
|
|
"github.com/pulumi/pulumi/pkg/workspace"
|
2017-12-01 22:50:32 +01:00
|
|
|
pulumirpc "github.com/pulumi/pulumi/sdk/proto/go"
|
Add basic analyzer support
This change introduces the basic requirements for analyzers, as per
pulumi/coconut#119. In particular, an analyzer can implement either,
or both, of the RPC methods, Analyze and AnalyzeResource. The former
is meant to check an overall deployment (e.g., to ensure it has been
signed off on) and the latter is to check individual resources (e.g.,
to ensure properties of them are correct, such as checking style,
security, etc. rules). These run simultaneous to overall checking.
Analyzers are loaded as plugins just like providers are. The difference
is mainly in their naming ("analyzer-" prefix, rather than "resource-"),
and the RPC methods that they support.
This isn't 100% functional since we need a way to specify at the CLI
that a particular analyzer should be run, in addition to a way of
recording which analyzers certain projects should use in their manifests.
2017-03-11 08:49:17 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// analyzer reflects an analyzer plugin, loaded dynamically for a single suite of checks.
|
|
|
|
type analyzer struct {
|
|
|
|
ctx *Context
|
|
|
|
name tokens.QName
|
|
|
|
plug *plugin
|
2017-12-01 22:50:32 +01:00
|
|
|
client pulumirpc.AnalyzerClient
|
Add basic analyzer support
This change introduces the basic requirements for analyzers, as per
pulumi/coconut#119. In particular, an analyzer can implement either,
or both, of the RPC methods, Analyze and AnalyzeResource. The former
is meant to check an overall deployment (e.g., to ensure it has been
signed off on) and the latter is to check individual resources (e.g.,
to ensure properties of them are correct, such as checking style,
security, etc. rules). These run simultaneous to overall checking.
Analyzers are loaded as plugins just like providers are. The difference
is mainly in their naming ("analyzer-" prefix, rather than "resource-"),
and the RPC methods that they support.
This isn't 100% functional since we need a way to specify at the CLI
that a particular analyzer should be run, in addition to a way of
recording which analyzers certain projects should use in their manifests.
2017-03-11 08:49:17 +01:00
|
|
|
}
|
|
|
|
|
2019-06-24 04:02:37 +02:00
|
|
|
var _ Analyzer = (*analyzer)(nil)
|
|
|
|
|
Add basic analyzer support
This change introduces the basic requirements for analyzers, as per
pulumi/coconut#119. In particular, an analyzer can implement either,
or both, of the RPC methods, Analyze and AnalyzeResource. The former
is meant to check an overall deployment (e.g., to ensure it has been
signed off on) and the latter is to check individual resources (e.g.,
to ensure properties of them are correct, such as checking style,
security, etc. rules). These run simultaneous to overall checking.
Analyzers are loaded as plugins just like providers are. The difference
is mainly in their naming ("analyzer-" prefix, rather than "resource-"),
and the RPC methods that they support.
This isn't 100% functional since we need a way to specify at the CLI
that a particular analyzer should be run, in addition to a way of
recording which analyzers certain projects should use in their manifests.
2017-03-11 08:49:17 +01:00
|
|
|
// NewAnalyzer binds to a given analyzer's plugin by name and creates a gRPC connection to it. If the associated plugin
|
|
|
|
// could not be found by name on the PATH, or an error occurs while creating the child process, an error is returned.
|
Introduce an interface to read config
This change adds an engine gRPC interface, and associated implementation,
so that plugins may do interesting things that require "phoning home".
Previously, the engine would fire up plugins and talk to them directly,
but there was no way for a plugin to ask the engine to do anything.
The motivation here is so that plugins can read evaluator state, such
as config information, but this change also allows richer logging
functionality than previously possible. We will still auto-log any
stdout/stderr writes; however, explicit errors, warnings, informational,
and even debug messages may be written over the Log API.
2017-06-21 04:45:07 +02:00
|
|
|
func NewAnalyzer(host Host, ctx *Context, name tokens.QName) (Analyzer, error) {
|
2018-02-06 16:20:04 +01:00
|
|
|
// Load the plugin's path by using the standard workspace logic.
|
2018-02-19 19:58:03 +01:00
|
|
|
_, path, err := workspace.GetPluginPath(
|
2018-02-06 16:20:04 +01:00
|
|
|
workspace.AnalyzerPlugin, strings.Replace(string(name), tokens.QNameDelimiter, "_", -1), nil)
|
|
|
|
if err != nil {
|
2018-03-29 02:07:35 +02:00
|
|
|
return nil, rpcerror.Convert(err)
|
2018-02-06 16:20:04 +01:00
|
|
|
} else if path == "" {
|
2019-03-11 23:17:01 +01:00
|
|
|
return nil, workspace.NewMissingError(workspace.PluginInfo{
|
2018-02-06 18:57:32 +01:00
|
|
|
Kind: workspace.AnalyzerPlugin,
|
|
|
|
Name: string(name),
|
|
|
|
})
|
2018-02-06 16:20:04 +01:00
|
|
|
}
|
|
|
|
|
2019-06-26 19:03:55 +02:00
|
|
|
plug, err := newPlugin(ctx, path, fmt.Sprintf("%v (analyzer)", name),
|
|
|
|
[]string{host.ServerAddr(), ctx.Pwd})
|
Add basic analyzer support
This change introduces the basic requirements for analyzers, as per
pulumi/coconut#119. In particular, an analyzer can implement either,
or both, of the RPC methods, Analyze and AnalyzeResource. The former
is meant to check an overall deployment (e.g., to ensure it has been
signed off on) and the latter is to check individual resources (e.g.,
to ensure properties of them are correct, such as checking style,
security, etc. rules). These run simultaneous to overall checking.
Analyzers are loaded as plugins just like providers are. The difference
is mainly in their naming ("analyzer-" prefix, rather than "resource-"),
and the RPC methods that they support.
This isn't 100% functional since we need a way to specify at the CLI
that a particular analyzer should be run, in addition to a way of
recording which analyzers certain projects should use in their manifests.
2017-03-11 08:49:17 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2018-02-06 16:20:04 +01:00
|
|
|
contract.Assertf(plug != nil, "unexpected nil analyzer plugin for %s", name)
|
Add basic analyzer support
This change introduces the basic requirements for analyzers, as per
pulumi/coconut#119. In particular, an analyzer can implement either,
or both, of the RPC methods, Analyze and AnalyzeResource. The former
is meant to check an overall deployment (e.g., to ensure it has been
signed off on) and the latter is to check individual resources (e.g.,
to ensure properties of them are correct, such as checking style,
security, etc. rules). These run simultaneous to overall checking.
Analyzers are loaded as plugins just like providers are. The difference
is mainly in their naming ("analyzer-" prefix, rather than "resource-"),
and the RPC methods that they support.
This isn't 100% functional since we need a way to specify at the CLI
that a particular analyzer should be run, in addition to a way of
recording which analyzers certain projects should use in their manifests.
2017-03-11 08:49:17 +01:00
|
|
|
|
|
|
|
return &analyzer{
|
|
|
|
ctx: ctx,
|
|
|
|
name: name,
|
|
|
|
plug: plug,
|
2017-12-01 22:50:32 +01:00
|
|
|
client: pulumirpc.NewAnalyzerClient(plug.Conn),
|
Add basic analyzer support
This change introduces the basic requirements for analyzers, as per
pulumi/coconut#119. In particular, an analyzer can implement either,
or both, of the RPC methods, Analyze and AnalyzeResource. The former
is meant to check an overall deployment (e.g., to ensure it has been
signed off on) and the latter is to check individual resources (e.g.,
to ensure properties of them are correct, such as checking style,
security, etc. rules). These run simultaneous to overall checking.
Analyzers are loaded as plugins just like providers are. The difference
is mainly in their naming ("analyzer-" prefix, rather than "resource-"),
and the RPC methods that they support.
This isn't 100% functional since we need a way to specify at the CLI
that a particular analyzer should be run, in addition to a way of
recording which analyzers certain projects should use in their manifests.
2017-03-11 08:49:17 +01:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2019-07-01 01:34:39 +02:00
|
|
|
const policyAnalyzerName = "policy"
|
|
|
|
|
|
|
|
// NewPolicyAnalyzer boots the nodejs analyzer plugin located at `policyPackpath`
|
|
|
|
func NewPolicyAnalyzer(
|
|
|
|
host Host, ctx *Context, name tokens.QName, policyPackPath string) (Analyzer, error) {
|
|
|
|
|
|
|
|
// Load the policy-booting analyzer plugin (i.e., `pulumi-analyzer-${policyAnalyzerName}`).
|
|
|
|
_, pluginPath, err := workspace.GetPluginPath(
|
|
|
|
workspace.AnalyzerPlugin, policyAnalyzerName, nil)
|
|
|
|
if err != nil {
|
|
|
|
return nil, rpcerror.Convert(err)
|
|
|
|
} else if pluginPath == "" {
|
2019-07-26 01:17:06 +02:00
|
|
|
return nil, fmt.Errorf("could not start policy pack %s because the built-in analyzer "+
|
|
|
|
"plugin that runs policy plugins is missing. This might occur when the plugin "+
|
|
|
|
"directory is not on your $PATH, or when the installed version of the Pulumi SDK "+
|
|
|
|
"does not support resource policies", string(name))
|
2019-07-01 01:34:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
plug, err := newPlugin(ctx, pluginPath, fmt.Sprintf("%v (analyzer)", name),
|
|
|
|
[]string{host.ServerAddr(), policyPackPath})
|
|
|
|
if err != nil {
|
2019-08-13 07:26:22 +02:00
|
|
|
return nil, errors.Wrapf(err,
|
|
|
|
"policy pack %s failed to start because of an internal error", string(name))
|
2019-07-01 01:34:39 +02:00
|
|
|
}
|
|
|
|
contract.Assertf(plug != nil, "unexpected nil analyzer plugin for %s", name)
|
|
|
|
|
|
|
|
return &analyzer{
|
|
|
|
ctx: ctx,
|
|
|
|
name: name,
|
|
|
|
plug: plug,
|
|
|
|
client: pulumirpc.NewAnalyzerClient(plug.Conn),
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
Add basic analyzer support
This change introduces the basic requirements for analyzers, as per
pulumi/coconut#119. In particular, an analyzer can implement either,
or both, of the RPC methods, Analyze and AnalyzeResource. The former
is meant to check an overall deployment (e.g., to ensure it has been
signed off on) and the latter is to check individual resources (e.g.,
to ensure properties of them are correct, such as checking style,
security, etc. rules). These run simultaneous to overall checking.
Analyzers are loaded as plugins just like providers are. The difference
is mainly in their naming ("analyzer-" prefix, rather than "resource-"),
and the RPC methods that they support.
This isn't 100% functional since we need a way to specify at the CLI
that a particular analyzer should be run, in addition to a way of
recording which analyzers certain projects should use in their manifests.
2017-03-11 08:49:17 +01:00
|
|
|
func (a *analyzer) Name() tokens.QName { return a.name }
|
|
|
|
|
2017-12-15 16:22:49 +01:00
|
|
|
// label returns a base label for tracing functions.
|
|
|
|
func (a *analyzer) label() string {
|
|
|
|
return fmt.Sprintf("Analyzer[%s]", a.name)
|
|
|
|
}
|
|
|
|
|
Make more progress on the new deployment model
This change restructures a lot more pertaining to deployments, snapshots,
environments, and the like.
The most notable change is that the notion of a deploy.Source is introduced,
which splits the responsibility between the deploy.Plan -- which simply
understands how to compute and carry out deployment plans -- and the idea
of something that can produce new objects on-demand during deployment.
The primary such implementation is evalSource, which encapsulates an
interpreter and takes a package, args, and config map, and proceeds to run
the interpreter in a distinct goroutine. It synchronizes as needed to
poke and prod the interpreter along its path to create new resource objects.
There are two other sources, however. First, a nullSource, which simply
refuses to create new objects. This can be handy when writing isolated
tests but is also used to simulate the "empty" environment as necessary to
do a complete teardown of the target environment. Second, a fixedSource,
which takes a pre-computed array of objects, and hands those, in order, to
the planning engine; this is mostly useful as a testing technique.
Boatloads of code is now changed and updated in the various CLI commands.
This further chugs along towards pulumi/lumi#90. The end is in sight.
2017-06-10 20:50:47 +02:00
|
|
|
// Analyze analyzes a single resource object, and returns any errors that it finds.
|
2019-06-11 00:20:44 +02:00
|
|
|
func (a *analyzer) Analyze(
|
|
|
|
t tokens.Type, props resource.PropertyMap) ([]AnalyzeDiagnostic, error) {
|
|
|
|
|
2017-12-15 16:22:49 +01:00
|
|
|
label := fmt.Sprintf("%s.Analyze(%s)", a.label(), t)
|
2018-05-16 00:28:00 +02:00
|
|
|
logging.V(7).Infof("%s executing (#props=%d)", label, len(props))
|
2019-07-19 20:52:21 +02:00
|
|
|
mprops, err := MarshalProperties(props, MarshalOptions{KeepUnknowns: true})
|
2017-09-15 01:40:44 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
Add basic analyzer support
This change introduces the basic requirements for analyzers, as per
pulumi/coconut#119. In particular, an analyzer can implement either,
or both, of the RPC methods, Analyze and AnalyzeResource. The former
is meant to check an overall deployment (e.g., to ensure it has been
signed off on) and the latter is to check individual resources (e.g.,
to ensure properties of them are correct, such as checking style,
security, etc. rules). These run simultaneous to overall checking.
Analyzers are loaded as plugins just like providers are. The difference
is mainly in their naming ("analyzer-" prefix, rather than "resource-"),
and the RPC methods that they support.
This isn't 100% functional since we need a way to specify at the CLI
that a particular analyzer should be run, in addition to a way of
recording which analyzers certain projects should use in their manifests.
2017-03-11 08:49:17 +01:00
|
|
|
}
|
|
|
|
|
2017-12-01 22:50:32 +01:00
|
|
|
resp, err := a.client.Analyze(a.ctx.Request(), &pulumirpc.AnalyzeRequest{
|
2017-09-15 01:40:44 +02:00
|
|
|
Type: string(t),
|
|
|
|
Properties: mprops,
|
|
|
|
})
|
Add basic analyzer support
This change introduces the basic requirements for analyzers, as per
pulumi/coconut#119. In particular, an analyzer can implement either,
or both, of the RPC methods, Analyze and AnalyzeResource. The former
is meant to check an overall deployment (e.g., to ensure it has been
signed off on) and the latter is to check individual resources (e.g.,
to ensure properties of them are correct, such as checking style,
security, etc. rules). These run simultaneous to overall checking.
Analyzers are loaded as plugins just like providers are. The difference
is mainly in their naming ("analyzer-" prefix, rather than "resource-"),
and the RPC methods that they support.
This isn't 100% functional since we need a way to specify at the CLI
that a particular analyzer should be run, in addition to a way of
recording which analyzers certain projects should use in their manifests.
2017-03-11 08:49:17 +01:00
|
|
|
if err != nil {
|
2018-03-29 02:07:35 +02:00
|
|
|
rpcError := rpcerror.Convert(err)
|
2018-05-16 00:28:00 +02:00
|
|
|
logging.V(7).Infof("%s failed: err=%v", label, rpcError)
|
2018-03-29 02:07:35 +02:00
|
|
|
return nil, rpcError
|
Add basic analyzer support
This change introduces the basic requirements for analyzers, as per
pulumi/coconut#119. In particular, an analyzer can implement either,
or both, of the RPC methods, Analyze and AnalyzeResource. The former
is meant to check an overall deployment (e.g., to ensure it has been
signed off on) and the latter is to check individual resources (e.g.,
to ensure properties of them are correct, such as checking style,
security, etc. rules). These run simultaneous to overall checking.
Analyzers are loaded as plugins just like providers are. The difference
is mainly in their naming ("analyzer-" prefix, rather than "resource-"),
and the RPC methods that they support.
This isn't 100% functional since we need a way to specify at the CLI
that a particular analyzer should be run, in addition to a way of
recording which analyzers certain projects should use in their manifests.
2017-03-11 08:49:17 +01:00
|
|
|
}
|
|
|
|
|
2019-06-11 00:20:44 +02:00
|
|
|
failures := resp.GetDiagnostics()
|
|
|
|
logging.V(7).Infof("%s success: failures=#%d", label, len(failures))
|
|
|
|
|
|
|
|
diags := []AnalyzeDiagnostic{}
|
|
|
|
for _, failure := range failures {
|
2019-06-24 04:02:37 +02:00
|
|
|
enforcementLevel, err := convertEnforcementLevel(failure.EnforcementLevel)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2019-06-11 00:20:44 +02:00
|
|
|
}
|
2019-06-24 04:02:37 +02:00
|
|
|
|
2019-06-11 00:20:44 +02:00
|
|
|
diags = append(diags, AnalyzeDiagnostic{
|
2019-06-14 01:14:48 +02:00
|
|
|
PolicyName: failure.PolicyName,
|
|
|
|
PolicyPackName: failure.PolicyPackName,
|
|
|
|
PolicyPackVersion: failure.PolicyPackVersion,
|
|
|
|
Description: failure.Description,
|
|
|
|
Message: failure.Message,
|
|
|
|
Tags: failure.Tags,
|
|
|
|
EnforcementLevel: enforcementLevel,
|
Overhaul resources, planning, and environments
This change, part of pulumi/lumi#90, overhauls quite a bit of the
core resource, planning, environments, and related areas.
The biggest amount of movement comes from the splitting of pkg/resource
into multiple sub-packages. This results in:
- pkg/resource: just the core resource data structures.
- pkg/resource/deployment: all planning and deployment logic.
- pkg/resource/environment: all environment, configuration, and
serialized checkpoint structures and logic.
- pkg/resource/plugin: all dynamically loaded analyzer and
provider logic, including the actual loading and RPC mechanisms.
This also splits the resource abstraction up. We now have:
- resource.Resource: a shared interface.
- resource.Object: a resource that is connected to a live object
that will periodically observe mutations due to ongoing
evaluation of computations. Snapshots of its state may be
taken; however, this is purely a "pre-planning" abstraction.
- resource.State: a snapshot of a resource's state that is frozen.
In other words, it is no longer connected to a live object.
This is what will store provider outputs (ID and properties),
and is what may be serialized into a deployment record.
The branch is in a half-baked state as of this change; more changes
are to come...
2017-06-09 01:37:40 +02:00
|
|
|
})
|
Add basic analyzer support
This change introduces the basic requirements for analyzers, as per
pulumi/coconut#119. In particular, an analyzer can implement either,
or both, of the RPC methods, Analyze and AnalyzeResource. The former
is meant to check an overall deployment (e.g., to ensure it has been
signed off on) and the latter is to check individual resources (e.g.,
to ensure properties of them are correct, such as checking style,
security, etc. rules). These run simultaneous to overall checking.
Analyzers are loaded as plugins just like providers are. The difference
is mainly in their naming ("analyzer-" prefix, rather than "resource-"),
and the RPC methods that they support.
This isn't 100% functional since we need a way to specify at the CLI
that a particular analyzer should be run, in addition to a way of
recording which analyzers certain projects should use in their manifests.
2017-03-11 08:49:17 +01:00
|
|
|
}
|
2019-06-11 00:20:44 +02:00
|
|
|
|
|
|
|
return diags, nil
|
Add basic analyzer support
This change introduces the basic requirements for analyzers, as per
pulumi/coconut#119. In particular, an analyzer can implement either,
or both, of the RPC methods, Analyze and AnalyzeResource. The former
is meant to check an overall deployment (e.g., to ensure it has been
signed off on) and the latter is to check individual resources (e.g.,
to ensure properties of them are correct, such as checking style,
security, etc. rules). These run simultaneous to overall checking.
Analyzers are loaded as plugins just like providers are. The difference
is mainly in their naming ("analyzer-" prefix, rather than "resource-"),
and the RPC methods that they support.
This isn't 100% functional since we need a way to specify at the CLI
that a particular analyzer should be run, in addition to a way of
recording which analyzers certain projects should use in their manifests.
2017-03-11 08:49:17 +01:00
|
|
|
}
|
|
|
|
|
2019-07-13 03:32:50 +02:00
|
|
|
// GetAnalyzerInfo returns metadata about the policies contained in this analyzer plugin.
|
2019-06-24 04:02:37 +02:00
|
|
|
func (a *analyzer) GetAnalyzerInfo() (AnalyzerInfo, error) {
|
|
|
|
label := fmt.Sprintf("%s.GetAnalyzerInfo()", a.label())
|
|
|
|
logging.V(7).Infof("%s executing", label)
|
|
|
|
resp, err := a.client.GetAnalyzerInfo(a.ctx.Request(), &pbempty.Empty{})
|
|
|
|
if err != nil {
|
|
|
|
rpcError := rpcerror.Convert(err)
|
|
|
|
logging.V(7).Infof("%s failed: err=%v", a.label(), rpcError)
|
|
|
|
return AnalyzerInfo{}, rpcError
|
|
|
|
}
|
|
|
|
|
|
|
|
policies := []apitype.Policy{}
|
|
|
|
for _, p := range resp.GetPolicies() {
|
|
|
|
enforcementLevel, err := convertEnforcementLevel(p.EnforcementLevel)
|
|
|
|
if err != nil {
|
|
|
|
return AnalyzerInfo{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
policies = append(policies, apitype.Policy{
|
|
|
|
Name: p.GetName(),
|
|
|
|
DisplayName: p.GetDisplayName(),
|
|
|
|
Description: p.GetDescription(),
|
|
|
|
EnforcementLevel: enforcementLevel,
|
|
|
|
Message: p.GetMessage(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
return AnalyzerInfo{
|
|
|
|
Name: resp.GetName(),
|
|
|
|
DisplayName: resp.GetDisplayName(),
|
|
|
|
Policies: policies,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2017-12-01 22:50:32 +01:00
|
|
|
// GetPluginInfo returns this plugin's information.
|
2018-02-06 18:57:32 +01:00
|
|
|
func (a *analyzer) GetPluginInfo() (workspace.PluginInfo, error) {
|
2017-12-15 16:22:49 +01:00
|
|
|
label := fmt.Sprintf("%s.GetPluginInfo()", a.label())
|
2018-05-16 00:28:00 +02:00
|
|
|
logging.V(7).Infof("%s executing", label)
|
2017-12-01 22:50:32 +01:00
|
|
|
resp, err := a.client.GetPluginInfo(a.ctx.Request(), &pbempty.Empty{})
|
|
|
|
if err != nil {
|
2018-03-29 02:07:35 +02:00
|
|
|
rpcError := rpcerror.Convert(err)
|
2018-05-16 00:28:00 +02:00
|
|
|
logging.V(7).Infof("%s failed: err=%v", a.label(), rpcError)
|
2018-03-29 02:07:35 +02:00
|
|
|
return workspace.PluginInfo{}, rpcError
|
2018-02-06 18:57:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
var version *semver.Version
|
|
|
|
if v := resp.Version; v != "" {
|
|
|
|
sv, err := semver.ParseTolerant(v)
|
|
|
|
if err != nil {
|
|
|
|
return workspace.PluginInfo{}, err
|
|
|
|
}
|
|
|
|
version = &sv
|
2017-12-01 22:50:32 +01:00
|
|
|
}
|
2018-02-06 18:57:32 +01:00
|
|
|
|
|
|
|
return workspace.PluginInfo{
|
2018-02-21 19:32:31 +01:00
|
|
|
Name: string(a.name),
|
|
|
|
Path: a.plug.Bin,
|
2018-02-06 18:57:32 +01:00
|
|
|
Kind: workspace.AnalyzerPlugin,
|
|
|
|
Version: version,
|
2017-12-01 22:50:32 +01:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
Add basic analyzer support
This change introduces the basic requirements for analyzers, as per
pulumi/coconut#119. In particular, an analyzer can implement either,
or both, of the RPC methods, Analyze and AnalyzeResource. The former
is meant to check an overall deployment (e.g., to ensure it has been
signed off on) and the latter is to check individual resources (e.g.,
to ensure properties of them are correct, such as checking style,
security, etc. rules). These run simultaneous to overall checking.
Analyzers are loaded as plugins just like providers are. The difference
is mainly in their naming ("analyzer-" prefix, rather than "resource-"),
and the RPC methods that they support.
This isn't 100% functional since we need a way to specify at the CLI
that a particular analyzer should be run, in addition to a way of
recording which analyzers certain projects should use in their manifests.
2017-03-11 08:49:17 +01:00
|
|
|
// Close tears down the underlying plugin RPC connection and process.
|
|
|
|
func (a *analyzer) Close() error {
|
|
|
|
return a.plug.Close()
|
|
|
|
}
|
2019-06-24 04:02:37 +02:00
|
|
|
|
|
|
|
func convertEnforcementLevel(el pulumirpc.EnforcementLevel) (apitype.EnforcementLevel, error) {
|
|
|
|
switch el {
|
|
|
|
case pulumirpc.EnforcementLevel_ADVISORY:
|
|
|
|
return apitype.Advisory, nil
|
|
|
|
case pulumirpc.EnforcementLevel_MANDATORY:
|
|
|
|
return apitype.Mandatory, nil
|
|
|
|
|
|
|
|
default:
|
|
|
|
return "", fmt.Errorf("Invalid enforcement level %d", el)
|
|
|
|
}
|
|
|
|
}
|