Compare commits

...

29 Commits

Author SHA1 Message Date
Alexander Matyushentsev
e4d0bd3926 Take into account number of unavailable replicas to decided if deployment is healthy or not (#270)
* Take into account number of unavailable replicas to decided if deployment is healthy or not

* Run one controller for all e2e tests to reduce tests duration

* Apply reviewer notes: use logic from kubectl/rollout_status.go to check deployment health
2018-06-07 11:09:38 -07:00
Jesse Suen
18dc82d14d Remove hard requirement of initializing OIDC app during server startup (resolves #272) 2018-06-07 02:12:36 -07:00
Jesse Suen
e720abb58b Bump version to v0.4.7 2018-06-06 14:28:14 -07:00
Jesse Suen
a2e9a9ee49 Repo names containing underscores were not being accepted (resolves #258) 2018-06-06 14:27:41 -07:00
Jesse Suen
cf3776903d Retry argocd app wait connection errors from EOF watch. Show detailed state changes 2018-06-06 10:45:59 -07:00
Jesse Suen
3acca5095e Add argocd app unset command to unset parameter overrides. Bump version to v0.4.5 2018-05-31 02:55:35 -07:00
Jesse Suen
5a62286127 Cookie token was not parsed properly when mixed with other site cookies 2018-05-31 02:37:15 -07:00
Jesse Suen
5452aff0be Add ability to show parameters and overrides in CLI (resolves #240) (#247) 2018-05-30 15:41:11 -07:00
Andrew Merenbach
0f4f1262af Add Events API endpoint (#237)
* Flesh out initial endpoint

* Update generated code

* Update prototype for list of events

* Update endpoints

* Update initialization of app service

* Use proper interfaces here

* Use event list

* Use preexisting events list struct

* Simplify initial architecture significantly

* Rename ListDirResponse => FileList, thanks @jessesuen

* Rm unneeded error check

* Narrow down event query, thanks @alexmt

* Use tests to fix bug

* Don't reinvent the wheel

* Rm comment

* Add Uid field, thanks @alexmt @jessesuen

* Update generated files

* Support external clusters, thanks @alexmt

* Filter by proper namespace
2018-05-30 15:30:58 -07:00
Jesse Suen
4e7f68ccba Update version to 0.4.4 2018-05-30 14:03:16 -07:00
Alexander Matyushentsev
96c05babe0 Issue #238 - add upsert flag to 'argocd app create' command (#245) 2018-05-30 13:49:20 -07:00
Andrew Merenbach
6b78cddb19 Add repo browsing endpoint (#229)
* Add skeleton ListDir endpoint

* Update proto with path field

* Add first working file retrieval

* Update git client to support paths

* Update proto file

* Flesh out prototype code for retrieving files

* Create repo server with repoclientset

* Rm unneeded test code

* Update generated code

* Use HTTP queries instead of URL components

* Error out properly

* Add missing fixture test

* Rm commented endpoint, thanks @alexmt

* Skip invalid app specs
2018-05-24 19:09:52 -07:00
Alexander Matyushentsev
12596ff936 Issue #233 - Controller does not persist rollback operation result (#234) 2018-05-24 10:50:33 -07:00
Jesse Suen
a240f1b2b9 Bump version to 0.5.0 2018-05-23 11:18:50 -07:00
Jesse Suen
f6da19672e Support subscribing to settings updates and auto-restart of dex and API server (resolves #174) (#227) 2018-05-23 10:01:07 -07:00
Jesse Suen
e81d30be9b Update getting_started.md to point to v0.4.3 2018-05-22 15:02:51 -07:00
Alexander Matyushentsev
13b090e3bd Issue #147 - App sync frequently fails due to concurrent app modification (#226) 2018-05-22 09:43:17 -07:00
Alexander Matyushentsev
d0479e6ddc Issue # 223 - Remove app finalizers during e2e fixture teardown (#225) 2018-05-22 09:23:42 -07:00
Andrew Merenbach
1432827006 Add error fields to cluster/repo, shell output (#200)
* Add error fields to cluster/repo, shell output

* Add missing format strings, thanks @alexmt

* Rename Error => Message

* Set JSON keys, thanks @jessesuen

* Update generated code
2018-05-22 08:48:24 -07:00
Jesse Suen
89bf4eac71 Bump version to 0.4.3 2018-05-21 15:27:01 -07:00
Jesse Suen
07aac0bdae Move local branch deletion as part of git Reset() (resolves #185) (#222) 2018-05-21 15:21:09 -07:00
Andrew Merenbach
61220b8d0d Fix exit code for app wait (#219) 2018-05-21 10:17:10 -07:00
Jesse Suen
4e470aaf09 Remove context name prompt during login. (#218)
* Show URL in argocd app get
* Rename force flag to cascade in argocd app delete
* Remove interactive context name prompt during login which broke login automation
* Rename apiclient.ServerClient to Client
2018-05-21 01:10:02 -07:00
Jesse Suen
76922b620b Update version to 0.4.2 2018-05-21 01:05:47 -07:00
Andrew Merenbach
ac0f623eda Add argocd app wait command (#216)
* Update CLI, server for wait request

* Update generated code

* Remove generated code

* Add timeout function, and use it

* Get first working prototype

* Properly fail and print success/fail messages

* Add missing reference pointer

* Remove unreachable code

* Show current state of all checks

* Print atypical health output status now

* Update short command description, thanks @jessesuen

* Use server-side watch command

* Use watch API

* Clean up wait function to use new API better

* Rm unused const, satisfy linter on caps names

* Rename channel and set direction

* Add infinite timeout by default
2018-05-18 11:50:01 -07:00
Jesse Suen
afd5450882 Bump version to v0.4.1 2018-05-17 18:31:46 -07:00
Jesse Suen
c17266fc21 Add documentation on how to configure SSO and Webhooks 2018-05-17 18:28:04 -07:00
Andrew Merenbach
f62c825495 Manifest endpoint (#207)
* Add manifests endpoint

* Draft app.go changes

* Fix some issues with imports, symbols, args

* Reduce duplication between components

* Revert "Reduce duplication between components"

This reverts commit 87b166885d53778683bc0a0a826671c2c67dc082.

* Add ManifestQuery type, thanks @jessesuen

* Add required/optional flags to protobuf

* Update generated code

* Add missing pointer dereferences

* Default to app target revision, thanks @jessesuen

* Account for nil
2018-05-17 16:33:04 -07:00
Jesse Suen
45f44dd4be Add v0.4.0 changelog 2018-05-17 03:10:41 -07:00
49 changed files with 4007 additions and 562 deletions

14
CHANGELOG.md Normal file
View File

@@ -0,0 +1,14 @@
# Changelog
## v0.4.0 (2018-05-17)
+ SSO Integration
+ GitHub Webhook
+ Add application health status
+ Sync/Rollback/Delete is asynchronously handled by controller
* Refactor CRUD operation on clusters and repos
* Sync will always perform kubectl apply
* Synced Status considers last-applied-configuration annotatoin
* Server & namespace are mandatory fields (still inferred from app.yaml)
* Manifests are memoized in repo server
- Fix connection timeouts to SSH repos

5
Gopkg.lock generated
View File

@@ -747,6 +747,8 @@
"discovery/fake",
"dynamic",
"dynamic/fake",
"informers/core/v1",
"informers/internalinterfaces",
"kubernetes",
"kubernetes/fake",
"kubernetes/scheme",
@@ -806,6 +808,7 @@
"kubernetes/typed/storage/v1alpha1/fake",
"kubernetes/typed/storage/v1beta1",
"kubernetes/typed/storage/v1beta1/fake",
"listers/core/v1",
"pkg/version",
"plugin/pkg/client/auth/gcp",
"plugin/pkg/client/auth/oidc",
@@ -876,6 +879,6 @@
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "736e8116bcf49bf0889c2caf8e832a78a43fd5af65c5d10c86a443993de63d3c"
inputs-digest = "e336c1acaf22142bbb031deed1513923d09b6fda70d228e48a9556f9d40cb785"
solver-name = "gps-cdcl"
solver-version = 1

View File

@@ -1 +1 @@
0.4.0
0.4.7

View File

@@ -53,10 +53,13 @@ func NewCommand() *cobra.Command {
DisableAuth: disableAuth,
}
argocd := server.NewServer(argoCDOpts)
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()
argocd.Run(ctx, 8080)
for {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
argocd.Run(ctx, 8080)
cancel()
}
},
}

View File

@@ -1,6 +1,7 @@
package main
import (
"context"
"fmt"
"io/ioutil"
"os"
@@ -10,6 +11,7 @@ import (
"github.com/argoproj/argo-cd/errors"
"github.com/argoproj/argo-cd/util/cli"
"github.com/argoproj/argo-cd/util/dex"
"github.com/argoproj/argo-cd/util/settings"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"k8s.io/client-go/kubernetes"
@@ -56,22 +58,57 @@ func NewRunDexCommand() *cobra.Command {
Use: "rundex",
Short: "Runs dex generating a config using settings from the ArgoCD configmap and secret",
RunE: func(c *cobra.Command, args []string) error {
dexPath, err := exec.LookPath("dex")
_, err := exec.LookPath("dex")
errors.CheckError(err)
dexCfgBytes, err := genDexConfig(clientConfig)
config, err := clientConfig.ClientConfig()
errors.CheckError(err)
if len(dexCfgBytes) == 0 {
log.Infof("dex is not configured")
// need to sleep forever since we run as a sidecar and kubernetes does not permit
// containers in a deployment to have restartPolicy anything other than Always.
// TODO: we should watch for a change in the dex.config key in the config-map
// to restart dex when there is a change (e.g. clientID and clientSecretKey changed)
select {}
namespace, _, err := clientConfig.Namespace()
errors.CheckError(err)
kubeClientset := kubernetes.NewForConfigOrDie(config)
settingsMgr := settings.NewSettingsManager(kubeClientset, namespace)
settings, err := settingsMgr.GetSettings()
errors.CheckError(err)
ctx := context.Background()
settingsMgr.StartNotifier(ctx, settings)
updateCh := make(chan struct{}, 1)
settingsMgr.Subscribe(updateCh)
for {
var cmd *exec.Cmd
dexCfgBytes, err := dex.GenerateDexConfigYAML(settings)
errors.CheckError(err)
if len(dexCfgBytes) == 0 {
log.Infof("dex is not configured")
} else {
err = ioutil.WriteFile("/tmp/dex.yaml", dexCfgBytes, 0644)
errors.CheckError(err)
log.Info(string(dexCfgBytes))
cmd = exec.Command("dex", "serve", "/tmp/dex.yaml")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err = cmd.Start()
errors.CheckError(err)
}
// loop until the dex config changes
for {
<-updateCh
newDexCfgBytes, err := dex.GenerateDexConfigYAML(settings)
errors.CheckError(err)
if string(newDexCfgBytes) != string(dexCfgBytes) {
log.Infof("dex config modified. restarting dex")
if cmd != nil && cmd.Process != nil {
err = cmd.Process.Signal(syscall.SIGTERM)
errors.CheckError(err)
_, err = cmd.Process.Wait()
errors.CheckError(err)
}
break
} else {
log.Infof("dex config unmodified")
}
}
}
err = ioutil.WriteFile("/tmp/dex.yaml", dexCfgBytes, 0644)
errors.CheckError(err)
log.Info(string(dexCfgBytes))
return syscall.Exec(dexPath, []string{"dex", "serve", "/tmp/dex.yaml"}, []string{})
},
}
@@ -88,7 +125,15 @@ func NewGenDexConfigCommand() *cobra.Command {
Use: "gendexcfg",
Short: "Generates a dex config from ArgoCD settings",
RunE: func(c *cobra.Command, args []string) error {
dexCfgBytes, err := genDexConfig(clientConfig)
config, err := clientConfig.ClientConfig()
errors.CheckError(err)
namespace, _, err := clientConfig.Namespace()
errors.CheckError(err)
kubeClientset := kubernetes.NewForConfigOrDie(config)
settingsMgr := settings.NewSettingsManager(kubeClientset, namespace)
settings, err := settingsMgr.GetSettings()
errors.CheckError(err)
dexCfgBytes, err := dex.GenerateDexConfigYAML(settings)
errors.CheckError(err)
if len(dexCfgBytes) == 0 {
log.Infof("dex is not configured")
@@ -109,16 +154,6 @@ func NewGenDexConfigCommand() *cobra.Command {
return &command
}
func genDexConfig(clientConfig clientcmd.ClientConfig) ([]byte, error) {
config, err := clientConfig.ClientConfig()
errors.CheckError(err)
namespace, _, err := clientConfig.Namespace()
errors.CheckError(err)
kubeClient := kubernetes.NewForConfigOrDie(config)
return dex.GenerateDexConfigYAML(kubeClient, namespace)
}
func main() {
if err := NewCommand().Execute(); err != nil {
fmt.Println(err)

View File

@@ -3,11 +3,13 @@ package commands
import (
"context"
"fmt"
"io"
"net/url"
"os"
"strconv"
"strings"
"text/tabwriter"
"time"
"github.com/argoproj/argo-cd/errors"
argocdclient "github.com/argoproj/argo-cd/pkg/apiclient"
@@ -21,6 +23,9 @@ import (
"github.com/spf13/pflag"
"github.com/yudai/gojsondiff/formatter"
"golang.org/x/crypto/ssh/terminal"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
@@ -38,11 +43,13 @@ func NewApplicationCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comman
command.AddCommand(NewApplicationGetCommand(clientOpts))
command.AddCommand(NewApplicationDiffCommand(clientOpts))
command.AddCommand(NewApplicationSetCommand(clientOpts))
command.AddCommand(NewApplicationUnsetCommand(clientOpts))
command.AddCommand(NewApplicationSyncCommand(clientOpts))
command.AddCommand(NewApplicationHistoryCommand(clientOpts))
command.AddCommand(NewApplicationRollbackCommand(clientOpts))
command.AddCommand(NewApplicationListCommand(clientOpts))
command.AddCommand(NewApplicationDeleteCommand(clientOpts))
command.AddCommand(NewApplicationWaitCommand(clientOpts))
return command
}
@@ -52,6 +59,7 @@ func NewApplicationCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra.
appOpts appOptions
fileURL string
appName string
upsert bool
)
var command = &cobra.Command{
Use: "create",
@@ -63,8 +71,8 @@ func NewApplicationCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra.
}
var app argoappv1.Application
if fileURL != "" {
_, err := url.ParseRequestURI(fileURL)
if err != nil {
parsedURL, err := url.ParseRequestURI(fileURL)
if err != nil || !(parsedURL.Scheme == "http" || parsedURL.Scheme == "https") {
err = cli.UnmarshalLocalFile(fileURL, &app)
} else {
err = cli.UnmarshalRemoteFile(fileURL, &app)
@@ -101,19 +109,24 @@ func NewApplicationCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra.
setParameterOverrides(&app, appOpts.parameters)
conn, appIf := argocdclient.NewClientOrDie(clientOpts).NewApplicationClientOrDie()
defer util.Close(conn)
created, err := appIf.Create(context.Background(), &app)
ctx := metadata.AppendToOutgoingContext(context.Background(), "upsert", strconv.FormatBool(upsert))
created, err := appIf.Create(ctx, &app)
errors.CheckError(err)
fmt.Printf("application '%s' created\n", created.ObjectMeta.Name)
},
}
command.Flags().StringVarP(&fileURL, "file", "f", "", "Filename or URL to Kubernetes manifests for the app")
command.Flags().StringVar(&appName, "name", "", "A name for the app, ignored if a file is set")
command.Flags().BoolVar(&upsert, "upsert", false, "Allows to override application with the same name even if supplied application spec is different from existing spec")
addAppFlags(command, &appOpts)
return command
}
// NewApplicationGetCommand returns a new instance of an `argocd app get` command
func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
var (
showParams bool
)
var command = &cobra.Command{
Use: "get APPNAME",
Short: "Get application details",
@@ -122,42 +135,84 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com
c.HelpFunc()(c, args)
os.Exit(1)
}
conn, appIf := argocdclient.NewClientOrDie(clientOpts).NewApplicationClientOrDie()
acdClient := argocdclient.NewClientOrDie(clientOpts)
conn, appIf := acdClient.NewApplicationClientOrDie()
defer util.Close(conn)
appName := args[0]
app, err := appIf.Get(context.Background(), &application.ApplicationQuery{Name: &appName})
errors.CheckError(err)
format := "%-15s%s\n"
fmt.Printf(format, "Name:", app.Name)
fmt.Printf(format, "Environment:", app.Spec.Source.Environment)
fmt.Printf(format, "Server:", app.Spec.Destination.Server)
fmt.Printf(format, "Namespace:", app.Spec.Destination.Namespace)
fmt.Printf(format, "URL:", appURL(acdClient, app))
fmt.Printf(format, "Environment:", app.Spec.Source.Environment)
fmt.Printf(format, "Repo:", app.Spec.Source.RepoURL)
fmt.Printf(format, "Path:", app.Spec.Source.Path)
if app.Spec.Source.TargetRevision == "" {
fmt.Printf(format, "Target:", "HEAD")
} else {
fmt.Printf(format, "Target:", app.Spec.Source.TargetRevision)
}
fmt.Printf(format, "Target:", app.Spec.Source.TargetRevision)
if app.Status.ComparisonResult.Error != "" {
fmt.Printf(format, "Error:", app.Status.ComparisonResult.Error)
}
if showParams {
printParams(app)
}
if len(app.Status.ComparisonResult.Resources) > 0 {
fmt.Println()
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
fmt.Fprintf(w, "KIND\tNAME\tSTATUS\tHEALTH\n")
for _, res := range app.Status.ComparisonResult.Resources {
targetObj, err := argoappv1.UnmarshalToUnstructured(res.TargetState)
errors.CheckError(err)
fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", targetObj.GetKind(), targetObj.GetName(), res.Status, res.Health.Status)
}
printAppResources(w, app)
_ = w.Flush()
}
},
}
command.Flags().BoolVar(&showParams, "show-params", false, "Show application parameters and overrides")
return command
}
// appURL returns the URL of an application
func appURL(acdClient argocdclient.Client, app *argoappv1.Application) string {
var scheme string
opts := acdClient.ClientOptions()
server := opts.ServerAddr
if opts.PlainText {
scheme = "http"
} else {
scheme = "https"
if strings.HasSuffix(opts.ServerAddr, ":443") {
server = server[0 : len(server)-4]
}
}
return fmt.Sprintf("%s://%s/applications/%s/%s", scheme, server, app.Namespace, app.Name)
}
func truncateString(str string, num int) string {
bnoden := str
if len(str) > num {
if num > 3 {
num -= 3
}
bnoden = str[0:num] + "..."
}
return bnoden
}
// printParams prints parameters and overrides
func printParams(app *argoappv1.Application) {
paramLenLimit := 80
overrides := make(map[string]string)
for _, p := range app.Spec.Source.ComponentParameterOverrides {
overrides[fmt.Sprintf("%s/%s", p.Component, p.Name)] = p.Value
}
fmt.Println()
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
fmt.Fprintf(w, "COMPONENT\tNAME\tVALUE\tOVERRIDE\n")
for _, p := range app.Status.Parameters {
overrideValue := overrides[fmt.Sprintf("%s/%s", p.Component, p.Name)]
fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", p.Component, p.Name, truncateString(p.Value, paramLenLimit), truncateString(overrideValue, paramLenLimit))
}
_ = w.Flush()
}
// NewApplicationSetCommand returns a new instance of an `argocd app set` command
func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
var (
@@ -231,6 +286,54 @@ func addAppFlags(command *cobra.Command, opts *appOptions) {
command.Flags().StringArrayVarP(&opts.parameters, "parameter", "p", []string{}, "set a parameter override (e.g. -p guestbook=image=example/guestbook:latest)")
}
// NewApplicationUnsetCommand returns a new instance of an `argocd app unset` command
func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
var (
parameters []string
)
var command = &cobra.Command{
Use: "unset APPNAME -p COMPONENT=PARAM",
Short: "Unset application parameters",
Run: func(c *cobra.Command, args []string) {
if len(args) != 1 || len(parameters) == 0 {
c.HelpFunc()(c, args)
os.Exit(1)
}
appName := args[0]
conn, appIf := argocdclient.NewClientOrDie(clientOpts).NewApplicationClientOrDie()
defer util.Close(conn)
app, err := appIf.Get(context.Background(), &application.ApplicationQuery{Name: &appName})
errors.CheckError(err)
updated := false
for _, paramStr := range parameters {
parts := strings.SplitN(paramStr, "=", 2)
if len(parts) != 2 {
log.Fatalf("Expected parameter of the form: component=param. Received: %s", paramStr)
}
overrides := app.Spec.Source.ComponentParameterOverrides
for i, override := range overrides {
if override.Component == parts[0] && override.Name == parts[1] {
app.Spec.Source.ComponentParameterOverrides = append(overrides[0:i], overrides[i+1:]...)
updated = true
break
}
}
}
if !updated {
return
}
_, err = appIf.UpdateSpec(context.Background(), &application.ApplicationSpecRequest{
AppName: &app.Name,
Spec: app.Spec,
})
errors.CheckError(err)
},
}
command.Flags().StringArrayVarP(&parameters, "parameter", "p", []string{}, "unset a parameter override (e.g. -p guestbook=image)")
return command
}
// NewApplicationDiffCommand returns a new instance of an `argocd app diff` command
func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
var command = &cobra.Command{
@@ -273,7 +376,7 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
// NewApplicationDeleteCommand returns a new instance of an `argocd app delete` command
func NewApplicationDeleteCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
var (
force bool
cascade bool
)
var command = &cobra.Command{
Use: "delete APPNAME",
@@ -286,25 +389,26 @@ func NewApplicationDeleteCommand(clientOpts *argocdclient.ClientOptions) *cobra.
conn, appIf := argocdclient.NewClientOrDie(clientOpts).NewApplicationClientOrDie()
defer util.Close(conn)
for _, appName := range args {
var cascade *bool
if c.Flag("force").Changed {
cascade = &force
}
appDeleteReq := application.DeleteApplicationRequest{
Name: &appName,
Cascade: cascade,
Name: &appName,
}
if c.Flag("cascade").Changed {
appDeleteReq.Cascade = &cascade
}
_, err := appIf.Delete(context.Background(), &appDeleteReq)
errors.CheckError(err)
}
},
}
command.Flags().BoolVar(&force, "force", false, "Force delete application even if cascaded deletion unsuccessful")
command.Flags().BoolVar(&cascade, "cascade", true, "Perform a cascaded deletion of all application resources")
return command
}
// NewApplicationListCommand returns a new instance of an `argocd app list` command
func NewApplicationListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
var (
output string
)
var command = &cobra.Command{
Use: "list",
Short: "List applications",
@@ -314,28 +418,197 @@ func NewApplicationListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
apps, err := appIf.List(context.Background(), &application.ApplicationQuery{})
errors.CheckError(err)
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
fmt.Fprintf(w, "NAME\tENVIRONMENT\tTARGET\tCLUSTER\tNAMESPACE\tSTATUS\tHEALTH\n")
var fmtStr string
headers := []interface{}{"NAME", "CLUSTER", "NAMESPACE", "STATUS", "HEALTH"}
if output == "wide" {
fmtStr = "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n"
headers = append(headers, "ENV", "REPO", "TARGET")
} else {
fmtStr = "%s\t%s\t%s\t%s\t%s\n"
}
fmt.Fprintf(w, fmtStr, headers...)
for _, app := range apps.Items {
targetRev := app.Spec.Source.TargetRevision
if targetRev == "" {
targetRev = "HEAD"
}
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
vals := []interface{}{
app.Name,
app.Spec.Source.Environment,
targetRev,
app.Spec.Destination.Server,
app.Spec.Destination.Namespace,
app.Status.ComparisonResult.Status,
app.Status.Health.Status,
)
}
if output == "wide" {
vals = append(vals, app.Spec.Source.Environment, app.Spec.Source.RepoURL, app.Spec.Source.TargetRevision)
}
fmt.Fprintf(w, fmtStr, vals...)
}
_ = w.Flush()
},
}
command.Flags().StringVarP(&output, "output", "o", "", "Output format. One of: wide")
return command
}
// NewApplicationWaitCommand returns a new instance of an `argocd app wait` command
func NewApplicationWaitCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
var (
syncOnly bool
healthOnly bool
timeout uint
)
const defaultCheckTimeoutSeconds = 0
var command = &cobra.Command{
Use: "wait APPNAME",
Short: "Wait for an application to reach a synced and healthy state",
Run: func(c *cobra.Command, args []string) {
if len(args) != 1 {
c.HelpFunc()(c, args)
os.Exit(1)
}
if syncOnly && healthOnly {
log.Fatalln("Please specify at most one of --sync-only or --health-only.")
}
appName := args[0]
conn, appIf := argocdclient.NewClientOrDie(clientOpts).NewApplicationClientOrDie()
defer util.Close(conn)
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()
if timeout != 0 {
time.AfterFunc(time.Duration(timeout)*time.Second, func() {
cancel()
})
}
// print the initial components to format the tabwriter columns
app, err := appIf.Get(ctx, &application.ApplicationQuery{Name: &appName})
errors.CheckError(err)
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
fmt.Fprintf(w, "KIND\tNAME\tSTATUS\tHEALTH\n")
printAppResources(w, app)
_ = w.Flush()
prevCompRes := &app.Status.ComparisonResult
appEventCh := watchApp(ctx, appIf, appName)
for appEvent := range appEventCh {
app := appEvent.Application
printAppStateChange(w, prevCompRes, &app)
_ = w.Flush()
prevCompRes = &app.Status.ComparisonResult
synced := (app.Status.ComparisonResult.Status == argoappv1.ComparisonStatusSynced)
healthy := (app.Status.Health.Status == argoappv1.HealthStatusHealthy)
if (synced && healthy) || (synced && syncOnly) || (healthy && healthOnly) {
log.Printf("App %q matches desired state", appName)
return
}
}
log.Fatalf("Timed out (%ds) waiting for app %q match desired state", timeout, appName)
},
}
command.Flags().BoolVar(&syncOnly, "sync-only", false, "Wait only for sync")
command.Flags().BoolVar(&healthOnly, "health-only", false, "Wait only for health")
command.Flags().UintVar(&timeout, "timeout", defaultCheckTimeoutSeconds, "Time out after this many seconds")
return command
}
func isCanceledContextErr(err error) bool {
if err == context.Canceled {
return true
}
if stat, ok := status.FromError(err); ok {
if stat.Code() == codes.Canceled {
return true
}
}
return false
}
// watchApp returns a channel of watch events for an app, retrying the watch upon errors. Closes
// the returned channel when the context is discovered to be canceled.
func watchApp(ctx context.Context, appIf application.ApplicationServiceClient, appName string) chan *argoappv1.ApplicationWatchEvent {
appEventsCh := make(chan *argoappv1.ApplicationWatchEvent)
go func() {
defer close(appEventsCh)
for {
wc, err := appIf.Watch(ctx, &application.ApplicationQuery{
Name: &appName,
})
if err != nil {
if isCanceledContextErr(err) {
return
}
if err != io.EOF {
log.Warnf("watch err: %v", err)
}
time.Sleep(1 * time.Second)
continue
}
for {
appEvent, err := wc.Recv()
if err != nil {
if isCanceledContextErr(err) {
return
}
if err != io.EOF {
log.Warnf("recv err: %v", err)
}
time.Sleep(1 * time.Second)
break
} else {
appEventsCh <- appEvent
}
}
}
}()
return appEventsCh
}
// printAppResources prints the resources of an application in a tabwriter table
func printAppResources(w io.Writer, app *argoappv1.Application) {
for _, res := range app.Status.ComparisonResult.Resources {
obj, err := argoappv1.UnmarshalToUnstructured(res.TargetState)
errors.CheckError(err)
if obj == nil {
obj, err = argoappv1.UnmarshalToUnstructured(res.LiveState)
errors.CheckError(err)
}
fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", obj.GetKind(), obj.GetName(), res.Status, res.Health.Status)
}
}
// printAppStateChange prints a component state change if it was different from the last time we saw it
func printAppStateChange(w io.Writer, prevComp *argoappv1.ComparisonResult, app *argoappv1.Application) {
getPrevResState := func(kind, name string) (argoappv1.ComparisonStatus, argoappv1.HealthStatusCode) {
for _, res := range prevComp.Resources {
obj, err := argoappv1.UnmarshalToUnstructured(res.TargetState)
errors.CheckError(err)
if obj == nil {
obj, err = argoappv1.UnmarshalToUnstructured(res.LiveState)
errors.CheckError(err)
}
if obj.GetKind() == kind && obj.GetName() == name {
return res.Status, res.Health.Status
}
}
return "", ""
}
if len(app.Status.ComparisonResult.Resources) > 0 {
for _, res := range app.Status.ComparisonResult.Resources {
obj, err := argoappv1.UnmarshalToUnstructured(res.TargetState)
errors.CheckError(err)
if obj == nil {
obj, err = argoappv1.UnmarshalToUnstructured(res.LiveState)
errors.CheckError(err)
}
prevSync, prevHealth := getPrevResState(obj.GetKind(), obj.GetName())
if prevSync != res.Status || prevHealth != res.Health.Status {
fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", obj.GetKind(), obj.GetName(), res.Status, res.Health.Status)
}
}
}
}
// NewApplicationSyncCommand returns a new instance of an `argocd app sync` command
func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
var (
@@ -390,11 +663,10 @@ func waitUntilOperationCompleted(appClient application.ApplicationServiceClient,
for {
if appEvent.Application.Status.OperationState != nil && appEvent.Application.Status.OperationState.Phase.Completed() {
return appEvent.Application.Status.OperationState, nil
} else {
appEvent, err = wc.Recv()
if err != nil {
return nil, err
}
}
appEvent, err = wc.Recv()
if err != nil {
return nil, err
}
}
}

View File

@@ -200,9 +200,9 @@ func NewClusterListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comman
clusters, err := clusterIf.List(context.Background(), &cluster.ClusterQuery{})
errors.CheckError(err)
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
fmt.Fprintf(w, "SERVER\tNAME\n")
fmt.Fprintf(w, "SERVER\tNAME\tMESSAGE\n")
for _, c := range clusters.Items {
fmt.Fprintf(w, "%s\t%s\n", c.Server, c.Name)
fmt.Fprintf(w, "%s\t%s\t%s\n", c.Server, c.Name, c.Message)
}
_ = w.Flush()
},

View File

@@ -71,7 +71,9 @@ func NewLoginCommand(globalClientOpts *argocdclient.ClientOptions) *cobra.Comman
setConn, setIf := acdClient.NewSettingsClientOrDie()
defer util.Close(setConn)
ctxName = cli.PromptMessage("Enter a name for this context", ctxName)
if ctxName == "" {
ctxName = server
}
// Perform the login
var tokenString string
@@ -249,7 +251,7 @@ func oauth2Login(host string, plaintext bool) string {
return tokenString
}
func passwordLogin(acdClient argocdclient.ServerClient, username, password string) string {
func passwordLogin(acdClient argocdclient.Client, username, password string) string {
username, password = cli.PromptCredentials(username, password)
sessConn, sessionIf := acdClient.NewSessionClientOrDie()
defer util.Close(sessConn)
@@ -262,7 +264,7 @@ func passwordLogin(acdClient argocdclient.ServerClient, username, password strin
return createdSession.Token
}
func tokenLogin(acdClient argocdclient.ServerClient, token string) string {
func tokenLogin(acdClient argocdclient.Client, token string) string {
sessConn, sessionIf := acdClient.NewSessionClientOrDie()
defer util.Close(sessConn)
sessionRequest := session.SessionCreateRequest{

View File

@@ -113,9 +113,9 @@ func NewRepoListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
repos, err := repoIf.List(context.Background(), &repository.RepoQuery{})
errors.CheckError(err)
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
fmt.Fprintf(w, "REPO\tUSER\n")
fmt.Fprintf(w, "REPO\tUSER\tMESSAGE\n")
for _, r := range repos.Items {
fmt.Fprintf(w, "%s\t%s\n", r.Repo, r.Username)
fmt.Fprintf(w, "%s\t%s\t%s\n", r.Repo, r.Username, r.Message)
}
_ = w.Flush()
},

View File

@@ -16,7 +16,7 @@ const (
SecretTypeCluster = "cluster"
// AuthCookieName is the HTTP cookie name where we store our auth token
AuthCookieName = "argocd.argoproj.io/auth-token"
AuthCookieName = "argocd.token"
// ResourcesFinalizerName is a number of application CRD finalizer
ResourcesFinalizerName = "resources-finalizer." + MetadataPrefix
)

View File

@@ -365,7 +365,7 @@ func (ctrl *ApplicationController) processRequestedAppOperation(app *appv1.Appli
opRes := ctrl.appStateManager.SyncAppState(app, deploymentInfo.Revision, &deploymentInfo.ComponentParameterOverrides, app.Operation.Rollback.DryRun, app.Operation.Rollback.Prune)
state.Phase = opRes.Phase
state.Message = opRes.Message
state.RollbackResult = opRes.RollbackResult
state.RollbackResult = opRes.SyncResult
}
} else {
state.Phase = appv1.OperationFailed

View File

@@ -60,30 +60,54 @@ func (ctrl *kubeAppHealthManager) getDeploymentHealth(config *rest.Config, names
if err != nil {
return nil, err
}
deploy, err := clientSet.AppsV1().Deployments(namespace).Get(name, metav1.GetOptions{})
deployment, err := clientSet.AppsV1().Deployments(namespace).Get(name, metav1.GetOptions{})
if err != nil {
return nil, err
}
health := appv1.HealthStatus{
Status: appv1.HealthStatusUnknown,
}
for _, condition := range deploy.Status.Conditions {
// deployment is healthy is it successfully progressed
if condition.Type == v1.DeploymentProgressing && condition.Status == "True" {
health.Status = appv1.HealthStatusHealthy
} else if condition.Type == v1.DeploymentReplicaFailure && condition.Status == "True" {
health.Status = appv1.HealthStatusDegraded
} else if condition.Type == v1.DeploymentProgressing && condition.Status == "False" {
health.Status = appv1.HealthStatusDegraded
} else if condition.Type == v1.DeploymentAvailable && condition.Status == "False" {
health.Status = appv1.HealthStatusDegraded
if deployment.Generation <= deployment.Status.ObservedGeneration {
cond := getDeploymentCondition(deployment.Status, v1.DeploymentProgressing)
if cond != nil && cond.Reason == "ProgressDeadlineExceeded" {
return &appv1.HealthStatus{
Status: appv1.HealthStatusDegraded,
StatusDetails: fmt.Sprintf("Deployment %q exceeded its progress deadline", name),
}, nil
} else if deployment.Spec.Replicas != nil && deployment.Status.UpdatedReplicas < *deployment.Spec.Replicas {
return &appv1.HealthStatus{
Status: appv1.HealthStatusProgressing,
StatusDetails: fmt.Sprintf("Waiting for rollout to finish: %d out of %d new replicas have been updated...\n", deployment.Status.UpdatedReplicas, *deployment.Spec.Replicas),
}, nil
} else if deployment.Status.Replicas > deployment.Status.UpdatedReplicas {
return &appv1.HealthStatus{
Status: appv1.HealthStatusProgressing,
StatusDetails: fmt.Sprintf("Waiting for rollout to finish: %d old replicas are pending termination...\n", deployment.Status.Replicas-deployment.Status.UpdatedReplicas),
}, nil
} else if deployment.Status.AvailableReplicas < deployment.Status.UpdatedReplicas {
return &appv1.HealthStatus{
Status: appv1.HealthStatusProgressing,
StatusDetails: fmt.Sprintf("Waiting for rollout to finish: %d of %d updated replicas are available...\n", deployment.Status.AvailableReplicas, deployment.Status.UpdatedReplicas),
}, nil
}
if health.Status != appv1.HealthStatusUnknown {
health.StatusDetails = fmt.Sprintf("%s:%s", condition.Reason, condition.Message)
break
} else {
return &appv1.HealthStatus{
Status: appv1.HealthStatusProgressing,
StatusDetails: "Waiting for rollout to finish: observed deployment generation less then desired generation",
}, nil
}
return &appv1.HealthStatus{
Status: appv1.HealthStatusHealthy,
}, nil
}
func getDeploymentCondition(status v1.DeploymentStatus, condType v1.DeploymentConditionType) *v1.DeploymentCondition {
for i := range status.Conditions {
c := status.Conditions[i]
if c.Type == condType {
return &c
}
}
return &health, nil
return nil
}
func (ctrl *kubeAppHealthManager) GetAppHealth(server string, namespace string, comparisonResult *appv1.ComparisonResult) (*appv1.HealthStatus, error) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

View File

@@ -11,7 +11,7 @@ An example Ksonnet guestbook application is provided to demonstrates how Argo CD
Download the latest Argo CD version
```
curl -sSL -o /usr/local/bin/argocd https://github.com/argoproj/argo-cd/releases/download/v0.3.1/argocd-darwin-amd64
curl -sSL -o /usr/local/bin/argocd https://github.com/argoproj/argo-cd/releases/download/v0.4.3/argocd-darwin-amd64
chmod +x /usr/local/bin/argocd
```
@@ -31,7 +31,7 @@ change service type to `LoadBalancer`:
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
```
# 4. Login to the server from the CLI
## 4. Login to the server from the CLI
```
argocd login $(minikube service argocd-server -n argocd --url | cut -d'/' -f 3)

72
docs/sso.md Normal file
View File

@@ -0,0 +1,72 @@
# SSO Configuration
## Overview
ArgoCD embeds and bundles [Dex](https://github.com/coreos/dex) as part of its installation, for the
purposes of delegating authentication to an external identity provider. Multiple types of identity
providers are supported (OIDC, SAML, LDAP, GitHub, etc...). SSO configuration of ArgoCD requires
editing the `argocd-cm` ConfigMap with a
[Dex connector](https://github.com/coreos/dex/tree/master/Documentation/connectors) settings.
This document describes how to configure ArgoCD SSO using GitHub (OAuth2) as an example, but the
steps should be similar for other identity providers.
### 1. Register the application in the identity provider
In GitHub, register a new application. The callback address should be the `/api/dex/callback`
endpoint of your ArgoCD URL (e.g. https://argocd.example.com/api/dex/callback).
![Register OAuth App](assets/register-app.png "Register OAuth App")
After registering the app, you will receive an OAuth2 client ID and secret. These values will be
inputted into the ArgoCD configmap.
![OAuth2 Client Config](assets/oauth2-config.png "OAuth2 Client Config")
### 2. Configure ArgoCD for SSO
Edit the argocd-cm configmap:
```
kubectl edit configmap argocd-cm
```
* In the `url` key, input the base URL of ArgoCD. In this example, it is https://argocd.example.com
* In the `dex.config` key, add the `github` connector to the `connectors` sub field. See Dex's
[GitHub connector](https://github.com/coreos/dex/blob/master/Documentation/connectors/github.md)
documentation for explanation of the fields. A minimal config should populate the clientID,
clientSecret generated in Step 1.
* You will very likely want to restrict logins to one ore more GitHub organization. In the
`connectors.config.orgs` list, add one or more GitHub organizations. Any member of the org will
then be able to login to ArgoCD to perform management tasks.
```
data:
url: https://argocd.example.com
dex.config: |
connectors:
- type: github
id: github
name: GitHub
config:
clientID: 5aae0fcec2c11634be8c
clientSecret: c6fcb18177869174bd09be2c51259fb049c9d4e5
orgs:
- name: your-github-org
```
NOTES:
* Any values which start with '$' will look to a key in argocd-secret of the same name (minus the $),
to obtain the actual value. This allows you to store the `clientSecret` as a kubernetes secret.
* There is no need to set `redirectURI` in the `connectors.config` as shown in the dex documentation.
ArgoCD will automatically use the correct `redirectURI` for any OAuth2 connectors, to match the
correct external callback URL (e.g. https://argocd.example.com/api/dex/callback)
### 3. Restart ArgoCD for changes to take effect
Any changes to the `argocd-cm` ConfigMap or `argocd-secret` Secret, currently require a restart of
the ArgoCD API server for the settings to take effect. Delete the `argocd-server` pod to force a
restart. [Issue #174](https://github.com/argoproj/argo-cd/issues/174) will address this limitation.
```
kubectl delete pod -l app=argocd-server
```

View File

@@ -2,10 +2,6 @@
An ArgoCD application spec provides several different ways of track kubernetes resource manifests in git. This document describes the different techniques and the means of deploying those manifests to the target environment.
## Auto-Sync
In all tracking strategies described below, the application has the option to sync automatically. If auto-sync is configured, the new resources manifests will be applied automatically -- as soon as a difference is detected between the target state (git) and live state. If auto-sync is disabled, a manual sync will be needed using the Argo UI, CLI, or API.
## Branch Tracking
If a branch name is specified, ArgoCD will continually compare live state against the resource manifests defined at the tip of the specified branch.
@@ -23,12 +19,13 @@ To redeploy an application, the user uses git to change the meaning of a tag by
If a git commit SHA is specified, the application is effectively pinned to the manifests defined at the specified commit. This is the most restrictive of the techniques and is typically used to control production environments.
Since commit SHAs cannot change meaning, the only way to change the live state of an application which is pinned to a commit, is by updating the tracking revision in the application to a different commit containing the new manifests.
Note that parameter overrides can still be made against a application which is pinned to a revision.
## Parameter Overrides
ArgoCD provides means to override the parameters of a ksonnet app. This gives some extra flexibility in having *some* parts of the k8s manifests determined dynamically. It also serves as an alternative way of redeploying an application by changing application parameters via ArgoCD, instead of making the changes to the manifests in git.
The following is an example of where this would be useful: A team maintains a "dev" environment, which needs to be continually updated with the latest version of their guestbook application after every build in the tip of master. To solve this, the ksonnet application would expose an parameter named `image`, whose value used in the `dev` environment contains a placeholder value (e.g. `example/guestbook:replaceme`) intended to be set externally (outside of git) such as by build systems. As part of the build pipeline, the parameter value of the `image` would be continually updated to the freshly built image (e.g. `example/guestbook:abcd123`). A sync operation would result in the application being redeployed with the new image.
The following is an example of where this would be useful: A team maintains a "dev" environment, which needs to be continually updated with the latest version of their guestbook application after every build in the tip of master. To address this use case, the ksonnet application should expose an parameter named `image`, whose value used in the `dev` environment contains a placeholder value (e.g. `example/guestbook:replaceme`), intended to be set externally (outside of git) such as a build systems. As part of the build pipeline, the parameter value of the `image` would be continually updated to the freshly built image (e.g. `example/guestbook:abcd123`). A sync operation would result in the application being redeployed with the new image.
ArgoCD provides these operations conveniently via the CLI, or alternatively via the gRPC/REST API.
```
@@ -38,3 +35,7 @@ $ argocd app sync guestbook
Note that in all tracking strategies, any parameter overrides set in the application instance will be honored.
## [Auto-Sync](https://github.com/argoproj/argo-cd/issues/79) (Not Yet Implemented)
In all tracking strategies, the application will have the option to sync automatically. If auto-sync is configured, the new resources manifests will be applied automatically -- as soon as a difference is detected between the target state (git) and live state. If auto-sync is disabled, a manual sync will be needed using the Argo UI, CLI, or API.

70
docs/webhook.md Normal file
View File

@@ -0,0 +1,70 @@
# Git Webhook Configuration
## Overview
ArgoCD will poll git repositories every three minutes for changes to the manifests. To eliminate
this delay from polling, the API server can be configured to receive webhook events. ArgoCD supports
git webhook notifications from GitHub, GitLab, and BitBucket. The following explains how to configure
a git webhook for GitHub, but the same process should be applicable to other providers.
### 1. Create the webhook in the git provider
In your git provider, navigate to the settings page where webhooks can be configured. The payload
URL configured in the git provider should use the /api/webhook endpoint of your ArgoCD instance
(e.g. https://argocd.example.com/api/webhook). Input an arbitrary value in the secret. The same
value will be used when configuring the webhook in step 2.
![Add Webhook](assets/webhook-config.png "Add Webhook")
### 2. Configure ArgoCD with the webhook secret
In the `argocd-secret` kubernetes secret, configure one of the following keys with the git provider
webhook secret configured in step 1.
| Provider | K8s Secret Key |
|---------- | ------------------------ |
| GitHub | `github.webhook.secret` |
| GitLab | `gitlab.webhook.secret` |
| BitBucket | `bitbucket.webhook.uuid` |
Edit the ArgoCD kubernetes secret:
```
kubectl edit secret argocd-secret
```
TIP: for ease of entering secrets, kubernetes supports inputting secrets in the `stringData` field,
which saves you the trouble of base64 encoding the values and copying it to the `data` field.
Simply copy the shared webhook secret created in step 1, to the corresponding
GitHub/GitLab/BitBucket key under the `stringData` field:
```
apiVersion: v1
kind: Secret
metadata:
name: argocd-secret
namespace: argocd
type: Opaque
data:
...
stringData:
# github webhook secret
github.webhook.secret: shhhh! it's a github secret
# gitlab webhook secret
gitlab.webhook.secret: shhhh! it's a gitlab secret
# bitbucket webhook secret
bitbucket.webhook.uuid: your-bitbucket-uuid
```
### 3. Restart ArgoCD for changes to take effect
Any changes to the `argocd-cm` ConfigMap or `argocd-secret` Secret, currently require a restart of
the ArgoCD API server for the settings to take effect. Delete the `argocd-server` pod to force a
restart. [Issue #174](https://github.com/argoproj/argo-cd/issues/174) will address this limitation.
```
kubectl delete pod -l app=argocd-server
```

View File

@@ -23,7 +23,7 @@ local appDeployment = deployment
params.replicas,
container
.new(params.name, params.image)
.withPorts(containerPort.new(targetPort)),
.withPorts(containerPort.new(targetPort)) + if params.command != null then { command: [ params.command ] } else {},
labels);
k.core.v1.list.new([appService, appDeployment])

View File

@@ -12,7 +12,8 @@
name: "guestbook-ui",
replicas: 1,
servicePort: 80,
type: "LoadBalancer",
type: "ClusterIP",
command: null,
},
},
}

View File

@@ -12,7 +12,10 @@ stringData:
# random server signature key for session validation
server.secretkey: aEDvv73vv70F77+9CRBSNu+/vTYQ77+9EUFh77+9LzFyJ++/vXfLsO+/vWRbeu+/ve+/vQ==
# these keys hold the shared secret for authenticating GitHub/GitLab webhook events
# The following keys hold the shared secret for authenticating GitHub/GitLab/BitBucket webhook
# events. To enable webhooks, configure one or more of the following keys with the shared git
# provider webhook secret. The payload URL configured in the git provider should use the
# /api/webhook endpoint of your ArgoCD instance (e.g. https://argocd.example.com/api/webhook)
github.webhook.secret: shhhh! it's a github secret
gitlab.webhook.secret: shhhh! it's a gitlab secret
bitbucket.webhook.uuid: your-bitbucket-uuid

View File

@@ -32,8 +32,9 @@ const (
EnvArgoCDAuthToken = "ARGOCD_AUTH_TOKEN"
)
// ServerClient defines an interface for interaction with an Argo CD server.
type ServerClient interface {
// Client defines an interface for interaction with an Argo CD server.
type Client interface {
ClientOptions() ClientOptions
NewConn() (*grpc.ClientConn, error)
NewRepoClient() (*grpc.ClientConn, repository.RepositoryServiceClient, error)
NewRepoClientOrDie() (*grpc.ClientConn, repository.RepositoryServiceClient)
@@ -69,7 +70,7 @@ type client struct {
}
// NewClient creates a new API client from a set of config options.
func NewClient(opts *ClientOptions) (ServerClient, error) {
func NewClient(opts *ClientOptions) (Client, error) {
var c client
localCfg, err := localconfig.ReadLocalConfig(opts.ConfigPath)
if err != nil {
@@ -134,7 +135,7 @@ func NewClient(opts *ClientOptions) (ServerClient, error) {
}
// NewClientOrDie creates a new API client from a set of config options, or fails fatally if the new client creation fails.
func NewClientOrDie(opts *ClientOptions) ServerClient {
func NewClientOrDie(opts *ClientOptions) Client {
client, err := NewClient(opts)
if err != nil {
log.Fatal(err)
@@ -181,6 +182,15 @@ func (c *client) NewConn() (*grpc.ClientConn, error) {
return grpc_util.BlockingDial(context.Background(), "tcp", c.ServerAddr, creds, grpc.WithPerRPCCredentials(endpointCredentials))
}
func (c *client) ClientOptions() ClientOptions {
return ClientOptions{
ServerAddr: c.ServerAddr,
PlainText: c.PlainText,
Insecure: c.Insecure,
AuthToken: c.AuthToken,
}
}
func (c *client) NewRepoClient() (*grpc.ClientConn, repository.RepositoryServiceClient, error) {
conn, err := c.NewConn()
if err != nil {

View File

@@ -556,6 +556,10 @@ func (m *Cluster) MarshalTo(dAtA []byte) (int, error) {
return 0, err
}
i += n12
dAtA[i] = 0x22
i++
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message)))
i += copy(dAtA[i:], m.Message)
return i, nil
}
@@ -943,6 +947,10 @@ func (m *Repository) MarshalTo(dAtA []byte) (int, error) {
i++
i = encodeVarintGenerated(dAtA, i, uint64(len(m.SSHPrivateKey)))
i += copy(dAtA[i:], m.SSHPrivateKey)
dAtA[i] = 0x2a
i++
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message)))
i += copy(dAtA[i:], m.Message)
return i, nil
}
@@ -1395,6 +1403,8 @@ func (m *Cluster) Size() (n int) {
n += 1 + l + sovGenerated(uint64(l))
l = m.Config.Size()
n += 1 + l + sovGenerated(uint64(l))
l = len(m.Message)
n += 1 + l + sovGenerated(uint64(l))
return n
}
@@ -1542,6 +1552,8 @@ func (m *Repository) Size() (n int) {
n += 1 + l + sovGenerated(uint64(l))
l = len(m.SSHPrivateKey)
n += 1 + l + sovGenerated(uint64(l))
l = len(m.Message)
n += 1 + l + sovGenerated(uint64(l))
return n
}
@@ -1777,6 +1789,7 @@ func (this *Cluster) String() string {
`Server:` + fmt.Sprintf("%v", this.Server) + `,`,
`Name:` + fmt.Sprintf("%v", this.Name) + `,`,
`Config:` + strings.Replace(strings.Replace(this.Config.String(), "ClusterConfig", "ClusterConfig", 1), `&`, ``, 1) + `,`,
`Message:` + fmt.Sprintf("%v", this.Message) + `,`,
`}`,
}, "")
return s
@@ -1892,6 +1905,7 @@ func (this *Repository) String() string {
`Username:` + fmt.Sprintf("%v", this.Username) + `,`,
`Password:` + fmt.Sprintf("%v", this.Password) + `,`,
`SSHPrivateKey:` + fmt.Sprintf("%v", this.SSHPrivateKey) + `,`,
`Message:` + fmt.Sprintf("%v", this.Message) + `,`,
`}`,
}, "")
return s
@@ -3270,6 +3284,35 @@ func (m *Cluster) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Message = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
@@ -4731,6 +4774,35 @@ func (m *Repository) Unmarshal(dAtA []byte) error {
}
m.SSHPrivateKey = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Message = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
@@ -5948,133 +6020,133 @@ func init() {
}
var fileDescriptorGenerated = []byte{
// 2038 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x59, 0xdd, 0x8f, 0x1b, 0x49,
0x11, 0x4f, 0xaf, 0x3f, 0xd6, 0x2e, 0xef, 0x47, 0xd2, 0xc7, 0x1d, 0xd6, 0x9e, 0xe4, 0x5d, 0x4d,
0x04, 0x04, 0xc4, 0xd9, 0x24, 0x70, 0x7c, 0x4a, 0x48, 0xb1, 0x37, 0x77, 0xd9, 0xdb, 0x4d, 0xb2,
0xb4, 0xf7, 0x40, 0x3a, 0x10, 0x30, 0x3b, 0xee, 0xb5, 0x27, 0x6b, 0xcf, 0xcc, 0x75, 0xb7, 0x1d,
0x59, 0x02, 0x74, 0x08, 0x21, 0xa1, 0x13, 0x9c, 0xf8, 0xf8, 0x07, 0x78, 0xe6, 0x05, 0x81, 0x78,
0xe2, 0x1d, 0xc8, 0xe3, 0x21, 0xf1, 0x70, 0x42, 0x28, 0x22, 0x7b, 0x2f, 0x27, 0xf1, 0x1f, 0xe4,
0x09, 0x75, 0x4f, 0x4f, 0x4f, 0xcf, 0x78, 0xf7, 0x36, 0x39, 0x3b, 0xd1, 0xbd, 0x79, 0xaa, 0x6a,
0xea, 0x57, 0x53, 0xdd, 0x55, 0xf5, 0xeb, 0x36, 0xec, 0xf4, 0x7d, 0x31, 0x18, 0x1f, 0x36, 0xbd,
0x70, 0xd4, 0x72, 0x59, 0x3f, 0x8c, 0x58, 0x78, 0x57, 0xfd, 0x78, 0xc9, 0xeb, 0xb5, 0xa2, 0xe3,
0x7e, 0xcb, 0x8d, 0x7c, 0xde, 0x72, 0xa3, 0x68, 0xe8, 0x7b, 0xae, 0xf0, 0xc3, 0xa0, 0x35, 0xb9,
0xea, 0x0e, 0xa3, 0x81, 0x7b, 0xb5, 0xd5, 0xa7, 0x01, 0x65, 0xae, 0xa0, 0xbd, 0x66, 0xc4, 0x42,
0x11, 0xe2, 0xaf, 0xa5, 0xae, 0x9a, 0x89, 0x2b, 0xf5, 0xe3, 0x07, 0x5e, 0xaf, 0x19, 0x1d, 0xf7,
0x9b, 0xd2, 0x55, 0xd3, 0x72, 0xd5, 0x4c, 0x5c, 0x6d, 0xbc, 0x64, 0x45, 0xd1, 0x0f, 0xfb, 0x61,
0x4b, 0x79, 0x3c, 0x1c, 0x1f, 0xa9, 0x27, 0xf5, 0xa0, 0x7e, 0xc5, 0x48, 0x1b, 0x5f, 0x3a, 0xfe,
0x2a, 0x6f, 0xfa, 0xa1, 0x8c, 0x6d, 0xe4, 0x7a, 0x03, 0x3f, 0xa0, 0x6c, 0x9a, 0x06, 0x3b, 0xa2,
0xc2, 0x6d, 0x4d, 0x66, 0xe2, 0xdb, 0x68, 0x9d, 0xf5, 0x16, 0x1b, 0x07, 0xc2, 0x1f, 0xd1, 0x99,
0x17, 0xbe, 0x7c, 0xde, 0x0b, 0xdc, 0x1b, 0xd0, 0x91, 0x3b, 0xf3, 0xde, 0x17, 0xcf, 0x7a, 0x6f,
0x2c, 0xfc, 0x61, 0xcb, 0x0f, 0x04, 0x17, 0x2c, 0xff, 0x92, 0xf3, 0xf7, 0x02, 0xd4, 0xae, 0xa7,
0xb9, 0xc1, 0x3f, 0x84, 0x8a, 0xfc, 0x90, 0x9e, 0x2b, 0xdc, 0x3a, 0xda, 0x42, 0x57, 0x6a, 0xd7,
0xbe, 0xd0, 0x8c, 0xfd, 0x36, 0x6d, 0xbf, 0x69, 0x62, 0xa5, 0x75, 0x73, 0x72, 0xb5, 0x79, 0xe7,
0xf0, 0x2e, 0xf5, 0xc4, 0x2d, 0x2a, 0xdc, 0x36, 0xbe, 0xff, 0x60, 0xf3, 0xc2, 0xc9, 0x83, 0x4d,
0x48, 0x65, 0xc4, 0x78, 0xc5, 0x43, 0x28, 0xf2, 0x88, 0x7a, 0xf5, 0x25, 0xe5, 0xfd, 0xb5, 0xe6,
0x47, 0x5e, 0xbe, 0xa6, 0x15, 0x77, 0x37, 0xa2, 0x5e, 0x7b, 0x45, 0xe3, 0x16, 0xe5, 0x13, 0x51,
0x28, 0x58, 0x40, 0x99, 0x0b, 0x57, 0x8c, 0x79, 0xbd, 0xa0, 0xf0, 0xf6, 0x16, 0x84, 0xa7, 0x7c,
0xb6, 0xd7, 0x34, 0x62, 0x39, 0x7e, 0x26, 0x1a, 0x0b, 0xbf, 0x09, 0xd5, 0x30, 0x92, 0x79, 0xf6,
0xc3, 0xa0, 0x5e, 0x54, 0xc0, 0xdb, 0x73, 0x00, 0xdf, 0x49, 0x7c, 0xb5, 0x57, 0x4f, 0x1e, 0x6c,
0x56, 0xcd, 0x23, 0x49, 0x51, 0x1c, 0x0f, 0x3e, 0x61, 0xc5, 0xd7, 0x09, 0x83, 0x9e, 0xaf, 0x16,
0x74, 0x0b, 0x8a, 0x62, 0x1a, 0x51, 0xb5, 0x98, 0xd5, 0x34, 0x45, 0x07, 0xd3, 0x88, 0x12, 0xa5,
0xc1, 0x9f, 0x85, 0xe5, 0x11, 0xe5, 0xdc, 0xed, 0x53, 0xb5, 0x26, 0xd5, 0xf6, 0xba, 0x36, 0x5a,
0xbe, 0x15, 0x8b, 0x49, 0xa2, 0x77, 0xde, 0x84, 0x17, 0x2c, 0x90, 0x6d, 0xca, 0x85, 0x1f, 0xc4,
0xfb, 0xe6, 0xd3, 0x50, 0xe6, 0x94, 0x4d, 0x28, 0xd3, 0x40, 0x69, 0x66, 0x94, 0x94, 0x68, 0x2d,
0x6e, 0x41, 0x35, 0x70, 0x47, 0x94, 0x47, 0xae, 0x97, 0xc0, 0x5d, 0xd2, 0xa6, 0xd5, 0xdb, 0x89,
0x82, 0xa4, 0x36, 0xce, 0x7f, 0x10, 0xac, 0x5b, 0x98, 0x7b, 0x3e, 0x17, 0xf8, 0x7b, 0x33, 0x9b,
0xb4, 0xf9, 0x78, 0x9b, 0x54, 0xbe, 0xad, 0xb6, 0xe8, 0x45, 0x8d, 0x59, 0x49, 0x24, 0xd6, 0x06,
0x3d, 0x86, 0x92, 0x2f, 0xe8, 0x88, 0xd7, 0x97, 0xb6, 0x0a, 0x57, 0x6a, 0xd7, 0x5e, 0x59, 0xcc,
0x8e, 0x69, 0xaf, 0x6a, 0xc8, 0xd2, 0x8e, 0x74, 0x4e, 0x62, 0x0c, 0xe7, 0x9d, 0x02, 0x5c, 0xb2,
0xf7, 0x55, 0x38, 0x66, 0x9e, 0x5a, 0x12, 0x46, 0xa3, 0xf0, 0x75, 0xb2, 0xa7, 0xd3, 0x69, 0x96,
0x84, 0xc4, 0x62, 0x92, 0xe8, 0xe5, 0xfa, 0x46, 0xae, 0x18, 0xe8, 0x5c, 0x9a, 0xf5, 0xdd, 0x77,
0xc5, 0x80, 0x28, 0x0d, 0x7e, 0x19, 0x6a, 0x34, 0x98, 0xf8, 0x2c, 0x0c, 0x46, 0x34, 0x10, 0xaa,
0x0e, 0xaa, 0xed, 0xe7, 0xb4, 0x61, 0xed, 0x46, 0xaa, 0x22, 0xb6, 0x1d, 0xfe, 0x26, 0xac, 0x09,
0x97, 0xf5, 0xa9, 0x20, 0x74, 0xe2, 0xf3, 0x64, 0x23, 0x57, 0xdb, 0x2f, 0xe8, 0x37, 0xd7, 0x0e,
0x32, 0x5a, 0x92, 0xb3, 0xc6, 0x7f, 0x41, 0xf0, 0xa2, 0x17, 0x8e, 0xa2, 0x30, 0xa0, 0x81, 0xd8,
0x77, 0x99, 0x3b, 0xa2, 0x82, 0xb2, 0x3b, 0x13, 0xca, 0x98, 0xdf, 0xa3, 0xbc, 0x5e, 0x52, 0xd9,
0xbd, 0x35, 0x47, 0x76, 0x3b, 0x33, 0xde, 0xdb, 0x97, 0x75, 0x70, 0x2f, 0x76, 0xce, 0x46, 0x26,
0x1f, 0x16, 0x96, 0xf3, 0xdb, 0xa5, 0xcc, 0x7e, 0xeb, 0x26, 0x4d, 0x44, 0x2d, 0x8c, 0xde, 0x6d,
0x8b, 0x6a, 0x22, 0xca, 0xa7, 0x55, 0x2a, 0xea, 0x99, 0x68, 0x2c, 0xfc, 0x0b, 0x04, 0xb5, 0x5e,
0x5a, 0x62, 0xba, 0x61, 0x7e, 0x6b, 0x31, 0xd8, 0x56, 0xed, 0xa6, 0x7b, 0xc1, 0x12, 0x12, 0x1b,
0xda, 0xf9, 0x7d, 0x39, 0xbb, 0x4b, 0xe3, 0x2e, 0xf7, 0x1b, 0x04, 0x17, 0x65, 0x2a, 0x5d, 0xe6,
0xf3, 0x30, 0x20, 0x94, 0x8f, 0x87, 0x42, 0x67, 0x68, 0x77, 0xce, 0x65, 0xb5, 0x5d, 0xb6, 0xeb,
0x3a, 0xbe, 0x8b, 0x79, 0x0d, 0x99, 0x81, 0xc7, 0x02, 0x96, 0x07, 0x3e, 0x17, 0x21, 0x9b, 0xea,
0xf2, 0xdd, 0x99, 0x23, 0x92, 0x6d, 0x1a, 0x0d, 0xc3, 0xa9, 0xac, 0x86, 0x9d, 0xe0, 0x28, 0x4c,
0x8b, 0xf0, 0x66, 0x8c, 0x40, 0x12, 0x28, 0xfc, 0x53, 0x04, 0x10, 0x25, 0x7b, 0x49, 0x8e, 0x9a,
0xa7, 0xb0, 0xb5, 0xcd, 0x54, 0x35, 0x22, 0x4e, 0x2c, 0x50, 0x1c, 0x42, 0x79, 0x40, 0xdd, 0xa1,
0x18, 0xe8, 0x81, 0xf3, 0xea, 0x1c, 0xf0, 0x37, 0x95, 0xa3, 0xfc, 0x90, 0x8b, 0xa5, 0x44, 0xc3,
0xe0, 0x9f, 0x23, 0x58, 0x33, 0xf3, 0x47, 0xda, 0xd2, 0x7a, 0x49, 0x21, 0xef, 0x2c, 0x62, 0xd4,
0x29, 0x87, 0x6d, 0x2c, 0x1b, 0x4d, 0x56, 0x46, 0x72, 0xa0, 0xf8, 0x67, 0x08, 0xc0, 0x4b, 0xe6,
0x1d, 0xaf, 0x97, 0x55, 0xf2, 0xef, 0x2c, 0xa6, 0x4c, 0xcc, 0x1c, 0x4d, 0xd3, 0x6f, 0x44, 0x9c,
0x58, 0xb0, 0xce, 0xfb, 0x08, 0x9e, 0xb7, 0x5e, 0xfc, 0x8e, 0x2b, 0xbc, 0xc1, 0x8d, 0x89, 0x6c,
0xa4, 0xbb, 0x99, 0x09, 0xfc, 0x15, 0x7b, 0x02, 0x3f, 0x7a, 0xb0, 0xf9, 0x99, 0xb3, 0x58, 0xdb,
0x3d, 0xe9, 0xa1, 0xa9, 0x5c, 0x58, 0xc3, 0xfa, 0xc7, 0x50, 0xb3, 0x62, 0xd6, 0x3d, 0x61, 0x51,
0x23, 0xca, 0x34, 0x02, 0x4b, 0x48, 0x6c, 0x3c, 0xe7, 0x6f, 0x08, 0x96, 0x3b, 0xc3, 0x31, 0x17,
0x94, 0x3d, 0xf6, 0xc8, 0xdf, 0x82, 0xa2, 0x1c, 0xe7, 0xf9, 0x09, 0x25, 0xa7, 0x3d, 0x51, 0x1a,
0x1c, 0x41, 0xd9, 0x0b, 0x83, 0x23, 0xbf, 0xaf, 0x49, 0xda, 0xcd, 0x79, 0x2a, 0x27, 0x8e, 0xae,
0xa3, 0xfc, 0xa5, 0x31, 0xc5, 0xcf, 0x44, 0xe3, 0x38, 0x7f, 0x5e, 0x82, 0xd5, 0x8c, 0x25, 0xfe,
0x3c, 0x54, 0xc6, 0x9c, 0x32, 0x15, 0x69, 0xfc, 0x3d, 0x86, 0x23, 0xbc, 0xae, 0xe5, 0xc4, 0x58,
0x48, 0xeb, 0xc8, 0xe5, 0xfc, 0x5e, 0xc8, 0x7a, 0xfa, 0xbb, 0x8c, 0xf5, 0xbe, 0x96, 0x13, 0x63,
0x21, 0x27, 0xf0, 0x21, 0x75, 0x19, 0x65, 0x07, 0xe1, 0x31, 0x0d, 0xf2, 0x13, 0xb8, 0x9d, 0xaa,
0x88, 0x6d, 0x87, 0x7f, 0x85, 0x60, 0x5d, 0x0c, 0x79, 0x67, 0xe8, 0xd3, 0x40, 0xc4, 0x61, 0xea,
0xda, 0x9e, 0x87, 0x35, 0x1f, 0xec, 0x75, 0x6d, 0x8f, 0xed, 0x4f, 0xea, 0x38, 0xd6, 0x73, 0x0a,
0x92, 0xc7, 0x76, 0xfe, 0x85, 0xa0, 0xa6, 0x93, 0xf6, 0x0c, 0x68, 0x58, 0x3f, 0x4b, 0xc3, 0xda,
0xf3, 0xef, 0x89, 0x33, 0x28, 0xd8, 0x3f, 0x0b, 0x30, 0x33, 0x59, 0xf0, 0xf7, 0x65, 0x4f, 0x91,
0x32, 0xda, 0xbb, 0x9e, 0x0c, 0xb5, 0xcf, 0x3d, 0xde, 0xd7, 0x1d, 0xf8, 0x23, 0x6a, 0xb7, 0x8b,
0xc4, 0x0b, 0xb1, 0x3c, 0xe2, 0xb7, 0x50, 0x0a, 0x70, 0x10, 0xea, 0x3a, 0x5e, 0x2c, 0xaf, 0x98,
0x09, 0xe1, 0x20, 0x24, 0x16, 0x26, 0xfe, 0xba, 0x39, 0x1a, 0x95, 0xd4, 0x86, 0x74, 0xb2, 0x87,
0x99, 0x47, 0x99, 0x81, 0x9b, 0x3b, 0xe0, 0x4c, 0xa1, 0xca, 0x68, 0xcc, 0x53, 0x92, 0x8e, 0x3b,
0x4f, 0xd1, 0x12, 0xed, 0x2b, 0x6e, 0xfa, 0xe6, 0x40, 0x90, 0x88, 0x39, 0x49, 0xd1, 0xf0, 0x65,
0x28, 0x51, 0xc6, 0x42, 0x56, 0x5f, 0x56, 0x51, 0x9b, 0x35, 0xbd, 0x21, 0x85, 0x24, 0xd6, 0x39,
0xbf, 0x44, 0x80, 0x67, 0x67, 0xa8, 0x3c, 0x7d, 0x18, 0xee, 0xa7, 0xab, 0xdc, 0x80, 0x19, 0x73,
0x92, 0xda, 0x3c, 0x46, 0xef, 0xba, 0x0c, 0xa5, 0x89, 0x3b, 0x1c, 0x53, 0x5d, 0xd5, 0x26, 0x9c,
0x6f, 0x4b, 0x21, 0x89, 0x75, 0xce, 0x07, 0x05, 0x58, 0xcb, 0x92, 0x09, 0x3c, 0x86, 0xb2, 0x1a,
0xde, 0xbc, 0x8e, 0x9e, 0x06, 0x5b, 0x30, 0x8d, 0x4f, 0x89, 0x38, 0xd1, 0x60, 0xb2, 0x71, 0xb1,
0x84, 0xcf, 0xe7, 0x1a, 0x97, 0x61, 0xf2, 0xc6, 0xe2, 0x5c, 0x0e, 0x5f, 0xf8, 0x58, 0x72, 0x78,
0x59, 0xbc, 0x3d, 0x95, 0x6d, 0x55, 0xbc, 0xc5, 0x8f, 0x5e, 0xbc, 0xdb, 0xc6, 0x0b, 0xb1, 0x3c,
0xe2, 0x0d, 0x58, 0xf2, 0x7b, 0xaa, 0x6a, 0x0a, 0x6d, 0xd0, 0xb6, 0x4b, 0x3b, 0xdb, 0x64, 0xc9,
0xef, 0x39, 0x1c, 0x56, 0x6c, 0xf6, 0xa4, 0xa6, 0x64, 0x5c, 0x65, 0xf9, 0x29, 0x99, 0xad, 0xa8,
0x6f, 0xc0, 0x6a, 0xfc, 0x6b, 0x9b, 0x0a, 0xd7, 0x1f, 0x72, 0xbd, 0x3a, 0xcf, 0x6b, 0xf3, 0xd5,
0xae, 0xad, 0x24, 0x59, 0x5b, 0xe7, 0x7f, 0x08, 0xd2, 0x5b, 0x01, 0x7c, 0x04, 0x45, 0x3e, 0x0d,
0x3c, 0xdd, 0xb5, 0xe6, 0xa9, 0xcb, 0xee, 0x34, 0xf0, 0xd2, 0xcb, 0x87, 0x8a, 0xba, 0x5b, 0x99,
0x06, 0x1e, 0x51, 0xfe, 0xf1, 0x04, 0x2a, 0x2c, 0x1c, 0x0e, 0x0f, 0x5d, 0xef, 0x78, 0x01, 0x0d,
0x8c, 0x68, 0x57, 0x29, 0xde, 0x8a, 0xda, 0x95, 0x5a, 0x4c, 0x0c, 0x96, 0xf3, 0xc7, 0x12, 0xe4,
0x38, 0x21, 0x1e, 0xdb, 0x17, 0x2e, 0x68, 0x81, 0x17, 0x2e, 0xa6, 0x3d, 0x9c, 0x76, 0xe9, 0x82,
0x5f, 0x86, 0x52, 0x34, 0x70, 0x79, 0xd2, 0x1f, 0x36, 0x93, 0xe2, 0xdf, 0x97, 0xc2, 0x47, 0x36,
0x75, 0x55, 0x12, 0x12, 0x5b, 0xdb, 0x37, 0x2e, 0x85, 0x0f, 0xbf, 0x71, 0xc1, 0x3f, 0x01, 0x90,
0xb9, 0xd6, 0x87, 0xab, 0x78, 0x2b, 0xdf, 0x5e, 0xd4, 0x8a, 0xea, 0xf3, 0xd5, 0x9a, 0xdc, 0xea,
0x5d, 0x83, 0x42, 0x2c, 0x44, 0xfc, 0x36, 0x82, 0xb5, 0x24, 0xf1, 0x3a, 0x88, 0xd2, 0x53, 0x09,
0x42, 0x31, 0x7d, 0x92, 0x41, 0x22, 0x39, 0x64, 0xfc, 0x5d, 0xa8, 0x72, 0xe1, 0x32, 0xa1, 0xca,
0xba, 0xfc, 0xc4, 0x65, 0x6d, 0xd6, 0xb2, 0x9b, 0x38, 0x21, 0xa9, 0x3f, 0xfc, 0x06, 0xc0, 0x91,
0x1f, 0xf8, 0x7c, 0xa0, 0xbc, 0x2f, 0x3f, 0xb1, 0x77, 0x95, 0xc5, 0x57, 0x8c, 0x07, 0x62, 0x79,
0x73, 0xfe, 0x81, 0x00, 0x08, 0x8d, 0x42, 0xee, 0xab, 0xe3, 0xe2, 0x16, 0x14, 0x19, 0x8d, 0xc2,
0xfc, 0x9d, 0x9c, 0xb4, 0x20, 0x4a, 0x93, 0x61, 0xa3, 0x4b, 0x4f, 0xc4, 0x46, 0x0b, 0xe7, 0xb2,
0x51, 0xd9, 0x69, 0xf8, 0x60, 0x9f, 0xf9, 0x13, 0x57, 0xd0, 0x5d, 0x3a, 0xd5, 0xf7, 0x3a, 0x69,
0xa7, 0xe9, 0xde, 0x4c, 0x95, 0x24, 0x6b, 0xeb, 0xfc, 0x1b, 0xc1, 0x5a, 0xfa, 0x25, 0xcf, 0x80,
0x06, 0xde, 0xcd, 0xd2, 0xc0, 0x1b, 0x73, 0xb1, 0x8c, 0x24, 0xee, 0x33, 0x98, 0xe0, 0x9f, 0x10,
0xac, 0x27, 0x9c, 0x43, 0xb7, 0x56, 0xc3, 0x00, 0xd0, 0x99, 0x0c, 0x60, 0x0b, 0x8a, 0xc7, 0x7e,
0xd0, 0xcb, 0x73, 0x84, 0x5d, 0x3f, 0xe8, 0x11, 0xa5, 0xc9, 0x5e, 0x7a, 0x16, 0xce, 0xbf, 0xf4,
0xb4, 0x1b, 0x44, 0xf1, 0x9c, 0x2b, 0xd9, 0x3f, 0x20, 0x58, 0x49, 0x62, 0xbe, 0x1d, 0xf6, 0x14,
0x21, 0xe1, 0xea, 0x30, 0x8e, 0xb2, 0x84, 0x24, 0x3e, 0x3c, 0xc7, 0x3a, 0x3c, 0x86, 0x8a, 0x37,
0xf0, 0x87, 0x3d, 0x46, 0x03, 0x9d, 0xd8, 0x57, 0x17, 0x40, 0xdf, 0x24, 0x7e, 0xba, 0x98, 0x1d,
0x0d, 0x40, 0x0c, 0x94, 0xf3, 0xd7, 0x02, 0xac, 0x66, 0xb8, 0x9e, 0x3c, 0x1a, 0xc5, 0xf7, 0x86,
0x5d, 0x2b, 0x66, 0x73, 0x34, 0x3a, 0x48, 0x55, 0xc4, 0xb6, 0x93, 0x19, 0x1d, 0xfa, 0x93, 0xd8,
0x47, 0xfe, 0x1a, 0x79, 0x2f, 0x51, 0x90, 0xd4, 0xc6, 0x22, 0xbb, 0x85, 0x27, 0x26, 0xbb, 0xbf,
0x43, 0x80, 0xd5, 0x27, 0x48, 0xcf, 0x86, 0x93, 0xd6, 0x8b, 0x8b, 0xcd, 0xdb, 0x86, 0x8e, 0x08,
0x77, 0x66, 0xa0, 0xc8, 0x29, 0xf0, 0xd6, 0x7d, 0x4f, 0xe9, 0x99, 0xdc, 0xf7, 0x38, 0x3f, 0x82,
0x4b, 0x33, 0x33, 0x5a, 0x53, 0x21, 0x74, 0x1a, 0x15, 0x92, 0x3b, 0x31, 0x62, 0xe3, 0x20, 0x5e,
0xa0, 0x4a, 0xba, 0x13, 0xf7, 0xa5, 0x90, 0xc4, 0x3a, 0xc9, 0x8f, 0x7a, 0x6c, 0x4a, 0xc6, 0xf1,
0xb1, 0xb8, 0x92, 0xa2, 0x6f, 0x2b, 0x29, 0xd1, 0x5a, 0xe7, 0x6d, 0x04, 0xab, 0x99, 0xb9, 0x91,
0xa1, 0xb2, 0xe8, 0x5c, 0x2a, 0xbb, 0xd0, 0x60, 0xde, 0x41, 0xf0, 0xdc, 0x29, 0x43, 0x0c, 0xdf,
0xb3, 0x8f, 0x45, 0x31, 0xaf, 0x7f, 0x6d, 0x01, 0xfb, 0x43, 0xf7, 0xa2, 0xf8, 0xdf, 0x9f, 0xd3,
0x0e, 0x45, 0xce, 0x07, 0x08, 0xf2, 0xe7, 0x77, 0x99, 0x1f, 0x3f, 0xe0, 0xd4, 0x1b, 0xb3, 0xb8,
0xae, 0x2a, 0x69, 0x7e, 0x76, 0xb4, 0x9c, 0x18, 0x0b, 0x7c, 0x0d, 0x20, 0xbe, 0xaf, 0xb9, 0x9d,
0xce, 0x1c, 0xc3, 0x83, 0xbb, 0x46, 0x43, 0x2c, 0x2b, 0x7c, 0x05, 0x2a, 0x1e, 0x65, 0x62, 0x5b,
0x76, 0x7e, 0x99, 0xb0, 0x95, 0x98, 0xb2, 0x75, 0xb4, 0x8c, 0x18, 0x2d, 0xfe, 0x14, 0x2c, 0x1f,
0xd3, 0xa9, 0x32, 0x2c, 0x2a, 0xc3, 0x9a, 0x6c, 0x66, 0xbb, 0xb1, 0x88, 0x24, 0x3a, 0xec, 0x40,
0xd9, 0x73, 0x95, 0x55, 0x49, 0x59, 0x81, 0xba, 0xba, 0xb9, 0xae, 0x8c, 0xb4, 0xa6, 0xdd, 0xbc,
0xff, 0xb0, 0x71, 0xe1, 0xdd, 0x87, 0x8d, 0x0b, 0xef, 0x3d, 0x6c, 0x5c, 0x78, 0xeb, 0xa4, 0x81,
0xee, 0x9f, 0x34, 0xd0, 0xbb, 0x27, 0x0d, 0xf4, 0xde, 0x49, 0x03, 0xfd, 0xf7, 0xa4, 0x81, 0x7e,
0xfd, 0x7e, 0xe3, 0xc2, 0x1b, 0x95, 0x24, 0x89, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0xf7, 0xf0,
0x30, 0x38, 0x6b, 0x1e, 0x00, 0x00,
// 2047 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x59, 0xcd, 0x8f, 0x23, 0x47,
0x15, 0x9f, 0x1a, 0x7f, 0x8c, 0xfd, 0xe6, 0x6b, 0xb7, 0x42, 0x82, 0x35, 0x91, 0x3c, 0xa3, 0x5e,
0x01, 0x0b, 0x22, 0x36, 0xbb, 0x10, 0x3e, 0x25, 0xa4, 0xb5, 0x67, 0x93, 0x9d, 0xcc, 0xec, 0xee,
0x50, 0x9e, 0x80, 0x14, 0x10, 0xd0, 0xd3, 0xae, 0xb1, 0x7b, 0xc7, 0xee, 0xee, 0x54, 0x95, 0xbd,
0xb2, 0x04, 0x28, 0x08, 0x21, 0xa1, 0x08, 0x22, 0x3e, 0xfe, 0x01, 0xce, 0x5c, 0x10, 0x88, 0x13,
0x7f, 0x00, 0xda, 0x63, 0x90, 0x38, 0x44, 0x08, 0xad, 0xd8, 0xc9, 0x25, 0x12, 0x17, 0xc4, 0x71,
0x4f, 0xa8, 0xaa, 0xab, 0xab, 0xab, 0xdb, 0x33, 0x99, 0x9d, 0xd8, 0xbb, 0xca, 0xcd, 0xfd, 0xde,
0xeb, 0xf7, 0x7b, 0xfd, 0xaa, 0xde, 0x7b, 0xbf, 0x2a, 0xc3, 0x4e, 0xcf, 0x17, 0xfd, 0xd1, 0x61,
0xc3, 0x0b, 0x87, 0x4d, 0x97, 0xf5, 0xc2, 0x88, 0x85, 0xf7, 0xd4, 0x8f, 0x97, 0xbc, 0x6e, 0x33,
0x3a, 0xee, 0x35, 0xdd, 0xc8, 0xe7, 0x4d, 0x37, 0x8a, 0x06, 0xbe, 0xe7, 0x0a, 0x3f, 0x0c, 0x9a,
0xe3, 0x6b, 0xee, 0x20, 0xea, 0xbb, 0xd7, 0x9a, 0x3d, 0x1a, 0x50, 0xe6, 0x0a, 0xda, 0x6d, 0x44,
0x2c, 0x14, 0x21, 0xfe, 0x5a, 0xea, 0xaa, 0x91, 0xb8, 0x52, 0x3f, 0x7e, 0xe0, 0x75, 0x1b, 0xd1,
0x71, 0xaf, 0x21, 0x5d, 0x35, 0x2c, 0x57, 0x8d, 0xc4, 0xd5, 0xc6, 0x4b, 0x56, 0x14, 0xbd, 0xb0,
0x17, 0x36, 0x95, 0xc7, 0xc3, 0xd1, 0x91, 0x7a, 0x52, 0x0f, 0xea, 0x57, 0x8c, 0xb4, 0xf1, 0xa5,
0xe3, 0xaf, 0xf2, 0x86, 0x1f, 0xca, 0xd8, 0x86, 0xae, 0xd7, 0xf7, 0x03, 0xca, 0x26, 0x69, 0xb0,
0x43, 0x2a, 0xdc, 0xe6, 0x78, 0x2a, 0xbe, 0x8d, 0xe6, 0x59, 0x6f, 0xb1, 0x51, 0x20, 0xfc, 0x21,
0x9d, 0x7a, 0xe1, 0xcb, 0xe7, 0xbd, 0xc0, 0xbd, 0x3e, 0x1d, 0xba, 0x53, 0xef, 0x7d, 0xf1, 0xac,
0xf7, 0x46, 0xc2, 0x1f, 0x34, 0xfd, 0x40, 0x70, 0xc1, 0xf2, 0x2f, 0x39, 0x7f, 0x2b, 0xc0, 0xf2,
0x8d, 0x34, 0x37, 0xf8, 0x87, 0x50, 0x91, 0x1f, 0xd2, 0x75, 0x85, 0x5b, 0x43, 0x5b, 0xe8, 0xea,
0xf2, 0xf5, 0x2f, 0x34, 0x62, 0xbf, 0x0d, 0xdb, 0x6f, 0x9a, 0x58, 0x69, 0xdd, 0x18, 0x5f, 0x6b,
0xdc, 0x3d, 0xbc, 0x47, 0x3d, 0x71, 0x9b, 0x0a, 0xb7, 0x85, 0x1f, 0x3c, 0xdc, 0x5c, 0x38, 0x79,
0xb8, 0x09, 0xa9, 0x8c, 0x18, 0xaf, 0x78, 0x00, 0x45, 0x1e, 0x51, 0xaf, 0xb6, 0xa8, 0xbc, 0xbf,
0xd6, 0xf8, 0xc8, 0xcb, 0xd7, 0xb0, 0xe2, 0xee, 0x44, 0xd4, 0x6b, 0xad, 0x68, 0xdc, 0xa2, 0x7c,
0x22, 0x0a, 0x05, 0x0b, 0x28, 0x73, 0xe1, 0x8a, 0x11, 0xaf, 0x15, 0x14, 0xde, 0xde, 0x9c, 0xf0,
0x94, 0xcf, 0xd6, 0x9a, 0x46, 0x2c, 0xc7, 0xcf, 0x44, 0x63, 0xe1, 0x37, 0xa1, 0x1a, 0x46, 0x32,
0xcf, 0x7e, 0x18, 0xd4, 0x8a, 0x0a, 0x78, 0x7b, 0x06, 0xe0, 0xbb, 0x89, 0xaf, 0xd6, 0xea, 0xc9,
0xc3, 0xcd, 0xaa, 0x79, 0x24, 0x29, 0x8a, 0xe3, 0xc1, 0x27, 0xac, 0xf8, 0xda, 0x61, 0xd0, 0xf5,
0xd5, 0x82, 0x6e, 0x41, 0x51, 0x4c, 0x22, 0xaa, 0x16, 0xb3, 0x9a, 0xa6, 0xe8, 0x60, 0x12, 0x51,
0xa2, 0x34, 0xf8, 0xb3, 0xb0, 0x34, 0xa4, 0x9c, 0xbb, 0x3d, 0xaa, 0xd6, 0xa4, 0xda, 0x5a, 0xd7,
0x46, 0x4b, 0xb7, 0x63, 0x31, 0x49, 0xf4, 0xce, 0x9b, 0xf0, 0x82, 0x05, 0xb2, 0x4d, 0xb9, 0xf0,
0x83, 0x78, 0xdf, 0x7c, 0x1a, 0xca, 0x9c, 0xb2, 0x31, 0x65, 0x1a, 0x28, 0xcd, 0x8c, 0x92, 0x12,
0xad, 0xc5, 0x4d, 0xa8, 0x06, 0xee, 0x90, 0xf2, 0xc8, 0xf5, 0x12, 0xb8, 0xcb, 0xda, 0xb4, 0x7a,
0x27, 0x51, 0x90, 0xd4, 0xc6, 0xf9, 0x17, 0x82, 0x75, 0x0b, 0x73, 0xcf, 0xe7, 0x02, 0x7f, 0x6f,
0x6a, 0x93, 0x36, 0x9e, 0x6c, 0x93, 0xca, 0xb7, 0xd5, 0x16, 0xbd, 0xa4, 0x31, 0x2b, 0x89, 0xc4,
0xda, 0xa0, 0xc7, 0x50, 0xf2, 0x05, 0x1d, 0xf2, 0xda, 0xe2, 0x56, 0xe1, 0xea, 0xf2, 0xf5, 0x57,
0xe6, 0xb3, 0x63, 0x5a, 0xab, 0x1a, 0xb2, 0xb4, 0x23, 0x9d, 0x93, 0x18, 0xc3, 0x79, 0xa7, 0x00,
0x97, 0xed, 0x7d, 0x15, 0x8e, 0x98, 0xa7, 0x96, 0x84, 0xd1, 0x28, 0x7c, 0x9d, 0xec, 0xe9, 0x74,
0x9a, 0x25, 0x21, 0xb1, 0x98, 0x24, 0x7a, 0xb9, 0xbe, 0x91, 0x2b, 0xfa, 0x3a, 0x97, 0x66, 0x7d,
0xf7, 0x5d, 0xd1, 0x27, 0x4a, 0x83, 0x5f, 0x86, 0x65, 0x1a, 0x8c, 0x7d, 0x16, 0x06, 0x43, 0x1a,
0x08, 0x55, 0x07, 0xd5, 0xd6, 0x73, 0xda, 0x70, 0xf9, 0x66, 0xaa, 0x22, 0xb6, 0x1d, 0xfe, 0x26,
0xac, 0x09, 0x97, 0xf5, 0xa8, 0x20, 0x74, 0xec, 0xf3, 0x64, 0x23, 0x57, 0x5b, 0x2f, 0xe8, 0x37,
0xd7, 0x0e, 0x32, 0x5a, 0x92, 0xb3, 0xc6, 0x7f, 0x41, 0xf0, 0xa2, 0x17, 0x0e, 0xa3, 0x30, 0xa0,
0x81, 0xd8, 0x77, 0x99, 0x3b, 0xa4, 0x82, 0xb2, 0xbb, 0x63, 0xca, 0x98, 0xdf, 0xa5, 0xbc, 0x56,
0x52, 0xd9, 0xbd, 0x3d, 0x43, 0x76, 0xdb, 0x53, 0xde, 0x5b, 0x57, 0x74, 0x70, 0x2f, 0xb6, 0xcf,
0x46, 0x26, 0x1f, 0x16, 0x96, 0xf3, 0xdb, 0xc5, 0xcc, 0x7e, 0xeb, 0x24, 0x4d, 0x44, 0x2d, 0x8c,
0xde, 0x6d, 0xf3, 0x6a, 0x22, 0xca, 0xa7, 0x55, 0x2a, 0xea, 0x99, 0x68, 0x2c, 0xfc, 0x0b, 0x04,
0xcb, 0xdd, 0xb4, 0xc4, 0x74, 0xc3, 0xfc, 0xd6, 0x7c, 0xb0, 0xad, 0xda, 0x4d, 0xf7, 0x82, 0x25,
0x24, 0x36, 0xb4, 0xf3, 0xfb, 0x72, 0x76, 0x97, 0xc6, 0x5d, 0xee, 0x37, 0x08, 0x2e, 0xc9, 0x54,
0xba, 0xcc, 0xe7, 0x61, 0x40, 0x28, 0x1f, 0x0d, 0x84, 0xce, 0xd0, 0xee, 0x8c, 0xcb, 0x6a, 0xbb,
0x6c, 0xd5, 0x74, 0x7c, 0x97, 0xf2, 0x1a, 0x32, 0x05, 0x8f, 0x05, 0x2c, 0xf5, 0x7d, 0x2e, 0x42,
0x36, 0xd1, 0xe5, 0xbb, 0x33, 0x43, 0x24, 0xdb, 0x34, 0x1a, 0x84, 0x13, 0x59, 0x0d, 0x3b, 0xc1,
0x51, 0x98, 0x16, 0xe1, 0xad, 0x18, 0x81, 0x24, 0x50, 0xf8, 0xa7, 0x08, 0x20, 0x4a, 0xf6, 0x92,
0x1c, 0x35, 0x4f, 0x61, 0x6b, 0x9b, 0xa9, 0x6a, 0x44, 0x9c, 0x58, 0xa0, 0x38, 0x84, 0x72, 0x9f,
0xba, 0x03, 0xd1, 0xd7, 0x03, 0xe7, 0xd5, 0x19, 0xe0, 0x6f, 0x29, 0x47, 0xf9, 0x21, 0x17, 0x4b,
0x89, 0x86, 0xc1, 0x3f, 0x47, 0xb0, 0x66, 0xe6, 0x8f, 0xb4, 0xa5, 0xb5, 0x92, 0x42, 0xde, 0x99,
0xc7, 0xa8, 0x53, 0x0e, 0x5b, 0x58, 0x36, 0x9a, 0xac, 0x8c, 0xe4, 0x40, 0xf1, 0xcf, 0x10, 0x80,
0x97, 0xcc, 0x3b, 0x5e, 0x2b, 0xab, 0xe4, 0xdf, 0x9d, 0x4f, 0x99, 0x98, 0x39, 0x9a, 0xa6, 0xdf,
0x88, 0x38, 0xb1, 0x60, 0x9d, 0xf7, 0x11, 0x3c, 0x6f, 0xbd, 0xf8, 0x1d, 0x57, 0x78, 0xfd, 0x9b,
0x63, 0xd9, 0x48, 0x77, 0x33, 0x13, 0xf8, 0x2b, 0xf6, 0x04, 0x7e, 0xfc, 0x70, 0xf3, 0x33, 0x67,
0xb1, 0xb6, 0xfb, 0xd2, 0x43, 0x43, 0xb9, 0xb0, 0x86, 0xf5, 0x8f, 0x61, 0xd9, 0x8a, 0x59, 0xf7,
0x84, 0x79, 0x8d, 0x28, 0xd3, 0x08, 0x2c, 0x21, 0xb1, 0xf1, 0x9c, 0xff, 0x22, 0x58, 0x6a, 0x0f,
0x46, 0x5c, 0x50, 0xf6, 0xc4, 0x23, 0x7f, 0x0b, 0x8a, 0x72, 0x9c, 0xe7, 0x27, 0x94, 0x9c, 0xf6,
0x44, 0x69, 0x70, 0x04, 0x65, 0x2f, 0x0c, 0x8e, 0xfc, 0x9e, 0x26, 0x69, 0xb7, 0x66, 0xa9, 0x9c,
0x38, 0xba, 0xb6, 0xf2, 0x97, 0xc6, 0x14, 0x3f, 0x13, 0x8d, 0x63, 0x73, 0x9e, 0xe2, 0x39, 0x9c,
0xe7, 0xcf, 0x8b, 0xb0, 0x9a, 0x71, 0x8a, 0x3f, 0x0f, 0x95, 0x11, 0xa7, 0x4c, 0x7d, 0x54, 0xfc,
0xe9, 0x86, 0x4e, 0xbc, 0xae, 0xe5, 0xc4, 0x58, 0x48, 0xeb, 0xc8, 0xe5, 0xfc, 0x7e, 0xc8, 0xba,
0x3a, 0x05, 0xc6, 0x7a, 0x5f, 0xcb, 0x89, 0xb1, 0x90, 0xc3, 0xfa, 0x90, 0xba, 0x8c, 0xb2, 0x83,
0xf0, 0x98, 0x06, 0xf9, 0x61, 0xdd, 0x4a, 0x55, 0xc4, 0xb6, 0xc3, 0xbf, 0x42, 0xb0, 0x2e, 0x06,
0xbc, 0x3d, 0xf0, 0x69, 0x20, 0xe2, 0x30, 0x75, 0x1b, 0x98, 0x85, 0x60, 0x1f, 0xec, 0x75, 0x6c,
0x8f, 0xad, 0x4f, 0xea, 0x38, 0xd6, 0x73, 0x0a, 0x92, 0xc7, 0x76, 0xfe, 0x81, 0x60, 0x59, 0x27,
0xed, 0x19, 0x30, 0xb6, 0x5e, 0x96, 0xb1, 0xb5, 0x66, 0xdf, 0x3e, 0x67, 0xb0, 0xb5, 0xbf, 0x17,
0x60, 0x6a, 0x08, 0xe1, 0xef, 0xcb, 0xf6, 0x23, 0x65, 0xb4, 0x7b, 0x23, 0x99, 0x7f, 0x9f, 0x7b,
0xb2, 0xaf, 0x3b, 0xf0, 0x87, 0xd4, 0xee, 0x2c, 0x89, 0x17, 0x62, 0x79, 0xc4, 0x6f, 0xa1, 0x14,
0xe0, 0x20, 0xd4, 0x25, 0x3f, 0x5f, 0x0a, 0x32, 0x15, 0xc2, 0x41, 0x48, 0x2c, 0x4c, 0xfc, 0x75,
0x73, 0x8a, 0x2a, 0xa9, 0x0d, 0xe9, 0x64, 0xcf, 0x3d, 0x8f, 0x33, 0xb3, 0x39, 0x77, 0x16, 0x9a,
0x40, 0x95, 0xd1, 0x98, 0xd2, 0x24, 0xcd, 0x79, 0x96, 0xfa, 0x26, 0xda, 0x57, 0x3c, 0x1f, 0xcc,
0xd9, 0x21, 0x11, 0x73, 0x92, 0xa2, 0xe1, 0x2b, 0x50, 0xa2, 0x8c, 0x85, 0xac, 0xb6, 0xa4, 0xa2,
0x36, 0x6b, 0x7a, 0x53, 0x0a, 0x49, 0xac, 0x73, 0x7e, 0x89, 0x00, 0x4f, 0x8f, 0x5b, 0x79, 0x50,
0x31, 0x34, 0x51, 0x57, 0xb9, 0x01, 0x33, 0xe6, 0x24, 0xb5, 0x79, 0x82, 0x36, 0x77, 0x05, 0x4a,
0x63, 0x77, 0x30, 0xa2, 0xba, 0xaa, 0x4d, 0x38, 0xdf, 0x96, 0x42, 0x12, 0xeb, 0x9c, 0x0f, 0x0a,
0xb0, 0x96, 0xe5, 0x1d, 0x78, 0x04, 0x65, 0x35, 0xe7, 0x79, 0x0d, 0x3d, 0x0d, 0x62, 0x61, 0x7a,
0xa4, 0x12, 0x71, 0xa2, 0xc1, 0x64, 0xe3, 0x62, 0x09, 0xf5, 0xcf, 0x35, 0x2e, 0x43, 0xfa, 0x8d,
0xc5, 0xb9, 0x74, 0xbf, 0xf0, 0xb1, 0xa4, 0xfb, 0xb2, 0x78, 0xbb, 0x2a, 0xdb, 0xaa, 0x78, 0x8b,
0x1f, 0xbd, 0x78, 0xb7, 0x8d, 0x17, 0x62, 0x79, 0xc4, 0x1b, 0xb0, 0xe8, 0x77, 0x55, 0xd5, 0x14,
0x5a, 0xa0, 0x6d, 0x17, 0x77, 0xb6, 0xc9, 0xa2, 0xdf, 0x75, 0x38, 0xac, 0xd8, 0x44, 0x4b, 0x0d,
0xd4, 0xb8, 0xca, 0xf2, 0x03, 0x35, 0x5b, 0x51, 0xdf, 0x80, 0xd5, 0xf8, 0xd7, 0x36, 0x15, 0xae,
0x3f, 0xe0, 0x7a, 0x75, 0x9e, 0xd7, 0xe6, 0xab, 0x1d, 0x5b, 0x49, 0xb2, 0xb6, 0xce, 0x7f, 0x10,
0xa4, 0x17, 0x08, 0xf8, 0x08, 0x8a, 0x7c, 0x12, 0x78, 0xba, 0x6b, 0xcd, 0x52, 0x97, 0x9d, 0x49,
0xe0, 0xa5, 0xf7, 0x14, 0x15, 0x75, 0x0d, 0x33, 0x09, 0x3c, 0xa2, 0xfc, 0xe3, 0x31, 0x54, 0x58,
0x38, 0x18, 0x1c, 0xba, 0xde, 0xf1, 0x1c, 0x1a, 0x18, 0xd1, 0xae, 0x52, 0xbc, 0x15, 0xb5, 0x2b,
0xb5, 0x98, 0x18, 0x2c, 0xe7, 0x8f, 0x25, 0xc8, 0xd1, 0x47, 0x3c, 0xb2, 0xef, 0x66, 0xd0, 0x1c,
0xef, 0x66, 0x4c, 0x7b, 0x38, 0xed, 0x7e, 0x06, 0xbf, 0x0c, 0xa5, 0xa8, 0xef, 0xf2, 0xa4, 0x3f,
0x6c, 0x26, 0xc5, 0xbf, 0x2f, 0x85, 0x8f, 0x6d, 0x96, 0xab, 0x24, 0x24, 0xb6, 0xb6, 0x89, 0x4a,
0xe1, 0xc3, 0x89, 0x0a, 0xfe, 0x09, 0x80, 0xcc, 0xb5, 0x3e, 0x87, 0xc5, 0x5b, 0xf9, 0xce, 0xbc,
0x56, 0x54, 0x1f, 0xc5, 0xd6, 0xe4, 0x56, 0xef, 0x18, 0x14, 0x62, 0x21, 0xe2, 0xb7, 0x11, 0xac,
0x25, 0x89, 0xd7, 0x41, 0x94, 0x9e, 0x4a, 0x10, 0xea, 0x50, 0x40, 0x32, 0x48, 0x24, 0x87, 0x8c,
0xbf, 0x0b, 0x55, 0x2e, 0x5c, 0x26, 0x54, 0x59, 0x97, 0x2f, 0x5c, 0xd6, 0x66, 0x2d, 0x3b, 0x89,
0x13, 0x92, 0xfa, 0xc3, 0x6f, 0x00, 0x1c, 0xf9, 0x81, 0xcf, 0xfb, 0xca, 0xfb, 0xd2, 0x85, 0xbd,
0xab, 0x2c, 0xbe, 0x62, 0x3c, 0x10, 0xcb, 0x9b, 0xf3, 0x3f, 0x04, 0x40, 0x68, 0x14, 0x72, 0x5f,
0x9d, 0x2c, 0xb7, 0xa0, 0xc8, 0x68, 0x14, 0xe6, 0xaf, 0xef, 0xa4, 0x05, 0x51, 0x9a, 0x0c, 0x1b,
0x5d, 0xbc, 0x10, 0x1b, 0x2d, 0x9c, 0xcb, 0x46, 0x65, 0xa7, 0xe1, 0xfd, 0x7d, 0xe6, 0x8f, 0x5d,
0x41, 0x77, 0xe9, 0x44, 0x93, 0xe5, 0xb4, 0xd3, 0x74, 0x6e, 0xa5, 0x4a, 0x92, 0xb5, 0xb5, 0xb7,
0x6e, 0xe9, 0x1c, 0x8e, 0xfd, 0x4f, 0x04, 0x6b, 0xe9, 0x47, 0x3f, 0x03, 0xc6, 0x78, 0x2f, 0xcb,
0x18, 0x6f, 0xce, 0x44, 0x48, 0x92, 0xb8, 0xcf, 0x20, 0x8d, 0x7f, 0x42, 0xb0, 0x9e, 0xd0, 0x13,
0xdd, 0x85, 0x0d, 0x59, 0x40, 0x67, 0x92, 0x85, 0x2d, 0x28, 0x1e, 0xfb, 0x41, 0x37, 0x4f, 0x27,
0x76, 0xfd, 0xa0, 0x4b, 0x94, 0x26, 0x7b, 0x95, 0x5a, 0x38, 0xff, 0x2a, 0xf5, 0x22, 0x87, 0x9e,
0x3f, 0x20, 0x58, 0x49, 0x62, 0xbe, 0x13, 0x76, 0x15, 0x77, 0xe1, 0xea, 0x88, 0x8f, 0xb2, 0xdc,
0x25, 0x3e, 0x92, 0xc7, 0x3a, 0x3c, 0x82, 0x8a, 0xd7, 0xf7, 0x07, 0x5d, 0x46, 0x03, 0x9d, 0xd8,
0x57, 0xe7, 0xc0, 0xf4, 0x24, 0x7e, 0xba, 0x98, 0x6d, 0x0d, 0x40, 0x0c, 0x94, 0xf3, 0xd7, 0x02,
0xac, 0x66, 0x68, 0xa1, 0x3c, 0x45, 0xc5, 0xb7, 0x91, 0x1d, 0x2b, 0x66, 0x73, 0x8a, 0x3a, 0x48,
0x55, 0xc4, 0xb6, 0x93, 0x19, 0x1d, 0xf8, 0xe3, 0xd8, 0x47, 0xfe, 0x72, 0x7a, 0x2f, 0x51, 0x90,
0xd4, 0xc6, 0xe2, 0xc5, 0x85, 0x0b, 0xf3, 0xe2, 0xdf, 0x21, 0xc0, 0xea, 0x13, 0xa4, 0x67, 0x43,
0x5f, 0x6b, 0xc5, 0xf9, 0xe6, 0x6d, 0x43, 0x47, 0x84, 0xdb, 0x53, 0x50, 0xe4, 0x14, 0x78, 0xeb,
0x16, 0xa9, 0xf4, 0x4c, 0x6e, 0x91, 0x9c, 0x1f, 0xc1, 0xe5, 0xa9, 0x71, 0xae, 0x59, 0x13, 0x3a,
0x8d, 0x35, 0xc9, 0x9d, 0x18, 0xb1, 0x51, 0x10, 0x2f, 0x50, 0x25, 0xdd, 0x89, 0xfb, 0x52, 0x48,
0x62, 0x9d, 0xa4, 0x52, 0x5d, 0x36, 0x21, 0xa3, 0xf8, 0x04, 0x5d, 0x49, 0xd1, 0xb7, 0x95, 0x94,
0x68, 0xad, 0xf3, 0x36, 0x82, 0xd5, 0xcc, 0x88, 0xc9, 0xb0, 0x5e, 0x74, 0x2e, 0xeb, 0x9d, 0x6b,
0x30, 0xef, 0x20, 0x78, 0xee, 0x94, 0x79, 0x87, 0xef, 0xdb, 0x27, 0xa8, 0xf8, 0x08, 0xf0, 0xda,
0x1c, 0xf6, 0x87, 0xee, 0x45, 0xf1, 0x7f, 0x4a, 0xa7, 0x9d, 0x9f, 0x9c, 0x0f, 0x10, 0xe4, 0x8f,
0xfa, 0x32, 0x3f, 0x7e, 0xc0, 0xa9, 0x37, 0x62, 0x71, 0x5d, 0x55, 0xd2, 0xfc, 0xec, 0x68, 0x39,
0x31, 0x16, 0xf8, 0x3a, 0x40, 0x7c, 0x0b, 0x74, 0x27, 0x1d, 0x4f, 0x86, 0x32, 0x77, 0x8c, 0x86,
0x58, 0x56, 0xf8, 0x2a, 0x54, 0x3c, 0xca, 0xc4, 0xb6, 0xec, 0xfc, 0x32, 0x61, 0x2b, 0x31, 0xbb,
0x6b, 0x6b, 0x19, 0x31, 0x5a, 0xfc, 0x29, 0x58, 0x3a, 0xa6, 0x13, 0x65, 0x58, 0x54, 0x86, 0xcb,
0xb2, 0x99, 0xed, 0xc6, 0x22, 0x92, 0xe8, 0xb0, 0x03, 0x65, 0xcf, 0x55, 0x56, 0x25, 0x65, 0x05,
0xea, 0x42, 0xe8, 0x86, 0x32, 0xd2, 0x9a, 0x56, 0xe3, 0xc1, 0xa3, 0xfa, 0xc2, 0xbb, 0x8f, 0xea,
0x0b, 0xef, 0x3d, 0xaa, 0x2f, 0xbc, 0x75, 0x52, 0x47, 0x0f, 0x4e, 0xea, 0xe8, 0xdd, 0x93, 0x3a,
0x7a, 0xef, 0xa4, 0x8e, 0xfe, 0x7d, 0x52, 0x47, 0xbf, 0x7e, 0xbf, 0xbe, 0xf0, 0x46, 0x25, 0x49,
0xe2, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0x41, 0x22, 0xb1, 0xcb, 0xc1, 0x1e, 0x00, 0x00,
}

View File

@@ -118,6 +118,9 @@ message Cluster {
// Config holds cluster information for connecting to a cluster
optional ClusterConfig config = 3;
// Message can hold a status message or error.
optional string message = 4;
}
// ClusterConfig is the configuration attributes. This structure is subset of the go-client
@@ -225,6 +228,8 @@ message Repository {
optional string password = 3;
optional string sshPrivateKey = 4;
optional string message = 5;
}
// RepositoryList is a collection of Repositories.

View File

@@ -244,6 +244,9 @@ type Cluster struct {
// Config holds cluster information for connecting to a cluster
Config ClusterConfig `json:"config" protobuf:"bytes,3,opt,name=config"`
// Message can hold a status message or error.
Message string `json:"message,omitempty" protobuf:"bytes,4,opt,name=message"`
}
// ClusterList is a collection of Clusters.
@@ -294,6 +297,7 @@ type Repository struct {
Username string `json:"username,omitempty" protobuf:"bytes,2,opt,name=username"`
Password string `json:"password,omitempty" protobuf:"bytes,3,opt,name=password"`
SSHPrivateKey string `json:"sshPrivateKey,omitempty" protobuf:"bytes,4,opt,name=sshPrivateKey"`
Message string `json:"message,omitempty" protobuf:"bytes,5,opt,name=message"`
}
// RepositoryList is a collection of Repositories.

View File

@@ -41,6 +41,54 @@ func NewService(gitFactory git.ClientFactory, cache cache.Cache) *Service {
}
}
// ListDir lists the contents of a GitHub repo
func (s *Service) ListDir(ctx context.Context, q *ListDirRequest) (*FileList, error) {
appRepoPath := tempRepoPath(q.Repo.Repo)
s.repoLock.Lock(appRepoPath)
defer s.repoLock.Unlock(appRepoPath)
gitClient := s.gitFactory.NewClient(q.Repo.Repo, appRepoPath, q.Repo.Username, q.Repo.Password, q.Repo.SSHPrivateKey)
err := gitClient.Init()
if err != nil {
return nil, err
}
commitSHA, err := gitClient.LsRemote(q.Revision)
if err != nil {
return nil, err
}
cacheKey := listDirCacheKey(commitSHA, q)
var res FileList
err = s.cache.Get(cacheKey, &res)
if err == nil {
log.Infof("manifest cache hit: %s", cacheKey)
return &res, nil
}
err = checkoutRevision(gitClient, q.Revision)
if err != nil {
return nil, err
}
lsFiles, err := gitClient.LsFiles(q.Path)
if err != nil {
return nil, err
}
res = FileList{
Items: lsFiles,
}
err = s.cache.Set(&cache.Item{
Key: cacheKey,
Object: &res,
Expiration: DefaultRepoCacheExpiration,
})
if err != nil {
return nil, err
}
return &res, nil
}
func (s *Service) GetFile(ctx context.Context, q *GetFileRequest) (*GetFileResponse, error) {
appRepoPath := tempRepoPath(q.Repo.Repo)
s.repoLock.Lock(appRepoPath)
@@ -206,3 +254,7 @@ func manifestCacheKey(commitSHA string, q *ManifestRequest) string {
pStr, _ := json.Marshal(q.ComponentParameterOverrides)
return fmt.Sprintf("mfst|%s|%s|%s|%s", q.Path, q.Environment, commitSHA, string(pStr))
}
func listDirCacheKey(commitSHA string, q *ListDirRequest) string {
return fmt.Sprintf("ldir|%s|%s", q.Path, commitSHA)
}

View File

@@ -10,6 +10,8 @@
It has these top-level messages:
ManifestRequest
ManifestResponse
ListDirRequest
FileList
GetFileRequest
GetFileResponse
*/
@@ -144,6 +146,56 @@ func (m *ManifestResponse) GetParams() []*github_com_argoproj_argo_cd_pkg_apis_a
return nil
}
// ListDirRequest requests a repository directory structure
type ListDirRequest struct {
Repo *github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.Repository `protobuf:"bytes,1,opt,name=repo" json:"repo,omitempty"`
Revision string `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"`
Path string `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"`
}
func (m *ListDirRequest) Reset() { *m = ListDirRequest{} }
func (m *ListDirRequest) String() string { return proto.CompactTextString(m) }
func (*ListDirRequest) ProtoMessage() {}
func (*ListDirRequest) Descriptor() ([]byte, []int) { return fileDescriptorRepository, []int{2} }
func (m *ListDirRequest) GetRepo() *github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.Repository {
if m != nil {
return m.Repo
}
return nil
}
func (m *ListDirRequest) GetRevision() string {
if m != nil {
return m.Revision
}
return ""
}
func (m *ListDirRequest) GetPath() string {
if m != nil {
return m.Path
}
return ""
}
// FileList returns the contents of the repo of a ListDir request
type FileList struct {
Items []string `protobuf:"bytes,1,rep,name=items" json:"items,omitempty"`
}
func (m *FileList) Reset() { *m = FileList{} }
func (m *FileList) String() string { return proto.CompactTextString(m) }
func (*FileList) ProtoMessage() {}
func (*FileList) Descriptor() ([]byte, []int) { return fileDescriptorRepository, []int{3} }
func (m *FileList) GetItems() []string {
if m != nil {
return m.Items
}
return nil
}
// GetFileRequest return
type GetFileRequest struct {
Repo *github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.Repository `protobuf:"bytes,1,opt,name=repo" json:"repo,omitempty"`
@@ -154,7 +206,7 @@ type GetFileRequest struct {
func (m *GetFileRequest) Reset() { *m = GetFileRequest{} }
func (m *GetFileRequest) String() string { return proto.CompactTextString(m) }
func (*GetFileRequest) ProtoMessage() {}
func (*GetFileRequest) Descriptor() ([]byte, []int) { return fileDescriptorRepository, []int{2} }
func (*GetFileRequest) Descriptor() ([]byte, []int) { return fileDescriptorRepository, []int{4} }
func (m *GetFileRequest) GetRepo() *github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.Repository {
if m != nil {
@@ -185,7 +237,7 @@ type GetFileResponse struct {
func (m *GetFileResponse) Reset() { *m = GetFileResponse{} }
func (m *GetFileResponse) String() string { return proto.CompactTextString(m) }
func (*GetFileResponse) ProtoMessage() {}
func (*GetFileResponse) Descriptor() ([]byte, []int) { return fileDescriptorRepository, []int{3} }
func (*GetFileResponse) Descriptor() ([]byte, []int) { return fileDescriptorRepository, []int{5} }
func (m *GetFileResponse) GetData() []byte {
if m != nil {
@@ -197,6 +249,8 @@ func (m *GetFileResponse) GetData() []byte {
func init() {
proto.RegisterType((*ManifestRequest)(nil), "repository.ManifestRequest")
proto.RegisterType((*ManifestResponse)(nil), "repository.ManifestResponse")
proto.RegisterType((*ListDirRequest)(nil), "repository.ListDirRequest")
proto.RegisterType((*FileList)(nil), "repository.FileList")
proto.RegisterType((*GetFileRequest)(nil), "repository.GetFileRequest")
proto.RegisterType((*GetFileResponse)(nil), "repository.GetFileResponse")
}
@@ -214,6 +268,8 @@ const _ = grpc.SupportPackageIsVersion4
type RepositoryServiceClient interface {
// Generate manifest for application in specified repo name and revision
GenerateManifest(ctx context.Context, in *ManifestRequest, opts ...grpc.CallOption) (*ManifestResponse, error)
// ListDir returns the file contents at the specified repo and path
ListDir(ctx context.Context, in *ListDirRequest, opts ...grpc.CallOption) (*FileList, error)
// GetFile returns the file contents at the specified repo and path
GetFile(ctx context.Context, in *GetFileRequest, opts ...grpc.CallOption) (*GetFileResponse, error)
}
@@ -235,6 +291,15 @@ func (c *repositoryServiceClient) GenerateManifest(ctx context.Context, in *Mani
return out, nil
}
func (c *repositoryServiceClient) ListDir(ctx context.Context, in *ListDirRequest, opts ...grpc.CallOption) (*FileList, error) {
out := new(FileList)
err := grpc.Invoke(ctx, "/repository.RepositoryService/ListDir", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *repositoryServiceClient) GetFile(ctx context.Context, in *GetFileRequest, opts ...grpc.CallOption) (*GetFileResponse, error) {
out := new(GetFileResponse)
err := grpc.Invoke(ctx, "/repository.RepositoryService/GetFile", in, out, c.cc, opts...)
@@ -249,6 +314,8 @@ func (c *repositoryServiceClient) GetFile(ctx context.Context, in *GetFileReques
type RepositoryServiceServer interface {
// Generate manifest for application in specified repo name and revision
GenerateManifest(context.Context, *ManifestRequest) (*ManifestResponse, error)
// ListDir returns the file contents at the specified repo and path
ListDir(context.Context, *ListDirRequest) (*FileList, error)
// GetFile returns the file contents at the specified repo and path
GetFile(context.Context, *GetFileRequest) (*GetFileResponse, error)
}
@@ -275,6 +342,24 @@ func _RepositoryService_GenerateManifest_Handler(srv interface{}, ctx context.Co
return interceptor(ctx, in, info, handler)
}
func _RepositoryService_ListDir_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ListDirRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(RepositoryServiceServer).ListDir(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/repository.RepositoryService/ListDir",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RepositoryServiceServer).ListDir(ctx, req.(*ListDirRequest))
}
return interceptor(ctx, in, info, handler)
}
func _RepositoryService_GetFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetFileRequest)
if err := dec(in); err != nil {
@@ -301,6 +386,10 @@ var _RepositoryService_serviceDesc = grpc.ServiceDesc{
MethodName: "GenerateManifest",
Handler: _RepositoryService_GenerateManifest_Handler,
},
{
MethodName: "ListDir",
Handler: _RepositoryService_ListDir_Handler,
},
{
MethodName: "GetFile",
Handler: _RepositoryService_GetFile_Handler,
@@ -437,6 +526,79 @@ func (m *ManifestResponse) MarshalTo(dAtA []byte) (int, error) {
return i, nil
}
func (m *ListDirRequest) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *ListDirRequest) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if m.Repo != nil {
dAtA[i] = 0xa
i++
i = encodeVarintRepository(dAtA, i, uint64(m.Repo.Size()))
n2, err := m.Repo.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n2
}
if len(m.Revision) > 0 {
dAtA[i] = 0x12
i++
i = encodeVarintRepository(dAtA, i, uint64(len(m.Revision)))
i += copy(dAtA[i:], m.Revision)
}
if len(m.Path) > 0 {
dAtA[i] = 0x1a
i++
i = encodeVarintRepository(dAtA, i, uint64(len(m.Path)))
i += copy(dAtA[i:], m.Path)
}
return i, nil
}
func (m *FileList) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *FileList) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if len(m.Items) > 0 {
for _, s := range m.Items {
dAtA[i] = 0xa
i++
l = len(s)
for l >= 1<<7 {
dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
l >>= 7
i++
}
dAtA[i] = uint8(l)
i++
i += copy(dAtA[i:], s)
}
}
return i, nil
}
func (m *GetFileRequest) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@@ -456,11 +618,11 @@ func (m *GetFileRequest) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0xa
i++
i = encodeVarintRepository(dAtA, i, uint64(m.Repo.Size()))
n2, err := m.Repo.MarshalTo(dAtA[i:])
n3, err := m.Repo.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n2
i += n3
}
if len(m.Revision) > 0 {
dAtA[i] = 0x12
@@ -572,6 +734,36 @@ func (m *ManifestResponse) Size() (n int) {
return n
}
func (m *ListDirRequest) Size() (n int) {
var l int
_ = l
if m.Repo != nil {
l = m.Repo.Size()
n += 1 + l + sovRepository(uint64(l))
}
l = len(m.Revision)
if l > 0 {
n += 1 + l + sovRepository(uint64(l))
}
l = len(m.Path)
if l > 0 {
n += 1 + l + sovRepository(uint64(l))
}
return n
}
func (m *FileList) Size() (n int) {
var l int
_ = l
if len(m.Items) > 0 {
for _, s := range m.Items {
l = len(s)
n += 1 + l + sovRepository(uint64(l))
}
}
return n
}
func (m *GetFileRequest) Size() (n int) {
var l int
_ = l
@@ -1040,6 +1232,226 @@ func (m *ManifestResponse) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *ListDirRequest) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRepository
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: ListDirRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: ListDirRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Repo", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRepository
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthRepository
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Repo == nil {
m.Repo = &github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.Repository{}
}
if err := m.Repo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Revision", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRepository
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthRepository
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Revision = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRepository
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthRepository
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Path = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipRepository(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthRepository
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *FileList) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRepository
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: FileList: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: FileList: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRepository
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthRepository
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Items = append(m.Items, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipRepository(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthRepository
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *GetFileRequest) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
@@ -1370,38 +1782,40 @@ var (
func init() { proto.RegisterFile("reposerver/repository/repository.proto", fileDescriptorRepository) }
var fileDescriptorRepository = []byte{
// 518 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x54, 0xdd, 0x8a, 0x13, 0x31,
0x18, 0x35, 0xbb, 0xdd, 0x6a, 0x53, 0x71, 0xd7, 0x20, 0x32, 0x4c, 0x4b, 0x29, 0x03, 0x4a, 0x6f,
0x4c, 0x68, 0xbd, 0xf1, 0x4e, 0xf0, 0x6f, 0x11, 0x5c, 0x56, 0xc6, 0x2b, 0xbd, 0x91, 0x74, 0xfa,
0x39, 0x8d, 0xed, 0x24, 0x31, 0xc9, 0x0e, 0xf8, 0x14, 0x3e, 0x80, 0x6f, 0xe0, 0x93, 0x78, 0xe9,
0x23, 0x48, 0xef, 0x04, 0x1f, 0x42, 0x26, 0x4d, 0x3b, 0xb3, 0xbb, 0x65, 0x6f, 0x44, 0xf0, 0xee,
0xe4, 0x7c, 0x99, 0x73, 0xbe, 0x39, 0x49, 0x3e, 0x7c, 0xdf, 0x80, 0x56, 0x16, 0x4c, 0x09, 0x86,
0x79, 0x28, 0x9c, 0x32, 0x9f, 0x1b, 0x90, 0x6a, 0xa3, 0x9c, 0x22, 0xb8, 0x66, 0xe2, 0x3b, 0xb9,
0xca, 0x95, 0xa7, 0x59, 0x85, 0xd6, 0x3b, 0xe2, 0x7e, 0xae, 0x54, 0xbe, 0x04, 0xc6, 0xb5, 0x60,
0x5c, 0x4a, 0xe5, 0xb8, 0x13, 0x4a, 0xda, 0x50, 0x4d, 0x16, 0x8f, 0x2c, 0x15, 0xca, 0x57, 0x33,
0x65, 0x80, 0x95, 0x63, 0x96, 0x83, 0x04, 0xc3, 0x1d, 0xcc, 0xc2, 0x9e, 0x97, 0xb9, 0x70, 0xf3,
0xb3, 0x29, 0xcd, 0x54, 0xc1, 0xb8, 0xf1, 0x16, 0x1f, 0x3d, 0x78, 0x90, 0xcd, 0x98, 0x5e, 0xe4,
0xd5, 0xc7, 0x96, 0x71, 0xad, 0x97, 0x22, 0xf3, 0xe2, 0xac, 0x1c, 0xf3, 0xa5, 0x9e, 0xf3, 0x4b,
0x52, 0xc9, 0xef, 0x3d, 0x7c, 0x78, 0xc2, 0xa5, 0xf8, 0x00, 0xd6, 0xa5, 0xf0, 0xe9, 0x0c, 0xac,
0x23, 0x6f, 0x71, 0xab, 0xfa, 0x89, 0x08, 0x0d, 0xd1, 0xa8, 0x3b, 0x79, 0x4e, 0x6b, 0x37, 0xba,
0x71, 0xf3, 0xe0, 0x7d, 0x36, 0xa3, 0x7a, 0x91, 0xd3, 0xca, 0x8d, 0x36, 0xdc, 0xe8, 0xc6, 0x8d,
0xa6, 0xdb, 0x2c, 0x52, 0x2f, 0x49, 0x62, 0x7c, 0xc3, 0x40, 0x29, 0xac, 0x50, 0x32, 0xda, 0x1b,
0xa2, 0x51, 0x27, 0xdd, 0xae, 0x09, 0xc1, 0x2d, 0xcd, 0xdd, 0x3c, 0xda, 0xf7, 0xbc, 0xc7, 0x64,
0x88, 0xbb, 0x20, 0x4b, 0x61, 0x94, 0x2c, 0x40, 0xba, 0xa8, 0xe5, 0x4b, 0x4d, 0xaa, 0x52, 0xe4,
0x5a, 0xbf, 0xe2, 0x53, 0x58, 0x46, 0x07, 0x6b, 0xc5, 0xcd, 0x9a, 0x7c, 0x41, 0xb8, 0x97, 0xa9,
0x42, 0x2b, 0x09, 0xd2, 0xbd, 0xe6, 0x86, 0x17, 0xe0, 0xc0, 0x9c, 0x96, 0x60, 0x8c, 0x98, 0x81,
0x8d, 0xda, 0xc3, 0xfd, 0x51, 0x77, 0x72, 0xf2, 0x17, 0x3f, 0xf8, 0xf4, 0x92, 0x7a, 0x7a, 0x95,
0x63, 0xf2, 0x0b, 0xe1, 0xa3, 0x3a, 0x6e, 0xab, 0x95, 0xb4, 0x40, 0xfa, 0xb8, 0x53, 0x04, 0xce,
0x46, 0x68, 0xb8, 0x3f, 0xea, 0xa4, 0x35, 0x51, 0x55, 0x25, 0x2f, 0xc0, 0x6a, 0x9e, 0x41, 0xc8,
0xac, 0x26, 0xc8, 0x5d, 0xdc, 0x5e, 0x5f, 0xca, 0x10, 0x5b, 0x58, 0x9d, 0x0b, 0xba, 0x75, 0x21,
0x68, 0xc0, 0x6d, 0x5d, 0xb5, 0x66, 0xa3, 0x83, 0x7f, 0x11, 0x40, 0x10, 0x4f, 0xbe, 0x22, 0x7c,
0xeb, 0x18, 0xdc, 0x0b, 0xb1, 0x84, 0xff, 0xef, 0x66, 0x25, 0xf7, 0xf0, 0xe1, 0xb6, 0xb9, 0x70,
0x0e, 0x04, 0xb7, 0x66, 0xdc, 0x71, 0xdf, 0xdd, 0xcd, 0xd4, 0xe3, 0xc9, 0x37, 0x84, 0x6f, 0xd7,
0x5e, 0x6f, 0xc0, 0x94, 0x22, 0x03, 0x72, 0x8a, 0x8f, 0x8e, 0xc3, 0x43, 0xda, 0x9c, 0x26, 0xe9,
0xd1, 0xc6, 0x2c, 0xb8, 0xf0, 0xa4, 0xe2, 0xfe, 0xee, 0xe2, 0xda, 0x38, 0xb9, 0x46, 0x9e, 0xe1,
0xeb, 0xa1, 0x1b, 0x12, 0x37, 0xb7, 0x9e, 0xcf, 0x2f, 0xee, 0xed, 0xac, 0x6d, 0x54, 0x9e, 0x3c,
0xfe, 0xbe, 0x1a, 0xa0, 0x1f, 0xab, 0x01, 0xfa, 0xb9, 0x1a, 0xa0, 0x77, 0xe3, 0xab, 0xa6, 0xc4,
0xce, 0x69, 0x36, 0x6d, 0xfb, 0xa1, 0xf0, 0xf0, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x37, 0x1e,
0x65, 0x64, 0xed, 0x04, 0x00, 0x00,
// 560 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x54, 0x4d, 0x8b, 0xd3, 0x40,
0x18, 0xde, 0x6c, 0x3f, 0x76, 0x3b, 0x15, 0x77, 0x1d, 0x8a, 0x84, 0xb4, 0x94, 0x10, 0x50, 0x7a,
0x31, 0xa1, 0xf5, 0xe2, 0x45, 0x04, 0x5d, 0x5d, 0x84, 0x5d, 0x56, 0xe2, 0x49, 0x2f, 0x32, 0x4d,
0x5f, 0xd3, 0xb1, 0xcd, 0xcc, 0x38, 0x33, 0x1b, 0xf0, 0x57, 0xf8, 0x03, 0xfc, 0x43, 0x1e, 0xfd,
0x09, 0xd2, 0xdb, 0x82, 0x3f, 0x42, 0x32, 0x9d, 0x34, 0xe9, 0x6e, 0xd9, 0x8b, 0x08, 0x7b, 0x7b,
0xbf, 0xf2, 0x3c, 0xcf, 0x3c, 0x79, 0x79, 0xd1, 0x63, 0x09, 0x82, 0x2b, 0x90, 0x39, 0xc8, 0xc8,
0x84, 0x54, 0x73, 0xf9, 0xad, 0x16, 0x86, 0x42, 0x72, 0xcd, 0x31, 0xaa, 0x2a, 0x5e, 0x2f, 0xe5,
0x29, 0x37, 0xe5, 0xa8, 0x88, 0xd6, 0x13, 0xde, 0x20, 0xe5, 0x3c, 0x5d, 0x42, 0x44, 0x04, 0x8d,
0x08, 0x63, 0x5c, 0x13, 0x4d, 0x39, 0x53, 0xb6, 0x1b, 0x2c, 0x9e, 0xa9, 0x90, 0x72, 0xd3, 0x4d,
0xb8, 0x84, 0x28, 0x1f, 0x47, 0x29, 0x30, 0x90, 0x44, 0xc3, 0xcc, 0xce, 0xbc, 0x4d, 0xa9, 0x9e,
0x5f, 0x4e, 0xc3, 0x84, 0x67, 0x11, 0x91, 0x86, 0xe2, 0x8b, 0x09, 0x9e, 0x24, 0xb3, 0x48, 0x2c,
0xd2, 0xe2, 0x63, 0x15, 0x11, 0x21, 0x96, 0x34, 0x31, 0xe0, 0x51, 0x3e, 0x26, 0x4b, 0x31, 0x27,
0x37, 0xa0, 0x82, 0x3f, 0xfb, 0xe8, 0xe8, 0x9c, 0x30, 0xfa, 0x19, 0x94, 0x8e, 0xe1, 0xeb, 0x25,
0x28, 0x8d, 0x3f, 0xa0, 0x66, 0xf1, 0x08, 0xd7, 0xf1, 0x9d, 0x51, 0x77, 0xf2, 0x3a, 0xac, 0xd8,
0xc2, 0x92, 0xcd, 0x04, 0x9f, 0x92, 0x59, 0x28, 0x16, 0x69, 0x58, 0xb0, 0x85, 0x35, 0xb6, 0xb0,
0x64, 0x0b, 0xe3, 0x8d, 0x17, 0xb1, 0x81, 0xc4, 0x1e, 0x3a, 0x94, 0x90, 0x53, 0x45, 0x39, 0x73,
0xf7, 0x7d, 0x67, 0xd4, 0x89, 0x37, 0x39, 0xc6, 0xa8, 0x29, 0x88, 0x9e, 0xbb, 0x0d, 0x53, 0x37,
0x31, 0xf6, 0x51, 0x17, 0x58, 0x4e, 0x25, 0x67, 0x19, 0x30, 0xed, 0x36, 0x4d, 0xab, 0x5e, 0x2a,
0x10, 0x89, 0x10, 0x67, 0x64, 0x0a, 0x4b, 0xb7, 0xb5, 0x46, 0x2c, 0x73, 0xfc, 0xdd, 0x41, 0xfd,
0x84, 0x67, 0x82, 0x33, 0x60, 0xfa, 0x1d, 0x91, 0x24, 0x03, 0x0d, 0xf2, 0x22, 0x07, 0x29, 0xe9,
0x0c, 0x94, 0xdb, 0xf6, 0x1b, 0xa3, 0xee, 0xe4, 0xfc, 0x1f, 0x1e, 0xf8, 0xea, 0x06, 0x7a, 0x7c,
0x1b, 0x63, 0x70, 0xe5, 0xa0, 0xe3, 0xca, 0x6e, 0x25, 0x38, 0x53, 0x80, 0x07, 0xa8, 0x93, 0xd9,
0x9a, 0x72, 0x1d, 0xbf, 0x31, 0xea, 0xc4, 0x55, 0xa1, 0xe8, 0x32, 0x92, 0x81, 0x12, 0x24, 0x01,
0xeb, 0x59, 0x55, 0xc0, 0x0f, 0x51, 0x7b, 0xbd, 0x94, 0xd6, 0x36, 0x9b, 0x6d, 0x19, 0xdd, 0xbc,
0x66, 0x34, 0xa0, 0xb6, 0x28, 0xa4, 0x29, 0xb7, 0xf5, 0x3f, 0x0c, 0xb0, 0xe0, 0xc1, 0x0f, 0x07,
0xdd, 0x3f, 0xa3, 0x4a, 0x9f, 0x50, 0x79, 0xf7, 0x36, 0x2b, 0xf0, 0xd1, 0xe1, 0x1b, 0xba, 0x84,
0x42, 0x20, 0xee, 0xa1, 0x16, 0xd5, 0x90, 0x95, 0xe6, 0xaf, 0x13, 0xa3, 0xff, 0x14, 0x74, 0x31,
0x75, 0x07, 0xf5, 0x3f, 0x42, 0x47, 0x1b, 0x71, 0x76, 0x8f, 0x30, 0x6a, 0xce, 0x88, 0x26, 0x46,
0xdd, 0xbd, 0xd8, 0xc4, 0x93, 0x2b, 0x07, 0x3d, 0xa8, 0xb8, 0xde, 0x83, 0xcc, 0x69, 0x02, 0xf8,
0x02, 0x1d, 0x9f, 0xda, 0x43, 0x50, 0x6e, 0x23, 0xee, 0x87, 0xb5, 0x5b, 0x76, 0xed, 0x24, 0x78,
0x83, 0xdd, 0xcd, 0x35, 0x71, 0xb0, 0x87, 0x9f, 0xa3, 0x03, 0xfb, 0xab, 0xb1, 0x57, 0x1f, 0xdd,
0xfe, 0xff, 0x5e, 0xaf, 0xde, 0x2b, 0xed, 0x0f, 0xf6, 0xf0, 0x09, 0x3a, 0xb0, 0x8f, 0xd9, 0xfe,
0x7c, 0xdb, 0x7e, 0xaf, 0xbf, 0xb3, 0x57, 0x8a, 0x78, 0xf9, 0xe2, 0xe7, 0x6a, 0xe8, 0xfc, 0x5a,
0x0d, 0x9d, 0xdf, 0xab, 0xa1, 0xf3, 0x71, 0x7c, 0xdb, 0x91, 0xdc, 0x79, 0xcc, 0xa7, 0x6d, 0x73,
0x13, 0x9f, 0xfe, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x01, 0x96, 0x09, 0x12, 0xec, 0x05, 0x00, 0x00,
}

View File

@@ -26,6 +26,18 @@ message ManifestResponse {
repeated github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.ComponentParameter params = 5;
}
// ListDirRequest requests a repository directory structure
message ListDirRequest {
github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.Repository repo = 1;
string revision = 2;
string path = 3;
}
// FileList returns the contents of the repo of a ListDir request
message FileList {
repeated string items = 1;
}
// GetFileRequest return
message GetFileRequest {
github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.Repository repo = 1;
@@ -46,6 +58,10 @@ service RepositoryService {
rpc GenerateManifest(ManifestRequest) returns (ManifestResponse) {
}
// ListDir returns the file contents at the specified repo and path
rpc ListDir(ListDirRequest) returns (FileList) {
}
// GetFile returns the file contents at the specified repo and path
rpc GetFile(GetFileRequest) returns (GetFileResponse) {
}

View File

@@ -23,10 +23,12 @@ import (
log "github.com/sirupsen/logrus"
"golang.org/x/net/context"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"k8s.io/api/core/v1"
apierr "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
@@ -68,6 +70,13 @@ func (s *Server) List(ctx context.Context, q *ApplicationQuery) (*appv1.Applicat
// Create creates an application
func (s *Server) Create(ctx context.Context, a *appv1.Application) (*appv1.Application, error) {
upsert := false
md, ok := metadata.FromIncomingContext(ctx)
if ok {
upsertMd := md["upsert"]
upsert = len(upsertMd) > 0 && upsertMd[0] == "true"
}
err := s.validateApp(ctx, &a.Spec)
if err != nil {
return nil, err
@@ -76,21 +85,92 @@ func (s *Server) Create(ctx context.Context, a *appv1.Application) (*appv1.Appli
out, err := s.appclientset.ArgoprojV1alpha1().Applications(s.ns).Create(a)
if apierr.IsAlreadyExists(err) {
// act idempotent if existing spec matches new spec
existing, err2 := s.appclientset.ArgoprojV1alpha1().Applications(s.ns).Get(a.Name, metav1.GetOptions{})
if err2 == nil {
existing, getErr := s.appclientset.ArgoprojV1alpha1().Applications(s.ns).Get(a.Name, metav1.GetOptions{})
if getErr != nil {
return nil, fmt.Errorf("unable to check existing application details: %v", err)
}
if upsert {
existing.Spec = a.Spec
out, err = s.appclientset.ArgoprojV1alpha1().Applications(s.ns).Update(existing)
} else {
if reflect.DeepEqual(existing.Spec, a.Spec) {
return existing, nil
} else {
return nil, fmt.Errorf("existing application spec is different, use upsert flag to force update")
}
}
}
return out, err
}
// GetManifests returns application manifests
func (s *Server) GetManifests(ctx context.Context, q *ManifestQuery) (*repository.ManifestResponse, error) {
app, err := s.appclientset.ArgoprojV1alpha1().Applications(s.ns).Get(*q.AppName, metav1.GetOptions{})
if err != nil {
return nil, err
}
repo := s.getRepo(ctx, app.Spec.Source.RepoURL)
conn, repoClient, err := s.repoClientset.NewRepositoryClient()
if err != nil {
return nil, err
}
defer util.Close(conn)
overrides := make([]*appv1.ComponentParameter, len(app.Spec.Source.ComponentParameterOverrides))
if app.Spec.Source.ComponentParameterOverrides != nil {
for i := range app.Spec.Source.ComponentParameterOverrides {
item := app.Spec.Source.ComponentParameterOverrides[i]
overrides[i] = &item
}
}
revision := app.Spec.Source.TargetRevision
if q.Revision != nil && *q.Revision != "" {
revision = *q.Revision
}
manifestInfo, err := repoClient.GenerateManifest(context.Background(), &repository.ManifestRequest{
Repo: repo,
Environment: app.Spec.Source.Environment,
Path: app.Spec.Source.Path,
Revision: revision,
ComponentParameterOverrides: overrides,
AppLabel: app.Name,
})
if err != nil {
return nil, err
}
return manifestInfo, nil
}
// Get returns an application by name
func (s *Server) Get(ctx context.Context, q *ApplicationQuery) (*appv1.Application, error) {
return s.appclientset.ArgoprojV1alpha1().Applications(s.ns).Get(*q.Name, metav1.GetOptions{})
}
// ListResourceEvents returns a list of event resources
func (s *Server) ListResourceEvents(ctx context.Context, q *ApplicationResourceEventsQuery) (*v1.EventList, error) {
config, namespace, err := s.getApplicationClusterConfig(*q.AppName)
if err != nil {
return nil, err
}
kubeClientset, err := kubernetes.NewForConfig(config)
if err != nil {
return nil, err
}
fieldSelector := fields.SelectorFromSet(map[string]string{
"involvedObject.name": *q.ResName,
"involvedObject.uid": *q.ResUid,
"involvedObject.namespace": namespace,
}).String()
log.Infof("Querying for resource events with field selector: %s", fieldSelector)
opts := metav1.ListOptions{FieldSelector: fieldSelector}
return kubeClientset.CoreV1().Events(namespace).List(opts)
}
// Update updates an application
func (s *Server) Update(ctx context.Context, a *appv1.Application) (*appv1.Application, error) {
err := s.validateApp(ctx, &a.Spec)
@@ -416,19 +496,25 @@ func (s *Server) Rollback(ctx context.Context, rollbackReq *ApplicationRollbackR
}
func (s *Server) setAppOperation(ctx context.Context, appName string, operationCreator func(app *appv1.Application) (*appv1.Operation, error)) (*appv1.Application, error) {
app, err := s.Get(ctx, &ApplicationQuery{Name: &appName})
if err != nil {
return nil, err
for {
a, err := s.Get(ctx, &ApplicationQuery{Name: &appName})
if err != nil {
return nil, err
}
if a.Operation != nil {
return nil, status.Errorf(codes.InvalidArgument, "another operation is already in progress")
}
op, err := operationCreator(a)
if err != nil {
return nil, err
}
a.Operation = op
a.Status.OperationState = nil
_, err = s.appclientset.ArgoprojV1alpha1().Applications(s.ns).Update(a)
if err != nil && apierr.IsConflict(err) {
log.Warnf("Failed to set operation for app '%s' due to update conflict. Retrying again...", appName)
} else {
return a, err
}
}
if app.Operation != nil {
return nil, status.Errorf(codes.InvalidArgument, "another operation is already in progress")
}
op, err := operationCreator(app)
if err != nil {
return nil, err
}
app.Operation = op
app.Status.OperationState = nil
_, err = s.Update(ctx, app)
return app, err
}

View File

@@ -13,6 +13,8 @@
It has these top-level messages:
ApplicationQuery
ApplicationResourceEventsQuery
ManifestQuery
ApplicationResponse
DeleteApplicationRequest
ApplicationSyncRequest
@@ -29,9 +31,10 @@ import fmt "fmt"
import math "math"
import _ "github.com/gogo/protobuf/gogoproto"
import _ "google.golang.org/genproto/googleapis/api/annotations"
import _ "k8s.io/api/core/v1"
import k8s_io_api_core_v1 "k8s.io/api/core/v1"
import k8s_io_apimachinery_pkg_apis_meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
import github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
import repository "github.com/argoproj/argo-cd/reposerver/repository"
import context "golang.org/x/net/context"
import grpc "google.golang.org/grpc"
@@ -67,6 +70,68 @@ func (m *ApplicationQuery) GetName() string {
return ""
}
// ApplicationEventsQuery is a query for application resource events
type ApplicationResourceEventsQuery struct {
AppName *string `protobuf:"bytes,1,req,name=appName" json:"appName,omitempty"`
ResName *string `protobuf:"bytes,2,req,name=resName" json:"resName,omitempty"`
ResUid *string `protobuf:"bytes,3,req,name=resUid" json:"resUid,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ApplicationResourceEventsQuery) Reset() { *m = ApplicationResourceEventsQuery{} }
func (m *ApplicationResourceEventsQuery) String() string { return proto.CompactTextString(m) }
func (*ApplicationResourceEventsQuery) ProtoMessage() {}
func (*ApplicationResourceEventsQuery) Descriptor() ([]byte, []int) {
return fileDescriptorApplication, []int{1}
}
func (m *ApplicationResourceEventsQuery) GetAppName() string {
if m != nil && m.AppName != nil {
return *m.AppName
}
return ""
}
func (m *ApplicationResourceEventsQuery) GetResName() string {
if m != nil && m.ResName != nil {
return *m.ResName
}
return ""
}
func (m *ApplicationResourceEventsQuery) GetResUid() string {
if m != nil && m.ResUid != nil {
return *m.ResUid
}
return ""
}
// ManifestQuery is a query for manifest resources
type ManifestQuery struct {
AppName *string `protobuf:"bytes,1,req,name=appName" json:"appName,omitempty"`
Revision *string `protobuf:"bytes,2,opt,name=revision" json:"revision,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ManifestQuery) Reset() { *m = ManifestQuery{} }
func (m *ManifestQuery) String() string { return proto.CompactTextString(m) }
func (*ManifestQuery) ProtoMessage() {}
func (*ManifestQuery) Descriptor() ([]byte, []int) { return fileDescriptorApplication, []int{2} }
func (m *ManifestQuery) GetAppName() string {
if m != nil && m.AppName != nil {
return *m.AppName
}
return ""
}
func (m *ManifestQuery) GetRevision() string {
if m != nil && m.Revision != nil {
return *m.Revision
}
return ""
}
type ApplicationResponse struct {
XXX_unrecognized []byte `json:"-"`
}
@@ -74,7 +139,7 @@ type ApplicationResponse struct {
func (m *ApplicationResponse) Reset() { *m = ApplicationResponse{} }
func (m *ApplicationResponse) String() string { return proto.CompactTextString(m) }
func (*ApplicationResponse) ProtoMessage() {}
func (*ApplicationResponse) Descriptor() ([]byte, []int) { return fileDescriptorApplication, []int{1} }
func (*ApplicationResponse) Descriptor() ([]byte, []int) { return fileDescriptorApplication, []int{3} }
type DeleteApplicationRequest struct {
Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
@@ -86,7 +151,7 @@ func (m *DeleteApplicationRequest) Reset() { *m = DeleteApplicationReque
func (m *DeleteApplicationRequest) String() string { return proto.CompactTextString(m) }
func (*DeleteApplicationRequest) ProtoMessage() {}
func (*DeleteApplicationRequest) Descriptor() ([]byte, []int) {
return fileDescriptorApplication, []int{2}
return fileDescriptorApplication, []int{4}
}
func (m *DeleteApplicationRequest) GetName() string {
@@ -116,7 +181,7 @@ func (m *ApplicationSyncRequest) Reset() { *m = ApplicationSyncRequest{}
func (m *ApplicationSyncRequest) String() string { return proto.CompactTextString(m) }
func (*ApplicationSyncRequest) ProtoMessage() {}
func (*ApplicationSyncRequest) Descriptor() ([]byte, []int) {
return fileDescriptorApplication, []int{3}
return fileDescriptorApplication, []int{5}
}
func (m *ApplicationSyncRequest) GetName() string {
@@ -158,7 +223,7 @@ func (m *ApplicationSpecRequest) Reset() { *m = ApplicationSpecRequest{}
func (m *ApplicationSpecRequest) String() string { return proto.CompactTextString(m) }
func (*ApplicationSpecRequest) ProtoMessage() {}
func (*ApplicationSpecRequest) Descriptor() ([]byte, []int) {
return fileDescriptorApplication, []int{4}
return fileDescriptorApplication, []int{6}
}
func (m *ApplicationSpecRequest) GetAppName() string {
@@ -187,7 +252,7 @@ func (m *ApplicationRollbackRequest) Reset() { *m = ApplicationRollbackR
func (m *ApplicationRollbackRequest) String() string { return proto.CompactTextString(m) }
func (*ApplicationRollbackRequest) ProtoMessage() {}
func (*ApplicationRollbackRequest) Descriptor() ([]byte, []int) {
return fileDescriptorApplication, []int{5}
return fileDescriptorApplication, []int{7}
}
func (m *ApplicationRollbackRequest) GetName() string {
@@ -227,7 +292,7 @@ type DeletePodQuery struct {
func (m *DeletePodQuery) Reset() { *m = DeletePodQuery{} }
func (m *DeletePodQuery) String() string { return proto.CompactTextString(m) }
func (*DeletePodQuery) ProtoMessage() {}
func (*DeletePodQuery) Descriptor() ([]byte, []int) { return fileDescriptorApplication, []int{6} }
func (*DeletePodQuery) Descriptor() ([]byte, []int) { return fileDescriptorApplication, []int{8} }
func (m *DeletePodQuery) GetApplicationName() string {
if m != nil && m.ApplicationName != nil {
@@ -257,7 +322,7 @@ type PodLogsQuery struct {
func (m *PodLogsQuery) Reset() { *m = PodLogsQuery{} }
func (m *PodLogsQuery) String() string { return proto.CompactTextString(m) }
func (*PodLogsQuery) ProtoMessage() {}
func (*PodLogsQuery) Descriptor() ([]byte, []int) { return fileDescriptorApplication, []int{7} }
func (*PodLogsQuery) Descriptor() ([]byte, []int) { return fileDescriptorApplication, []int{9} }
func (m *PodLogsQuery) GetApplicationName() string {
if m != nil && m.ApplicationName != nil {
@@ -317,7 +382,7 @@ type LogEntry struct {
func (m *LogEntry) Reset() { *m = LogEntry{} }
func (m *LogEntry) String() string { return proto.CompactTextString(m) }
func (*LogEntry) ProtoMessage() {}
func (*LogEntry) Descriptor() ([]byte, []int) { return fileDescriptorApplication, []int{8} }
func (*LogEntry) Descriptor() ([]byte, []int) { return fileDescriptorApplication, []int{10} }
func (m *LogEntry) GetContent() string {
if m != nil {
@@ -335,6 +400,8 @@ func (m *LogEntry) GetTimeStamp() k8s_io_apimachinery_pkg_apis_meta_v1.Time {
func init() {
proto.RegisterType((*ApplicationQuery)(nil), "application.ApplicationQuery")
proto.RegisterType((*ApplicationResourceEventsQuery)(nil), "application.ApplicationResourceEventsQuery")
proto.RegisterType((*ManifestQuery)(nil), "application.ManifestQuery")
proto.RegisterType((*ApplicationResponse)(nil), "application.ApplicationResponse")
proto.RegisterType((*DeleteApplicationRequest)(nil), "application.DeleteApplicationRequest")
proto.RegisterType((*ApplicationSyncRequest)(nil), "application.ApplicationSyncRequest")
@@ -358,12 +425,16 @@ const _ = grpc.SupportPackageIsVersion4
type ApplicationServiceClient interface {
// List returns list of applications
List(ctx context.Context, in *ApplicationQuery, opts ...grpc.CallOption) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ApplicationList, error)
// ListResourceEvents returns a list of event resources
ListResourceEvents(ctx context.Context, in *ApplicationResourceEventsQuery, opts ...grpc.CallOption) (*k8s_io_api_core_v1.EventList, error)
// Watch returns stream of application change events.
Watch(ctx context.Context, in *ApplicationQuery, opts ...grpc.CallOption) (ApplicationService_WatchClient, error)
// Create creates an application
Create(ctx context.Context, in *github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.Application, opts ...grpc.CallOption) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.Application, error)
// Get returns an application by name
Get(ctx context.Context, in *ApplicationQuery, opts ...grpc.CallOption) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.Application, error)
// GetManifests returns application manifests
GetManifests(ctx context.Context, in *ManifestQuery, opts ...grpc.CallOption) (*repository.ManifestResponse, error)
// Update updates an application
Update(ctx context.Context, in *github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.Application, opts ...grpc.CallOption) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.Application, error)
// Update updates an application spec
@@ -397,6 +468,15 @@ func (c *applicationServiceClient) List(ctx context.Context, in *ApplicationQuer
return out, nil
}
func (c *applicationServiceClient) ListResourceEvents(ctx context.Context, in *ApplicationResourceEventsQuery, opts ...grpc.CallOption) (*k8s_io_api_core_v1.EventList, error) {
out := new(k8s_io_api_core_v1.EventList)
err := grpc.Invoke(ctx, "/application.ApplicationService/ListResourceEvents", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *applicationServiceClient) Watch(ctx context.Context, in *ApplicationQuery, opts ...grpc.CallOption) (ApplicationService_WatchClient, error) {
stream, err := grpc.NewClientStream(ctx, &_ApplicationService_serviceDesc.Streams[0], c.cc, "/application.ApplicationService/Watch", opts...)
if err != nil {
@@ -447,6 +527,15 @@ func (c *applicationServiceClient) Get(ctx context.Context, in *ApplicationQuery
return out, nil
}
func (c *applicationServiceClient) GetManifests(ctx context.Context, in *ManifestQuery, opts ...grpc.CallOption) (*repository.ManifestResponse, error) {
out := new(repository.ManifestResponse)
err := grpc.Invoke(ctx, "/application.ApplicationService/GetManifests", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *applicationServiceClient) Update(ctx context.Context, in *github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.Application, opts ...grpc.CallOption) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.Application, error) {
out := new(github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.Application)
err := grpc.Invoke(ctx, "/application.ApplicationService/Update", in, out, c.cc, opts...)
@@ -538,12 +627,16 @@ func (x *applicationServicePodLogsClient) Recv() (*LogEntry, error) {
type ApplicationServiceServer interface {
// List returns list of applications
List(context.Context, *ApplicationQuery) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ApplicationList, error)
// ListResourceEvents returns a list of event resources
ListResourceEvents(context.Context, *ApplicationResourceEventsQuery) (*k8s_io_api_core_v1.EventList, error)
// Watch returns stream of application change events.
Watch(*ApplicationQuery, ApplicationService_WatchServer) error
// Create creates an application
Create(context.Context, *github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.Application) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.Application, error)
// Get returns an application by name
Get(context.Context, *ApplicationQuery) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.Application, error)
// GetManifests returns application manifests
GetManifests(context.Context, *ManifestQuery) (*repository.ManifestResponse, error)
// Update updates an application
Update(context.Context, *github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.Application) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.Application, error)
// Update updates an application spec
@@ -582,6 +675,24 @@ func _ApplicationService_List_Handler(srv interface{}, ctx context.Context, dec
return interceptor(ctx, in, info, handler)
}
func _ApplicationService_ListResourceEvents_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ApplicationResourceEventsQuery)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ApplicationServiceServer).ListResourceEvents(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/application.ApplicationService/ListResourceEvents",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ApplicationServiceServer).ListResourceEvents(ctx, req.(*ApplicationResourceEventsQuery))
}
return interceptor(ctx, in, info, handler)
}
func _ApplicationService_Watch_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(ApplicationQuery)
if err := stream.RecvMsg(m); err != nil {
@@ -639,6 +750,24 @@ func _ApplicationService_Get_Handler(srv interface{}, ctx context.Context, dec f
return interceptor(ctx, in, info, handler)
}
func _ApplicationService_GetManifests_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ManifestQuery)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ApplicationServiceServer).GetManifests(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/application.ApplicationService/GetManifests",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ApplicationServiceServer).GetManifests(ctx, req.(*ManifestQuery))
}
return interceptor(ctx, in, info, handler)
}
func _ApplicationService_Update_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.Application)
if err := dec(in); err != nil {
@@ -776,6 +905,10 @@ var _ApplicationService_serviceDesc = grpc.ServiceDesc{
MethodName: "List",
Handler: _ApplicationService_List_Handler,
},
{
MethodName: "ListResourceEvents",
Handler: _ApplicationService_ListResourceEvents_Handler,
},
{
MethodName: "Create",
Handler: _ApplicationService_Create_Handler,
@@ -784,6 +917,10 @@ var _ApplicationService_serviceDesc = grpc.ServiceDesc{
MethodName: "Get",
Handler: _ApplicationService_Get_Handler,
},
{
MethodName: "GetManifests",
Handler: _ApplicationService_GetManifests_Handler,
},
{
MethodName: "Update",
Handler: _ApplicationService_Update_Handler,
@@ -851,6 +988,86 @@ func (m *ApplicationQuery) MarshalTo(dAtA []byte) (int, error) {
return i, nil
}
func (m *ApplicationResourceEventsQuery) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *ApplicationResourceEventsQuery) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if m.AppName == nil {
return 0, proto.NewRequiredNotSetError("appName")
} else {
dAtA[i] = 0xa
i++
i = encodeVarintApplication(dAtA, i, uint64(len(*m.AppName)))
i += copy(dAtA[i:], *m.AppName)
}
if m.ResName == nil {
return 0, proto.NewRequiredNotSetError("resName")
} else {
dAtA[i] = 0x12
i++
i = encodeVarintApplication(dAtA, i, uint64(len(*m.ResName)))
i += copy(dAtA[i:], *m.ResName)
}
if m.ResUid == nil {
return 0, proto.NewRequiredNotSetError("resUid")
} else {
dAtA[i] = 0x1a
i++
i = encodeVarintApplication(dAtA, i, uint64(len(*m.ResUid)))
i += copy(dAtA[i:], *m.ResUid)
}
if m.XXX_unrecognized != nil {
i += copy(dAtA[i:], m.XXX_unrecognized)
}
return i, nil
}
func (m *ManifestQuery) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *ManifestQuery) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if m.AppName == nil {
return 0, proto.NewRequiredNotSetError("appName")
} else {
dAtA[i] = 0xa
i++
i = encodeVarintApplication(dAtA, i, uint64(len(*m.AppName)))
i += copy(dAtA[i:], *m.AppName)
}
if m.Revision != nil {
dAtA[i] = 0x12
i++
i = encodeVarintApplication(dAtA, i, uint64(len(*m.Revision)))
i += copy(dAtA[i:], *m.Revision)
}
if m.XXX_unrecognized != nil {
i += copy(dAtA[i:], m.XXX_unrecognized)
}
return i, nil
}
func (m *ApplicationResponse) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@@ -1202,6 +1419,44 @@ func (m *ApplicationQuery) Size() (n int) {
return n
}
func (m *ApplicationResourceEventsQuery) Size() (n int) {
var l int
_ = l
if m.AppName != nil {
l = len(*m.AppName)
n += 1 + l + sovApplication(uint64(l))
}
if m.ResName != nil {
l = len(*m.ResName)
n += 1 + l + sovApplication(uint64(l))
}
if m.ResUid != nil {
l = len(*m.ResUid)
n += 1 + l + sovApplication(uint64(l))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func (m *ManifestQuery) Size() (n int) {
var l int
_ = l
if m.AppName != nil {
l = len(*m.AppName)
n += 1 + l + sovApplication(uint64(l))
}
if m.Revision != nil {
l = len(*m.Revision)
n += 1 + l + sovApplication(uint64(l))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func (m *ApplicationResponse) Size() (n int) {
var l int
_ = l
@@ -1425,6 +1680,276 @@ func (m *ApplicationQuery) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *ApplicationResourceEventsQuery) Unmarshal(dAtA []byte) error {
var hasFields [1]uint64
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApplication
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: ApplicationResourceEventsQuery: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: ApplicationResourceEventsQuery: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field AppName", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApplication
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthApplication
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
s := string(dAtA[iNdEx:postIndex])
m.AppName = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000001)
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ResName", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApplication
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthApplication
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
s := string(dAtA[iNdEx:postIndex])
m.ResName = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000002)
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ResUid", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApplication
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthApplication
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
s := string(dAtA[iNdEx:postIndex])
m.ResUid = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000004)
default:
iNdEx = preIndex
skippy, err := skipApplication(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthApplication
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if hasFields[0]&uint64(0x00000001) == 0 {
return proto.NewRequiredNotSetError("appName")
}
if hasFields[0]&uint64(0x00000002) == 0 {
return proto.NewRequiredNotSetError("resName")
}
if hasFields[0]&uint64(0x00000004) == 0 {
return proto.NewRequiredNotSetError("resUid")
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *ManifestQuery) Unmarshal(dAtA []byte) error {
var hasFields [1]uint64
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApplication
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: ManifestQuery: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: ManifestQuery: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field AppName", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApplication
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthApplication
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
s := string(dAtA[iNdEx:postIndex])
m.AppName = &s
iNdEx = postIndex
hasFields[0] |= uint64(0x00000001)
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Revision", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApplication
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthApplication
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
s := string(dAtA[iNdEx:postIndex])
m.Revision = &s
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipApplication(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthApplication
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if hasFields[0]&uint64(0x00000001) == 0 {
return proto.NewRequiredNotSetError("appName")
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *ApplicationResponse) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
@@ -2630,67 +3155,76 @@ var (
func init() { proto.RegisterFile("server/application/application.proto", fileDescriptorApplication) }
var fileDescriptorApplication = []byte{
// 990 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x57, 0x4f, 0x6f, 0xdc, 0x44,
0x14, 0x67, 0x9c, 0xed, 0xfe, 0x79, 0x29, 0x7f, 0x34, 0xb4, 0x95, 0xeb, 0xa6, 0xc9, 0xca, 0x49,
0x61, 0x09, 0xc2, 0x6e, 0x22, 0x10, 0xa8, 0x2a, 0x07, 0x42, 0x0b, 0x2d, 0x8a, 0xaa, 0xb0, 0x29,
0x42, 0xe2, 0x82, 0xa6, 0xf6, 0xe0, 0x98, 0x78, 0x67, 0x8c, 0x67, 0x76, 0xd1, 0x52, 0xe5, 0x00,
0x07, 0x04, 0x27, 0x84, 0xb8, 0x70, 0x83, 0x0f, 0x50, 0x3e, 0x00, 0xdf, 0xa0, 0xdc, 0x90, 0xb8,
0x57, 0x28, 0xe2, 0xcc, 0x67, 0x40, 0x33, 0xb6, 0xd7, 0xb3, 0xc9, 0xee, 0x96, 0x3f, 0x3e, 0x70,
0x1b, 0xbf, 0x79, 0xf3, 0xde, 0xef, 0xbd, 0xdf, 0x9b, 0x79, 0xcf, 0xb0, 0x21, 0x68, 0x36, 0xa2,
0x99, 0x4f, 0xd2, 0x34, 0x89, 0x03, 0x22, 0x63, 0xce, 0xcc, 0xb5, 0x97, 0x66, 0x5c, 0x72, 0xbc,
0x6c, 0x88, 0x9c, 0x73, 0x11, 0x8f, 0xb8, 0x96, 0xfb, 0x6a, 0x95, 0xab, 0x38, 0x2b, 0x11, 0xe7,
0x51, 0x42, 0x7d, 0x92, 0xc6, 0x3e, 0x61, 0x8c, 0x4b, 0xad, 0x2c, 0x8a, 0x5d, 0xf7, 0xf0, 0x35,
0xe1, 0xc5, 0x5c, 0xef, 0x06, 0x3c, 0xa3, 0xfe, 0x68, 0xcb, 0x8f, 0x28, 0xa3, 0x19, 0x91, 0x34,
0x2c, 0x74, 0x5e, 0xae, 0x74, 0x06, 0x24, 0x38, 0x88, 0x19, 0xcd, 0xc6, 0x7e, 0x7a, 0x18, 0x29,
0x81, 0xf0, 0x07, 0x54, 0x92, 0x59, 0xa7, 0x6e, 0x47, 0xb1, 0x3c, 0x18, 0xde, 0xf3, 0x02, 0x3e,
0xf0, 0x49, 0xa6, 0x81, 0x7d, 0xac, 0x17, 0x2f, 0x05, 0x61, 0x75, 0xda, 0x0c, 0x6f, 0xb4, 0x45,
0x92, 0xf4, 0x80, 0x9c, 0x32, 0xe5, 0x3e, 0x07, 0xcf, 0xbc, 0x51, 0xe9, 0xbd, 0x3b, 0xa4, 0xd9,
0x18, 0x63, 0x68, 0x30, 0x32, 0xa0, 0x36, 0xea, 0xa2, 0x5e, 0xa7, 0xaf, 0xd7, 0xee, 0x79, 0x78,
0xd6, 0xd0, 0xeb, 0x53, 0x91, 0x72, 0x26, 0xa8, 0x7b, 0x0b, 0xec, 0x1b, 0x34, 0xa1, 0x92, 0x4e,
0x6d, 0x7e, 0x32, 0xa4, 0x42, 0x1a, 0x66, 0xac, 0xd2, 0x0c, 0xb6, 0xa1, 0x15, 0x10, 0x11, 0x90,
0x90, 0xda, 0x56, 0x17, 0xf5, 0xda, 0xfd, 0xf2, 0xd3, 0xfd, 0x0a, 0xc1, 0x05, 0xc3, 0xc8, 0xfe,
0x98, 0x05, 0x8b, 0x0c, 0x75, 0xa1, 0x9d, 0xd1, 0x51, 0x2c, 0x62, 0xce, 0x6c, 0x4b, 0xc9, 0x77,
0x1a, 0x0f, 0x1f, 0xad, 0x3d, 0xd1, 0x9f, 0x48, 0xf1, 0x0a, 0x34, 0xc3, 0x6c, 0xdc, 0x1f, 0x32,
0x7b, 0xa9, 0x6b, 0xf5, 0xda, 0xc5, 0x7e, 0x21, 0xc3, 0x0e, 0x9c, 0x49, 0xb3, 0x21, 0xa3, 0x76,
0xc3, 0xd8, 0xcc, 0x45, 0xee, 0xf7, 0x27, 0xa0, 0xa4, 0x74, 0x02, 0xc5, 0x86, 0x16, 0x49, 0xd3,
0x3b, 0x15, 0x9a, 0xf2, 0x13, 0x87, 0xd0, 0x10, 0x29, 0x0d, 0x34, 0x98, 0xe5, 0xed, 0x77, 0xbc,
0x8a, 0x22, 0xaf, 0xa4, 0x48, 0x2f, 0x3e, 0x0c, 0x42, 0x2f, 0x3d, 0x8c, 0x3c, 0x45, 0x91, 0x67,
0x56, 0x5d, 0x49, 0x91, 0x77, 0xc2, 0x75, 0x81, 0x4d, 0x5b, 0x77, 0xbf, 0x44, 0xe0, 0x98, 0xa9,
0xe6, 0x49, 0x72, 0x8f, 0x04, 0x87, 0x8b, 0x32, 0xe5, 0x80, 0x15, 0x87, 0x1a, 0xd6, 0xd2, 0x0e,
0x28, 0x53, 0xc7, 0x8f, 0xd6, 0xac, 0xdb, 0x37, 0xfa, 0x56, 0x1c, 0xfe, 0x87, 0x1c, 0xdd, 0x85,
0xa7, 0x72, 0xe2, 0xf7, 0x78, 0x98, 0x57, 0x4d, 0x0f, 0x9e, 0x36, 0xc2, 0x31, 0x52, 0x74, 0x52,
0xac, 0x92, 0x98, 0xf2, 0x50, 0x6b, 0x58, 0x79, 0x12, 0x8b, 0x4f, 0xf7, 0x81, 0x05, 0x67, 0xf7,
0x78, 0xb8, 0xcb, 0x23, 0x51, 0x9b, 0x51, 0xec, 0x42, 0x27, 0xe0, 0x4c, 0x12, 0x75, 0xb9, 0x74,
0x9c, 0x65, 0xad, 0x54, 0x62, 0xdc, 0x83, 0xb3, 0x22, 0x66, 0x01, 0xdd, 0xa7, 0x01, 0x67, 0xa1,
0xd0, 0x11, 0x2f, 0x15, 0x6a, 0x53, 0x3b, 0xf8, 0x16, 0x74, 0xf4, 0xf7, 0xdd, 0x78, 0x40, 0xed,
0x33, 0x5d, 0xd4, 0x5b, 0xde, 0xde, 0xf4, 0xf2, 0x5b, 0xec, 0x99, 0xb7, 0xb8, 0x22, 0x59, 0xdd,
0x62, 0x6f, 0xb4, 0xe5, 0xa9, 0x13, 0xfd, 0xea, 0xb0, 0xc2, 0x25, 0x49, 0x9c, 0xec, 0xc6, 0x8c,
0x0a, 0xbb, 0x69, 0x38, 0xac, 0xc4, 0x8a, 0xa0, 0x8f, 0x78, 0x92, 0xf0, 0x4f, 0xed, 0x96, 0x49,
0x50, 0x2e, 0x73, 0x3f, 0x83, 0xf6, 0x2e, 0x8f, 0x6e, 0x32, 0x99, 0x8d, 0xf1, 0x2a, 0xb4, 0x54,
0x38, 0x94, 0xc9, 0x3c, 0x43, 0x85, 0x6a, 0x29, 0xc4, 0x77, 0xa0, 0x23, 0xe3, 0x01, 0xdd, 0x97,
0x64, 0x90, 0x16, 0x45, 0xfa, 0x0f, 0x70, 0x4f, 0x90, 0x95, 0x26, 0xb6, 0xff, 0x7c, 0x12, 0xb0,
0x59, 0xa9, 0x34, 0x1b, 0xc5, 0x01, 0xc5, 0xdf, 0x20, 0x68, 0xec, 0xc6, 0x42, 0xe2, 0xcb, 0x53,
0xc5, 0x7d, 0xf2, 0x8d, 0x71, 0x6a, 0xba, 0x20, 0xca, 0x95, 0xbb, 0xf2, 0xc5, 0x6f, 0x7f, 0x7c,
0x67, 0x5d, 0xc0, 0xe7, 0xf4, 0x53, 0x3b, 0xda, 0x32, 0x5f, 0x3e, 0x81, 0x7f, 0x40, 0x70, 0xe6,
0x7d, 0x22, 0x83, 0x83, 0xc7, 0x41, 0xda, 0xab, 0x07, 0x92, 0xf6, 0x75, 0x73, 0x44, 0x99, 0x74,
0xd7, 0x35, 0xb0, 0xcb, 0xf8, 0x52, 0x09, 0x4c, 0xc8, 0x8c, 0x92, 0xc1, 0x14, 0xbe, 0xab, 0x08,
0xff, 0x8c, 0xa0, 0xf9, 0x66, 0x46, 0x89, 0xa4, 0xf8, 0xad, 0x7a, 0x30, 0x38, 0x35, 0xd9, 0x71,
0xd7, 0x74, 0x04, 0x17, 0xdd, 0x99, 0xa9, 0xbd, 0x86, 0x36, 0xf1, 0xb7, 0x08, 0x96, 0xde, 0xa6,
0x8f, 0xa5, 0xbb, 0x2e, 0x3c, 0xa7, 0x32, 0x6a, 0xe2, 0xf1, 0xef, 0xab, 0x07, 0xef, 0x08, 0xff,
0x82, 0xa0, 0xf9, 0x5e, 0x1a, 0xfe, 0x1f, 0xf3, 0xe9, 0x6b, 0xfc, 0x2f, 0x38, 0x1b, 0xb3, 0xf1,
0xab, 0x2b, 0x17, 0x12, 0x49, 0x3c, 0x1d, 0x88, 0xca, 0xef, 0x4f, 0x08, 0x20, 0x8f, 0x45, 0xf5,
0x02, 0xbc, 0x3e, 0x2f, 0xcd, 0x46, 0x93, 0x72, 0x6a, 0x6c, 0x3e, 0xae, 0xa7, 0x01, 0xf7, 0x9c,
0xf5, 0xd9, 0x80, 0x8b, 0xee, 0x77, 0xe4, 0xab, 0xee, 0xa4, 0xf0, 0x8e, 0xa0, 0x99, 0xf7, 0x05,
0x7c, 0x65, 0xca, 0xc1, 0xbc, 0x29, 0xc1, 0xe9, 0xce, 0x8b, 0x68, 0x32, 0x63, 0x14, 0x9c, 0x6f,
0x2e, 0xe4, 0xfc, 0x47, 0x04, 0x0d, 0x35, 0x33, 0x2c, 0xc8, 0x50, 0x35, 0x51, 0xd4, 0x46, 0xe7,
0x8b, 0x1a, 0xda, 0x15, 0xb7, 0xbb, 0x00, 0x9a, 0x2f, 0xc6, 0x4c, 0xa7, 0xe6, 0x01, 0x82, 0x76,
0xd9, 0xb0, 0xf1, 0xf3, 0x73, 0xc3, 0x9e, 0x6e, 0xe9, 0x75, 0x57, 0x9e, 0xbb, 0xb1, 0x08, 0x6a,
0x56, 0x38, 0x57, 0x70, 0xbf, 0x46, 0xd0, 0x99, 0xb4, 0x78, 0x7c, 0x69, 0x06, 0x9b, 0x65, 0xeb,
0xff, 0x1b, 0x1c, 0xbe, 0xae, 0xbd, 0xbf, 0xba, 0xf9, 0xca, 0xdc, 0x32, 0x32, 0x9b, 0xf9, 0x91,
0x9f, 0xf2, 0x50, 0xf8, 0xf7, 0x8b, 0x0e, 0x7e, 0x84, 0x3f, 0x47, 0xd0, 0x2a, 0xe6, 0x02, 0x7c,
0x71, 0xca, 0x99, 0x39, 0x2d, 0x38, 0xe7, 0xa7, 0xb6, 0xca, 0xd6, 0xe8, 0xee, 0x68, 0xe7, 0xd7,
0xf1, 0xb5, 0x7f, 0xe5, 0xdc, 0x4f, 0x78, 0x24, 0xae, 0xa2, 0x9d, 0xeb, 0x0f, 0x8f, 0x57, 0xd1,
0xaf, 0xc7, 0xab, 0xe8, 0xf7, 0xe3, 0x55, 0xf4, 0x81, 0xb7, 0x68, 0x04, 0x3f, 0xfd, 0x7f, 0xf1,
0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa5, 0xe1, 0x3c, 0x55, 0x74, 0x0c, 0x00, 0x00,
// 1132 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x57, 0xcd, 0x6e, 0x1c, 0xc5,
0x13, 0xff, 0xf7, 0x7a, 0xbd, 0xf6, 0xb6, 0xfd, 0x27, 0xa8, 0x49, 0xac, 0xcd, 0xc4, 0x5f, 0x1a,
0xdb, 0x64, 0x71, 0x94, 0x19, 0xdb, 0x02, 0x81, 0xa2, 0x70, 0xc0, 0xc4, 0x24, 0x41, 0x26, 0x32,
0xeb, 0x44, 0x48, 0x5c, 0x50, 0x67, 0xa6, 0x32, 0x1e, 0x3c, 0x3b, 0x3d, 0x74, 0xf7, 0x2e, 0xda,
0x44, 0x3e, 0xc0, 0x01, 0xc1, 0x09, 0x21, 0x2e, 0xdc, 0xe0, 0x01, 0xc2, 0x03, 0xf0, 0x06, 0xe1,
0x86, 0xc4, 0x3d, 0x42, 0x16, 0x8f, 0xc1, 0x01, 0x75, 0xcf, 0xcc, 0x4e, 0x8f, 0xbd, 0x1f, 0x7c,
0xec, 0x81, 0x5b, 0x77, 0x55, 0x75, 0xd5, 0xaf, 0x3e, 0xa6, 0xaa, 0x06, 0xaf, 0x0b, 0xe0, 0x5d,
0xe0, 0x2e, 0x4d, 0x92, 0x28, 0xf4, 0xa8, 0x0c, 0x59, 0x6c, 0x9e, 0x9d, 0x84, 0x33, 0xc9, 0xc8,
0x9c, 0x41, 0xb2, 0x2e, 0x06, 0x2c, 0x60, 0x9a, 0xee, 0xaa, 0x53, 0x2a, 0x62, 0x2d, 0x06, 0x8c,
0x05, 0x11, 0xb8, 0x34, 0x09, 0x5d, 0x1a, 0xc7, 0x4c, 0x6a, 0x61, 0x91, 0x71, 0xed, 0xe3, 0x37,
0x84, 0x13, 0x32, 0xcd, 0xf5, 0x18, 0x07, 0xb7, 0xbb, 0xed, 0x06, 0x10, 0x03, 0xa7, 0x12, 0xfc,
0x4c, 0xe6, 0xd5, 0x42, 0xa6, 0x4d, 0xbd, 0xa3, 0x30, 0x06, 0xde, 0x73, 0x93, 0xe3, 0x40, 0x11,
0x84, 0xdb, 0x06, 0x49, 0x07, 0xbd, 0xba, 0x1b, 0x84, 0xf2, 0xa8, 0xf3, 0xd0, 0xf1, 0x58, 0xdb,
0xa5, 0x5c, 0x03, 0xfb, 0x58, 0x1f, 0xae, 0x7b, 0x7e, 0xf1, 0xda, 0x74, 0xaf, 0xbb, 0x4d, 0xa3,
0xe4, 0x88, 0x9e, 0x57, 0xb5, 0x3b, 0x4a, 0x15, 0x87, 0x84, 0x65, 0xb1, 0xd2, 0xc7, 0x50, 0x32,
0xde, 0x33, 0x8e, 0xa9, 0x0e, 0xfb, 0x65, 0xfc, 0xe2, 0x5b, 0x85, 0xad, 0xf7, 0x3b, 0xc0, 0x7b,
0x84, 0xe0, 0x6a, 0x4c, 0xdb, 0xd0, 0x40, 0xab, 0xa8, 0x59, 0x6f, 0xe9, 0xb3, 0x1d, 0xe1, 0x65,
0x43, 0xae, 0x05, 0x82, 0x75, 0xb8, 0x07, 0x7b, 0x5d, 0x88, 0xa5, 0x48, 0x5f, 0x35, 0xf0, 0x0c,
0x4d, 0x92, 0x7b, 0xe9, 0xc3, 0x4a, 0xb3, 0xde, 0xca, 0xaf, 0x8a, 0xc3, 0x41, 0x68, 0x4e, 0x25,
0xe5, 0x64, 0x57, 0xb2, 0x80, 0x6b, 0x1c, 0xc4, 0x83, 0xd0, 0x6f, 0x4c, 0x69, 0x46, 0x76, 0xb3,
0xf7, 0xf0, 0xff, 0xdf, 0xa3, 0x71, 0xf8, 0x08, 0x84, 0x1c, 0xa7, 0xdc, 0xc2, 0xb3, 0x1c, 0xba,
0xa1, 0x08, 0x59, 0xdc, 0xa8, 0x68, 0xc0, 0xfd, 0xbb, 0x7d, 0x09, 0xbf, 0x54, 0x06, 0x9d, 0xb0,
0x58, 0x80, 0x7d, 0x07, 0x37, 0x6e, 0x41, 0x04, 0x12, 0x4a, 0xcc, 0x4f, 0x3a, 0x20, 0xa4, 0xe1,
0x7b, 0x25, 0xf7, 0x5d, 0x19, 0xf7, 0xa8, 0xf0, 0xa8, 0x0f, 0xda, 0xc2, 0x6c, 0x2b, 0xbf, 0xda,
0x5f, 0x22, 0xbc, 0x60, 0x28, 0x39, 0xec, 0xc5, 0xde, 0x28, 0x45, 0xab, 0x25, 0xac, 0x95, 0x66,
0x7d, 0xb7, 0xfa, 0xec, 0xf9, 0xca, 0xff, 0x0a, 0xc4, 0x64, 0x11, 0xd7, 0x7c, 0xde, 0x6b, 0x75,
0x62, 0x1d, 0x90, 0xd9, 0x8c, 0x9f, 0xd1, 0x88, 0x85, 0xa7, 0x13, 0xde, 0x89, 0xa1, 0x51, 0x35,
0x98, 0x29, 0xc9, 0xfe, 0xee, 0x0c, 0x94, 0x04, 0xfa, 0x50, 0x86, 0x07, 0xcf, 0xc7, 0x55, 0x91,
0x80, 0xa7, 0xc1, 0xcc, 0xed, 0xbc, 0xeb, 0x14, 0x05, 0xe5, 0xe4, 0x05, 0xa5, 0x0f, 0x1f, 0x79,
0xbe, 0x93, 0x1c, 0x07, 0x8e, 0xaa, 0x4d, 0xc7, 0xfc, 0xdc, 0xf2, 0xda, 0x74, 0xce, 0x98, 0xce,
0xb0, 0x69, 0xed, 0xf6, 0x17, 0x08, 0x5b, 0x66, 0xa8, 0x59, 0x14, 0x3d, 0xa4, 0xde, 0xf1, 0xa8,
0x48, 0x59, 0xb8, 0x12, 0xfa, 0x1a, 0xd6, 0xd4, 0x2e, 0x56, 0xaa, 0x4e, 0x9f, 0xaf, 0x54, 0xee,
0xde, 0x6a, 0x55, 0x42, 0xff, 0x5f, 0xc4, 0xe8, 0x3e, 0x7e, 0x21, 0x4d, 0xfc, 0x01, 0xf3, 0xd3,
0xba, 0x6a, 0xe2, 0x0b, 0x86, 0x3b, 0x46, 0x88, 0xce, 0x92, 0x55, 0x10, 0x13, 0xe6, 0x9b, 0x45,
0x9c, 0x5d, 0xed, 0xa7, 0x15, 0x3c, 0x7f, 0xc0, 0xfc, 0x7d, 0x16, 0x88, 0x89, 0x29, 0x25, 0x36,
0xae, 0x7b, 0x2c, 0x96, 0x54, 0x75, 0x95, 0xf4, 0xe3, 0xc8, 0x5c, 0x29, 0xc8, 0xa4, 0x89, 0xe7,
0x45, 0x18, 0x7b, 0x70, 0x08, 0x1e, 0x8b, 0x7d, 0xa1, 0x3d, 0x9e, 0xca, 0xc4, 0x4a, 0x1c, 0x72,
0x07, 0xd7, 0xf5, 0xfd, 0x7e, 0xd8, 0x86, 0xc6, 0xf4, 0x2a, 0x6a, 0xce, 0xed, 0x6c, 0x3a, 0x69,
0xfb, 0x72, 0xcc, 0xf6, 0x55, 0x24, 0x59, 0xb5, 0x2f, 0xa7, 0xbb, 0xed, 0xa8, 0x17, 0xad, 0xe2,
0xb1, 0xc2, 0x25, 0x69, 0x18, 0xed, 0x87, 0x31, 0x88, 0x46, 0xcd, 0x30, 0x58, 0x90, 0x55, 0x82,
0x1e, 0xb1, 0x28, 0x62, 0x9f, 0x36, 0x66, 0xcc, 0x04, 0xa5, 0x34, 0xfb, 0x31, 0x9e, 0xdd, 0x67,
0xc1, 0x5e, 0x2c, 0x79, 0x8f, 0x2c, 0xe3, 0x19, 0xe5, 0x0e, 0xc4, 0x32, 0x8d, 0x50, 0x26, 0x9a,
0x13, 0xc9, 0x3d, 0x5c, 0x97, 0x61, 0x1b, 0x0e, 0x25, 0x6d, 0x27, 0x59, 0x91, 0xfe, 0x0d, 0xdc,
0x7d, 0x64, 0xb9, 0x8a, 0x9d, 0x3f, 0x2e, 0x60, 0x62, 0x56, 0x2a, 0xf0, 0x6e, 0xe8, 0x01, 0xf9,
0x1a, 0xe1, 0xea, 0x7e, 0x28, 0x24, 0x59, 0x2a, 0x15, 0xf7, 0xd9, 0xc6, 0x68, 0x4d, 0xe8, 0x03,
0x51, 0xa6, 0xec, 0xc5, 0xcf, 0x7f, 0xfd, 0xfd, 0xdb, 0xca, 0x02, 0xb9, 0xa8, 0x67, 0x4c, 0x77,
0xdb, 0x6c, 0xf9, 0x42, 0x21, 0x22, 0x4a, 0xac, 0xdc, 0x68, 0xc9, 0xb5, 0x61, 0xf8, 0x06, 0x34,
0x64, 0x6b, 0xc9, 0x88, 0x94, 0xa3, 0x86, 0x98, 0x8a, 0x8b, 0x16, 0xd0, 0x00, 0xae, 0x6b, 0x00,
0x57, 0xc9, 0xc6, 0x20, 0x00, 0xee, 0x93, 0xac, 0x45, 0x9c, 0xb8, 0x90, 0x9a, 0xfe, 0x1e, 0xe1,
0xe9, 0x0f, 0xa8, 0xf4, 0x8e, 0xc6, 0x05, 0xe9, 0x60, 0x32, 0x41, 0xd2, 0xb6, 0x34, 0x5a, 0x7b,
0x4d, 0x23, 0x5d, 0x22, 0x57, 0x72, 0xa4, 0x42, 0x72, 0xa0, 0xed, 0x12, 0xe0, 0x2d, 0x44, 0x7e,
0x42, 0xb8, 0xf6, 0x36, 0x07, 0x2a, 0x81, 0xbc, 0x33, 0x19, 0x0c, 0xd6, 0x84, 0xf4, 0xd8, 0x2b,
0xda, 0x83, 0xcb, 0xf6, 0xc0, 0x64, 0xdf, 0x40, 0x9b, 0xe4, 0x1b, 0x84, 0xa7, 0x6e, 0xc3, 0xd8,
0x02, 0x9c, 0x14, 0x9e, 0x73, 0x11, 0x2d, 0xe7, 0x5e, 0xb5, 0xe0, 0x13, 0xf2, 0x18, 0xcf, 0xdf,
0x06, 0x99, 0xcf, 0x61, 0x41, 0xac, 0x92, 0xde, 0xd2, 0x7c, 0xb6, 0x16, 0x1d, 0x63, 0xb3, 0xc8,
0x59, 0xfd, 0x81, 0xbb, 0xa5, 0xcd, 0x6d, 0x92, 0xe6, 0x98, 0x52, 0x6b, 0xf7, 0x6d, 0xfd, 0x8c,
0x70, 0xed, 0x41, 0xe2, 0xff, 0x17, 0x73, 0xe9, 0x6a, 0x67, 0x5e, 0xb1, 0xd6, 0x07, 0x3b, 0xa3,
0x1a, 0x90, 0x4f, 0x25, 0x75, 0x74, 0x10, 0x55, 0x6e, 0x7f, 0x44, 0x18, 0xa7, 0xbe, 0xa8, 0xc9,
0x48, 0xd6, 0x86, 0xa5, 0xd8, 0x18, 0xd9, 0xd6, 0x04, 0x47, 0xb1, 0xed, 0x68, 0xc0, 0x4d, 0x6b,
0x6d, 0x4c, 0xf4, 0xd5, 0xac, 0x56, 0x78, 0xbb, 0xb8, 0x96, 0x4e, 0x49, 0xb2, 0x51, 0x32, 0x30,
0x6c, 0x67, 0xb2, 0x56, 0x47, 0x74, 0xa5, 0xb4, 0x00, 0xb2, 0x7a, 0xdb, 0x1c, 0x59, 0x6f, 0x3f,
0x20, 0x5c, 0x55, 0x1b, 0xd4, 0x88, 0x08, 0x15, 0xfb, 0xd5, 0xc4, 0xd2, 0x79, 0x4d, 0x43, 0xdb,
0xb0, 0x57, 0x47, 0x40, 0x73, 0x45, 0x2f, 0xd6, 0xa1, 0x79, 0x8a, 0xf0, 0x6c, 0xbe, 0xbe, 0x90,
0xab, 0x43, 0xdd, 0x2e, 0x2f, 0x38, 0x93, 0xae, 0x3c, 0x7b, 0x7d, 0x14, 0x54, 0x9e, 0x19, 0x57,
0x70, 0xbf, 0x42, 0xb8, 0xde, 0x5f, 0x78, 0xc8, 0x95, 0x01, 0xd9, 0xcc, 0x17, 0xa1, 0xbf, 0x90,
0xc3, 0x37, 0xb5, 0xf5, 0xd7, 0x37, 0x5f, 0x1b, 0x5a, 0x46, 0xe6, 0x6a, 0x73, 0xe2, 0x26, 0xcc,
0x17, 0xee, 0x93, 0x6c, 0x9f, 0x39, 0x21, 0x9f, 0x21, 0x3c, 0x93, 0x6d, 0x49, 0xe4, 0x72, 0xc9,
0x98, 0xb9, 0x3b, 0x59, 0x97, 0x4a, 0xac, 0x7c, 0x51, 0xb0, 0x77, 0xb5, 0xf1, 0x9b, 0xe4, 0xc6,
0x3f, 0x32, 0xee, 0x46, 0x2c, 0x10, 0x5b, 0x68, 0xf7, 0xe6, 0xb3, 0xd3, 0x65, 0xf4, 0xcb, 0xe9,
0x32, 0xfa, 0xed, 0x74, 0x19, 0x7d, 0xe8, 0x8c, 0xfa, 0x7d, 0x3a, 0xff, 0x9b, 0xf9, 0x67, 0x00,
0x00, 0x00, 0xff, 0xff, 0x60, 0x44, 0x17, 0x91, 0x7b, 0x0e, 0x00, 0x00,
}

View File

@@ -46,6 +46,41 @@ func request_ApplicationService_List_0(ctx context.Context, marshaler runtime.Ma
}
var (
filter_ApplicationService_ListResourceEvents_0 = &utilities.DoubleArray{Encoding: map[string]int{"appName": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
)
func request_ApplicationService_ListResourceEvents_0(ctx context.Context, marshaler runtime.Marshaler, client ApplicationServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq ApplicationResourceEventsQuery
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["appName"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "appName")
}
protoReq.AppName, err = runtime.StringP(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "appName", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_ApplicationService_ListResourceEvents_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.ListResourceEvents(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
var (
filter_ApplicationService_Watch_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
)
@@ -111,6 +146,41 @@ func request_ApplicationService_Get_0(ctx context.Context, marshaler runtime.Mar
}
var (
filter_ApplicationService_GetManifests_0 = &utilities.DoubleArray{Encoding: map[string]int{"appName": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
)
func request_ApplicationService_GetManifests_0(ctx context.Context, marshaler runtime.Marshaler, client ApplicationServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq ManifestQuery
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["appName"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "appName")
}
protoReq.AppName, err = runtime.StringP(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "appName", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_ApplicationService_GetManifests_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.GetManifests(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func request_ApplicationService_Update_0(ctx context.Context, marshaler runtime.Marshaler, client ApplicationServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq v1alpha1.Application
var metadata runtime.ServerMetadata
@@ -429,6 +499,35 @@ func RegisterApplicationServiceHandlerClient(ctx context.Context, mux *runtime.S
})
mux.Handle("GET", pattern_ApplicationService_ListResourceEvents_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
if cn, ok := w.(http.CloseNotifier); ok {
go func(done <-chan struct{}, closed <-chan bool) {
select {
case <-done:
case <-closed:
cancel()
}
}(ctx.Done(), cn.CloseNotify())
}
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_ApplicationService_ListResourceEvents_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_ApplicationService_ListResourceEvents_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_ApplicationService_Watch_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@@ -516,6 +615,35 @@ func RegisterApplicationServiceHandlerClient(ctx context.Context, mux *runtime.S
})
mux.Handle("GET", pattern_ApplicationService_GetManifests_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
if cn, ok := w.(http.CloseNotifier); ok {
go func(done <-chan struct{}, closed <-chan bool) {
select {
case <-done:
case <-closed:
cancel()
}
}(ctx.Done(), cn.CloseNotify())
}
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_ApplicationService_GetManifests_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_ApplicationService_GetManifests_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("PUT", pattern_ApplicationService_Update_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@@ -725,12 +853,16 @@ func RegisterApplicationServiceHandlerClient(ctx context.Context, mux *runtime.S
var (
pattern_ApplicationService_List_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "applications"}, ""))
pattern_ApplicationService_ListResourceEvents_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v1", "applications", "appName", "events"}, ""))
pattern_ApplicationService_Watch_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "stream", "applications"}, ""))
pattern_ApplicationService_Create_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "applications"}, ""))
pattern_ApplicationService_Get_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "applications", "name"}, ""))
pattern_ApplicationService_GetManifests_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v1", "applications", "appName", "manifests"}, ""))
pattern_ApplicationService_Update_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "applications", "metadata.name"}, ""))
pattern_ApplicationService_UpdateSpec_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v1", "applications", "appName", "spec"}, ""))
@@ -749,12 +881,16 @@ var (
var (
forward_ApplicationService_List_0 = runtime.ForwardResponseMessage
forward_ApplicationService_ListResourceEvents_0 = runtime.ForwardResponseMessage
forward_ApplicationService_Watch_0 = runtime.ForwardResponseStream
forward_ApplicationService_Create_0 = runtime.ForwardResponseMessage
forward_ApplicationService_Get_0 = runtime.ForwardResponseMessage
forward_ApplicationService_GetManifests_0 = runtime.ForwardResponseMessage
forward_ApplicationService_Update_0 = runtime.ForwardResponseMessage
forward_ApplicationService_UpdateSpec_0 = runtime.ForwardResponseMessage

View File

@@ -11,6 +11,7 @@ import "google/api/annotations.proto";
import "k8s.io/api/core/v1/generated.proto";
import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto";
import "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1/generated.proto";
import "github.com/argoproj/argo-cd/reposerver/repository/repository.proto";
// ApplicationQuery is a query for application resources
@@ -18,6 +19,19 @@ message ApplicationQuery {
optional string name = 1;
}
// ApplicationEventsQuery is a query for application resource events
message ApplicationResourceEventsQuery {
required string appName = 1;
required string resName = 2;
required string resUid = 3;
}
// ManifestQuery is a query for manifest resources
message ManifestQuery {
required string appName = 1;
optional string revision = 2;
}
message ApplicationResponse {}
message DeleteApplicationRequest {
@@ -74,6 +88,11 @@ service ApplicationService {
option (google.api.http).get = "/api/v1/applications";
}
// ListResourceEvents returns a list of event resources
rpc ListResourceEvents(ApplicationResourceEventsQuery) returns (k8s.io.api.core.v1.EventList) {
option (google.api.http).get = "/api/v1/applications/{appName}/events";
}
// Watch returns stream of application change events.
rpc Watch(ApplicationQuery) returns (stream github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.ApplicationWatchEvent) {
option (google.api.http).get = "/api/v1/stream/applications";
@@ -92,6 +111,11 @@ service ApplicationService {
option (google.api.http).get = "/api/v1/applications/{name}";
}
// GetManifests returns application manifests
rpc GetManifests(ManifestQuery) returns (repository.ManifestResponse) {
option (google.api.http).get = "/api/v1/applications/{appName}/manifests";
}
// Update updates an application
rpc Update(github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.Application) returns (github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.Application) {
option (google.api.http) = {

View File

@@ -2,19 +2,28 @@ package repository
import (
appsv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/reposerver"
"github.com/argoproj/argo-cd/reposerver/repository"
"github.com/argoproj/argo-cd/util"
"github.com/argoproj/argo-cd/util/db"
"github.com/ghodss/yaml"
"golang.org/x/net/context"
)
// Server provides a Repository service
type Server struct {
db db.ArgoDB
db db.ArgoDB
repoClientset reposerver.Clientset
}
// NewServer returns a new instance of the Repository service
func NewServer(db db.ArgoDB) *Server {
func NewServer(
repoClientset reposerver.Clientset,
db db.ArgoDB,
) *Server {
return &Server{
db: db,
db: db,
repoClientset: repoClientset,
}
}
@@ -29,6 +38,59 @@ func (s *Server) List(ctx context.Context, q *RepoQuery) (*appsv1.RepositoryList
return repoList, err
}
// ListKsonnetApps returns list of Ksonnet apps in the repo
func (s *Server) ListKsonnetApps(ctx context.Context, q *RepoKsonnetQuery) (*RepoKsonnetResponse, error) {
repo, err := s.db.GetRepository(ctx, q.Repo)
if err != nil {
return nil, err
}
// Test the repo
conn, repoClient, err := s.repoClientset.NewRepositoryClient()
if err != nil {
return nil, err
}
defer util.Close(conn)
revision := q.Revision
if revision == "" {
revision = "HEAD"
}
// Verify app.yaml is functional
req := repository.ListDirRequest{
Repo: repo,
Revision: revision,
Path: "*app.yaml",
}
getRes, err := repoClient.ListDir(ctx, &req)
if err != nil {
return nil, err
}
out := make([]*KsonnetAppSpec, 0)
for _, path := range getRes.Items {
getFileRes, err := repoClient.GetFile(ctx, &repository.GetFileRequest{
Repo: repo,
Revision: revision,
Path: path,
})
if err != nil {
return nil, err
}
var appSpec KsonnetAppSpec
err = yaml.Unmarshal(getFileRes.Data, &appSpec)
if err == nil && appSpec.Name != "" && len(appSpec.Environments) > 0 {
out = append(out, &appSpec)
}
}
return &RepoKsonnetResponse{
Data: out,
}, nil
}
// Create creates a repository
func (s *Server) Create(ctx context.Context, r *appsv1.Repository) (*appsv1.Repository, error) {
repo, err := s.db.CreateRepository(ctx, r)

File diff suppressed because it is too large Load Diff

View File

@@ -46,6 +46,23 @@ func request_RepositoryService_List_0(ctx context.Context, marshaler runtime.Mar
}
var (
filter_RepositoryService_ListKsonnetApps_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
)
func request_RepositoryService_ListKsonnetApps_0(ctx context.Context, marshaler runtime.Marshaler, client RepositoryServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq RepoKsonnetQuery
var metadata runtime.ServerMetadata
if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_RepositoryService_ListKsonnetApps_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.ListKsonnetApps(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func request_RepositoryService_Create_0(ctx context.Context, marshaler runtime.Marshaler, client RepositoryServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq v1alpha1.Repository
var metadata runtime.ServerMetadata
@@ -211,6 +228,35 @@ func RegisterRepositoryServiceHandlerClient(ctx context.Context, mux *runtime.Se
})
mux.Handle("GET", pattern_RepositoryService_ListKsonnetApps_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
if cn, ok := w.(http.CloseNotifier); ok {
go func(done <-chan struct{}, closed <-chan bool) {
select {
case <-done:
case <-closed:
cancel()
}
}(ctx.Done(), cn.CloseNotify())
}
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_RepositoryService_ListKsonnetApps_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_RepositoryService_ListKsonnetApps_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("POST", pattern_RepositoryService_Create_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@@ -333,6 +379,8 @@ func RegisterRepositoryServiceHandlerClient(ctx context.Context, mux *runtime.Se
var (
pattern_RepositoryService_List_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "repositories"}, ""))
pattern_RepositoryService_ListKsonnetApps_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "repositories", "ksonnet"}, ""))
pattern_RepositoryService_Create_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "repositories"}, ""))
pattern_RepositoryService_Get_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "repositories", "repo"}, ""))
@@ -345,6 +393,8 @@ var (
var (
forward_RepositoryService_List_0 = runtime.ForwardResponseMessage
forward_RepositoryService_ListKsonnetApps_0 = runtime.ForwardResponseMessage
forward_RepositoryService_Create_0 = runtime.ForwardResponseMessage
forward_RepositoryService_Get_0 = runtime.ForwardResponseMessage

View File

@@ -11,6 +11,41 @@ import "google/api/annotations.proto";
import "k8s.io/api/core/v1/generated.proto";
import "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1/generated.proto";
// RepoKsonnetQuery is a query for Repository contents matching a particular path
message RepoKsonnetQuery {
string repo = 1;
string revision = 2;
}
// RepoKsonnetResponse is a response for Repository contents matching a particular path
message RepoKsonnetResponse {
repeated KsonnetAppSpec data = 1;
}
// KsonnetAppSpec contains Ksonnet app response
// This roughly reflects: ksonnet/ksonnet/metadata/app/schema.go
message KsonnetAppSpec {
string name = 1;
map<string, KsonnetEnvironment> environments = 2;
}
message KsonnetEnvironment {
// Name is the user defined name of an environment
string name = 1;
// KubernetesVersion is the kubernetes version the targetted cluster is running on.
string k8sVersion = 2;
// Path is the relative project path containing metadata for this environment.
string path = 3;
// Destination stores the cluster address that this environment points to.
KsonnetEnvironmentDestination destination = 4;
}
message KsonnetEnvironmentDestination {
// Server is the Kubernetes server that the cluster is running on.
string server = 1;
// Namespace is the namespace of the Kubernetes server that targets should be deployed to
string namespace = 2;
}
// RepoQuery is a query for Repository resources
message RepoQuery {
@@ -32,6 +67,11 @@ service RepositoryService {
option (google.api.http).get = "/api/v1/repositories";
}
// ListKsonnetApps returns list of Ksonnet apps in the repo
rpc ListKsonnetApps(RepoKsonnetQuery) returns (RepoKsonnetResponse) {
option (google.api.http).get = "/api/v1/repositories/ksonnet";
}
// Create creates a repo
rpc Create(github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.Repository) returns (github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.Repository) {
option (google.api.http) = {

View File

@@ -22,6 +22,7 @@ import (
"github.com/argoproj/argo-cd/server/settings"
"github.com/argoproj/argo-cd/server/version"
"github.com/argoproj/argo-cd/util/db"
"github.com/argoproj/argo-cd/util/dex"
dexutil "github.com/argoproj/argo-cd/util/dex"
grpc_util "github.com/argoproj/argo-cd/util/grpc"
jsonutil "github.com/argoproj/argo-cd/util/json"
@@ -50,6 +51,13 @@ var (
ErrNoSession = status.Errorf(codes.Unauthenticated, "no session information")
)
var backoff = wait.Backoff{
Steps: 5,
Duration: 500 * time.Millisecond,
Factor: 1.0,
Jitter: 0.1,
}
// ArgoCDServer is the API server for ArgoCD
type ArgoCDServer struct {
ArgoCDServerOpts
@@ -59,6 +67,9 @@ type ArgoCDServer struct {
log *log.Entry
sessionMgr *util_session.SessionManager
settingsMgr *settings_util.SettingsManager
// stopCh is the channel which when closed, will shutdown the ArgoCD server
stopCh chan struct{}
}
type ArgoCDServerOpts struct {
@@ -103,10 +114,20 @@ func (a *ArgoCDServer) Run(ctx context.Context, port int) {
httpS = a.newHTTPServer(ctx, port)
}
// Cmux is used to support servicing gRPC and HTTP1.1+JSON on the same port
conn, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
errors.CheckError(err)
// Start listener
var conn net.Listener
var realErr error
_ = wait.ExponentialBackoff(backoff, func() (bool, error) {
conn, realErr = net.Listen("tcp", fmt.Sprintf(":%d", port))
if realErr != nil {
a.log.Warnf("failed listen: %v", realErr)
return false, nil
}
return true, nil
})
errors.CheckError(realErr)
// Cmux is used to support servicing gRPC and HTTP1.1+JSON on the same port
tcpm := cmux.New(conn)
var tlsm cmux.CMux
var grpcL net.Listener
@@ -135,46 +156,81 @@ func (a *ArgoCDServer) Run(ctx context.Context, port int) {
// Start the muxed listeners for our servers
log.Infof("argocd %s serving on port %d (url: %s, tls: %v, namespace: %s, sso: %v)",
argocd.GetVersion(), port, a.settings.URL, a.useTLS(), a.Namespace, a.settings.IsSSOConfigured())
go func() { errors.CheckError(grpcS.Serve(grpcL)) }()
go func() { errors.CheckError(httpS.Serve(httpL)) }()
go func() { a.checkServeErr("grpcS", grpcS.Serve(grpcL)) }()
go func() { a.checkServeErr("httpS", httpS.Serve(httpL)) }()
if a.useTLS() {
go func() { errors.CheckError(httpsS.Serve(httpsL)) }()
go func() { errors.CheckError(tlsm.Serve()) }()
go func() { a.checkServeErr("httpsS", httpsS.Serve(httpsL)) }()
go func() { a.checkServeErr("tlsm", tlsm.Serve()) }()
}
go a.initializeOIDCClientApp()
err = tcpm.Serve()
errors.CheckError(err)
go a.watchSettings(ctx)
go func() { a.checkServeErr("tcpm", tcpm.Serve()) }()
a.stopCh = make(chan struct{})
<-a.stopCh
errors.CheckError(conn.Close())
}
// initializeOIDCClientApp initializes the OIDC Client application, querying the well known oidc
// configuration path. Because ArgoCD is a OIDC client to itself, we have a chicken-and-egg problem
// of (1) serving dex over HTTP, and (2) querying the OIDC provider (ourselves) to initialize the
// app (HTTP GET http://example-argocd.com/api/dex/.well-known/openid-configuration)
// This method is expected to be invoked right after we start listening over HTTP
func (a *ArgoCDServer) initializeOIDCClientApp() {
if !a.settings.IsSSOConfigured() {
return
}
// wait for dex to become ready
dexClient, err := dexutil.NewDexClient()
errors.CheckError(err)
dexClient.WaitUntilReady()
var backoff = wait.Backoff{
Steps: 5,
Duration: 1 * time.Second,
Factor: 1.0,
Jitter: 0.1,
}
var realErr error
_ = wait.ExponentialBackoff(backoff, func() (bool, error) {
_, realErr = a.sessionMgr.OIDCProvider()
if realErr != nil {
a.log.Warnf("failed to initialize client app: %v", realErr)
return false, nil
// checkServeErr checks the error from a .Serve() call to decide if it was a graceful shutdown
func (a *ArgoCDServer) checkServeErr(name string, err error) {
if err != nil {
if a.stopCh == nil {
// a nil stopCh indicates a graceful shutdown
log.Infof("graceful shutdown %s: %v", name, err)
} else {
log.Fatalf("%s: %v", name, err)
}
return true, nil
})
errors.CheckError(realErr)
} else {
log.Infof("graceful shutdown %s", name)
}
}
func (a *ArgoCDServer) Shutdown() {
log.Info("Shut down requested")
stopCh := a.stopCh
a.stopCh = nil
if stopCh != nil {
close(stopCh)
}
}
// watchSettings watches the configmap and secret for any setting updates that would warrant a
// restart of the API server.
func (a *ArgoCDServer) watchSettings(ctx context.Context) {
a.settingsMgr.StartNotifier(ctx, a.settings)
updateCh := make(chan struct{}, 1)
a.settingsMgr.Subscribe(updateCh)
prevDexCfgBytes, err := dex.GenerateDexConfigYAML(a.settings)
errors.CheckError(err)
prevGitHubSecret := a.settings.WebhookGitHubSecret
prevGitLabSecret := a.settings.WebhookGitLabSecret
prevBitBucketUUID := a.settings.WebhookBitbucketUUID
for {
<-updateCh
newDexCfgBytes, err := dex.GenerateDexConfigYAML(a.settings)
errors.CheckError(err)
if string(newDexCfgBytes) != string(prevDexCfgBytes) {
log.Infof("dex config modified. restarting")
break
}
if prevGitHubSecret != a.settings.WebhookGitHubSecret {
log.Infof("github secret modified. restarting")
break
}
if prevGitLabSecret != a.settings.WebhookGitLabSecret {
log.Infof("gitlab secret modified. restarting")
break
}
if prevBitBucketUUID != a.settings.WebhookBitbucketUUID {
log.Infof("bitbucket uuid modified. restarting")
break
}
}
log.Info("shutting down settings watch")
a.Shutdown()
a.settingsMgr.Unsubscribe(updateCh)
close(updateCh)
}
func (a *ArgoCDServer) useTLS() bool {
@@ -204,7 +260,7 @@ func (a *ArgoCDServer) newGRPCServer() *grpc.Server {
grpcS := grpc.NewServer(sOpts...)
db := db.NewDB(a.Namespace, a.KubeClientset)
clusterService := cluster.NewServer(db)
repoService := repository.NewServer(db)
repoService := repository.NewServer(a.RepoClientset, db)
sessionService := session.NewServer(a.sessionMgr)
applicationService := application.NewServer(a.Namespace, a.KubeClientset, a.AppClientset, a.RepoClientset, db)
settingsService := settings.NewServer(a.settingsMgr)
@@ -377,9 +433,12 @@ func getToken(md metadata.MD) string {
}
// check the HTTP cookie
for _, cookieToken := range md["grpcgateway-cookie"] {
tokenPair := strings.SplitN(cookieToken, "=", 2)
if len(tokenPair) == 2 && tokenPair[0] == common.AuthCookieName {
return tokenPair[1]
header := http.Header{}
header.Add("Cookie", cookieToken)
request := http.Request{Header: header}
token, err := request.Cookie(common.AuthCookieName)
if err == nil {
return token.Value
}
}
return ""

View File

@@ -1,7 +1,6 @@
package e2e
import (
"context"
"strconv"
"testing"
"time"
@@ -18,9 +17,7 @@ import (
)
func TestAppManagement(t *testing.T) {
testApp := &v1alpha1.Application{
ObjectMeta: metav1.ObjectMeta{GenerateName: "e2e-test"},
Spec: v1alpha1.ApplicationSpec{
Source: v1alpha1.ApplicationSource{
RepoURL: "https://github.com/argoproj/argo-cd.git", Path: ".", Environment: "minikube",
@@ -72,20 +69,12 @@ func TestAppManagement(t *testing.T) {
})
t.Run("TestTrackAppStateAndSyncApp", func(t *testing.T) {
ctrl := fixture.CreateController()
ctx, cancel := context.WithCancel(context.Background())
go ctrl.Run(ctx, 1, 1)
defer cancel()
// create app and ensure it reaches OutOfSync state
app := fixture.CreateApp(t, testApp)
WaitUntil(t, func() (done bool, err error) {
app, err = fixture.AppClient.ArgoprojV1alpha1().Applications(fixture.Namespace).Get(app.ObjectMeta.Name, metav1.GetOptions{})
return err == nil && app.Status.ComparisonResult.Status != v1alpha1.ComparisonStatusUnknown, err
})
assert.Equal(t, v1alpha1.ComparisonStatusOutOfSync, app.Status.ComparisonResult.Status)
// sync app and make sure it reaches InSync state
_, err := fixture.RunCli("app", "sync", app.Name)
if err != nil {
@@ -103,30 +92,30 @@ func TestAppManagement(t *testing.T) {
t.Run("TestAppRollbackSuccessful", func(t *testing.T) {
appWithHistory := testApp.DeepCopy()
appWithHistory.Status.History = []v1alpha1.DeploymentInfo{{
ID: 1,
Revision: "abc",
}, {
ID: 2,
Revision: "cdb",
}}
ctrl := fixture.CreateController()
ctx, cancel := context.WithCancel(context.Background())
go ctrl.Run(ctx, 1, 1)
defer cancel()
// create app and ensure it reaches OutOfSync state
// create app and ensure it's comparion status is not ComparisonStatusUnknown
app := fixture.CreateApp(t, appWithHistory)
app.Status.History = []v1alpha1.DeploymentInfo{{
ID: 1,
Revision: "abc",
ComponentParameterOverrides: app.Spec.Source.ComponentParameterOverrides,
}, {
ID: 2,
Revision: "cdb",
ComponentParameterOverrides: app.Spec.Source.ComponentParameterOverrides,
}}
app, err := fixture.AppClient.ArgoprojV1alpha1().Applications(fixture.Namespace).Update(app)
if err != nil {
t.Fatalf("Unable to update app %v", err)
}
WaitUntil(t, func() (done bool, err error) {
app, err = fixture.AppClient.ArgoprojV1alpha1().Applications(fixture.Namespace).Get(app.ObjectMeta.Name, metav1.GetOptions{})
return err == nil && app.Status.ComparisonResult.Status != v1alpha1.ComparisonStatusUnknown, err
})
assert.Equal(t, v1alpha1.ComparisonStatusOutOfSync, app.Status.ComparisonResult.Status)
// sync app and make sure it reaches InSync state
_, err := fixture.RunCli("app", "rollback", app.Name, "1")
_, err = fixture.RunCli("app", "rollback", app.Name, "1")
if err != nil {
t.Fatalf("Unable to sync app %v", err)
}
@@ -137,6 +126,7 @@ func TestAppManagement(t *testing.T) {
})
assert.Equal(t, v1alpha1.ComparisonStatusSynced, app.Status.ComparisonResult.Status)
assert.True(t, app.Status.OperationState.RollbackResult != nil)
assert.Equal(t, 2, len(app.Status.OperationState.RollbackResult.Resources))
assert.True(t, app.Status.OperationState.Phase == v1alpha1.OperationSucceeded)
assert.Equal(t, 3, len(app.Status.History))
})
@@ -145,11 +135,6 @@ func TestAppManagement(t *testing.T) {
invalidApp := testApp.DeepCopy()
invalidApp.Spec.Destination.Server = "https://not-registered-cluster/api"
ctrl := fixture.CreateController()
ctx, cancel := context.WithCancel(context.Background())
go ctrl.Run(ctx, 1, 1)
defer cancel()
app := fixture.CreateApp(t, invalidApp)
WaitUntil(t, func() (done bool, err error) {
@@ -164,4 +149,39 @@ func TestAppManagement(t *testing.T) {
assert.Equal(t, v1alpha1.ComparisonStatusError, app.Status.ComparisonResult.Status)
})
t.Run("TestArgoCDWaitEnsureAppIsNotCrashing", func(t *testing.T) {
updatedApp := testApp.DeepCopy()
// deploy app and make sure it is healthy
app := fixture.CreateApp(t, updatedApp)
_, err := fixture.RunCli("app", "sync", app.Name)
if err != nil {
t.Fatalf("Unable to sync app %v", err)
}
WaitUntil(t, func() (done bool, err error) {
app, err = fixture.AppClient.ArgoprojV1alpha1().Applications(fixture.Namespace).Get(app.ObjectMeta.Name, metav1.GetOptions{})
return err == nil && app.Status.ComparisonResult.Status == v1alpha1.ComparisonStatusSynced && app.Status.Health.Status == v1alpha1.HealthStatusHealthy, err
})
// deploy app which fails and make sure it became unhealthy
app.Spec.Source.ComponentParameterOverrides = append(
app.Spec.Source.ComponentParameterOverrides,
v1alpha1.ComponentParameter{Name: "command", Value: "wrong-command", Component: "guestbook-ui"})
_, err = fixture.AppClient.ArgoprojV1alpha1().Applications(fixture.Namespace).Update(app)
if err != nil {
t.Fatalf("Unable to set app parameter %v", err)
}
_, err = fixture.RunCli("app", "sync", app.Name)
if err != nil {
t.Fatalf("Unable to sync app %v", err)
}
WaitUntil(t, func() (done bool, err error) {
app, err = fixture.AppClient.ArgoprojV1alpha1().Applications(fixture.Namespace).Get(app.ObjectMeta.Name, metav1.GetOptions{})
return err == nil && app.Status.ComparisonResult.Status == v1alpha1.ComparisonStatusSynced && app.Status.Health.Status == v1alpha1.HealthStatusDegraded, err
})
})
}

View File

@@ -1,7 +1,6 @@
package e2e
import (
"bytes"
"context"
"fmt"
"log"
@@ -11,6 +10,10 @@ import (
"testing"
"time"
"encoding/json"
"strings"
"github.com/argoproj/argo-cd/cmd/argocd/commands"
"github.com/argoproj/argo-cd/common"
"github.com/argoproj/argo-cd/controller"
@@ -31,6 +34,7 @@ import (
"k8s.io/api/core/v1"
apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
@@ -125,22 +129,11 @@ func (f *Fixture) setup() error {
})
ctx, cancel := context.WithCancel(context.Background())
go func() {
err = repoServerGRPC.Serve(repoServerListener)
}()
go func() {
apiServer.Run(ctx, apiServerPort)
}()
f.tearDownCallback = func() {
cancel()
repoServerGRPC.Stop()
}
if err != nil {
return err
}
return waitUntilE(func() (done bool, err error) {
err = waitUntilE(func() (done bool, err error) {
clientset, err := f.NewApiClientset()
if err != nil {
return false, nil
@@ -153,6 +146,22 @@ func (f *Fixture) setup() error {
_, err = appClient.List(context.Background(), &application.ApplicationQuery{})
return err == nil, nil
})
ctrl := f.createController()
ctrlCtx, cancelCtrl := context.WithCancel(context.Background())
go ctrl.Run(ctrlCtx, 1, 1)
go func() {
err = repoServerGRPC.Serve(repoServerListener)
}()
f.tearDownCallback = func() {
cancel()
cancelCtrl()
repoServerGRPC.Stop()
}
return err
}
func (f *Fixture) ensureClusterRegistered() error {
@@ -176,7 +185,28 @@ func (f *Fixture) TearDown() {
if f.tearDownCallback != nil {
f.tearDownCallback()
}
err := f.KubeClient.CoreV1().Namespaces().Delete(f.Namespace, &metav1.DeleteOptions{})
apps, err := f.AppClient.ArgoprojV1alpha1().Applications(f.Namespace).List(metav1.ListOptions{})
if err == nil {
for _, app := range apps.Items {
if len(app.Finalizers) > 0 {
var patch []byte
patch, err = json.Marshal(map[string]interface{}{
"metadata": map[string]interface{}{
"finalizers": make([]string, 0),
},
})
if err == nil {
_, err = f.AppClient.ArgoprojV1alpha1().Applications(app.Namespace).Patch(app.Name, types.MergePatchType, patch)
}
}
if err != nil {
break
}
}
}
if err == nil {
err = f.KubeClient.CoreV1().Namespaces().Delete(f.Namespace, &metav1.DeleteOptions{})
}
if err != nil {
println("Unable to tear down fixture")
}
@@ -227,6 +257,8 @@ func NewFixture() (*Fixture, error) {
// CreateApp creates application with appropriate controller instance id.
func (f *Fixture) CreateApp(t *testing.T, application *v1alpha1.Application) *v1alpha1.Application {
application = application.DeepCopy()
application.Name = fmt.Sprintf("e2e-test-%v", time.Now().Unix())
labels := application.ObjectMeta.Labels
if labels == nil {
labels = make(map[string]string)
@@ -234,6 +266,10 @@ func (f *Fixture) CreateApp(t *testing.T, application *v1alpha1.Application) *v1
}
labels[common.LabelKeyApplicationControllerInstanceID] = f.InstanceID
application.Spec.Source.ComponentParameterOverrides = append(
application.Spec.Source.ComponentParameterOverrides,
v1alpha1.ComponentParameter{Name: "name", Value: application.Name, Component: "guestbook-ui"})
app, err := f.AppClient.ArgoprojV1alpha1().Applications(f.Namespace).Create(application)
if err != nil {
t.Fatal(fmt.Sprintf("Unable to create app %v", err))
@@ -241,8 +277,8 @@ func (f *Fixture) CreateApp(t *testing.T, application *v1alpha1.Application) *v1
return app
}
// CreateController creates new controller instance
func (f *Fixture) CreateController() *controller.ApplicationController {
// createController creates new controller instance
func (f *Fixture) createController() *controller.ApplicationController {
appStateManager := controller.NewAppStateManager(
f.DB, f.AppClient, reposerver.NewRepositoryServerClientset(f.RepoServerAddress), f.Namespace)
@@ -259,7 +295,7 @@ func (f *Fixture) CreateController() *controller.ApplicationController {
&controller.ApplicationControllerConfig{Namespace: f.Namespace, InstanceID: f.InstanceID})
}
func (f *Fixture) NewApiClientset() (argocdclient.ServerClient, error) {
func (f *Fixture) NewApiClientset() (argocdclient.Client, error) {
return argocdclient.NewClient(&argocdclient.ClientOptions{
Insecure: true,
PlainText: true,
@@ -268,12 +304,21 @@ func (f *Fixture) NewApiClientset() (argocdclient.ServerClient, error) {
}
func (f *Fixture) RunCli(args ...string) (string, error) {
cmd := commands.NewCommand()
cmd.SetArgs(append(args, "--server", f.ApiServerAddress, "--plaintext"))
output := new(bytes.Buffer)
cmd.SetOutput(output)
err := cmd.Execute()
return output.String(), err
args = append([]string{"run", "../../cmd/argocd/main.go"}, args...)
cmd := exec.Command("go", append(args, "--server", f.ApiServerAddress, "--plaintext")...)
outBytes, err := cmd.Output()
if err != nil {
exErr, ok := err.(*exec.ExitError)
if !ok {
return "", err
}
errOutput := string(exErr.Stderr)
if outBytes != nil {
errOutput = string(outBytes) + "\n" + errOutput
}
return "", fmt.Errorf(strings.TrimSpace(errOutput))
}
return string(outBytes), nil
}
func waitUntilE(condition wait.ConditionFunc) error {
@@ -346,6 +391,10 @@ func (c *FakeGitClient) LsRemote(s string) (string, error) {
return "abcdef123456890", nil
}
func (c *FakeGitClient) LsFiles(s string) ([]string, error) {
return []string{"abcdef123456890"}, nil
}
func (c *FakeGitClient) CommitSHA() (string, error) {
return "abcdef123456890", nil
}

View File

@@ -123,7 +123,8 @@ func repoURLToSecretName(repo string) string {
h := fnv.New32a()
_, _ = h.Write([]byte(repo))
parts := strings.Split(strings.TrimSuffix(repo, ".git"), "/")
return fmt.Sprintf("repo-%s-%v", parts[len(parts)-1], h.Sum32())
shortName := strings.Replace(parts[len(parts)-1], "_", "-", -1)
return fmt.Sprintf("repo-%s-%v", shortName, h.Sum32())
}
// repoToStringData converts a repository object to string data for serialization to a secret

View File

@@ -8,6 +8,7 @@ func TestRepoURLToSecretName(t *testing.T) {
"https://github.com/argoproj/ARGO-cd": "repo-argo-cd-821842295",
"https://github.com/argoproj/argo-cd": "repo-argo-cd-821842295",
"https://github.com/argoproj/argo-cd.git": "repo-argo-cd-821842295",
"https://github.com/argoproj/argo_cd.git": "repo-argo-cd-1049844989",
"ssh://git@github.com/argoproj/argo-cd.git": "repo-argo-cd-1019298066",
}

View File

@@ -8,21 +8,14 @@ import (
"github.com/argoproj/argo-cd/util/settings"
"github.com/ghodss/yaml"
log "github.com/sirupsen/logrus"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
)
func GenerateDexConfigYAML(kubeClientset kubernetes.Interface, namespace string) ([]byte, error) {
settingsMgr := settings.NewSettingsManager(kubeClientset, namespace)
settings, err := settingsMgr.GetSettings()
if err != nil {
return nil, err
}
func GenerateDexConfigYAML(settings *settings.ArgoCDSettings) ([]byte, error) {
if !settings.IsSSOConfigured() {
return nil, nil
}
var dexCfg map[string]interface{}
err = yaml.Unmarshal([]byte(settings.DexConfig), &dexCfg)
err := yaml.Unmarshal([]byte(settings.DexConfig), &dexCfg)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal dex.config from configmap: %v", err)
}
@@ -70,28 +63,10 @@ func GenerateDexConfigYAML(kubeClientset kubernetes.Interface, namespace string)
connectors[i] = connector
}
dexCfg["connectors"] = connectors
secretValues, err := getSecretValues(kubeClientset, namespace)
if err != nil {
return nil, err
}
dexCfg = replaceMapSecrets(dexCfg, secretValues)
dexCfg = replaceMapSecrets(dexCfg, settings.Secrets)
return yaml.Marshal(dexCfg)
}
// getSecretValues is a convenience to get the ArgoCD secret data as a map[string]string
func getSecretValues(kubeClientset kubernetes.Interface, namespace string) (map[string]string, error) {
sec, err := kubeClientset.CoreV1().Secrets(namespace).Get(common.ArgoCDSecretName, metav1.GetOptions{})
if err != nil {
return nil, err
}
secretValues := make(map[string]string, len(sec.Data))
for k, v := range sec.Data {
secretValues[k] = string(v)
}
return secretValues, nil
}
// replaceMapSecrets takes a json object and recursively looks for any secret key references in the
// object and replaces the value with the secret value
func replaceMapSecrets(obj map[string]interface{}, secretValues map[string]string) map[string]interface{} {

View File

@@ -12,17 +12,18 @@ import (
"os"
"time"
"github.com/argoproj/argo-cd/common"
"github.com/argoproj/argo-cd/errors"
"github.com/argoproj/argo-cd/util/cache"
"github.com/argoproj/argo-cd/util/session"
"github.com/argoproj/argo-cd/util/settings"
"github.com/coreos/dex/api"
oidc "github.com/coreos/go-oidc"
jwt "github.com/dgrijalva/jwt-go"
log "github.com/sirupsen/logrus"
"golang.org/x/oauth2"
"google.golang.org/grpc"
"github.com/argoproj/argo-cd/common"
"github.com/argoproj/argo-cd/errors"
"github.com/argoproj/argo-cd/util/cache"
"github.com/argoproj/argo-cd/util/session"
"github.com/argoproj/argo-cd/util/settings"
)
const (
@@ -141,15 +142,18 @@ func NewClientApp(settings *settings.ArgoCDSettings, sessionMgr *session.Session
return &a, nil
}
func (a *ClientApp) oauth2Config(scopes []string) *oauth2.Config {
provider, _ := a.sessionMgr.OIDCProvider()
func (a *ClientApp) oauth2Config(scopes []string) (*oauth2.Config, error) {
provider, err := a.sessionMgr.OIDCProvider()
if err != nil {
return nil, err
}
return &oauth2.Config{
ClientID: a.clientID,
ClientSecret: a.clientSecret,
Endpoint: provider.Endpoint(),
Scopes: scopes,
RedirectURL: a.redirectURI,
}
}, nil
}
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
@@ -196,18 +200,23 @@ func (a *ClientApp) verifyAppState(state string) (*appState, error) {
}
func (a *ClientApp) HandleLogin(w http.ResponseWriter, r *http.Request) {
var authCodeURL string
var opts []oauth2.AuthCodeOption
returnURL := r.FormValue("return_url")
scopes := []string{"openid", "profile", "email", "groups"}
appState := a.generateAppState(returnURL)
if r.FormValue("offline_access") != "yes" {
authCodeURL = a.oauth2Config(scopes).AuthCodeURL(appState)
// no-op
} else if a.sessionMgr.OfflineAsScope() {
scopes = append(scopes, "offline_access")
authCodeURL = a.oauth2Config(scopes).AuthCodeURL(appState)
} else {
authCodeURL = a.oauth2Config(scopes).AuthCodeURL(appState, oauth2.AccessTypeOffline)
opts = append(opts, oauth2.AccessTypeOffline)
}
oauth2Config, err := a.oauth2Config(scopes)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
authCodeURL := oauth2Config.AuthCodeURL(appState, opts...)
http.Redirect(w, r, authCodeURL, http.StatusSeeOther)
}
@@ -219,7 +228,11 @@ func (a *ClientApp) HandleCallback(w http.ResponseWriter, r *http.Request) {
)
ctx := oidc.ClientContext(r.Context(), a.client)
oauth2Config := a.oauth2Config(nil)
oauth2Config, err := a.oauth2Config(nil)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
switch r.Method {
case "GET":
// Authorization redirect callback from OAuth2 auth flow.

View File

@@ -19,6 +19,7 @@ type Client interface {
Fetch() error
Checkout(revision string) error
LsRemote(revision string) (string, error)
LsFiles(path string) ([]string, error)
CommitSHA() (string, error)
Reset() error
}
@@ -144,8 +145,27 @@ func (m *nativeGitClient) Fetch() error {
if _, err := m.runCmd("git", "remote", "set-head", "origin", "-a"); err != nil {
return err
}
return nil
}
// LsFiles lists the local working tree, including only files that are under source control
func (m *nativeGitClient) LsFiles(path string) ([]string, error) {
out, err := m.runCmd("git", "ls-files", "--full-name", "-z", "--", path)
if err != nil {
return nil, err
}
// remove last element, which is blank regardless of whether we're using nullbyte or newline
ss := strings.Split(out, "\000")
return ss[:len(ss)-1], nil
}
// Reset resets local changes in a repository
func (m *nativeGitClient) Reset() error {
if _, err := m.runCmd("git", "reset", "--hard", "origin/HEAD"); err != nil {
return err
}
// Delete all local branches (we must first detach so we are not checked out a branch we are about to delete)
if _, err = m.runCmd("git", "checkout", "--detach", "origin/HEAD"); err != nil {
if _, err := m.runCmd("git", "checkout", "--detach", "origin/HEAD"); err != nil {
return err
}
branchesOut, err := m.runCmd("git", "for-each-ref", "--format=%(refname:short)", "refs/heads/")
@@ -161,14 +181,6 @@ func (m *nativeGitClient) Fetch() error {
return err
}
}
return nil
}
// Reset resets local changes in a repository
func (m *nativeGitClient) Reset() error {
if _, err := m.runCmd("git", "reset", "--hard", "origin/HEAD"); err != nil {
return err
}
if _, err := m.runCmd("git", "clean", "-f"); err != nil {
return err
}

View File

@@ -98,10 +98,12 @@ func TestRepo(repo, username, password string, sshPrivateKey string) error {
cmd.Env = env
_, err = cmd.Output()
if err != nil {
exErr := err.(*exec.ExitError)
errOutput := strings.Split(string(exErr.Stderr), "\n")[0]
errOutput = redactPassword(errOutput, password)
return fmt.Errorf("%s: %s", repo, errOutput)
if exErr, ok := err.(*exec.ExitError); ok {
errOutput := strings.Split(string(exErr.Stderr), "\n")[0]
errOutput = redactPassword(errOutput, password)
return fmt.Errorf("%s: %s", repo, errOutput)
}
return err
}
return nil
}

View File

@@ -197,7 +197,11 @@ func MakeCookieMetadata(key, value string, flags ...string) string {
return strings.Join(components, "; ")
}
// OIDCProvider lazily returns the OIDC provider
// OIDCProvider lazily initializes and returns the OIDC provider, querying the well known oidc
// configuration path (http://example-argocd.com/api/dex/.well-known/openid-configuration).
// We have to initialize the proviver lazily since ArgoCD is an OIDC client to itself, which
// presents a chicken-and-egg problem of (1) serving dex over HTTP, and (2) querying the OIDC
// provider (ourselves) to initialize the app.
func (mgr *SessionManager) OIDCProvider() (*oidc.Provider, error) {
if mgr.provider != nil {
return mgr.provider, nil

View File

@@ -1,11 +1,14 @@
package settings
import (
"context"
"crypto/sha256"
"crypto/tls"
"crypto/x509"
"encoding/base64"
"fmt"
"sync"
"time"
"github.com/argoproj/argo-cd/common"
tlsutil "github.com/argoproj/argo-cd/util/tls"
@@ -14,7 +17,10 @@ import (
apiv1 "k8s.io/api/core/v1"
apierr "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/client-go/informers/core/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/cache"
)
// ArgoCDSettings holds in-memory runtime configuration options.
@@ -37,6 +43,8 @@ type ArgoCDSettings struct {
WebhookGitLabSecret string
// WebhookBitbucketUUID holds the UUID for authenticating Bitbucket webhook events
WebhookBitbucketUUID string
// Secrets holds all secrets in argocd-secret as a map[string]string
Secrets map[string]string
}
const (
@@ -64,33 +72,47 @@ const (
type SettingsManager struct {
clientset kubernetes.Interface
namespace string
// subscribers is a list of subscribers to settings updates
subscribers []chan<- struct{}
// mutex protects the subscribers list from concurrent updates
mutex *sync.Mutex
}
// GetSettings retrieves settings from the ConfigManager.
// GetSettings retrieves settings from the ArgoCD configmap and secret.
func (mgr *SettingsManager) GetSettings() (*ArgoCDSettings, error) {
var settings ArgoCDSettings
argoCDCM, err := mgr.clientset.CoreV1().ConfigMaps(mgr.namespace).Get(common.ArgoCDConfigMapName, metav1.GetOptions{})
if err != nil {
return nil, err
}
updateSettingsFromConfigMap(&settings, argoCDCM)
argoCDSecret, err := mgr.clientset.CoreV1().Secrets(mgr.namespace).Get(common.ArgoCDSecretName, metav1.GetOptions{})
if err != nil {
return nil, err
}
err = updateSettingsFromSecret(&settings, argoCDSecret)
if err != nil {
return nil, err
}
return &settings, nil
}
var settings ArgoCDSettings
func updateSettingsFromConfigMap(settings *ArgoCDSettings, argoCDCM *apiv1.ConfigMap) {
settings.DexConfig = argoCDCM.Data[settingDexConfigKey]
settings.URL = argoCDCM.Data[settingURLKey]
}
func updateSettingsFromSecret(settings *ArgoCDSettings, argoCDSecret *apiv1.Secret) error {
adminPasswordHash, ok := argoCDSecret.Data[settingAdminPasswordKey]
if !ok {
return nil, fmt.Errorf("admin user not found")
return fmt.Errorf("admin user not found")
}
settings.LocalUsers = map[string]string{
common.ArgoCDAdminUsername: string(adminPasswordHash),
}
secretKey, ok := argoCDSecret.Data[settingServerSignatureKey]
if !ok {
return nil, fmt.Errorf("server secret key not found")
return fmt.Errorf("server secret key not found")
}
settings.ServerSignature = secretKey
if githubWebhookSecret := argoCDSecret.Data[settingsWebhookGitHubSecretKey]; len(githubWebhookSecret) > 0 {
@@ -108,11 +130,16 @@ func (mgr *SettingsManager) GetSettings() (*ArgoCDSettings, error) {
if certOk && keyOk {
cert, err := tls.X509KeyPair(serverCert, serverKey)
if err != nil {
return nil, fmt.Errorf("invalid x509 key pair %s/%s in secret: %s", settingServerCertificate, settingServerPrivateKey, err)
return fmt.Errorf("invalid x509 key pair %s/%s in secret: %s", settingServerCertificate, settingServerPrivateKey, err)
}
settings.Certificate = &cert
}
return &settings, nil
secretValues := make(map[string]string, len(argoCDSecret.Data))
for k, v := range argoCDSecret.Data {
secretValues[k] = string(v)
}
settings.Secrets = secretValues
return nil
}
// SaveSettings serializes ArgoCD settings and upserts it into K8s secret/configmap
@@ -196,9 +223,11 @@ func NewSettingsManager(clientset kubernetes.Interface, namespace string) *Setti
return &SettingsManager{
clientset: clientset,
namespace: namespace,
mutex: &sync.Mutex{},
}
}
// IsSSOConfigured returns whether or not single-sign-on is configured
func (a *ArgoCDSettings) IsSSOConfigured() bool {
if a.URL == "" {
return false
@@ -249,3 +278,107 @@ func (a *ArgoCDSettings) OAuth2ClientSecret() string {
sha := h.Sum(nil)
return base64.URLEncoding.EncodeToString(sha)[:40]
}
// newInformers returns two new informers on the ArgoCD
func (mgr *SettingsManager) newInformers() (cache.SharedIndexInformer, cache.SharedIndexInformer) {
tweakConfigMap := func(options *metav1.ListOptions) {
cmFieldSelector := fields.ParseSelectorOrDie(fmt.Sprintf("metadata.name=%s", common.ArgoCDConfigMapName))
options.FieldSelector = cmFieldSelector.String()
}
cmInformer := v1.NewFilteredConfigMapInformer(mgr.clientset, mgr.namespace, 3*time.Minute, cache.Indexers{}, tweakConfigMap)
tweakSecret := func(options *metav1.ListOptions) {
secFieldSelector := fields.ParseSelectorOrDie(fmt.Sprintf("metadata.name=%s", common.ArgoCDSecretName))
options.FieldSelector = secFieldSelector.String()
}
secInformer := v1.NewFilteredSecretInformer(mgr.clientset, mgr.namespace, 3*time.Minute, cache.Indexers{}, tweakSecret)
return cmInformer, secInformer
}
// StartNotifier starts background goroutines to update the supplied settings instance with new updates
func (mgr *SettingsManager) StartNotifier(ctx context.Context, a *ArgoCDSettings) {
log.Info("Starting settings notifier")
cmInformer, secInformer := mgr.newInformers()
cmInformer.AddEventHandler(
cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
if cm, ok := obj.(*apiv1.ConfigMap); ok {
updateSettingsFromConfigMap(a, cm)
mgr.notifySubscribers()
}
},
UpdateFunc: func(old, new interface{}) {
oldCM := old.(*apiv1.ConfigMap)
newCM := new.(*apiv1.ConfigMap)
if oldCM.ResourceVersion == newCM.ResourceVersion {
return
}
log.Infof("%s updated", common.ArgoCDConfigMapName)
updateSettingsFromConfigMap(a, newCM)
mgr.notifySubscribers()
},
},
)
secInformer.AddEventHandler(
cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
if sec, ok := obj.(*apiv1.Secret); ok {
if err := updateSettingsFromSecret(a, sec); err != nil {
log.Errorf("new settings had error: %v", err)
}
mgr.notifySubscribers()
}
},
UpdateFunc: func(old, new interface{}) {
oldSec := old.(*apiv1.Secret)
newSec := new.(*apiv1.Secret)
if oldSec.ResourceVersion == newSec.ResourceVersion {
return
}
log.Infof("%s updated", common.ArgoCDSecretName)
if err := updateSettingsFromSecret(a, newSec); err != nil {
log.Errorf("new settings had error: %v", err)
}
mgr.notifySubscribers()
},
},
)
log.Info("Starting configmap/secret informers")
go func() {
cmInformer.Run(ctx.Done())
log.Info("configmap informer cancelled")
}()
go func() {
secInformer.Run(ctx.Done())
log.Info("secret informer cancelled")
}()
}
// Subscribe registers a channel in which to subscribe to settings updates
func (mgr *SettingsManager) Subscribe(subCh chan<- struct{}) {
mgr.mutex.Lock()
defer mgr.mutex.Unlock()
mgr.subscribers = append(mgr.subscribers, subCh)
log.Infof("%v subscribed to settings updates", subCh)
}
// Unsubscribe unregisters a channel from receiving of settings updates
func (mgr *SettingsManager) Unsubscribe(subCh chan<- struct{}) {
mgr.mutex.Lock()
defer mgr.mutex.Unlock()
for i, ch := range mgr.subscribers {
if ch == subCh {
mgr.subscribers = append(mgr.subscribers[:i], mgr.subscribers[i+1:]...)
log.Infof("%v unsubscribed from settings updates", subCh)
return
}
}
}
func (mgr *SettingsManager) notifySubscribers() {
mgr.mutex.Lock()
defer mgr.mutex.Unlock()
log.Infof("Notifying %d settings subscribers: %v", len(mgr.subscribers), mgr.subscribers)
for _, sub := range mgr.subscribers {
sub <- struct{}{}
}
}

View File

@@ -1,5 +1,9 @@
package util
import (
"time"
)
type Closer interface {
Close() error
}
@@ -9,3 +13,27 @@ type Closer interface {
func Close(c Closer) {
_ = c.Close()
}
// Wait takes a check interval and timeout and waits for a function to return `true`.
// Wait will return `true` on success and `false` on timeout.
// The passed function, in turn, should pass `true` (or anything, really) to the channel when it's done.
// Pass `0` as the timeout to run infinitely until completion.
func Wait(timeout uint, f func(chan<- bool)) bool {
done := make(chan bool)
go f(done)
// infinite
if timeout == 0 {
return <-done
}
timedOut := time.After(time.Duration(timeout) * time.Second)
for {
select {
case <-done:
return true
case <-timedOut:
return false
}
}
}