harness-drone/plugin/converter/remote.go
Doug Simmons 677d7cc2f7 Add configurable timeout for config, convert, and validate plugins
Also run 'go fmt' on changed files
2020-08-28 12:04:08 -07:00

144 lines
3.3 KiB
Go

// Copyright 2019 Drone.IO Inc. All rights reserved.
// Use of this source code is governed by the Drone Non-Commercial License
// that can be found in the LICENSE file.
// +build !oss
package converter
import (
"context"
"strings"
"time"
"github.com/drone/drone-go/drone"
"github.com/drone/drone-go/plugin/converter"
"github.com/drone/drone/core"
)
// Remote returns a conversion service that converts the
// configuration file using a remote http service.
func Remote(endpoint, signer, extension string, skipVerify bool, timeout time.Duration) core.ConvertService {
if endpoint == "" {
return new(remote)
}
return &remote{
extension: extension,
client: converter.Client(
endpoint,
signer,
skipVerify,
),
timeout: timeout,
}
}
type remote struct {
client converter.Plugin
extension string
timeout time.Duration
}
func (g *remote) Convert(ctx context.Context, in *core.ConvertArgs) (*core.Config, error) {
if g.client == nil {
return nil, nil
}
if g.extension != "" {
if !strings.HasSuffix(in.Repo.Config, g.extension) {
return nil, nil
}
}
// include a timeout to prevent an API call from
// hanging the build process indefinitely. The
// external service must return a response within
// the configured timeout (default 1m).
ctx, cancel := context.WithTimeout(ctx, g.timeout)
defer cancel()
req := &converter.Request{
Repo: toRepo(in.Repo),
Build: toBuild(in.Build),
Config: drone.Config{
Data: in.Config.Data,
},
}
res, err := g.client.Convert(ctx, req)
if err != nil {
return nil, err
}
if res == nil {
return nil, nil
}
// if no error is returned and the secret is empty,
// this indicates the client returned No Content,
// and we should exit with no secret, but no error.
if res.Data == "" {
return nil, nil
}
return &core.Config{
Kind: res.Kind,
Data: res.Data,
}, nil
}
func toRepo(from *core.Repository) drone.Repo {
return drone.Repo{
ID: from.ID,
UID: from.UID,
UserID: from.UserID,
Namespace: from.Namespace,
Name: from.Name,
Slug: from.Slug,
SCM: from.SCM,
HTTPURL: from.HTTPURL,
SSHURL: from.SSHURL,
Link: from.Link,
Branch: from.Branch,
Private: from.Private,
Visibility: from.Visibility,
Active: from.Active,
Config: from.Config,
Trusted: from.Trusted,
Protected: from.Protected,
Timeout: from.Timeout,
}
}
func toBuild(from *core.Build) drone.Build {
return drone.Build{
ID: from.ID,
RepoID: from.RepoID,
Trigger: from.Trigger,
Number: from.Number,
Parent: from.Parent,
Status: from.Status,
Error: from.Error,
Event: from.Event,
Action: from.Action,
Link: from.Link,
Timestamp: from.Timestamp,
Title: from.Title,
Message: from.Message,
Before: from.Before,
After: from.After,
Ref: from.Ref,
Fork: from.Fork,
Source: from.Source,
Target: from.Target,
Author: from.Author,
AuthorName: from.AuthorName,
AuthorEmail: from.AuthorEmail,
AuthorAvatar: from.AuthorAvatar,
Sender: from.Sender,
Params: from.Params,
Deploy: from.Deploy,
Started: from.Started,
Finished: from.Finished,
Created: from.Created,
Updated: from.Updated,
Version: from.Version,
}
}