1
0
mirror of https://github.com/go-micro/go-micro.git synced 2025-05-25 21:53:14 +02:00

Add Kubernetes resources (#2236)

* Refact new command implementation

Everytime I want to add or modify files in the new command, I will have
to do so in 2 places. This change will consolidate functionality so
there's only a single place to modify.

* Move Kubernetes resources to its own file

* Add Kubernetes resources
This commit is contained in:
Niek den Breeje 2021-09-02 14:35:00 +02:00 committed by GitHub
parent ed9053ed94
commit 993e2f55bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 183 additions and 137 deletions

View File

@ -37,6 +37,102 @@ type file struct {
Tmpl string
}
// NewCommand returns a new new cli command.
func NewCommand() *cli.Command {
return &cli.Command{
Name: "new",
Usage: "Create a project template",
Subcommands: []*cli.Command{
{
Name: "function",
Usage: "Create a function template, e.g. " + cmd.App().Name + " new function greeter",
Action: Function,
Flags: flags,
},
{
Name: "service",
Usage: "Create a service template, e.g. " + cmd.App().Name + " new service greeter",
Action: Service,
Flags: flags,
},
},
}
}
// Function creates a new function project template. Exits on error.
func Function(ctx *cli.Context) error {
return createProject(ctx, true)
}
// Service creates a new service project template. Exits on error.
func Service(ctx *cli.Context) error {
return createProject(ctx, false)
}
func createProject(ctx *cli.Context, fn bool) error {
name := ctx.Args().First()
if len(name) == 0 {
return cli.ShowSubcommandHelp(ctx)
}
if path.IsAbs(name) {
fmt.Println("must provide a relative path as service name")
return nil
}
if _, err := os.Stat(name); !os.IsNotExist(err) {
return fmt.Errorf("%s already exists", name)
}
if fn {
fmt.Printf("creating function %s\n", name)
} else {
fmt.Printf("creating service %s\n", name)
}
files := []file{
{".dockerignore", tmpl.DockerIgnore},
{".gitignore", tmpl.GitIgnore},
{"Dockerfile", tmpl.Dockerfile},
{"Makefile", tmpl.Makefile},
{"go.mod", tmpl.Module},
}
if fn {
files = append(files, []file{
{"handler/" + name + ".go", tmpl.HandlerFNC},
{"main.go", tmpl.MainFNC},
{"proto/" + name + ".proto", tmpl.ProtoFNC},
}...)
} else {
files = append(files, []file{
{"handler/" + name + ".go", tmpl.HandlerSRV},
{"main.go", tmpl.MainSRV},
{"proto/" + name + ".proto", tmpl.ProtoSRV},
}...)
}
if ctx.Bool("skaffold") {
files = append(files, []file{
{"plugins.go", tmpl.Plugins},
{"resources/clusterrole.yaml", tmpl.KubernetesClusterRole},
{"resources/configmap.yaml", tmpl.KubernetesEnv},
{"resources/deployment.yaml", tmpl.KubernetesDeployment},
{"resources/rolebinding.yaml", tmpl.KubernetesRoleBinding},
{"skaffold.yaml", tmpl.SkaffoldCFG},
}...)
}
c := config{
Alias: name,
Comments: protoComments(name),
Dir: name,
Jaeger: ctx.Bool("jaeger"),
Skaffold: ctx.Bool("skaffold"),
}
return create(files, c)
}
func protoComments(alias string) []string {
return []string{
"\ndownload protoc zip packages (protoc-$VERSION-$PLATFORM.zip) and install:\n",
@ -93,115 +189,3 @@ func create(files []file, c config) error {
return nil
}
// NewCommand returns a new new cli command.
func NewCommand() *cli.Command {
return &cli.Command{
Name: "new",
Usage: "Create a project template",
Subcommands: []*cli.Command{
{
Name: "function",
Usage: "Create a function template, e.g. " + cmd.App().Name + " new function greeter",
Action: Function,
Flags: flags,
},
{
Name: "service",
Usage: "Create a service template, e.g. " + cmd.App().Name + " new service greeter",
Action: Service,
Flags: flags,
},
},
}
}
// Function creates a new function project template. Exits on error.
func Function(ctx *cli.Context) error {
function := ctx.Args().First()
if len(function) == 0 {
return cli.ShowSubcommandHelp(ctx)
}
if path.IsAbs(function) {
fmt.Println("must provide a relative path as function name")
return nil
}
if _, err := os.Stat(function); !os.IsNotExist(err) {
return fmt.Errorf("%s already exists", function)
}
fmt.Printf("creating function %s\n", function)
files := []file{
{".gitignore", tmpl.GitIgnore},
{"Dockerfile", tmpl.Dockerfile},
{"Makefile", tmpl.Makefile},
{"go.mod", tmpl.Module},
{"handler/" + function + ".go", tmpl.HandlerFNC},
{"main.go", tmpl.MainFNC},
{"proto/" + function + ".proto", tmpl.ProtoFNC},
}
if ctx.Bool("skaffold") {
files = append(files, []file{
{"skaffold.yaml", tmpl.SkaffoldCFG},
{"resources/deployment.yaml", tmpl.SkaffoldDEP},
}...)
}
c := config{
Alias: function,
Comments: protoComments(function),
Dir: function,
Jaeger: ctx.Bool("jaeger"),
}
return create(files, c)
}
// Service creates a new service project template. Exits on error.
func Service(ctx *cli.Context) error {
service := ctx.Args().First()
if len(service) == 0 {
return cli.ShowSubcommandHelp(ctx)
}
if path.IsAbs(service) {
fmt.Println("must provide a relative path as service name")
return nil
}
if _, err := os.Stat(service); !os.IsNotExist(err) {
return fmt.Errorf("%s already exists", service)
}
fmt.Printf("creating service %s\n", service)
files := []file{
{".dockerignore", tmpl.DockerIgnore},
{".gitignore", tmpl.GitIgnore},
{"Dockerfile", tmpl.Dockerfile},
{"Makefile", tmpl.Makefile},
{"go.mod", tmpl.Module},
{"handler/" + service + ".go", tmpl.HandlerSRV},
{"main.go", tmpl.MainSRV},
{"proto/" + service + ".proto", tmpl.ProtoSRV},
}
if ctx.Bool("skaffold") {
files = append(files, []file{
{"skaffold.yaml", tmpl.SkaffoldCFG},
{"resources/deployment.yaml", tmpl.SkaffoldDEP},
}...)
}
c := config{
Alias: service,
Comments: protoComments(service),
Dir: service,
Jaeger: ctx.Bool("jaeger"),
Skaffold: ctx.Bool("skaffold"),
}
return create(files, c)
}

View File

@ -0,0 +1,78 @@
package template
// KubernetesEnv is a Kubernetes configmap manifest template used for
// environment variables in new projects.
var KubernetesEnv = `---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{.Alias}}-env
data:
MICRO_REGISTRY: kubernetes
`
// KubernetesClusterRole is a Kubernetes cluster role manifest template
// required for the Kubernetes registry plugin to function correctly.
var KubernetesClusterRole = `---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: micro-registry
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- list
- patch
- watch
`
// KubernetesRoleBinding is a Kubernetes role binding manifest template
// required for the Kubernetes registry plugin to function correctly.
var KubernetesRoleBinding = `---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: micro-registry
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: micro-registry
subjects:
- kind: ServiceAccount
name: default
namespace: default
`
// KubernetesDeployment is a Kubernetes deployment manifest template used for
// new projects.
var KubernetesDeployment = `---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{.Alias}}
labels:
app: {{.Alias}}
spec:
replicas: 1
selector:
matchLabels:
app: {{.Alias}}
template:
metadata:
labels:
app: {{.Alias}}
spec:
containers:
- name: {{.Alias}}
image: {{.Alias}}:latest
envFrom:
- configMapRef:
name: {{.Alias}}-env
`

View File

@ -0,0 +1,9 @@
package template
// Plugins is the plugins template used for new projects.
var Plugins = `package main
import (
_ "github.com/asim/go-micro/plugins/registry/kubernetes/v3"
)
`

View File

@ -15,28 +15,3 @@ deploy:
manifests:
- resources/*.yaml
`
// SkaffoldDEP is the Kubernetes deployment manifest template used for new
// projects.
var SkaffoldDEP = `---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{.Alias}}
labels:
app: {{.Alias}}
spec:
replicas: 1
selector:
matchLabels:
app: {{.Alias}}
template:
metadata:
labels:
app: {{.Alias}}
spec:
containers:
- name: {{.Alias}}
image: {{.Alias}}:latest
`