-
Notifications
You must be signed in to change notification settings - Fork 432
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(api): add grpc plugin action handlers (#3308)
- Loading branch information
Showing
94 changed files
with
5,880 additions
and
115 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
clair.exe | ||
clair | ||
dist/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
.PHONY: clean | ||
|
||
VERSION := $(if ${CDS_SEMVER},${CDS_SEMVER},snapshot) | ||
|
||
TARGET_DIR = ./dist | ||
TARGET_NAME = clair | ||
|
||
define PLUGIN_MANIFEST_BINARY | ||
os: %os% | ||
arch: %arch% | ||
cmd: ./%filename% | ||
endef | ||
export PLUGIN_MANIFEST_BINARY | ||
|
||
TARGET_LDFLAGS = -ldflags "-X github.com/ovh/cds/sdk.VERSION=$(VERSION)" | ||
TARGET_OS = $(if ${OS},${OS},windows darwin linux freebsd) | ||
TARGET_ARCH = $(if ${ARCH},${ARCH},amd64 arm 386) | ||
|
||
GO_BUILD = go build -v | ||
|
||
|
||
$(TARGET_DIR): | ||
$(info create $(TARGET_DIR) directory) | ||
@mkdir -p $(TARGET_DIR) | ||
|
||
default: build | ||
|
||
clean: | ||
@rm -rf $(TARGET_DIR) | ||
|
||
build: $(TARGET_DIR) | ||
@cp $(TARGET_NAME).yml $(TARGET_DIR)/plugin.yml | ||
@for GOOS in $(TARGET_OS); do \ | ||
for GOARCH in $(TARGET_ARCH); do \ | ||
EXTENSION=""; \ | ||
if test "$$GOOS" = "windows" ; then EXTENSION=".exe"; fi; \ | ||
echo Compiling $(TARGET_DIR)/$(TARGET_NAME)-$$GOOS-$$GOARCH$$EXTENSION $(VERSION); \ | ||
FILENAME=$(TARGET_NAME)-$$GOOS-$$GOARCH$$EXTENSION; \ | ||
GOOS=$$GOOS GOARCH=$$GOARCH $(GO_BUILD) $(TARGET_LDFLAGS) -o $(TARGET_DIR)/$$FILENAME; \ | ||
echo "$$PLUGIN_MANIFEST_BINARY" > $(TARGET_DIR)/plugin-$$GOOS-$$GOARCH.yml; \ | ||
sed -i "" "s/%os%/$$GOOS/" $(TARGET_DIR)/plugin-$$GOOS-$$GOARCH.yml; \ | ||
sed -i "" "s/%arch%/$$GOARCH/" $(TARGET_DIR)/plugin-$$GOOS-$$GOARCH.yml; \ | ||
sed -i "" "s/%filename%/$$FILENAME/" $(TARGET_DIR)/plugin-$$GOOS-$$GOARCH.yml; \ | ||
done; \ | ||
done | ||
|
||
publish: | ||
@echo "Updating plugin..." | ||
cdsctl admin plugins import $(TARGET_DIR)/plugin.yml | ||
@for GOOS in $(TARGET_OS); do \ | ||
for GOARCH in $(TARGET_ARCH); do \ | ||
EXTENSION=""; \ | ||
if test "$$GOOS" = "windows" ; then EXTENSION=".exe"; fi; \ | ||
echo "Updating plugin binary $(TARGET_NAME)-$$GOOS-$$GOARCH$$EXTENSION"; \ | ||
cdsctl admin plugins binary-add plugin-clair $(TARGET_DIR)/plugin-$$GOOS-$$GOARCH.yml $(TARGET_DIR)/$(TARGET_NAME)-$$GOOS-$$GOARCH$$EXTENSION; \ | ||
done; \ | ||
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
name: plugin-clair | ||
type: action | ||
author: "Steven GUIHEUX <[email protected]>" | ||
description: This is a plugin to run clair analysis | ||
parameters: | ||
image: | ||
type: string | ||
description: Image to analyze |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/docker/distribution" | ||
"github.com/docker/distribution/reference" | ||
"github.com/golang/protobuf/ptypes/empty" | ||
"github.com/jgsqware/clairctl/clair" | ||
"github.com/jgsqware/clairctl/config" | ||
"github.com/jgsqware/clairctl/docker" | ||
"github.com/spf13/viper" | ||
|
||
"github.com/ovh/cds/sdk" | ||
"github.com/ovh/cds/sdk/grpcplugin/actionplugin" | ||
"github.com/ovh/cds/sdk/plugin" | ||
) | ||
|
||
/* | ||
$ make build | ||
$ make publish | ||
*/ | ||
|
||
type clairActionPlugin struct { | ||
actionplugin.Common | ||
} | ||
|
||
func (actPlugin *clairActionPlugin) Manifest(ctx context.Context, _ *empty.Empty) (*actionplugin.ActionPluginManifest, error) { | ||
return &actionplugin.ActionPluginManifest{ | ||
Name: "plugin-clair", | ||
Author: "Steven GUIHEUX <[email protected]>", | ||
Description: `This is a plugin to run clair analysis`, | ||
Version: sdk.VERSION, | ||
}, nil | ||
} | ||
|
||
func (actPlugin *clairActionPlugin) Run(ctx context.Context, q *actionplugin.ActionQuery) (*actionplugin.ActionResult, error) { | ||
// get clair configuration | ||
fmt.Printf("Retrieve clair configuration...") | ||
serv, err := plugin.GetExternalServices(actPlugin.HTTPPort, "clair") | ||
if err != nil { | ||
return fail("Unable to get clair configuration: %s", err) | ||
} | ||
viper.Set("clair.uri", serv.URL) | ||
viper.Set("clair.port", serv.Port) | ||
viper.Set("clair.healthPort", serv.HealthPort) | ||
viper.Set("clair.report.path", ".") | ||
viper.Set("clair.report.format", "json") | ||
clair.Config() | ||
|
||
dockerImage := q.GetOptions()["image"] | ||
|
||
fmt.Printf("Pushing image %s into clair", dockerImage) | ||
image, manifest, err := pushImage(dockerImage) | ||
if err != nil { | ||
return fail("Unable to push image on Clair: %s", err) | ||
} | ||
|
||
fmt.Printf("Running analysis") | ||
analysis := clair.Analyze(image, manifest) | ||
|
||
fmt.Printf("Creating report") | ||
|
||
var vulnerabilities []sdk.Vulnerability | ||
summary := make(map[string]int64) | ||
if analysis.MostRecentLayer().Layer != nil { | ||
for _, feat := range analysis.MostRecentLayer().Layer.Features { | ||
for _, vuln := range feat.Vulnerabilities { | ||
v := sdk.Vulnerability{ | ||
Version: feat.Version, | ||
Component: feat.Name, | ||
Description: vuln.Description, | ||
Link: vuln.Link, | ||
FixIn: vuln.FixedBy, | ||
Severity: sdk.ToVulnerabilitySeverity(vuln.Severity), | ||
Origin: feat.AddedBy, | ||
CVE: vuln.Name, | ||
Title: fmt.Sprintf("%s %s", feat.Name, feat.Version), | ||
} | ||
vulnerabilities = append(vulnerabilities, v) | ||
|
||
count := summary[v.Severity] | ||
summary[v.Severity] = count + 1 | ||
|
||
} | ||
} | ||
} | ||
|
||
report := sdk.VulnerabilityWorkerReport{ | ||
Vulnerabilities: vulnerabilities, | ||
Summary: summary, | ||
Type: "docker", | ||
} | ||
if err := plugin.SendVulnerabilityReport(actPlugin.HTTPPort, report); err != nil { | ||
return fail("Unable to send report: %s", err) | ||
} | ||
return &actionplugin.ActionResult{ | ||
Status: sdk.StatusSuccess.String(), | ||
}, nil | ||
} | ||
|
||
func (actPlugin *clairActionPlugin) WorkerHTTPPort(ctx context.Context, q *actionplugin.WorkerHTTPPortQuery) (*empty.Empty, error) { | ||
actPlugin.HTTPPort = q.Port | ||
return &empty.Empty{}, nil | ||
} | ||
|
||
func main() { | ||
actPlugin := clairActionPlugin{} | ||
if err := actionplugin.Start(context.Background(), &actPlugin); err != nil { | ||
panic(err) | ||
} | ||
return | ||
|
||
} | ||
|
||
func fail(format string, args ...interface{}) (*actionplugin.ActionResult, error) { | ||
msg := fmt.Sprintf(format, args...) | ||
fmt.Println(msg) | ||
return &actionplugin.ActionResult{ | ||
Details: msg, | ||
Status: sdk.StatusFail.String(), | ||
}, nil | ||
} | ||
|
||
func pushImage(dockerImage string) (reference.NamedTagged, distribution.Manifest, error) { | ||
config.ImageName = dockerImage | ||
image, manifest, err := docker.RetrieveManifest(config.ImageName, true) | ||
if err != nil { | ||
return image, manifest, fmt.Errorf("pushImage> unable to retrieve manifest: %v", err) | ||
} | ||
|
||
if err := clair.Push(image, manifest); err != nil { | ||
if err != nil { | ||
return image, manifest, fmt.Errorf("pushImage> unable to push image %q: %v", image.String(), err) | ||
} | ||
} | ||
return image, manifest, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
download | ||
download.exe | ||
dist/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
.PHONY: clean | ||
|
||
VERSION := $(if ${CDS_SEMVER},${CDS_SEMVER},snapshot) | ||
|
||
TARGET_DIR = ./dist | ||
TARGET_NAME = download | ||
|
||
define PLUGIN_MANIFEST_BINARY | ||
os: %os% | ||
arch: %arch% | ||
cmd: ./%filename% | ||
endef | ||
export PLUGIN_MANIFEST_BINARY | ||
|
||
TARGET_LDFLAGS = -ldflags "-X github.com/ovh/cds/sdk.VERSION=$(VERSION)" | ||
TARGET_OS = $(if ${OS},${OS},windows darwin linux freebsd) | ||
TARGET_ARCH = $(if ${ARCH},${ARCH},amd64 arm 386) | ||
|
||
GO_BUILD = go build -v | ||
|
||
|
||
$(TARGET_DIR): | ||
$(info create $(TARGET_DIR) directory) | ||
@mkdir -p $(TARGET_DIR) | ||
|
||
default: build | ||
|
||
clean: | ||
@rm -rf $(TARGET_DIR) | ||
|
||
build: $(TARGET_DIR) | ||
@cp $(TARGET_NAME).yml $(TARGET_DIR)/plugin.yml | ||
@for GOOS in $(TARGET_OS); do \ | ||
for GOARCH in $(TARGET_ARCH); do \ | ||
EXTENSION=""; \ | ||
if test "$$GOOS" = "windows" ; then EXTENSION=".exe"; fi; \ | ||
echo Compiling $(TARGET_DIR)/$(TARGET_NAME)-$$GOOS-$$GOARCH$$EXTENSION $(VERSION); \ | ||
FILENAME=$(TARGET_NAME)-$$GOOS-$$GOARCH$$EXTENSION; \ | ||
GOOS=$$GOOS GOARCH=$$GOARCH $(GO_BUILD) $(TARGET_LDFLAGS) -o $(TARGET_DIR)/$$FILENAME; \ | ||
echo "$$PLUGIN_MANIFEST_BINARY" > $(TARGET_DIR)/plugin-$$GOOS-$$GOARCH.yml; \ | ||
sed -i "" "s/%os%/$$GOOS/" $(TARGET_DIR)/plugin-$$GOOS-$$GOARCH.yml; \ | ||
sed -i "" "s/%arch%/$$GOARCH/" $(TARGET_DIR)/plugin-$$GOOS-$$GOARCH.yml; \ | ||
sed -i "" "s/%filename%/$$FILENAME/" $(TARGET_DIR)/plugin-$$GOOS-$$GOARCH.yml; \ | ||
done; \ | ||
done | ||
|
||
publish: | ||
@echo "Updating plugin..." | ||
cdsctl admin plugins import $(TARGET_DIR)/plugin.yml | ||
@for GOOS in $(TARGET_OS); do \ | ||
for GOARCH in $(TARGET_ARCH); do \ | ||
EXTENSION=""; \ | ||
if test "$$GOOS" = "windows" ; then EXTENSION=".exe"; fi; \ | ||
echo "Updating plugin binary $(TARGET_NAME)-$$GOOS-$$GOARCH$$EXTENSION"; \ | ||
cdsctl admin plugins binary-add plugin-download $(TARGET_DIR)/plugin-$$GOOS-$$GOARCH.yml $(TARGET_DIR)/$(TARGET_NAME)-$$GOOS-$$GOARCH$$EXTENSION; \ | ||
done; \ | ||
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
name: plugin-download | ||
type: action | ||
author: Benjamin COENEN <[email protected]> | ||
description: This is a plugin to download file from URL | ||
parameters: | ||
url: | ||
type: string | ||
description: The url of your file | ||
default: '{{.cds.app.downloadUrl}}' | ||
filepath: | ||
type: string | ||
description: The destination of your file to be copied | ||
default: '.' | ||
headers: | ||
type: text | ||
description: Specific headers to add to your request ("headerName"="value" newline separated list) |
Oops, something went wrong.