Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor internal services #915

Merged
merged 32 commits into from
Feb 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
df09748
addons
anbraten Feb 7, 2024
69824f2
further improvements
anbraten Feb 7, 2024
ba2b536
improve logic
anbraten Feb 7, 2024
d824a1c
cleanup
anbraten Feb 7, 2024
80e8fcd
cleanup
anbraten Feb 7, 2024
f2e43ee
undo unrelated change
anbraten Feb 7, 2024
b094c9c
rename folder
anbraten Feb 7, 2024
dc0be46
fixes
anbraten Feb 7, 2024
59f237a
cleanup
anbraten Feb 7, 2024
ffe4c90
rename plugins to services
anbraten Feb 7, 2024
b87ceb2
cleanup
anbraten Feb 7, 2024
a85fdf0
improve
anbraten Feb 7, 2024
80c4e3b
prettier
anbraten Feb 7, 2024
78275f1
remove addon types
anbraten Feb 8, 2024
cb25cc0
remove unused config
anbraten Feb 8, 2024
88d3732
rename to extensions
anbraten Feb 8, 2024
23bd3c8
Merge remote-tracking branch 'upstream/main' into repo-plugins
anbraten Feb 8, 2024
71c122d
prettier
anbraten Feb 8, 2024
b38b722
update readme
anbraten Feb 8, 2024
535ee6b
service => extension
anbraten Feb 9, 2024
6f5c285
Merge branch 'main' into repo-plugins
anbraten Feb 9, 2024
a2df3a0
add todos
anbraten Feb 9, 2024
fc4dfdf
Merge branch 'repo-plugins' of github.com:anbraten/woodpecker into re…
anbraten Feb 9, 2024
b3ef5fb
adjust todo
anbraten Feb 9, 2024
6ec6ef8
rename to ExtensionsMangager
anbraten Feb 9, 2024
7d0e442
add migration note
anbraten Feb 9, 2024
1a5c4e1
Merge remote-tracking branch 'upstream/main' into repo-plugins
anbraten Feb 11, 2024
d5c574d
rename back to service
anbraten Feb 11, 2024
5976fd4
extension => service
anbraten Feb 11, 2024
6e0f1aa
update
anbraten Feb 11, 2024
8285801
cleanup
anbraten Feb 11, 2024
f1133e0
fix config fetching
anbraten Feb 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 7 additions & 35 deletions cmd/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,11 @@
woodpeckerGrpcServer "go.woodpecker-ci.org/woodpecker/v2/server/grpc"
"go.woodpecker-ci.org/woodpecker/v2/server/logging"
"go.woodpecker-ci.org/woodpecker/v2/server/model"
// "go.woodpecker-ci.org/woodpecker/v2/server/plugins/encryption"
// encryptedStore "go.woodpecker-ci.org/woodpecker/v2/server/plugins/encryption/wrapper/store"
"go.woodpecker-ci.org/woodpecker/v2/server/plugins/permissions"
"go.woodpecker-ci.org/woodpecker/v2/server/pubsub"
"go.woodpecker-ci.org/woodpecker/v2/server/router"
"go.woodpecker-ci.org/woodpecker/v2/server/router/middleware"
"go.woodpecker-ci.org/woodpecker/v2/server/services"
"go.woodpecker-ci.org/woodpecker/v2/server/services/permissions"
"go.woodpecker-ci.org/woodpecker/v2/server/store"
"go.woodpecker-ci.org/woodpecker/v2/server/web"
"go.woodpecker-ci.org/woodpecker/v2/shared/constant"
Expand Down Expand Up @@ -271,48 +270,21 @@
return g.Wait()
}

func setupEvilGlobals(c *cli.Context, v store.Store, f forge.Forge) error {
func setupEvilGlobals(c *cli.Context, s store.Store, f forge.Forge) error {

Check warning on line 273 in cmd/server/server.go

View check run for this annotation

Codecov / codecov/patch

cmd/server/server.go#L273

Added line #L273 was not covered by tests
// forge
server.Config.Services.Forge = f
server.Config.Services.Timeout = c.Duration("forge-timeout")

// services
server.Config.Services.Queue = setupQueue(c, v)
server.Config.Services.Queue = setupQueue(c, s)

Check warning on line 278 in cmd/server/server.go

View check run for this annotation

Codecov / codecov/patch

cmd/server/server.go#L278

Added line #L278 was not covered by tests
server.Config.Services.Logs = logging.New()
server.Config.Services.Pubsub = pubsub.New()
var err error
server.Config.Services.Registries, err = setupRegistryService(c, v)
if err != nil {
return err
}

// TODO(1544): fix encrypted store
// // encryption
// encryptedSecretStore := encryptedStore.NewSecretStore(v)
// err := encryption.Encryption(c, v).WithClient(encryptedSecretStore).Build()
// if err != nil {
// log.Fatal().Err(err).Msg("could not create encryption service")
// }
// server.Config.Services.Secrets = setupSecretService(c, encryptedSecretStore)
server.Config.Services.Secrets, err = setupSecretService(c, v)
if err != nil {
return err
}
server.Config.Services.Environ, err = setupEnvironService(c, v)
if err != nil {
return err
}
server.Config.Services.Membership = setupMembershipService(c, f)

server.Config.Services.SignaturePrivateKey, server.Config.Services.SignaturePublicKey, err = setupSignatureKeys(v)
serviceMangager, err := services.NewManager(c, s)

Check warning on line 283 in cmd/server/server.go

View check run for this annotation

Codecov / codecov/patch

cmd/server/server.go#L283

Added line #L283 was not covered by tests
if err != nil {
return err
}

server.Config.Services.ConfigService, err = setupConfigService(c)
if err != nil {
return err
return fmt.Errorf("could not setup service manager: %w", err)

Check warning on line 285 in cmd/server/server.go

View check run for this annotation

Codecov / codecov/patch

cmd/server/server.go#L285

Added line #L285 was not covered by tests
}
server.Config.Services.Manager = serviceMangager

Check warning on line 287 in cmd/server/server.go

View check run for this annotation

Codecov / codecov/patch

cmd/server/server.go#L287

Added line #L287 was not covered by tests

// authentication
server.Config.Pipeline.AuthenticatePublicRepos = c.Bool("authenticate-public-repos")
Expand Down
96 changes: 0 additions & 96 deletions cmd/server/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ package main

import (
"context"
"crypto"
"crypto/ed25519"
"crypto/rand"
"encoding/hex"
"errors"
"fmt"
"net/url"
"os"
Expand All @@ -41,15 +36,9 @@ import (
"go.woodpecker-ci.org/woodpecker/v2/server/forge/gitea"
"go.woodpecker-ci.org/woodpecker/v2/server/forge/github"
"go.woodpecker-ci.org/woodpecker/v2/server/forge/gitlab"
"go.woodpecker-ci.org/woodpecker/v2/server/model"
"go.woodpecker-ci.org/woodpecker/v2/server/plugins/config"
"go.woodpecker-ci.org/woodpecker/v2/server/plugins/environments"
"go.woodpecker-ci.org/woodpecker/v2/server/plugins/registry"
"go.woodpecker-ci.org/woodpecker/v2/server/plugins/secrets"
"go.woodpecker-ci.org/woodpecker/v2/server/queue"
"go.woodpecker-ci.org/woodpecker/v2/server/store"
"go.woodpecker-ci.org/woodpecker/v2/server/store/datastore"
"go.woodpecker-ci.org/woodpecker/v2/server/store/types"
"go.woodpecker-ci.org/woodpecker/v2/shared/addon"
addonTypes "go.woodpecker-ci.org/woodpecker/v2/shared/addon/types"
)
Expand Down Expand Up @@ -111,48 +100,6 @@ func setupQueue(c *cli.Context, s store.Store) queue.Queue {
return queue.WithTaskStore(queue.New(c.Context), s)
}

func setupSecretService(c *cli.Context, s model.SecretStore) (model.SecretService, error) {
addonService, err := addon.Load[model.SecretService](c.StringSlice("addons"), addonTypes.TypeSecretService)
if err != nil {
return nil, err
}
if addonService != nil {
return addonService.Value, nil
}

return secrets.New(c.Context, s), nil
}

func setupRegistryService(c *cli.Context, s store.Store) (model.RegistryService, error) {
addonService, err := addon.Load[model.RegistryService](c.StringSlice("addons"), addonTypes.TypeRegistryService)
if err != nil {
return nil, err
}
if addonService != nil {
return addonService.Value, nil
}

if c.String("docker-config") != "" {
return registry.Combined(
registry.New(s),
registry.Filesystem(c.String("docker-config")),
), nil
}
return registry.New(s), nil
}

func setupEnvironService(c *cli.Context, _ store.Store) (model.EnvironService, error) {
addonService, err := addon.Load[model.EnvironService](c.StringSlice("addons"), addonTypes.TypeEnvironmentService)
if err != nil {
return nil, err
}
if addonService != nil {
return addonService.Value, nil
}

return environments.Parse(c.StringSlice("environment")), nil
}

func setupMembershipService(_ *cli.Context, r forge.Forge) cache.MembershipService {
return cache.NewMembershipService(r)
}
Expand Down Expand Up @@ -292,46 +239,3 @@ func setupMetrics(g *errgroup.Group, _store store.Store) {
}
})
}

// setupSignatureKeys generate or load key pair to sign webhooks requests (i.e. used for extensions)
func setupSignatureKeys(_store store.Store) (crypto.PrivateKey, crypto.PublicKey, error) {
privKeyID := "signature-private-key"

privKey, err := _store.ServerConfigGet(privKeyID)
if errors.Is(err, types.RecordNotExist) {
_, privKey, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
return nil, nil, fmt.Errorf("failed to generate private key: %w", err)
}
err = _store.ServerConfigSet(privKeyID, hex.EncodeToString(privKey))
if err != nil {
return nil, nil, fmt.Errorf("failed to store private key: %w", err)
}
log.Debug().Msg("created private key")
return privKey, privKey.Public(), nil
} else if err != nil {
return nil, nil, fmt.Errorf("failed to load private key: %w", err)
}
privKeyStr, err := hex.DecodeString(privKey)
if err != nil {
return nil, nil, fmt.Errorf("failed to decode private key: %w", err)
}
privateKey := ed25519.PrivateKey(privKeyStr)
return privateKey, privateKey.Public(), nil
}

func setupConfigService(c *cli.Context) (config.Extension, error) {
addonExt, err := addon.Load[config.Extension](c.StringSlice("addons"), addonTypes.TypeConfigService)
if err != nil {
return nil, err
}
if addonExt != nil {
return addonExt.Value, nil
}

if endpoint := c.String("config-service-endpoint"); endpoint != "" {
return config.NewHTTP(endpoint, server.Config.Services.SignaturePrivateKey), nil
}

return nil, nil
}
1 change: 1 addition & 0 deletions docs/docs/20-usage/15-terminiology/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
- **YAML File**: A file format used to define and configure [workflows][Workflow].
- **Dependency**: [Workflows][Workflow] can depend on each other, and if possible, they are executed in parallel.
- **Status**: Status refers to the outcome of a step or [workflow][Workflow] after it has been executed, determined by the internal command exit code. At the end of a [workflow][Workflow], its status is sent to the [forge][Forge].
- **Service extension**: Some parts of woodpecker internal services like secrets storage or config fetcher can be replaced through service extensions.

## Pipeline events

Expand Down
4 changes: 0 additions & 4 deletions docs/docs/30-administration/75-addons/00-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ To adapt Woodpecker to your needs beyond the [configuration](../10-server-config
Addons can be used for:

- Forges
- Config services
- Secret services
- Environment services
- Registry services

## Restrictions

Expand Down
10 changes: 3 additions & 7 deletions docs/docs/30-administration/75-addons/20-creating-addons.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,9 @@ Directly import Woodpecker's Go package (`go.woodpecker-ci.org/woodpecker/woodpe

### Return types

| Addon type | Return type |
| -------------------- | ---------------------------------------------------------------------- |
| `Forge` | `"go.woodpecker-ci.org/woodpecker/woodpecker/v2/server/forge".Forge` |
| `ConfigService` | `"go.woodpecker-ci.org/woodpecker/v2/server/plugins/config".Extension` |
| `SecretService` | `"go.woodpecker-ci.org/woodpecker/v2/server/model".SecretService` |
| `EnvironmentService` | `"go.woodpecker-ci.org/woodpecker/v2/server/model".EnvironmentService` |
| `RegistryService` | `"go.woodpecker-ci.org/woodpecker/v2/server/model".RegistryService` |
| Addon type | Return type |
| ---------- | -------------------------------------------------------------------- |
| `Forge` | `"go.woodpecker-ci.org/woodpecker/woodpecker/v2/server/forge".Forge` |
anbraten marked this conversation as resolved.
Show resolved Hide resolved

### Using configurations

Expand Down
19 changes: 13 additions & 6 deletions server/api/global_secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
// @Param page query int false "for response pagination, page offset number" default(1)
// @Param perPage query int false "for response pagination, max items per page" default(50)
func GetGlobalSecretList(c *gin.Context) {
list, err := server.Config.Services.Secrets.GlobalSecretList(session.Pagination(c))
secretService := server.Config.Services.Manager.SecretService()
list, err := secretService.GlobalSecretList(session.Pagination(c))

Check warning on line 39 in server/api/global_secret.go

View check run for this annotation

Codecov / codecov/patch

server/api/global_secret.go#L38-L39

Added lines #L38 - L39 were not covered by tests
if err != nil {
c.String(http.StatusInternalServerError, "Error getting global secret list. %s", err)
return
Expand All @@ -59,7 +60,8 @@
// @Param secret path string true "the secret's name"
func GetGlobalSecret(c *gin.Context) {
name := c.Param("secret")
secret, err := server.Config.Services.Secrets.GlobalSecretFind(name)
secretService := server.Config.Services.Manager.SecretService()
secret, err := secretService.GlobalSecretFind(name)

Check warning on line 64 in server/api/global_secret.go

View check run for this annotation

Codecov / codecov/patch

server/api/global_secret.go#L63-L64

Added lines #L63 - L64 were not covered by tests
if err != nil {
handleDBError(c, err)
return
Expand Down Expand Up @@ -92,7 +94,9 @@
c.String(http.StatusBadRequest, "Error inserting global secret. %s", err)
return
}
if err := server.Config.Services.Secrets.GlobalSecretCreate(secret); err != nil {

secretService := server.Config.Services.Manager.SecretService()
if err := secretService.GlobalSecretCreate(secret); err != nil {

Check warning on line 99 in server/api/global_secret.go

View check run for this annotation

Codecov / codecov/patch

server/api/global_secret.go#L98-L99

Added lines #L98 - L99 were not covered by tests
c.String(http.StatusInternalServerError, "Error inserting global secret %q. %s", in.Name, err)
return
}
Expand All @@ -119,7 +123,8 @@
return
}

secret, err := server.Config.Services.Secrets.GlobalSecretFind(name)
secretService := server.Config.Services.Manager.SecretService()
secret, err := secretService.GlobalSecretFind(name)

Check warning on line 127 in server/api/global_secret.go

View check run for this annotation

Codecov / codecov/patch

server/api/global_secret.go#L126-L127

Added lines #L126 - L127 were not covered by tests
if err != nil {
handleDBError(c, err)
return
Expand All @@ -138,7 +143,8 @@
c.String(http.StatusBadRequest, "Error updating global secret. %s", err)
return
}
if err := server.Config.Services.Secrets.GlobalSecretUpdate(secret); err != nil {

if err := secretService.GlobalSecretUpdate(secret); err != nil {

Check warning on line 147 in server/api/global_secret.go

View check run for this annotation

Codecov / codecov/patch

server/api/global_secret.go#L147

Added line #L147 was not covered by tests
c.String(http.StatusInternalServerError, "Error updating global secret %q. %s", in.Name, err)
return
}
Expand All @@ -156,7 +162,8 @@
// @Param secret path string true "the secret's name"
func DeleteGlobalSecret(c *gin.Context) {
name := c.Param("secret")
if err := server.Config.Services.Secrets.GlobalSecretDelete(name); err != nil {
secretService := server.Config.Services.Manager.SecretService()
if err := secretService.GlobalSecretDelete(name); err != nil {

Check warning on line 166 in server/api/global_secret.go

View check run for this annotation

Codecov / codecov/patch

server/api/global_secret.go#L165-L166

Added lines #L165 - L166 were not covered by tests
handleDBError(c, err)
return
}
Expand Down
19 changes: 13 additions & 6 deletions server/api/org_secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@
return
}

secret, err := server.Config.Services.Secrets.OrgSecretFind(orgID, name)
secretService := server.Config.Services.Manager.SecretService()
secret, err := secretService.OrgSecretFind(orgID, name)

Check warning on line 48 in server/api/org_secret.go

View check run for this annotation

Codecov / codecov/patch

server/api/org_secret.go#L47-L48

Added lines #L47 - L48 were not covered by tests
if err != nil {
handleDBError(c, err)
return
Expand All @@ -70,7 +71,8 @@
return
}

list, err := server.Config.Services.Secrets.OrgSecretList(orgID, session.Pagination(c))
secretService := server.Config.Services.Manager.SecretService()
list, err := secretService.OrgSecretList(orgID, session.Pagination(c))

Check warning on line 75 in server/api/org_secret.go

View check run for this annotation

Codecov / codecov/patch

server/api/org_secret.go#L74-L75

Added lines #L74 - L75 were not covered by tests
if err != nil {
c.String(http.StatusInternalServerError, "Error getting secret list for %q. %s", orgID, err)
return
Expand Down Expand Up @@ -116,7 +118,9 @@
c.String(http.StatusUnprocessableEntity, "Error inserting org %q secret. %s", orgID, err)
return
}
if err := server.Config.Services.Secrets.OrgSecretCreate(orgID, secret); err != nil {

secretService := server.Config.Services.Manager.SecretService()
if err := secretService.OrgSecretCreate(orgID, secret); err != nil {

Check warning on line 123 in server/api/org_secret.go

View check run for this annotation

Codecov / codecov/patch

server/api/org_secret.go#L122-L123

Added lines #L122 - L123 were not covered by tests
c.String(http.StatusInternalServerError, "Error inserting org %q secret %q. %s", orgID, in.Name, err)
return
}
Expand Down Expand Up @@ -149,7 +153,8 @@
return
}

secret, err := server.Config.Services.Secrets.OrgSecretFind(orgID, name)
secretService := server.Config.Services.Manager.SecretService()
secret, err := secretService.OrgSecretFind(orgID, name)

Check warning on line 157 in server/api/org_secret.go

View check run for this annotation

Codecov / codecov/patch

server/api/org_secret.go#L156-L157

Added lines #L156 - L157 were not covered by tests
if err != nil {
handleDBError(c, err)
return
Expand All @@ -168,7 +173,8 @@
c.String(http.StatusUnprocessableEntity, "Error updating org %q secret. %s", orgID, err)
return
}
if err := server.Config.Services.Secrets.OrgSecretUpdate(orgID, secret); err != nil {

if err := secretService.OrgSecretUpdate(orgID, secret); err != nil {

Check warning on line 177 in server/api/org_secret.go

View check run for this annotation

Codecov / codecov/patch

server/api/org_secret.go#L177

Added line #L177 was not covered by tests
c.String(http.StatusInternalServerError, "Error updating org %q secret %q. %s", orgID, in.Name, err)
return
}
Expand All @@ -193,7 +199,8 @@
return
}

if err := server.Config.Services.Secrets.OrgSecretDelete(orgID, name); err != nil {
secretService := server.Config.Services.Manager.SecretService()
if err := secretService.OrgSecretDelete(orgID, name); err != nil {

Check warning on line 203 in server/api/org_secret.go

View check run for this annotation

Codecov / codecov/patch

server/api/org_secret.go#L202-L203

Added lines #L202 - L203 were not covered by tests
handleDBError(c, err)
return
}
Expand Down
8 changes: 1 addition & 7 deletions server/api/pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -434,13 +434,7 @@
}
}

netrc, err := server.Config.Services.Forge.Netrc(user, repo)
if err != nil {
handlePipelineErr(c, err)
return
}

newpipeline, err := pipeline.Restart(c, _store, pl, user, repo, envs, netrc)
newpipeline, err := pipeline.Restart(c, _store, pl, user, repo, envs)

Check warning on line 437 in server/api/pipeline.go

View check run for this annotation

Codecov / codecov/patch

server/api/pipeline.go#L437

Added line #L437 was not covered by tests
if err != nil {
handlePipelineErr(c, err)
} else {
Expand Down
Loading