Skip to content

Commit db9c222

Browse files
Alexander MatyushentsevAlexander Matyushentsev
Alexander Matyushentsev
authored and
Alexander Matyushentsev
committed
Issue argoproj#21 - Support rollback without updating spec in git repo
1 parent e3c0263 commit db9c222

File tree

9 files changed

+130
-70
lines changed

9 files changed

+130
-70
lines changed

Procfile

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
controller: go run ./cmd/argocd-application-controller/main.go
2+
api-server: go run ./cmd/argocd-server/main.go
3+
repo-server: go run ./cmd/argocd-repo-server/main.go

cmd/argocd-server/commands/root.go

+8-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package commands
33
import (
44
"github.com/argoproj/argo-cd/errors"
55
appclientset "github.com/argoproj/argo-cd/pkg/client/clientset/versioned"
6+
"github.com/argoproj/argo-cd/reposerver"
67
"github.com/argoproj/argo-cd/server"
78
"github.com/argoproj/argo-cd/util/cli"
89
log "github.com/sirupsen/logrus"
@@ -14,9 +15,10 @@ import (
1415
// NewCommand returns a new instance of an argocd command
1516
func NewCommand() *cobra.Command {
1617
var (
17-
logLevel string
18-
clientConfig clientcmd.ClientConfig
19-
staticAssetsDir string
18+
logLevel string
19+
clientConfig clientcmd.ClientConfig
20+
staticAssetsDir string
21+
repoServerAddress string
2022
)
2123
var command = &cobra.Command{
2224
Use: cliName,
@@ -35,15 +37,17 @@ func NewCommand() *cobra.Command {
3537

3638
kubeclientset := kubernetes.NewForConfigOrDie(config)
3739
appclientset := appclientset.NewForConfigOrDie(config)
40+
repoclientset := reposerver.NewRepositoryServerClientset(repoServerAddress)
3841

39-
argocd := server.NewServer(kubeclientset, appclientset, namespace, staticAssetsDir)
42+
argocd := server.NewServer(kubeclientset, appclientset, repoclientset, namespace, staticAssetsDir)
4043
argocd.Run()
4144
},
4245
}
4346

4447
clientConfig = cli.AddKubectlFlagsToCmd(command)
4548
command.Flags().StringVar(&staticAssetsDir, "staticassets", "", "Static assets directory path")
4649
command.Flags().StringVar(&logLevel, "loglevel", "info", "Set the logging level. One of: debug|info|warn|error")
50+
command.Flags().StringVar(&repoServerAddress, "repo-server", "localhost:8081", "Repo server address.")
4751
command.AddCommand(cli.NewVersionCmd(cliName))
4852
return command
4953
}

controller/controller.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -156,13 +156,13 @@ func (ctrl *ApplicationController) tryRefreshAppStatus(app *appv1.Application) (
156156
}
157157
targetObjs := make([]*unstructured.Unstructured, len(manifestInfo.Manifests))
158158
for i, manifestStr := range manifestInfo.Manifests {
159-
var obj map[string]interface{}
159+
var obj unstructured.Unstructured
160160
if err := json.Unmarshal([]byte(manifestStr), &obj); err != nil {
161161
if err != nil {
162162
return nil, err
163163
}
164164
}
165-
targetObjs[i] = &unstructured.Unstructured{Object: obj}
165+
targetObjs[i] = &obj
166166
}
167167
comparisonResult, err := ctrl.appComparator.CompareAppState(manifestInfo.Server, manifestInfo.Namespace, targetObjs, app)
168168
if err != nil {

install/manifests/03d_argocd-server-deployment.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ spec:
2121
- mountPath: /shared
2222
name: static-files
2323
containers:
24-
- command: [/argocd-server, --staticassets, /shared/app]
24+
- command: [/argocd-server, --staticassets, /shared/app, --repo-server, 'argocd-repo-server:8081']
2525
image: argoproj/argocd-server:latest
2626
name: argocd-server
2727
volumeMounts:

reposerver/repository/repository.pb.go

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/application/application.go

+53-15
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,18 @@ import (
55

66
appv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
77
appclientset "github.com/argoproj/argo-cd/pkg/client/clientset/versioned"
8+
"github.com/argoproj/argo-cd/reposerver"
9+
"github.com/argoproj/argo-cd/reposerver/repository"
810
"github.com/argoproj/argo-cd/server/cluster"
11+
apirepository "github.com/argoproj/argo-cd/server/repository"
12+
"github.com/argoproj/argo-cd/util"
913
"github.com/argoproj/argo-cd/util/diff"
1014
"github.com/argoproj/argo-cd/util/kube"
1115
log "github.com/sirupsen/logrus"
1216
"golang.org/x/net/context"
1317
apiv1 "k8s.io/api/core/v1"
1418
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
19+
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
1520
"k8s.io/client-go/kubernetes"
1621
)
1722

@@ -20,17 +25,28 @@ type Server struct {
2025
ns string
2126
kubeclientset kubernetes.Interface
2227
appclientset appclientset.Interface
28+
repoClientset reposerver.Clientset
2329
// TODO(jessesuen): move common cluster code to shared libraries
2430
clusterService cluster.ClusterServiceServer
31+
repoService apirepository.RepositoryServiceServer
2532
}
2633

2734
// NewServer returns a new instance of the Application service
28-
func NewServer(namespace string, kubeclientset kubernetes.Interface, appclientset appclientset.Interface, clusterService cluster.ClusterServiceServer) ApplicationServiceServer {
35+
func NewServer(
36+
namespace string,
37+
kubeclientset kubernetes.Interface,
38+
appclientset appclientset.Interface,
39+
repoClientset reposerver.Clientset,
40+
repoService apirepository.RepositoryServiceServer,
41+
clusterService cluster.ClusterServiceServer) ApplicationServiceServer {
42+
2943
return &Server{
3044
ns: namespace,
3145
appclientset: appclientset,
3246
kubeclientset: kubeclientset,
3347
clusterService: clusterService,
48+
repoClientset: repoClientset,
49+
repoService: repoService,
3450
}
3551
}
3652

@@ -102,27 +118,48 @@ func (s *Server) Sync(ctx context.Context, syncReq *ApplicationSyncRequest) (*Ap
102118
if err != nil {
103119
return nil, err
104120
}
105-
var syncRes ApplicationSyncResult
106-
switch app.Status.ComparisonResult.Status {
107-
case appv1.ComparisonStatusSynced:
108-
case appv1.ComparisonStatusOutOfSync:
109-
default:
110-
appState := app.Status.ComparisonResult.Status
111-
if appState == "" {
112-
appState = "Unknown"
113-
}
114-
return nil, fmt.Errorf("Cannot sync application '%s' while in an '%s' state", app.ObjectMeta.Name, appState)
121+
122+
repo, err := s.repoService.Get(ctx, &apirepository.RepoQuery{Repo: app.Spec.Source.RepoURL})
123+
if err != nil {
124+
return nil, err
115125
}
116-
clst, err := s.clusterService.Get(ctx, &cluster.ClusterQuery{Server: app.Status.ComparisonResult.Server})
126+
127+
conn, repoClient, err := s.repoClientset.NewRepositoryClient()
117128
if err != nil {
118129
return nil, err
119130
}
120-
config := clst.RESTConfig()
121-
targetNamespace := app.Status.ComparisonResult.Namespace
122-
targetObjs, err := app.Status.ComparisonResult.TargetObjects()
131+
defer util.Close(conn)
132+
revision := syncReq.Revision
133+
if revision == "" {
134+
revision = app.Spec.Source.TargetRevision
135+
}
136+
137+
manifestInfo, err := repoClient.GenerateManifest(ctx, &repository.ManifestRequest{
138+
Repo: repo,
139+
Environment: app.Spec.Source.Environment,
140+
Path: app.Spec.Source.Path,
141+
Revision: revision,
142+
})
123143
if err != nil {
124144
return nil, err
125145
}
146+
147+
clst, err := s.clusterService.Get(ctx, &cluster.ClusterQuery{Server: manifestInfo.Server})
148+
if err != nil {
149+
return nil, err
150+
}
151+
config := clst.RESTConfig()
152+
targetNamespace := manifestInfo.Namespace
153+
154+
targetObjs := make([]*unstructured.Unstructured, len(manifestInfo.Manifests))
155+
for i, manifest := range manifestInfo.Manifests {
156+
obj, err := appv1.UnmarshalToUnstructured(manifest)
157+
if err != nil {
158+
return nil, err
159+
}
160+
targetObjs[i] = obj
161+
}
162+
126163
liveObjs, err := kube.GetLiveResources(config, targetObjs, targetNamespace)
127164
if err != nil {
128165
return nil, err
@@ -131,6 +168,7 @@ func (s *Server) Sync(ctx context.Context, syncReq *ApplicationSyncRequest) (*Ap
131168
if err != nil {
132169
return nil, err
133170
}
171+
var syncRes ApplicationSyncResult
134172
syncRes.Resources = make([]*ResourceDetails, 0)
135173
for i, diffRes := range diffResList.Diffs {
136174
resDetails := ResourceDetails{

server/application/application.pb.go

+51-42
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/application/application.proto

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ message ApplicationResponse {}
2222
// ApplicationSyncRequest is a request to apply the config state to live state
2323
message ApplicationSyncRequest {
2424
string name = 1;
25-
bool dryRun = 2;
25+
string revision = 2;
26+
bool dryRun = 3;
2627
}
2728

2829
// ApplicationSyncResult is a result of a sync requeswt

server/server.go

+8-3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010

1111
argocd "github.com/argoproj/argo-cd"
1212
appclientset "github.com/argoproj/argo-cd/pkg/client/clientset/versioned"
13+
"github.com/argoproj/argo-cd/reposerver"
1314
"github.com/argoproj/argo-cd/server/application"
1415
"github.com/argoproj/argo-cd/server/cluster"
1516
"github.com/argoproj/argo-cd/server/repository"
@@ -39,15 +40,18 @@ type ArgoCDServer struct {
3940
staticAssetsDir string
4041
kubeclientset kubernetes.Interface
4142
appclientset appclientset.Interface
43+
repoclientset reposerver.Clientset
4244
log *log.Entry
4345
}
4446

4547
// NewServer returns a new instance of the ArgoCD API server
46-
func NewServer(kubeclientset kubernetes.Interface, appclientset appclientset.Interface, namespace string, staticAssetsDir string) *ArgoCDServer {
48+
func NewServer(
49+
kubeclientset kubernetes.Interface, appclientset appclientset.Interface, repoclientset reposerver.Clientset, namespace string, staticAssetsDir string) *ArgoCDServer {
4750
return &ArgoCDServer{
4851
ns: namespace,
4952
kubeclientset: kubeclientset,
5053
appclientset: appclientset,
54+
repoclientset: repoclientset,
5155
log: log.NewEntry(log.New()),
5256
staticAssetsDir: staticAssetsDir,
5357
}
@@ -85,9 +89,10 @@ func (a *ArgoCDServer) Run() {
8589
)
8690
version.RegisterVersionServiceServer(grpcS, &version.Server{})
8791
clusterService := cluster.NewServer(a.ns, a.kubeclientset, a.appclientset)
92+
repoService := repository.NewServer(a.ns, a.kubeclientset, a.appclientset)
8893
cluster.RegisterClusterServiceServer(grpcS, clusterService)
89-
application.RegisterApplicationServiceServer(grpcS, application.NewServer(a.ns, a.kubeclientset, a.appclientset, clusterService))
90-
repository.RegisterRepositoryServiceServer(grpcS, repository.NewServer(a.ns, a.kubeclientset, a.appclientset))
94+
application.RegisterApplicationServiceServer(grpcS, application.NewServer(a.ns, a.kubeclientset, a.appclientset, a.repoclientset, repoService, clusterService))
95+
repository.RegisterRepositoryServiceServer(grpcS, repoService)
9196

9297
// HTTP 1.1+JSON Server
9398
// grpc-ecosystem/grpc-gateway is used to proxy HTTP requests to the corresponding gRPC call

0 commit comments

Comments
 (0)