Various enhancements in configuration (#1645)

- backends: move to cli flags instead of os.Getenv
- ssh: support 2fa with key and password
- allow to set grpc jwt secret (solves todo)
- allow to set default and max timeout (solves todo)

Closes https://github.com/woodpecker-ci/woodpecker/issues/896
Closes https://github.com/woodpecker-ci/woodpecker/issues/1131
This commit is contained in:
qwerty287 2023-03-19 20:24:43 +01:00 committed by GitHub
parent 56e6639396
commit f582ad3159
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 221 additions and 104 deletions

View file

@ -203,14 +203,15 @@ func execWithAxis(c *cli.Context, file, repoPath string, axis matrix.Axis) error
return err
}
backend.Init(context.WithValue(c.Context, types.CliContext, c))
backendCtx := context.WithValue(c.Context, types.CliContext, c)
backend.Init(backendCtx)
engine, err := backend.FindEngine(c.String("backend-engine"))
engine, err := backend.FindEngine(backendCtx, c.String("backend-engine"))
if err != nil {
return err
}
if err = engine.Load(); err != nil {
if err = engine.Load(backendCtx); err != nil {
return err
}

View file

@ -268,7 +268,50 @@ var flags = []cli.Flag{
Name: "env",
},
// TODO: add flags of backends
// backend docker
&cli.BoolFlag{
EnvVars: []string{"WOODPECKER_BACKEND_DOCKER_ENABLE_IPV6"},
Name: "backend-docker-ipv6",
Usage: "backend docker enable IPV6",
Value: false,
},
&cli.StringFlag{
EnvVars: []string{"WOODPECKER_BACKEND_DOCKER_NETWORK"},
Name: "backend-docker-network",
Usage: "backend docker network",
},
&cli.StringFlag{
EnvVars: []string{"WOODPECKER_BACKEND_DOCKER_VOLUMES"},
Name: "backend-docker-volumes",
Usage: "backend docker volumes (comma separated)",
},
// backend ssh
&cli.StringFlag{
EnvVars: []string{"WOODPECKER_BACKEND_SSH_ADDRESS"},
Name: "backend-ssh-address",
Usage: "backend ssh address",
},
&cli.StringFlag{
EnvVars: []string{"WOODPECKER_BACKEND_SSH_USER"},
Name: "backend-ssh-user",
Usage: "backend ssh user",
},
&cli.StringFlag{
EnvVars: []string{"WOODPECKER_BACKEND_SSH_KEY"},
Name: "backend-ssh-key",
Usage: "backend ssh key file",
},
&cli.StringFlag{
EnvVars: []string{"WOODPECKER_BACKEND_SSH_KEY_PASSWORD"},
Name: "backend-ssh-key-password",
Usage: "backend ssh key password",
},
&cli.StringFlag{
EnvVars: []string{"WOODPECKER_BACKEND_SSH_PASSWORD"},
Name: "backend-ssh-password",
Usage: "backend ssh password",
},
// backend k8s
&cli.StringFlag{

View file

@ -154,14 +154,15 @@ func loop(c *cli.Context) error {
sigterm.Set()
})
backend.Init(context.WithValue(ctx, types.CliContext, c))
backendCtx := context.WithValue(ctx, types.CliContext, c)
backend.Init(backendCtx)
var wg sync.WaitGroup
parallel := c.Int("max-workflows")
wg.Add(parallel)
// new engine
engine, err := backend.FindEngine(c.String("backend-engine"))
engine, err := backend.FindEngine(backendCtx, c.String("backend-engine"))
if err != nil {
log.Error().Err(err).Msgf("cannot find backend engine '%s'", c.String("backend-engine"))
return err
@ -195,7 +196,7 @@ func loop(c *cli.Context) error {
defer wg.Done()
// load engine (e.g. init api client)
err = engine.Load()
err = engine.Load(backendCtx)
if err != nil {
log.Error().Err(err).Msg("cannot load backend engine")
return

View file

@ -108,7 +108,50 @@ var flags = []cli.Flag{
Value: "auto-detect",
},
// TODO: add flags of backends
// backend docker
&cli.BoolFlag{
EnvVars: []string{"WOODPECKER_BACKEND_DOCKER_ENABLE_IPV6"},
Name: "backend-docker-ipv6",
Usage: "backend docker enable IPV6",
Value: false,
},
&cli.StringFlag{
EnvVars: []string{"WOODPECKER_BACKEND_DOCKER_NETWORK"},
Name: "backend-docker-network",
Usage: "backend docker network",
},
&cli.StringFlag{
EnvVars: []string{"WOODPECKER_BACKEND_DOCKER_VOLUMES"},
Name: "backend-docker-volumes",
Usage: "backend docker volumes (comma separated)",
},
// backend ssh
&cli.StringFlag{
EnvVars: []string{"WOODPECKER_BACKEND_SSH_ADDRESS"},
Name: "backend-ssh-address",
Usage: "backend ssh address",
},
&cli.StringFlag{
EnvVars: []string{"WOODPECKER_BACKEND_SSH_USER"},
Name: "backend-ssh-user",
Usage: "backend ssh user",
},
&cli.StringFlag{
EnvVars: []string{"WOODPECKER_BACKEND_SSH_KEY"},
Name: "backend-ssh-key",
Usage: "backend ssh key file",
},
&cli.StringFlag{
EnvVars: []string{"WOODPECKER_BACKEND_SSH_KEY_PASSWORD"},
Name: "backend-ssh-key-password",
Usage: "backend ssh key password",
},
&cli.StringFlag{
EnvVars: []string{"WOODPECKER_BACKEND_SSH_PASSWORD"},
Name: "backend-ssh-password",
Usage: "backend ssh password",
},
// backend k8s
&cli.StringFlag{

View file

@ -77,6 +77,12 @@ var flags = []cli.Flag{
Usage: "grpc address",
Value: ":9000",
},
&cli.StringFlag{
EnvVars: []string{"WOODPECKER_GRPC_SECRET"},
Name: "grpc-secret",
Usage: "grpc jwt secret",
Value: "secret",
},
&cli.StringFlag{
EnvVars: []string{"WOODPECKER_METRICS_SERVER_ADDR"},
Name: "metrics-server-addr",
@ -120,6 +126,18 @@ var flags = []cli.Flag{
Usage: "The default docker image to be used when cloning the repo",
Value: constant.DefaultCloneImage,
},
&cli.Int64Flag{
EnvVars: []string{"WOODPECKER_DEFAULT_PIPELINE_TIMEOUT"},
Name: "default-pipeline-timeout",
Usage: "The default time in minutes for a repo in minutes before a pipeline gets killed",
Value: 60,
},
&cli.Int64Flag{
EnvVars: []string{"WOODPECKER_MAX_PIPELINE_TIMEOUT"},
Name: "max-pipeline-timeout",
Usage: "The maximum time in minutes you can set in the repo settings before a pipeline gets killed",
Value: 120,
},
&cli.StringFlag{
EnvVars: []string{"WOODPECKER_DOCS"},
Name: "docs",

View file

@ -135,7 +135,7 @@ func run(c *cli.Context) error {
return err
}
jwtSecret := "secret" // TODO: make configurable
jwtSecret := c.String("grpc-secret")
jwtManager := woodpeckerGrpcServer.NewJWTManager(jwtSecret)
authorizer := woodpeckerGrpcServer.NewAuthorizer(jwtManager)
@ -321,6 +321,8 @@ func setupEvilGlobals(c *cli.Context, v store.Store, f forge.Forge) {
events = append(events, model.WebhookEvent(v))
}
server.Config.Pipeline.DefaultCancelPreviousPipelineEvents = events
server.Config.Pipeline.DefaultTimeout = c.Int64("default-pipeline-timeout")
server.Config.Pipeline.MaxTimeout = c.Int64("max-pipeline-timeout")
// limits
server.Config.Pipeline.Limits.MemSwapLimit = c.Int64("limit-mem-swap")

View file

@ -160,6 +160,11 @@ Automatically generates an SSL certificate using Let's Encrypt, and configures t
Configures the gRPC listener port.
### `WOODPECKER_GRPC_SECRET`
> Default: `secret`
Configures the gRPC JWT secret.
### `WOODPECKER_METRICS_SERVER_ADDR`
> Default: empty
@ -213,6 +218,16 @@ List of event names that will be canceled when a new pipeline for the same conte
The default docker image to be used when cloning the repo
### `WOODPECKER_DEFAULT_PIPELINE_TIMEOUT`
> 60 (minutes)
The default time for a repo in minutes before a pipeline gets killed
### `WOODPECKER_MAX_PIPELINE_TIMEOUT`
> 120 (minutes)
The maximum time in minutes you can set in the repo settings before a pipeline gets killed
### `WOODPECKER_SESSION_EXPIRES`
> Default: `72h`

View file

@ -30,20 +30,20 @@ func Init(ctx context.Context) {
}
}
func FindEngine(engineName string) (types.Engine, error) {
func FindEngine(ctx context.Context, engineName string) (types.Engine, error) {
if engineName == "auto-detect" {
for _, engine := range engines {
if engine.IsAvailable() {
if engine.IsAvailable(ctx) {
return engine, nil
}
}
return nil, fmt.Errorf("Can't detect an available backend engine")
return nil, fmt.Errorf("can't detect an available backend engine")
}
engine, ok := enginesByName[engineName]
if !ok {
return nil, fmt.Errorf("Backend engine '%s' not found", engineName)
return nil, fmt.Errorf("backend engine '%s' not found", engineName)
}
return engine, nil

View file

@ -18,7 +18,6 @@ import (
"context"
"io"
"os"
"strconv"
"strings"
"github.com/docker/docker/api/types"
@ -29,6 +28,7 @@ import (
"github.com/moby/moby/pkg/stdcopy"
"github.com/moby/term"
"github.com/rs/zerolog/log"
"github.com/urfave/cli/v2"
backend "github.com/woodpecker-ci/woodpecker/pipeline/backend/types"
"github.com/woodpecker-ci/woodpecker/shared/utils"
@ -41,9 +41,6 @@ type docker struct {
volumes []string
}
// make sure docker implements Engine
var _ backend.Engine = &docker{}
// New returns a new Docker Engine.
func New() backend.Engine {
return &docker{
@ -55,7 +52,7 @@ func (e *docker) Name() string {
return "docker"
}
func (e *docker) IsAvailable() bool {
func (e *docker) IsAvailable(context.Context) bool {
if os.Getenv("DOCKER_HOST") != "" {
return true
}
@ -64,18 +61,22 @@ func (e *docker) IsAvailable() bool {
}
// Load new client for Docker Engine using environment variables.
func (e *docker) Load() error {
cli, err := client.NewClientWithOpts(client.FromEnv)
func (e *docker) Load(ctx context.Context) error {
cl, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
return err
}
e.client = cli
e.client = cl
e.enableIPv6, _ = strconv.ParseBool(os.Getenv("WOODPECKER_BACKEND_DOCKER_ENABLE_IPV6"))
c, ok := ctx.Value(backend.CliContext).(*cli.Context)
if !ok {
return backend.ErrNoCliContextFound
}
e.enableIPv6 = c.Bool("backend-docker-ipv6")
e.network = os.Getenv("WOODPECKER_BACKEND_DOCKER_NETWORK")
e.network = c.String("backend-docker-network")
volumes := strings.Split(os.Getenv("WOODPECKER_BACKEND_DOCKER_VOLUMES"), ",")
volumes := strings.Split(c.String("backend-docker-volumes"), ",")
e.volumes = make([]string, 0, len(volumes))
// Validate provided volume definitions
for _, v := range volumes {

View file

@ -2,7 +2,6 @@ package kubernetes
import (
"context"
std_errors "errors"
"fmt"
"io"
"os"
@ -27,10 +26,7 @@ import (
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
)
var (
ErrNoCliContextFound = std_errors.New("No CliContext in context found.")
noContext = context.Background()
)
var noContext = context.Background()
type kube struct {
ctx context.Context
@ -75,7 +71,7 @@ func configFromCliContext(ctx context.Context) (*Config, error) {
}
}
return nil, ErrNoCliContextFound
return nil, types.ErrNoCliContextFound
}
// New returns a new Kubernetes Engine.
@ -89,12 +85,12 @@ func (e *kube) Name() string {
return "kubernetes"
}
func (e *kube) IsAvailable() bool {
func (e *kube) IsAvailable(context.Context) bool {
host := os.Getenv("KUBERNETES_SERVICE_HOST")
return len(host) > 0
}
func (e *kube) Load() error {
func (e *kube) Load(context.Context) error {
config, err := configFromCliContext(e.ctx)
if err != nil {
return err

View file

@ -47,9 +47,6 @@ type local struct {
workingdir string
}
// make sure local implements Engine
var _ types.Engine = &local{}
// New returns a new local Engine.
func New() types.Engine {
return &local{}
@ -59,11 +56,11 @@ func (e *local) Name() string {
return "local"
}
func (e *local) IsAvailable() bool {
func (e *local) IsAvailable(context.Context) bool {
return true
}
func (e *local) Load() error {
func (e *local) Load(context.Context) error {
dir, err := os.MkdirTemp("", "woodpecker-local-*")
e.workingdir = dir
return err

View file

@ -2,12 +2,11 @@ package ssh
import (
"context"
"fmt"
"io"
"os"
"strings"
"github.com/melbahja/goph"
"github.com/urfave/cli/v2"
"github.com/woodpecker-ci/woodpecker/pipeline/backend/common"
"github.com/woodpecker-ci/woodpecker/pipeline/backend/types"
@ -29,9 +28,6 @@ func (c readCloser) Close() error {
return nil
}
// make sure local implements Engine
var _ types.Engine = &ssh{}
// New returns a new ssh Engine.
func New() types.Engine {
return &ssh{}
@ -41,11 +37,12 @@ func (e *ssh) Name() string {
return "ssh"
}
func (e *ssh) IsAvailable() bool {
return os.Getenv("WOODPECKER_BACKEND_SSH_KEY") != "" || os.Getenv("WOODPECKER_BACKEND_SSH_PASSWORD") != ""
func (e *ssh) IsAvailable(ctx context.Context) bool {
c, ok := ctx.Value(types.CliContext).(*cli.Context)
return ok && c.String("backend-ssh-address") != "" && c.String("backend-ssh-user") != "" && (c.String("backend-ssh-key") != "" || c.String("backend-ssh-password") != "")
}
func (e *ssh) Load() error {
func (e *ssh) Load(ctx context.Context) error {
cmd, err := e.client.Command("/bin/env", "mktemp", "-d", "-p", "/tmp", "woodpecker-ssh-XXXXXXXXXX")
if err != nil {
return err
@ -57,23 +54,22 @@ func (e *ssh) Load() error {
}
e.workingdir = string(dir)
address := os.Getenv("WOODPECKER_BACKEND_SSH_ADDRESS")
if address == "" {
return fmt.Errorf("missing SSH address")
}
user := os.Getenv("WOODPECKER_BACKEND_SSH_USER")
if user == "" {
return fmt.Errorf("missing SSH user")
c, ok := ctx.Value(types.CliContext).(*cli.Context)
if !ok {
return types.ErrNoCliContextFound
}
address := c.String("backend-ssh-address")
user := c.String("backend-ssh-user")
var auth goph.Auth
if file, has := os.LookupEnv("WOODPECKER_BACKEND_SSH_KEY"); has {
var err error
auth, err = goph.Key(file, os.Getenv("WOODPECKER_BACKEND_SSH_KEY_PASSWORD"))
if file := c.String("backend-ssh-key"); file != "" {
keyAuth, err := goph.Key(file, c.String("backend-ssh-key-password"))
if err != nil {
return err
}
} else {
auth = goph.Password(os.Getenv("WOODPECKER_BACKEND_SSH_PASSWORD"))
auth = append(auth, keyAuth...)
}
if password := c.String("backend-ssh-password"); password != "" {
auth = append(auth, goph.Password(password)...)
}
client, err := goph.New(user, address, auth)
if err != nil {
@ -91,7 +87,7 @@ func (e *ssh) Setup(_ context.Context, _ *types.Config) error {
// Exec the pipeline step.
func (e *ssh) Exec(ctx context.Context, step *types.Step) error {
// Get environment variables
command := []string{}
var command []string
for a, b := range step.Environment {
if a != "HOME" && a != "SHELL" { // Don't override $HOME and $SHELL
command = append(command, a+"="+b)

View file

@ -9,8 +9,8 @@ import (
// to create and manage container resources.
type Engine interface {
Name() string
IsAvailable() bool
Load() error
IsAvailable(context.Context) bool
Load(context.Context) error
// Setup the pipeline environment.
Setup(context.Context, *Config) error

View file

@ -0,0 +1,5 @@
package types
import "errors"
var ErrNoCliContextFound = errors.New("no CliContext in context found")

View file

@ -7,10 +7,11 @@
package proto
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
)
const (
@ -1326,31 +1327,33 @@ func file_woodpecker_proto_rawDescGZIP() []byte {
return file_woodpecker_proto_rawDescData
}
var file_woodpecker_proto_msgTypes = make([]protoimpl.MessageInfo, 22)
var file_woodpecker_proto_goTypes = []interface{}{
(*File)(nil), // 0: proto.File
(*State)(nil), // 1: proto.State
(*Line)(nil), // 2: proto.Line
(*Filter)(nil), // 3: proto.Filter
(*Pipeline)(nil), // 4: proto.Pipeline
(*NextRequest)(nil), // 5: proto.NextRequest
(*NextReply)(nil), // 6: proto.NextReply
(*InitRequest)(nil), // 7: proto.InitRequest
(*WaitRequest)(nil), // 8: proto.WaitRequest
(*DoneRequest)(nil), // 9: proto.DoneRequest
(*ExtendRequest)(nil), // 10: proto.ExtendRequest
(*UploadRequest)(nil), // 11: proto.UploadRequest
(*UpdateRequest)(nil), // 12: proto.UpdateRequest
(*LogRequest)(nil), // 13: proto.LogRequest
(*Empty)(nil), // 14: proto.Empty
(*ReportHealthRequest)(nil), // 15: proto.ReportHealthRequest
(*RegisterAgentRequest)(nil), // 16: proto.RegisterAgentRequest
(*RegisterAgentResponse)(nil), // 17: proto.RegisterAgentResponse
(*AuthRequest)(nil), // 18: proto.AuthRequest
(*AuthReply)(nil), // 19: proto.AuthReply
nil, // 20: proto.File.MetaEntry
nil, // 21: proto.Filter.LabelsEntry
}
var (
file_woodpecker_proto_msgTypes = make([]protoimpl.MessageInfo, 22)
file_woodpecker_proto_goTypes = []interface{}{
(*File)(nil), // 0: proto.File
(*State)(nil), // 1: proto.State
(*Line)(nil), // 2: proto.Line
(*Filter)(nil), // 3: proto.Filter
(*Pipeline)(nil), // 4: proto.Pipeline
(*NextRequest)(nil), // 5: proto.NextRequest
(*NextReply)(nil), // 6: proto.NextReply
(*InitRequest)(nil), // 7: proto.InitRequest
(*WaitRequest)(nil), // 8: proto.WaitRequest
(*DoneRequest)(nil), // 9: proto.DoneRequest
(*ExtendRequest)(nil), // 10: proto.ExtendRequest
(*UploadRequest)(nil), // 11: proto.UploadRequest
(*UpdateRequest)(nil), // 12: proto.UpdateRequest
(*LogRequest)(nil), // 13: proto.LogRequest
(*Empty)(nil), // 14: proto.Empty
(*ReportHealthRequest)(nil), // 15: proto.ReportHealthRequest
(*RegisterAgentRequest)(nil), // 16: proto.RegisterAgentRequest
(*RegisterAgentResponse)(nil), // 17: proto.RegisterAgentResponse
(*AuthRequest)(nil), // 18: proto.AuthRequest
(*AuthReply)(nil), // 19: proto.AuthReply
nil, // 20: proto.File.MetaEntry
nil, // 21: proto.Filter.LabelsEntry
}
)
var file_woodpecker_proto_depIdxs = []int32{
20, // 0: proto.File.meta:type_name -> proto.File.MetaEntry
21, // 1: proto.Filter.labels:type_name -> proto.Filter.LabelsEntry

View file

@ -32,12 +32,6 @@ import (
"github.com/woodpecker-ci/woodpecker/shared/token"
)
// TODO: make it set system wide via environment variables
const (
defaultTimeout int64 = 60 // 1 hour default pipeline time
maxTimeout int64 = defaultTimeout * 2
)
func PostRepo(c *gin.Context) {
forge := server.Config.Services.Forge
_store := store.FromContext(c)
@ -62,9 +56,9 @@ func PostRepo(c *gin.Context) {
}
if repo.Timeout == 0 {
repo.Timeout = defaultTimeout
} else if repo.Timeout > maxTimeout {
repo.Timeout = maxTimeout
repo.Timeout = server.Config.Pipeline.DefaultTimeout
} else if repo.Timeout > server.Config.Pipeline.MaxTimeout {
repo.Timeout = server.Config.Pipeline.MaxTimeout
}
if repo.Hash == "" {
@ -126,8 +120,8 @@ func PatchRepo(c *gin.Context) {
return
}
if in.Timeout != nil && *in.Timeout > maxTimeout && !user.Admin {
c.String(http.StatusForbidden, fmt.Sprintf("Timeout is not allowed to be higher than max timeout (%dmin)", maxTimeout))
if in.Timeout != nil && *in.Timeout > server.Config.Pipeline.MaxTimeout && !user.Admin {
c.String(http.StatusForbidden, fmt.Sprintf("Timeout is not allowed to be higher than max timeout (%dmin)", server.Config.Pipeline.MaxTimeout))
}
if in.IsTrusted != nil && *in.IsTrusted != repo.IsTrusted && !user.Admin {
log.Trace().Msgf("user '%s' wants to make repo trusted without being an instance admin ", user.Login)

View file

@ -81,6 +81,8 @@ var Config = struct {
Volumes []string
Networks []string
Privileged []string
DefaultTimeout int64
MaxTimeout int64
}
FlatPermissions bool // TODO(485) temporary workaround to not hit api rate limits
}{}

View file

@ -34,7 +34,7 @@ func (_m *Forge) Activate(ctx context.Context, u *model.User, r *model.Repo, lin
}
// Auth provides a mock function with given fields: ctx, token, secret
func (_m *Forge) Auth(ctx context.Context, token string, secret string) (string, error) {
func (_m *Forge) Auth(ctx context.Context, token, secret string) (string, error) {
ret := _m.Called(ctx, token, secret)
var r0 string
@ -353,7 +353,7 @@ func (_m *Forge) PullRequests(ctx context.Context, u *model.User, r *model.Repo,
}
// Repo provides a mock function with given fields: ctx, u, remoteID, owner, name
func (_m *Forge) Repo(ctx context.Context, u *model.User, remoteID model.ForgeRemoteID, owner string, name string) (*model.Repo, error) {
func (_m *Forge) Repo(ctx context.Context, u *model.User, remoteID model.ForgeRemoteID, owner, name string) (*model.Repo, error) {
ret := _m.Called(ctx, u, remoteID, owner, name)
var r0 *model.Repo

View file

@ -406,7 +406,7 @@ func (_m *Store) CronList(_a0 *model.Repo) ([]*model.Cron, error) {
}
// CronListNextExecute provides a mock function with given fields: _a0, _a1
func (_m *Store) CronListNextExecute(_a0 int64, _a1 int64) ([]*model.Cron, error) {
func (_m *Store) CronListNextExecute(_a0, _a1 int64) ([]*model.Cron, error) {
ret := _m.Called(_a0, _a1)
var r0 []*model.Cron
@ -618,7 +618,7 @@ func (_m *Store) GetPipeline(_a0 int64) (*model.Pipeline, error) {
}
// GetPipelineCommit provides a mock function with given fields: _a0, _a1, _a2
func (_m *Store) GetPipelineCommit(_a0 *model.Repo, _a1 string, _a2 string) (*model.Pipeline, error) {
func (_m *Store) GetPipelineCommit(_a0 *model.Repo, _a1, _a2 string) (*model.Pipeline, error) {
ret := _m.Called(_a0, _a1, _a2)
var r0 *model.Pipeline
@ -1210,7 +1210,7 @@ func (_m *Store) Migrate() error {
}
// OrgSecretFind provides a mock function with given fields: _a0, _a1
func (_m *Store) OrgSecretFind(_a0 string, _a1 string) (*model.Secret, error) {
func (_m *Store) OrgSecretFind(_a0, _a1 string) (*model.Secret, error) {
ret := _m.Called(_a0, _a1)
var r0 *model.Secret
@ -1676,7 +1676,7 @@ func (_m *Store) ServerConfigGet(_a0 string) (string, error) {
}
// ServerConfigSet provides a mock function with given fields: _a0, _a1
func (_m *Store) ServerConfigSet(_a0 string, _a1 string) error {
func (_m *Store) ServerConfigSet(_a0, _a1 string) error {
ret := _m.Called(_a0, _a1)
var r0 error