Skip to content

Commit

Permalink
Implement api server installer (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexmt authored Mar 1, 2018
1 parent 7009c13 commit 336b077
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 21 deletions.
10 changes: 6 additions & 4 deletions cmd/argocd-server/commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import (
// NewCommand returns a new instance of an argocd command
func NewCommand() *cobra.Command {
var (
logLevel string
configMap string
kubeConfig string
logLevel string
configMap string
kubeConfig string
staticAssetsDir string
)
var command = &cobra.Command{
Use: cliName,
Expand All @@ -32,12 +33,13 @@ func NewCommand() *cobra.Command {
kubeclientset := kubernetes.NewForConfigOrDie(config)
appclientset := appclientset.NewForConfigOrDie(config)

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

command.Flags().StringVar(&kubeConfig, "kubeconfig", "", "Kubernetes config (used when running outside of cluster)")
command.Flags().StringVar(&staticAssetsDir, "staticassets", "", "Static assets directory path")
command.Flags().StringVar(&configMap, "configmap", defaultArgoCDConfigMap, "Name of K8s configmap to retrieve argocd configuration")
command.Flags().StringVar(&logLevel, "loglevel", "info", "Set the logging level. One of: debug|info|warn|error")
command.AddCommand(cli.NewVersionCmd(cliName))
Expand Down
5 changes: 5 additions & 0 deletions cmd/argocd/commands/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ var (

// These are the default image names which `argo install` uses during install
DefaultControllerImage = imageNamespace + "/argocd-application-controller:" + imageTag
DefaultUiImage = imageNamespace + "/argocd-ui:" + imageTag
DefaultServerImage = imageNamespace + "/argocd-server:" + imageTag
)

// NewInstallCommand returns a new instance of `argocd install` command
Expand All @@ -45,6 +47,9 @@ func NewInstallCommand() *cobra.Command {
command.Flags().StringVar(&installParams.Namespace, "install-namespace", common.DefaultControllerNamespace, "install into a specific Namespace")
command.Flags().StringVar(&installParams.ControllerName, "controller-name", common.DefaultControllerDeploymentName, "name of controller deployment")
command.Flags().StringVar(&installParams.ControllerImage, "controller-image", DefaultControllerImage, "use a specified controller image")
command.Flags().StringVar(&installParams.ServerName, "server-name", common.DefaultServerDeploymentName, "name of api server deployment")
command.Flags().StringVar(&installParams.ServerImage, "server-image", DefaultServerImage, "use a specified api server image")
command.Flags().StringVar(&installParams.UiImage, "ui-image", DefaultUiImage, "use a specified ui image")
command.Flags().StringVar(&installParams.ServiceAccount, "service-account", "", "use a specified service account for the workflow-controller deployment")
clientConfig = addKubectlFlagsToCmd(command)
return command
Expand Down
3 changes: 3 additions & 0 deletions common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ const (
// DefaultControllerDeploymentName is the default deployment name of the application controller
DefaultControllerDeploymentName = "application-controller"

// DefaultServerDeploymentName is the default deployment name of the api server
DefaultServerDeploymentName = "argocd-server"

// DefaultControllerNamespace is the default namespace where the application controller is installed
DefaultControllerNamespace = "kube-system"
)
Expand Down
84 changes: 79 additions & 5 deletions common/installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,22 @@ import (
"k8s.io/client-go/rest"
)

const (
StaticFilesVolumeName = "static-files"
)

// InstallParameters has all the required parameters for installing ArgoCD.
type InstallParameters struct {
Upgrade bool
DryRun bool
Namespace string
ControllerName string
ControllerImage string
ServerName string
UiImage string
ServerImage string
ServiceAccount string
SkipController bool
CrdOnly bool
}

// Installer allows to install ArgoCD resources.
Expand All @@ -42,8 +49,9 @@ type Installer struct {
// Install performs installation
func (installer *Installer) Install(parameters InstallParameters) {
installer.installAppCRD(parameters.DryRun)
if !parameters.SkipController {
if !parameters.CrdOnly {
installer.installController(parameters)
installer.installServer(parameters)
}
}

Expand Down Expand Up @@ -143,9 +151,10 @@ func (installer *Installer) installController(args InstallParameters) {
ServiceAccountName: args.ServiceAccount,
Containers: []apiv1.Container{
{
Name: args.ControllerName,
Image: args.ControllerImage,
Command: []string{"argocd-application-controller"},
Name: args.ControllerName,
Image: args.ControllerImage,
ImagePullPolicy: apiv1.PullIfNotPresent,
Command: []string{"/argocd-application-controller"},
},
},
},
Expand All @@ -155,6 +164,71 @@ func (installer *Installer) installController(args InstallParameters) {
installer.createDeploymentHelper(&controllerDeployment, args)
}

func (installer *Installer) installServer(args InstallParameters) {
serverDeployment := appsv1beta2.Deployment{
TypeMeta: metav1.TypeMeta{
APIVersion: "apps/v1beta2",
Kind: "Deployment",
},
ObjectMeta: metav1.ObjectMeta{
Name: args.ServerName,
Namespace: args.Namespace,
},
Spec: appsv1beta2.DeploymentSpec{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"app": args.ServerName,
},
},
Template: apiv1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
"app": args.ServerName,
},
},
Spec: apiv1.PodSpec{
ServiceAccountName: args.ServiceAccount,
Containers: []apiv1.Container{
{
Name: args.ServerName,
Image: args.ServerImage,
Command: []string{"/argocd-server", "--staticassets", "/shared/app"},
ImagePullPolicy: apiv1.PullIfNotPresent,
VolumeMounts: []apiv1.VolumeMount{
{
Name: StaticFilesVolumeName,
MountPath: "/shared",
},
},
},
{
Name: args.ServerName + "-ui",
Image: args.UiImage,
ImagePullPolicy: apiv1.PullIfNotPresent,
Command: []string{"sh", "-c", "cp -r /app /shared && tail -f /dev/null"},
VolumeMounts: []apiv1.VolumeMount{
{
Name: StaticFilesVolumeName,
MountPath: "/shared",
},
},
},
},
Volumes: []apiv1.Volume{
{
Name: StaticFilesVolumeName,
VolumeSource: apiv1.VolumeSource{
EmptyDir: &apiv1.EmptyDirVolumeSource{},
},
},
},
},
},
},
}
installer.createDeploymentHelper(&serverDeployment, args)
}

// createDeploymentHelper is helper to create or update an existing deployment (if --upgrade was supplied)
func (installer *Installer) createDeploymentHelper(deployment *appsv1beta2.Deployment, args InstallParameters) {
depClient := installer.clientset.AppsV1beta2().Deployments(args.Namespace)
Expand Down
45 changes: 35 additions & 10 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"net"
"net/http"

"strings"

argocd "github.com/argoproj/argo-cd"
appclientset "github.com/argoproj/argo-cd/pkg/client/clientset/versioned"
"github.com/argoproj/argo-cd/server/application"
Expand Down Expand Up @@ -33,19 +35,21 @@ var (

// ArgoCDServer is the API server for ArgoCD
type ArgoCDServer struct {
ns string
kubeclientset kubernetes.Interface
appclientset appclientset.Interface
log *log.Entry
ns string
staticAssetsDir string
kubeclientset kubernetes.Interface
appclientset appclientset.Interface
log *log.Entry
}

// NewServer returns a new instance of the ArgoCD API server
func NewServer(kubeclientset kubernetes.Interface, appclientset appclientset.Interface) *ArgoCDServer {
func NewServer(kubeclientset kubernetes.Interface, appclientset appclientset.Interface, staticAssetsDir string) *ArgoCDServer {
return &ArgoCDServer{
ns: "default",
kubeclientset: kubeclientset,
appclientset: appclientset,
log: log.NewEntry(log.New()),
ns: "default",
kubeclientset: kubeclientset,
appclientset: appclientset,
log: log.NewEntry(log.New()),
staticAssetsDir: staticAssetsDir,
}
}

Expand Down Expand Up @@ -94,12 +98,33 @@ func (a *ArgoCDServer) Run() {
// we use our own Marshaler
gwMuxOpts := runtime.WithMarshalerOption(runtime.MIMEWildcard, new(jsonutil.JSONMarshaler))
gwmux := runtime.NewServeMux(gwMuxOpts)
mux.Handle("/", gwmux)
mux.Handle("/api/", gwmux)
dOpts := []grpc.DialOption{grpc.WithInsecure()}
mustRegisterGWHandler(version.RegisterVersionServiceHandlerFromEndpoint, ctx, gwmux, endpoint, dOpts)
mustRegisterGWHandler(cluster.RegisterClusterServiceHandlerFromEndpoint, ctx, gwmux, endpoint, dOpts)
mustRegisterGWHandler(application.RegisterApplicationServiceHandlerFromEndpoint, ctx, gwmux, endpoint, dOpts)
mustRegisterGWHandler(repository.RegisterRepositoryServiceHandlerFromEndpoint, ctx, gwmux, endpoint, dOpts)

if a.staticAssetsDir != "" {
mux.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
acceptHtml := false
for _, acceptType := range strings.Split(request.Header.Get("Accept"), ",") {
if acceptType == "text/html" || acceptType == "html" {
acceptHtml = true
break
}
}
fileRequest := request.URL.Path != "/index.html" && strings.Contains(request.URL.Path, ".")

// serve index.html for non file requests to support HTML5 History API
if acceptHtml && !fileRequest && (request.Method == "GET" || request.Method == "HEAD") {
http.ServeFile(writer, request, a.staticAssetsDir+"/index.html")
} else {
http.ServeFile(writer, request, a.staticAssetsDir+request.URL.Path)
}
})
}

httpS := &http.Server{
Addr: endpoint,
Handler: mux,
Expand Down
4 changes: 2 additions & 2 deletions test/e2e/fixture.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ func createNamespace(kubeClient *kubernetes.Clientset) (string, error) {

func (f *Fixture) setup() error {
common.NewInstaller(f.ExtensionsClient, f.KubeClient).Install(common.InstallParameters{
DryRun: false,
SkipController: true,
DryRun: false,
CrdOnly: true,
})
return nil
}
Expand Down

0 comments on commit 336b077

Please sign in to comment.