mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-03-26 18:38:48 +01:00
Compare commits
29 Commits
v0.4.0
...
release-0.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4d0bd3926 | ||
|
|
18dc82d14d | ||
|
|
e720abb58b | ||
|
|
a2e9a9ee49 | ||
|
|
cf3776903d | ||
|
|
3acca5095e | ||
|
|
5a62286127 | ||
|
|
5452aff0be | ||
|
|
0f4f1262af | ||
|
|
4e7f68ccba | ||
|
|
96c05babe0 | ||
|
|
6b78cddb19 | ||
|
|
12596ff936 | ||
|
|
a240f1b2b9 | ||
|
|
f6da19672e | ||
|
|
e81d30be9b | ||
|
|
13b090e3bd | ||
|
|
d0479e6ddc | ||
|
|
1432827006 | ||
|
|
89bf4eac71 | ||
|
|
07aac0bdae | ||
|
|
61220b8d0d | ||
|
|
4e470aaf09 | ||
|
|
76922b620b | ||
|
|
ac0f623eda | ||
|
|
afd5450882 | ||
|
|
c17266fc21 | ||
|
|
f62c825495 | ||
|
|
45f44dd4be |
14
CHANGELOG.md
Normal file
14
CHANGELOG.md
Normal 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
5
Gopkg.lock
generated
@@ -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
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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(¶meters, "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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
},
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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()
|
||||
},
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
BIN
docs/assets/oauth2-config.png
Normal file
BIN
docs/assets/oauth2-config.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 60 KiB |
BIN
docs/assets/register-app.png
Normal file
BIN
docs/assets/register-app.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 70 KiB |
BIN
docs/assets/webhook-config.png
Normal file
BIN
docs/assets/webhook-config.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 92 KiB |
@@ -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
72
docs/sso.md
Normal 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).
|
||||
|
||||

|
||||
|
||||
After registering the app, you will receive an OAuth2 client ID and secret. These values will be
|
||||
inputted into the ArgoCD configmap.
|
||||
|
||||

|
||||
|
||||
### 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
|
||||
```
|
||||
@@ -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
70
docs/webhook.md
Normal 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.
|
||||
|
||||

|
||||
|
||||
### 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
|
||||
```
|
||||
@@ -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])
|
||||
@@ -12,7 +12,8 @@
|
||||
name: "guestbook-ui",
|
||||
replicas: 1,
|
||||
servicePort: 80,
|
||||
type: "LoadBalancer",
|
||||
type: "ClusterIP",
|
||||
command: null,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) = {
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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) = {
|
||||
|
||||
143
server/server.go
143
server/server.go
@@ -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 ""
|
||||
|
||||
@@ -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
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
}
|
||||
|
||||
|
||||
@@ -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{} {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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{}{}
|
||||
}
|
||||
}
|
||||
|
||||
28
util/util.go
28
util/util.go
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user