Skip to content

Commit

Permalink
Issue #21 - Support rollback without updating spec in git repo (#23)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexmt authored Mar 7, 2018
1 parent e3c0263 commit 2eeeea3
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 70 deletions.
3 changes: 3 additions & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
controller: go run ./cmd/argocd-application-controller/main.go
api-server: go run ./cmd/argocd-server/main.go
repo-server: go run ./cmd/argocd-repo-server/main.go
12 changes: 8 additions & 4 deletions cmd/argocd-server/commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package commands
import (
"github.com/argoproj/argo-cd/errors"
appclientset "github.com/argoproj/argo-cd/pkg/client/clientset/versioned"
"github.com/argoproj/argo-cd/reposerver"
"github.com/argoproj/argo-cd/server"
"github.com/argoproj/argo-cd/util/cli"
log "github.com/sirupsen/logrus"
Expand All @@ -14,9 +15,10 @@ import (
// NewCommand returns a new instance of an argocd command
func NewCommand() *cobra.Command {
var (
logLevel string
clientConfig clientcmd.ClientConfig
staticAssetsDir string
logLevel string
clientConfig clientcmd.ClientConfig
staticAssetsDir string
repoServerAddress string
)
var command = &cobra.Command{
Use: cliName,
Expand All @@ -35,15 +37,17 @@ func NewCommand() *cobra.Command {

kubeclientset := kubernetes.NewForConfigOrDie(config)
appclientset := appclientset.NewForConfigOrDie(config)
repoclientset := reposerver.NewRepositoryServerClientset(repoServerAddress)

argocd := server.NewServer(kubeclientset, appclientset, namespace, staticAssetsDir)
argocd := server.NewServer(kubeclientset, appclientset, repoclientset, namespace, staticAssetsDir)
argocd.Run()
},
}

clientConfig = cli.AddKubectlFlagsToCmd(command)
command.Flags().StringVar(&staticAssetsDir, "staticassets", "", "Static assets directory path")
command.Flags().StringVar(&logLevel, "loglevel", "info", "Set the logging level. One of: debug|info|warn|error")
command.Flags().StringVar(&repoServerAddress, "repo-server", "localhost:8081", "Repo server address.")
command.AddCommand(cli.NewVersionCmd(cliName))
return command
}
4 changes: 2 additions & 2 deletions controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,13 @@ func (ctrl *ApplicationController) tryRefreshAppStatus(app *appv1.Application) (
}
targetObjs := make([]*unstructured.Unstructured, len(manifestInfo.Manifests))
for i, manifestStr := range manifestInfo.Manifests {
var obj map[string]interface{}
var obj unstructured.Unstructured
if err := json.Unmarshal([]byte(manifestStr), &obj); err != nil {
if err != nil {
return nil, err
}
}
targetObjs[i] = &unstructured.Unstructured{Object: obj}
targetObjs[i] = &obj
}
comparisonResult, err := ctrl.appComparator.CompareAppState(manifestInfo.Server, manifestInfo.Namespace, targetObjs, app)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion install/manifests/03d_argocd-server-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ spec:
- mountPath: /shared
name: static-files
containers:
- command: [/argocd-server, --staticassets, /shared/app]
- command: [/argocd-server, --staticassets, /shared/app, --repo-server, 'argocd-repo-server:8081']
image: argoproj/argocd-server:latest
name: argocd-server
volumeMounts:
Expand Down
4 changes: 2 additions & 2 deletions reposerver/repository/repository.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

68 changes: 53 additions & 15 deletions server/application/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@ import (

appv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
appclientset "github.com/argoproj/argo-cd/pkg/client/clientset/versioned"
"github.com/argoproj/argo-cd/reposerver"
"github.com/argoproj/argo-cd/reposerver/repository"
"github.com/argoproj/argo-cd/server/cluster"
apirepository "github.com/argoproj/argo-cd/server/repository"
"github.com/argoproj/argo-cd/util"
"github.com/argoproj/argo-cd/util/diff"
"github.com/argoproj/argo-cd/util/kube"
log "github.com/sirupsen/logrus"
"golang.org/x/net/context"
apiv1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/client-go/kubernetes"
)

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

// NewServer returns a new instance of the Application service
func NewServer(namespace string, kubeclientset kubernetes.Interface, appclientset appclientset.Interface, clusterService cluster.ClusterServiceServer) ApplicationServiceServer {
func NewServer(
namespace string,
kubeclientset kubernetes.Interface,
appclientset appclientset.Interface,
repoClientset reposerver.Clientset,
repoService apirepository.RepositoryServiceServer,
clusterService cluster.ClusterServiceServer) ApplicationServiceServer {

return &Server{
ns: namespace,
appclientset: appclientset,
kubeclientset: kubeclientset,
clusterService: clusterService,
repoClientset: repoClientset,
repoService: repoService,
}
}

Expand Down Expand Up @@ -102,27 +118,48 @@ func (s *Server) Sync(ctx context.Context, syncReq *ApplicationSyncRequest) (*Ap
if err != nil {
return nil, err
}
var syncRes ApplicationSyncResult
switch app.Status.ComparisonResult.Status {
case appv1.ComparisonStatusSynced:
case appv1.ComparisonStatusOutOfSync:
default:
appState := app.Status.ComparisonResult.Status
if appState == "" {
appState = "Unknown"
}
return nil, fmt.Errorf("Cannot sync application '%s' while in an '%s' state", app.ObjectMeta.Name, appState)

repo, err := s.repoService.Get(ctx, &apirepository.RepoQuery{Repo: app.Spec.Source.RepoURL})
if err != nil {
return nil, err
}
clst, err := s.clusterService.Get(ctx, &cluster.ClusterQuery{Server: app.Status.ComparisonResult.Server})

conn, repoClient, err := s.repoClientset.NewRepositoryClient()
if err != nil {
return nil, err
}
config := clst.RESTConfig()
targetNamespace := app.Status.ComparisonResult.Namespace
targetObjs, err := app.Status.ComparisonResult.TargetObjects()
defer util.Close(conn)
revision := syncReq.Revision
if revision == "" {
revision = app.Spec.Source.TargetRevision
}

manifestInfo, err := repoClient.GenerateManifest(ctx, &repository.ManifestRequest{
Repo: repo,
Environment: app.Spec.Source.Environment,
Path: app.Spec.Source.Path,
Revision: revision,
})
if err != nil {
return nil, err
}

clst, err := s.clusterService.Get(ctx, &cluster.ClusterQuery{Server: manifestInfo.Server})
if err != nil {
return nil, err
}
config := clst.RESTConfig()
targetNamespace := manifestInfo.Namespace

targetObjs := make([]*unstructured.Unstructured, len(manifestInfo.Manifests))
for i, manifest := range manifestInfo.Manifests {
obj, err := appv1.UnmarshalToUnstructured(manifest)
if err != nil {
return nil, err
}
targetObjs[i] = obj
}

liveObjs, err := kube.GetLiveResources(config, targetObjs, targetNamespace)
if err != nil {
return nil, err
Expand All @@ -131,6 +168,7 @@ func (s *Server) Sync(ctx context.Context, syncReq *ApplicationSyncRequest) (*Ap
if err != nil {
return nil, err
}
var syncRes ApplicationSyncResult
syncRes.Resources = make([]*ResourceDetails, 0)
for i, diffRes := range diffResList.Diffs {
resDetails := ResourceDetails{
Expand Down
93 changes: 51 additions & 42 deletions server/application/application.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion server/application/application.proto
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ message ApplicationResponse {}
// ApplicationSyncRequest is a request to apply the config state to live state
message ApplicationSyncRequest {
string name = 1;
bool dryRun = 2;
string revision = 2;
bool dryRun = 3;
}

// ApplicationSyncResult is a result of a sync requeswt
Expand Down
11 changes: 8 additions & 3 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

argocd "github.com/argoproj/argo-cd"
appclientset "github.com/argoproj/argo-cd/pkg/client/clientset/versioned"
"github.com/argoproj/argo-cd/reposerver"
"github.com/argoproj/argo-cd/server/application"
"github.com/argoproj/argo-cd/server/cluster"
"github.com/argoproj/argo-cd/server/repository"
Expand Down Expand Up @@ -39,15 +40,18 @@ type ArgoCDServer struct {
staticAssetsDir string
kubeclientset kubernetes.Interface
appclientset appclientset.Interface
repoclientset reposerver.Clientset
log *log.Entry
}

// NewServer returns a new instance of the ArgoCD API server
func NewServer(kubeclientset kubernetes.Interface, appclientset appclientset.Interface, namespace string, staticAssetsDir string) *ArgoCDServer {
func NewServer(
kubeclientset kubernetes.Interface, appclientset appclientset.Interface, repoclientset reposerver.Clientset, namespace string, staticAssetsDir string) *ArgoCDServer {
return &ArgoCDServer{
ns: namespace,
kubeclientset: kubeclientset,
appclientset: appclientset,
repoclientset: repoclientset,
log: log.NewEntry(log.New()),
staticAssetsDir: staticAssetsDir,
}
Expand Down Expand Up @@ -85,9 +89,10 @@ func (a *ArgoCDServer) Run() {
)
version.RegisterVersionServiceServer(grpcS, &version.Server{})
clusterService := cluster.NewServer(a.ns, a.kubeclientset, a.appclientset)
repoService := repository.NewServer(a.ns, a.kubeclientset, a.appclientset)
cluster.RegisterClusterServiceServer(grpcS, clusterService)
application.RegisterApplicationServiceServer(grpcS, application.NewServer(a.ns, a.kubeclientset, a.appclientset, clusterService))
repository.RegisterRepositoryServiceServer(grpcS, repository.NewServer(a.ns, a.kubeclientset, a.appclientset))
application.RegisterApplicationServiceServer(grpcS, application.NewServer(a.ns, a.kubeclientset, a.appclientset, a.repoclientset, repoService, clusterService))
repository.RegisterRepositoryServiceServer(grpcS, repoService)

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

0 comments on commit 2eeeea3

Please sign in to comment.