mirror of https://github.com/harness/drone.git
feat: [CDE-85]: Adding impl for docker provider (#2131)
parent
d06dd5c2fd
commit
f53480a8ad
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package infraprovider
|
||||
|
||||
import "context"
|
||||
|
||||
type Client interface {
|
||||
// Close closes the underlying client.
|
||||
Close(ctx context.Context)
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package infraprovider
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/docker/docker/client"
|
||||
)
|
||||
|
||||
var _ Client = (*DockerClient)(nil)
|
||||
|
||||
type DockerClient struct {
|
||||
dockerClient *client.Client
|
||||
closeFunc func(ctx context.Context)
|
||||
}
|
||||
|
||||
func (d DockerClient) Close(ctx context.Context) {
|
||||
d.closeFunc(ctx)
|
||||
}
|
|
@ -0,0 +1,172 @@
|
|||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package infraprovider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/harness/gitness/infraprovider/enum"
|
||||
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/go-connections/tlsconfig"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
var _ InfraProvider = (*dockerProvider)(nil)
|
||||
|
||||
type Config struct {
|
||||
DockerHost string
|
||||
DockerAPIVersion string
|
||||
DockerCertPath string
|
||||
DockerTLSVerify string
|
||||
}
|
||||
|
||||
type dockerProvider struct {
|
||||
config *Config
|
||||
}
|
||||
|
||||
func NewDockerProvider(config *Config) InfraProvider {
|
||||
return &dockerProvider{
|
||||
config: config,
|
||||
}
|
||||
}
|
||||
|
||||
// Provision assumes a docker engine is already running on the Gitness host machine and re-uses that as infra.
|
||||
// It does not start docker engine.
|
||||
func (d dockerProvider) Provision(ctx context.Context, _ string, params []Parameter) (Infrastructure, error) {
|
||||
dockerClient, closeFunc, err := d.getClient(params)
|
||||
if err != nil {
|
||||
return Infrastructure{}, err
|
||||
}
|
||||
defer closeFunc(ctx)
|
||||
info, err := dockerClient.Info(ctx)
|
||||
if err != nil {
|
||||
return Infrastructure{}, fmt.Errorf("unable to connect to docker engine: %w", err)
|
||||
}
|
||||
return Infrastructure{
|
||||
Identifier: info.ID,
|
||||
ProviderType: enum.InfraProviderTypeDocker,
|
||||
Status: enum.InfraStatusProvisioned,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d dockerProvider) Find(_ context.Context, _ string, _ []Parameter) (Infrastructure, error) {
|
||||
// TODO implement me
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
// Stop is NOOP as this provider uses already running docker engine. It does not stop the docker engine.
|
||||
func (d dockerProvider) Stop(_ context.Context, infra Infrastructure) (Infrastructure, error) {
|
||||
return infra, nil
|
||||
}
|
||||
|
||||
// Destroy is NOOP as this provider uses already running docker engine. It does not stop the docker engine.
|
||||
func (d dockerProvider) Destroy(_ context.Context, infra Infrastructure) (Infrastructure, error) {
|
||||
return infra, nil
|
||||
}
|
||||
|
||||
func (d dockerProvider) Status(_ context.Context, _ Infrastructure) (enum.InfraStatus, error) {
|
||||
// TODO implement me
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
// AvailableParams returns empty slice as no params are defined.
|
||||
func (d dockerProvider) AvailableParams() []ParameterSchema {
|
||||
return []ParameterSchema{}
|
||||
}
|
||||
|
||||
// ValidateParams returns nil as no params are defined.
|
||||
func (d dockerProvider) ValidateParams(_ []Parameter) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TemplateParams returns nil as no template params are used.
|
||||
func (d dockerProvider) TemplateParams() []ParameterSchema {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ProvisioningType returns existing as docker provider doesn't create new resources.
|
||||
func (d dockerProvider) ProvisioningType() enum.InfraProvisioningType {
|
||||
return enum.InfraProvisioningTypeExisting
|
||||
}
|
||||
|
||||
func (d dockerProvider) Exec(_ context.Context, _ Infrastructure, _ []string) (io.Reader, io.Reader, error) {
|
||||
// TODO implement me
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
// Client returns a new docker client created using params.
|
||||
func (d dockerProvider) Client(_ context.Context, infra Infrastructure) (Client, error) {
|
||||
dockerClient, closeFunc, err := d.getClient(infra.Parameters)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &DockerClient{
|
||||
dockerClient: dockerClient,
|
||||
closeFunc: closeFunc,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// getClient returns a new docker client created using values from gitness docker config.
|
||||
func (d dockerProvider) getClient(_ []Parameter) (*client.Client, func(context.Context), error) {
|
||||
var opts []client.Opt
|
||||
|
||||
opts = append(opts, client.WithHost(d.config.DockerHost))
|
||||
|
||||
opts = append(opts, client.WithVersion(d.config.DockerAPIVersion))
|
||||
|
||||
if d.config.DockerCertPath != "" {
|
||||
httpsClient, err := d.getHTTPSClient()
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("unable to create https client for docker client: %w", err)
|
||||
}
|
||||
opts = append(opts, client.WithHTTPClient(httpsClient))
|
||||
}
|
||||
|
||||
dockerClient, err := client.NewClientWithOpts(opts...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("unable to create docker client: %w", err)
|
||||
}
|
||||
|
||||
closeFunc := func(ctx context.Context) {
|
||||
closingErr := dockerClient.Close()
|
||||
if closingErr != nil {
|
||||
log.Ctx(ctx).Warn().Err(closingErr).Msg("failed to close docker client")
|
||||
}
|
||||
}
|
||||
|
||||
return dockerClient, closeFunc, nil
|
||||
}
|
||||
|
||||
func (d dockerProvider) getHTTPSClient() (*http.Client, error) {
|
||||
options := tlsconfig.Options{
|
||||
CAFile: filepath.Join(d.config.DockerCertPath, "ca.pem"),
|
||||
CertFile: filepath.Join(d.config.DockerCertPath, "cert.pem"),
|
||||
KeyFile: filepath.Join(d.config.DockerCertPath, "key.pem"),
|
||||
InsecureSkipVerify: d.config.DockerTLSVerify == "",
|
||||
}
|
||||
tlsc, err := tlsconfig.Client(options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &http.Client{
|
||||
Transport: &http.Transport{TLSClientConfig: tlsc},
|
||||
CheckRedirect: client.CheckRedirect,
|
||||
}, nil
|
||||
}
|
|
@ -14,14 +14,14 @@
|
|||
|
||||
package enum
|
||||
|
||||
type ProviderType string
|
||||
type InfraProviderType string
|
||||
|
||||
func (ProviderType) Enum() []interface{} { return toInterfaceSlice(providerTypes) }
|
||||
func (InfraProviderType) Enum() []interface{} { return toInterfaceSlice(providerTypes) }
|
||||
|
||||
var providerTypes = []ProviderType{
|
||||
ProviderTypeDocker,
|
||||
var providerTypes = []InfraProviderType{
|
||||
InfraProviderTypeDocker,
|
||||
}
|
||||
|
||||
const (
|
||||
ProviderTypeDocker ProviderType = "docker"
|
||||
InfraProviderTypeDocker InfraProviderType = "docker"
|
||||
)
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package enum
|
||||
|
||||
type InfraProvisioningType string
|
||||
|
||||
func (InfraProvisioningType) Enum() []interface{} { return toInterfaceSlice(provisioningTypes) }
|
||||
|
||||
var provisioningTypes = []InfraProvisioningType{
|
||||
InfraProvisioningTypeExisting, InfraProvisioningTypeNew,
|
||||
}
|
||||
|
||||
const (
|
||||
InfraProvisioningTypeExisting InfraProvisioningType = "existing"
|
||||
InfraProvisioningTypeNew InfraProvisioningType = "new"
|
||||
)
|
|
@ -36,6 +36,13 @@ type InfraProvider interface {
|
|||
AvailableParams() []ParameterSchema
|
||||
// ValidateParams validates the supplied params before defining the infrastructure resource .
|
||||
ValidateParams(parameters []Parameter) error
|
||||
// TemplateParams provides a list of params which are of type template.
|
||||
TemplateParams() []ParameterSchema
|
||||
// ProvisioningType specifies whether the provider will provision new infra resources or it will reuse existing.
|
||||
ProvisioningType() enum.InfraProvisioningType
|
||||
// Exec executes a shell command in the infrastructure.
|
||||
Exec(ctx context.Context, infra Infrastructure, cmd []string) (io.Reader, io.Reader, error)
|
||||
// Client returns a client which can be used to connect the provided infra.
|
||||
// The responsibility of calling the close func lies with the user.
|
||||
Client(ctx context.Context, infra Infrastructure) (Client, error)
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ type Parameter struct {
|
|||
type Infrastructure struct {
|
||||
Identifier string
|
||||
ResourceKey string
|
||||
ProviderType enum.ProviderType
|
||||
ProviderType enum.InfraProviderType
|
||||
Parameters []Parameter
|
||||
Status enum.InfraStatus
|
||||
Host string
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package infraprovider
|
||||
|
||||
import (
|
||||
"github.com/harness/gitness/types"
|
||||
|
||||
"github.com/google/wire"
|
||||
)
|
||||
|
||||
// WireSet provides a wire set for this package.
|
||||
var WireSet = wire.NewSet(
|
||||
ProvideDockerProvider,
|
||||
)
|
||||
|
||||
func ProvideDockerProvider(config *types.Config) InfraProvider {
|
||||
dockerConfig := Config{
|
||||
DockerHost: config.Docker.Host,
|
||||
DockerAPIVersion: config.Docker.APIVersion,
|
||||
DockerCertPath: config.Docker.CertPath,
|
||||
DockerTLSVerify: config.Docker.TLSVerify,
|
||||
}
|
||||
return NewDockerProvider(&dockerConfig)
|
||||
}
|
|
@ -375,4 +375,15 @@ type Config struct {
|
|||
// DeletedRetentionTime is the duration after which deleted repositories will be purged.
|
||||
DeletedRetentionTime time.Duration `envconfig:"GITNESS_REPOS_DELETED_RETENTION_TIME" default:"2160h"` // 90 days
|
||||
}
|
||||
|
||||
Docker struct {
|
||||
// Host sets the url to the docker server.
|
||||
Host string `envconfig:"GITNESS_DOCKER_HOST"`
|
||||
// APIVersion sets the version of the API to reach, leave empty for latest.
|
||||
APIVersion string `envconfig:"GITNESS_DOCKER_API_VERSION"`
|
||||
// CertPath sets the path to load the TLS certificates from.
|
||||
CertPath string `envconfig:"GITNESS_DOCKER_CERT_PATH"`
|
||||
// TLSVerify enables or disables TLS verification, off by default.
|
||||
TLSVerify string `envconfig:"GITNESS_DOCKER_TLS_VERIFY"`
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue