зеркало из https://github.com/Azure/acs-engine.git
Restructure commands. Introduce cobra/logrus
This commit is contained in:
Родитель
cb47749394
Коммит
362923e886
6
Makefile
6
Makefile
|
@ -5,13 +5,17 @@
|
|||
VERSION=`git describe --always --long --dirty`
|
||||
BUILD=`date +%FT%T%z`
|
||||
|
||||
all: build
|
||||
|
||||
prereqs:
|
||||
go get github.com/jteeuwen/go-bindata/...
|
||||
go get github.com/Sirupsen/logrus
|
||||
go get github.com/spf13/cobra
|
||||
|
||||
build: prereqs
|
||||
go generate -v ./...
|
||||
go get .
|
||||
go build -v -ldflags="-X main.AcsEngineBuildSHA=${VERSION} -X main.AcsEngineBuildTime=${BUILD}"
|
||||
go build -v -ldflags="-X github.com/Azure/acs-engine/cmd.BuildSHA=${VERSION} -X github.com/Azure/acs-engine/cmd.BuildTime=${BUILD}"
|
||||
cd test/acs-engine-test; go build -v
|
||||
|
||||
test: prereqs test_fmt
|
||||
|
|
|
@ -48,7 +48,7 @@ $ vim examples/kubernetes.classic.json
|
|||
# insert your preferred, unique DNS prefix
|
||||
# insert your SSH public key
|
||||
|
||||
$ ./acs-engine examples/kubernetes.classic.json
|
||||
$ ./acs-engine generate examples/kubernetes.classic.json
|
||||
```
|
||||
|
||||
This produces a new directory inside `_output/` that contains an ARM template
|
||||
|
|
|
@ -44,7 +44,7 @@ $ vim examples/kubernetes.classic.json
|
|||
# 修改默认的DNS prefix
|
||||
# 修改ssh public key
|
||||
|
||||
$ ./acs-engine examples/kubernetes.classic.json
|
||||
$ ./acs-engine generate examples/kubernetes.classic.json
|
||||
```
|
||||
|
||||
This produces a new directory inside `_output/` that contains an ARM template
|
||||
|
|
237
acs-engine.go
237
acs-engine.go
|
@ -1,237 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/acs-engine/pkg/acsengine"
|
||||
"github.com/Azure/acs-engine/pkg/api"
|
||||
)
|
||||
|
||||
func writeArtifacts(containerService *api.ContainerService, apiVersion, template, parameters, artifactsDir string, certsGenerated bool, parametersOnly bool) error {
|
||||
if len(artifactsDir) == 0 {
|
||||
artifactsDir = fmt.Sprintf("%s-%s", containerService.Properties.OrchestratorProfile.OrchestratorType, acsengine.GenerateClusterID(containerService.Properties))
|
||||
artifactsDir = path.Join("_output", artifactsDir)
|
||||
}
|
||||
|
||||
// convert back the API object, and write it
|
||||
var b []byte
|
||||
var err error
|
||||
if !parametersOnly {
|
||||
b, err = api.SerializeContainerService(containerService, apiVersion)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if e := saveFile(artifactsDir, "apimodel.json", b); e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
if e := saveFileString(artifactsDir, "azuredeploy.json", template); e != nil {
|
||||
return e
|
||||
}
|
||||
}
|
||||
|
||||
if e := saveFileString(artifactsDir, "azuredeploy.parameters.json", parameters); e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
if certsGenerated {
|
||||
properties := containerService.Properties
|
||||
if properties.OrchestratorProfile.OrchestratorType == api.Kubernetes {
|
||||
directory := path.Join(artifactsDir, "kubeconfig")
|
||||
var locations []string
|
||||
if containerService.Location != "" {
|
||||
locations = []string{containerService.Location}
|
||||
} else {
|
||||
locations = acsengine.AzureLocations
|
||||
}
|
||||
|
||||
for _, location := range locations {
|
||||
b, gkcerr := acsengine.GenerateKubeConfig(properties, location)
|
||||
if gkcerr != nil {
|
||||
return gkcerr
|
||||
}
|
||||
if e := saveFileString(directory, fmt.Sprintf("kubeconfig.%s.json", location), b); e != nil {
|
||||
return e
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if e := saveFileString(artifactsDir, "ca.key", properties.CertificateProfile.GetCAPrivateKey()); e != nil {
|
||||
return e
|
||||
}
|
||||
if e := saveFileString(artifactsDir, "ca.crt", properties.CertificateProfile.CaCertificate); e != nil {
|
||||
return e
|
||||
}
|
||||
if e := saveFileString(artifactsDir, "apiserver.key", properties.CertificateProfile.APIServerPrivateKey); e != nil {
|
||||
return e
|
||||
}
|
||||
if e := saveFileString(artifactsDir, "apiserver.crt", properties.CertificateProfile.APIServerCertificate); e != nil {
|
||||
return e
|
||||
}
|
||||
if e := saveFileString(artifactsDir, "client.key", properties.CertificateProfile.ClientPrivateKey); e != nil {
|
||||
return e
|
||||
}
|
||||
if e := saveFileString(artifactsDir, "client.crt", properties.CertificateProfile.ClientCertificate); e != nil {
|
||||
return e
|
||||
}
|
||||
if e := saveFileString(artifactsDir, "kubectlClient.key", properties.CertificateProfile.KubeConfigPrivateKey); e != nil {
|
||||
return e
|
||||
}
|
||||
if e := saveFileString(artifactsDir, "kubectlClient.crt", properties.CertificateProfile.KubeConfigCertificate); e != nil {
|
||||
return e
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func saveFileString(dir string, file string, data string) error {
|
||||
return saveFile(dir, file, []byte(data))
|
||||
}
|
||||
|
||||
func saveFile(dir string, file string, data []byte) error {
|
||||
if _, err := os.Stat(dir); os.IsNotExist(err) {
|
||||
if e := os.MkdirAll(dir, 0700); e != nil {
|
||||
return fmt.Errorf("error creating directory '%s': %s", dir, e.Error())
|
||||
}
|
||||
}
|
||||
|
||||
path := path.Join(dir, file)
|
||||
if err := ioutil.WriteFile(path, []byte(data), 0600); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Fprintf(os.Stderr, "wrote %s\n", path)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func usage(errs ...error) {
|
||||
for _, err := range errs {
|
||||
fmt.Fprintf(os.Stderr, "error: %s\n\n", err.Error())
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "usage: %s [OPTIONS] ClusterDefinitionFile\n", os.Args[0])
|
||||
fmt.Fprintf(os.Stderr, " read the ClusterDefinitionFile and output an arm template")
|
||||
fmt.Fprintf(os.Stderr, "\n")
|
||||
fmt.Fprintf(os.Stderr, "options:\n")
|
||||
flag.PrintDefaults()
|
||||
fmt.Fprintf(os.Stderr, "\n%s --version or -v to get the build version \n", os.Args[0])
|
||||
}
|
||||
|
||||
var noPrettyPrint = flag.Bool("noPrettyPrint", false, "do not pretty print output")
|
||||
var artifactsDir = flag.String("artifacts", "", "directory where artifacts will be written")
|
||||
var classicMode = flag.Bool("classicMode", false, "enable classic parameters and outputs")
|
||||
var parametersOnly = flag.Bool("parametersOnly", false, "only output the parameters")
|
||||
|
||||
// AcsEngineBuildSHA is the Git SHA-1 of the last commit
|
||||
var AcsEngineBuildSHA string
|
||||
|
||||
// AcsEngineBuildTime is the timestamp of when acs-engine was built
|
||||
var AcsEngineBuildTime string
|
||||
|
||||
// acs-engine takes the caKey and caCert as args, since the caKey is stored separately
|
||||
// from the api model since this cannot be easily revoked like the server and client key
|
||||
var caCertificatePath = flag.String("caCertificatePath", "", "the path to the CA Certificate file")
|
||||
var caKeyPath = flag.String("caKeyPath", "", "the path to the CA key file")
|
||||
|
||||
func main() {
|
||||
if (len(os.Args) == 2) &&
|
||||
((os.Args[1] == "--version") || (os.Args[1] == "-v")) {
|
||||
if len(AcsEngineBuildSHA) == 0 {
|
||||
fmt.Fprintf(os.Stderr, "No version set. Please run `make build`\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Fprintf(os.Stdout, "Git commit: %s\nBuild Timestamp: %s\n", AcsEngineBuildSHA, AcsEngineBuildTime)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
defer func(s time.Time) {
|
||||
fmt.Fprintf(os.Stderr, "acsengine took %s\n", time.Since(s))
|
||||
}(start)
|
||||
var containerService *api.ContainerService
|
||||
var caCertificateBytes []byte
|
||||
var caKeyBytes []byte
|
||||
var template string
|
||||
var parameters string
|
||||
var apiVersion string
|
||||
var err error
|
||||
|
||||
flag.Parse()
|
||||
|
||||
if argCount := len(flag.Args()); argCount == 0 {
|
||||
usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
jsonFile := flag.Arg(0)
|
||||
if _, err = os.Stat(jsonFile); os.IsNotExist(err) {
|
||||
usage(fmt.Errorf("file %s does not exist", jsonFile))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if (len(*caCertificatePath) > 0 && len(*caKeyPath) == 0) ||
|
||||
(len(*caCertificatePath) == 0 && len(*caKeyPath) > 0) {
|
||||
usage(errors.New("caKeyPath and caCertificatePath must be specified together"))
|
||||
os.Exit(1)
|
||||
}
|
||||
if len(*caCertificatePath) > 0 {
|
||||
if caCertificateBytes, err = ioutil.ReadFile(*caCertificatePath); err != nil {
|
||||
usage(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if caKeyBytes, err = ioutil.ReadFile(*caKeyPath); err != nil {
|
||||
usage(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
templateGenerator, e := acsengine.InitializeTemplateGenerator(*classicMode)
|
||||
if e != nil {
|
||||
fmt.Fprintf(os.Stderr, "generator initialization failed: %s\n", e.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if containerService, apiVersion, err = api.LoadContainerServiceFromFile(jsonFile); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error while loading %s: %s", jsonFile, err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if len(caKeyBytes) != 0 {
|
||||
// the caKey is not in the api model, and should be stored separately from the model
|
||||
// we put these in the model after model is deserialized
|
||||
containerService.Properties.CertificateProfile.CaCertificate = string(caCertificateBytes)
|
||||
containerService.Properties.CertificateProfile.SetCAPrivateKey(string(caKeyBytes))
|
||||
}
|
||||
|
||||
certsGenerated := false
|
||||
if template, parameters, certsGenerated, err = templateGenerator.GenerateTemplate(containerService); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error generating template %s: %s", jsonFile, err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if !*noPrettyPrint {
|
||||
if template, err = acsengine.PrettyPrintArmTemplate(template); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error pretty printing template: %s \n", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
if parameters, err = acsengine.PrettyPrintJSON(parameters); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error pretty printing template parameters: %s \n", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
if err = writeArtifacts(containerService, apiVersion, template, parameters, *artifactsDir, certsGenerated, *parametersOnly); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error writing artifacts: %s \n", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/Azure/acs-engine/pkg/acsengine"
|
||||
"github.com/Azure/acs-engine/pkg/api"
|
||||
)
|
||||
|
||||
const (
|
||||
generateName = "generate"
|
||||
generateShortDescription = "Generate an Azure Resource Manager template"
|
||||
generateLongDescription = "Generates an Azure Resource Manager template, parameters file and other assets for a cluster"
|
||||
)
|
||||
|
||||
type generateCmd struct {
|
||||
apimodelPath string
|
||||
outputDirectory string // can be auto-determined from clusterDefinition
|
||||
caCertificatePath string
|
||||
caPrivateKeyPath string
|
||||
classicMode bool
|
||||
noPrettyPrint bool
|
||||
parametersOnly bool
|
||||
|
||||
// Parsed from inputs
|
||||
containerService *api.ContainerService
|
||||
apiVersion string
|
||||
}
|
||||
|
||||
func NewGenerateCmd() *cobra.Command {
|
||||
gc := generateCmd{}
|
||||
|
||||
generateCmd := &cobra.Command{
|
||||
Use: generateName,
|
||||
Short: generateShortDescription,
|
||||
Long: generateLongDescription,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return gc.run(cmd, args)
|
||||
},
|
||||
}
|
||||
|
||||
f := generateCmd.Flags()
|
||||
f.StringVar(&gc.apimodelPath, "api-model", "", "")
|
||||
f.StringVar(&gc.outputDirectory, "output-directory", "", "output directory (derived from FQDN if absent)")
|
||||
f.StringVar(&gc.caCertificatePath, "ca-certificate-path", "", "path to the CA certificate to use for Kubernetes PKI assets")
|
||||
f.StringVar(&gc.caPrivateKeyPath, "ca-private-key-path", "", "path to the CA private key to use for Kubernetes PKI assets")
|
||||
f.BoolVar(&gc.classicMode, "classic-mode", false, "enable classic parameters and outputs")
|
||||
f.BoolVar(&gc.noPrettyPrint, "no-pretty-print", false, "skip pretty printing the output")
|
||||
f.BoolVar(&gc.parametersOnly, "parameters-only", false, "only output parameters files")
|
||||
|
||||
return generateCmd
|
||||
}
|
||||
|
||||
func (gc *generateCmd) validate(cmd *cobra.Command, args []string) {
|
||||
var caCertificateBytes []byte
|
||||
var caKeyBytes []byte
|
||||
|
||||
if gc.apimodelPath == "" {
|
||||
if len(args) > 0 {
|
||||
gc.apimodelPath = args[0]
|
||||
} else if len(args) > 1 {
|
||||
cmd.Usage()
|
||||
log.Fatalln("too many arguments were provided to 'generate'")
|
||||
} else {
|
||||
cmd.Usage()
|
||||
log.Fatalln("--api-model was not supplied, nor was one specified as a positional argument")
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := os.Stat(gc.apimodelPath); os.IsNotExist(err) {
|
||||
log.Fatalf("specified api model does not exist (%s)", gc.apimodelPath)
|
||||
}
|
||||
|
||||
containerService, apiVersion, err := api.LoadContainerServiceFromFile(gc.apimodelPath)
|
||||
if err != nil {
|
||||
log.Fatalf("error parsing the api model: %s", err.Error())
|
||||
}
|
||||
|
||||
if gc.outputDirectory == "" {
|
||||
gc.outputDirectory = path.Join("_output", containerService.Properties.MasterProfile.DNSPrefix)
|
||||
}
|
||||
|
||||
if len(caKeyBytes) != 0 {
|
||||
// the caKey is not in the api model, and should be stored separately from the model
|
||||
// we put these in the model after model is deserialized
|
||||
containerService.Properties.CertificateProfile.CaCertificate = string(caCertificateBytes)
|
||||
containerService.Properties.CertificateProfile.SetCAPrivateKey(string(caKeyBytes))
|
||||
}
|
||||
|
||||
gc.containerService = containerService
|
||||
gc.apiVersion = apiVersion
|
||||
}
|
||||
|
||||
func (gc *generateCmd) run(cmd *cobra.Command, args []string) error {
|
||||
gc.validate(cmd, args)
|
||||
log.Infoln("Generating...")
|
||||
|
||||
templateGenerator, err := acsengine.InitializeTemplateGenerator(gc.classicMode)
|
||||
if err != nil {
|
||||
log.Fatalln("failed to initialize template generator: %s", err.Error())
|
||||
}
|
||||
|
||||
certsGenerated := false
|
||||
template, parameters, certsGenerated, err := templateGenerator.GenerateTemplate(gc.containerService)
|
||||
if err != nil {
|
||||
log.Fatalf("error generating template %s: %s", gc.apimodelPath, err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if !gc.noPrettyPrint {
|
||||
if template, err = acsengine.PrettyPrintArmTemplate(template); err != nil {
|
||||
log.Fatalf("error pretty printing template: %s \n", err.Error())
|
||||
}
|
||||
if parameters, err = acsengine.PrettyPrintJSON(parameters); err != nil {
|
||||
log.Fatalf("error pretty printing template parameters: %s \n", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
if err = acsengine.WriteArtifacts(gc.containerService, gc.apiVersion, template, parameters, gc.outputDirectory, certsGenerated, gc.parametersOnly); err != nil {
|
||||
log.Fatalf("error writing artifacts: %s \n", err.Error())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
const (
|
||||
rootName = "acs-engine"
|
||||
rootShortDescription = "ACS-Engine deploys and manages container orchestrators in Azure"
|
||||
rootLongDescription = "ACS-Engine deploys and manages Kubernetes, Swarm Mode, and DC/OS clusters in Azure"
|
||||
)
|
||||
|
||||
var (
|
||||
debug bool
|
||||
)
|
||||
|
||||
func NewRootCmd() *cobra.Command {
|
||||
rootCmd := &cobra.Command{
|
||||
Use: rootName,
|
||||
Short: rootShortDescription,
|
||||
Long: rootLongDescription,
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
if debug {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
p := rootCmd.PersistentFlags()
|
||||
p.BoolVar(&debug, "debug", false, "enable verbose debug logs")
|
||||
|
||||
rootCmd.AddCommand(NewVersionCmd())
|
||||
rootCmd.AddCommand(NewGenerateCmd())
|
||||
|
||||
return rootCmd
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
BuildSHA = "unset"
|
||||
BuildTime = "unset"
|
||||
)
|
||||
|
||||
func NewVersionCmd() *cobra.Command {
|
||||
versionCmd := &cobra.Command{
|
||||
Use: "version",
|
||||
Short: "Print the version of ACS-Engine",
|
||||
Long: "Print the version of ACS-Engine",
|
||||
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
log.Infof("ACS-Engine Version: %s (%s)", BuildSHA, BuildTime)
|
||||
},
|
||||
}
|
||||
return versionCmd
|
||||
}
|
|
@ -138,7 +138,7 @@ Here is an example of how to generate a new deployment. This example assumes yo
|
|||
|
||||
1. Before starting ensure you have generated a valid [SSH Public/Private key pair](ssh.md#ssh-key-generation).
|
||||
2. edit [examples/kubernetes.json](../examples/kubernetes.json) and fill in the blanks.
|
||||
3. run `acs-engine examples/kubernetes.json` to generate the templates in the _output/Kubernetes-UNIQUEID directory. The UNIQUEID is a hash of your master's FQDN prefix.
|
||||
3. run `acs-engine generate examples/kubernetes.json` to generate the templates in the _output/Kubernetes-UNIQUEID directory. The UNIQUEID is a hash of your master's FQDN prefix.
|
||||
4. now you can use the `azuredeploy.json` and `azuredeploy.parameters.json` for deployment as described in [deployment usage](../README.md#deployment-usage).
|
||||
|
||||
# Deploying templates
|
||||
|
|
|
@ -132,7 +132,7 @@ ACS引擎使用json格式的[集群定义文件](clusterdefinition.md)作为输
|
|||
|
||||
1. 首先需要准备一个[SSH 公钥私钥对](ssh.md#ssh-key-generation).
|
||||
2. 编辑[examples/kubernetes.json](../examples/kubernetes.json)将其需要的参数配置好.
|
||||
3. 运行`acs-engine examples/kubernetes.json`命令在_output/Kubernetes-UNIQUEID目录中生成对应的模板。(UNIQUEID是master节点的FQDN前缀的hash值)
|
||||
3. 运行`acs-engine generate examples/kubernetes.json`命令在_output/Kubernetes-UNIQUEID目录中生成对应的模板。(UNIQUEID是master节点的FQDN前缀的hash值)
|
||||
4. 按照README中指定的方式使用`azuredeploy.json`和`azuredeploy.parameters.json`部署容器集群 [deployment usage](../README.md#deployment-usage).
|
||||
|
||||
# 部署方法
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/Azure/acs-engine/cmd"
|
||||
log "github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
ClientID = "76e0feec-6b7f-41f0-81a7-b1b944520261"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := cmd.NewRootCmd().Execute(); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
package acsengine
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/Azure/acs-engine/pkg/api"
|
||||
)
|
||||
|
||||
func WriteArtifacts(containerService *api.ContainerService, apiVersion, template, parameters, artifactsDir string, certsGenerated bool, parametersOnly bool) error {
|
||||
if len(artifactsDir) == 0 {
|
||||
artifactsDir = fmt.Sprintf("%s-%s", containerService.Properties.OrchestratorProfile.OrchestratorType, GenerateClusterID(containerService.Properties))
|
||||
artifactsDir = path.Join("_output", artifactsDir)
|
||||
}
|
||||
|
||||
// convert back the API object, and write it
|
||||
var b []byte
|
||||
var err error
|
||||
if !parametersOnly {
|
||||
b, err = api.SerializeContainerService(containerService, apiVersion)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if e := saveFile(artifactsDir, "apimodel.json", b); e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
if e := saveFileString(artifactsDir, "azuredeploy.json", template); e != nil {
|
||||
return e
|
||||
}
|
||||
}
|
||||
|
||||
if e := saveFileString(artifactsDir, "azuredeploy.parameters.json", parameters); e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
if certsGenerated {
|
||||
properties := containerService.Properties
|
||||
if properties.OrchestratorProfile.OrchestratorType == api.Kubernetes {
|
||||
directory := path.Join(artifactsDir, "kubeconfig")
|
||||
var locations []string
|
||||
if containerService.Location != "" {
|
||||
locations = []string{containerService.Location}
|
||||
} else {
|
||||
locations = AzureLocations
|
||||
}
|
||||
|
||||
for _, location := range locations {
|
||||
b, gkcerr := GenerateKubeConfig(properties, location)
|
||||
if gkcerr != nil {
|
||||
return gkcerr
|
||||
}
|
||||
if e := saveFileString(directory, fmt.Sprintf("kubeconfig.%s.json", location), b); e != nil {
|
||||
return e
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if e := saveFileString(artifactsDir, "ca.key", properties.CertificateProfile.GetCAPrivateKey()); e != nil {
|
||||
return e
|
||||
}
|
||||
if e := saveFileString(artifactsDir, "ca.crt", properties.CertificateProfile.CaCertificate); e != nil {
|
||||
return e
|
||||
}
|
||||
if e := saveFileString(artifactsDir, "apiserver.key", properties.CertificateProfile.APIServerPrivateKey); e != nil {
|
||||
return e
|
||||
}
|
||||
if e := saveFileString(artifactsDir, "apiserver.crt", properties.CertificateProfile.APIServerCertificate); e != nil {
|
||||
return e
|
||||
}
|
||||
if e := saveFileString(artifactsDir, "client.key", properties.CertificateProfile.ClientPrivateKey); e != nil {
|
||||
return e
|
||||
}
|
||||
if e := saveFileString(artifactsDir, "client.crt", properties.CertificateProfile.ClientCertificate); e != nil {
|
||||
return e
|
||||
}
|
||||
if e := saveFileString(artifactsDir, "kubectlClient.key", properties.CertificateProfile.KubeConfigPrivateKey); e != nil {
|
||||
return e
|
||||
}
|
||||
if e := saveFileString(artifactsDir, "kubectlClient.crt", properties.CertificateProfile.KubeConfigCertificate); e != nil {
|
||||
return e
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func saveFileString(dir string, file string, data string) error {
|
||||
return saveFile(dir, file, []byte(data))
|
||||
}
|
||||
|
||||
func saveFile(dir string, file string, data []byte) error {
|
||||
if _, err := os.Stat(dir); os.IsNotExist(err) {
|
||||
if e := os.MkdirAll(dir, 0700); e != nil {
|
||||
return fmt.Errorf("error creating directory '%s': %s", dir, e.Error())
|
||||
}
|
||||
}
|
||||
|
||||
path := path.Join(dir, file)
|
||||
if err := ioutil.WriteFile(path, []byte(data), 0600); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Fprintf(os.Stderr, "wrote %s\n", path)
|
||||
|
||||
return nil
|
||||
}
|
|
@ -64,7 +64,7 @@ function generate_template() {
|
|||
jqi "${FINAL_CLUSTER_DEFINITION}" ".properties.windowsProfile.secrets[0].vaultCertificates[0].certificateStore = \"My\""
|
||||
fi
|
||||
# Generate template
|
||||
"${DIR}/../acs-engine" -artifacts "${OUTPUT}" "${FINAL_CLUSTER_DEFINITION}"
|
||||
"${DIR}/../acs-engine" generate --output-directory "${OUTPUT}" "${FINAL_CLUSTER_DEFINITION}"
|
||||
|
||||
# Fill in custom hyperkube spec, if it was set
|
||||
if [[ ! -z "${CUSTOM_HYPERKUBE_SPEC:-}" ]]; then
|
||||
|
|
Загрузка…
Ссылка в новой задаче