Skip to content
This repository has been archived by the owner on Oct 24, 2023. It is now read-only.

Commit

Permalink
First round of i18n in acs-engine based on gettext. Subsequent change… (
Browse files Browse the repository at this point in the history
#627)

* First round of i18n in acs-engine based on gettext. Subsequent changes will replace and extract resource strings in acs-engine and make acsengine/api package's i18n used by other go program.

* Update acs-engine go source to use translation functions. Generate translation resource files.

* Vendor github.com/leonelquinteros/gotext package using glide

* Rebase and update translation for update and deploy command

* Move test translation files so that translations directory is used for go-bindata

* Use go-bindata to add resource strings to acs-engine binary

* Fix reading bindata and unit test

* Update translation files

* More fix/refactor after rebase and add README

* Update resource files

* Add LCG files converted from PO files.

* Update translation bindata

* Remove go generated translation bindata
  • Loading branch information
JiangtianLi authored Jul 31, 2017
1 parent 2b09dca commit b41df8f
Show file tree
Hide file tree
Showing 716 changed files with 18,087 additions and 131 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ test/acs-engine-test/acs-engine-test.exe
pkg/operations/junit.xml
pkg/operations/kubernetesupgrade/junit.xml
pkg/acsengine/templates.go
pkg/i18n/translations.go
6 changes: 5 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ FROM buildpack-deps:xenial

RUN apt-get update \
&& apt-get -y upgrade \
&& apt-get -y install python-pip make build-essential curl openssl vim jq \
&& apt-get -y install python-pip make build-essential curl openssl vim jq gettext \
&& rm -rf /var/lib/apt/lists/*

ENV GO_VERSION 1.8
Expand Down Expand Up @@ -34,6 +34,10 @@ RUN git clone https://github.com/akesterson/cmdarg.git /tmp/cmdarg \
RUN git clone https://github.com/akesterson/shunit.git /tmp/shunit \
&& cd /tmp/shunit && make install && rm -rf /tmp/shunit

# Go tool for internationalization and localization
RUN go get github.com/JiangtianLi/gettext/... \
&& go install github.com/JiangtianLi/gettext/...

# Used by some CI jobs
ADD ./test/bootstrap/checkout-pr.sh /tmp/checkout-pr.sh

Expand Down
45 changes: 37 additions & 8 deletions cmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ import (
"time"

log "github.com/Sirupsen/logrus"
"github.com/leonelquinteros/gotext"
"github.com/spf13/cobra"

"encoding/json"

"github.com/Azure/acs-engine/pkg/acsengine"
"github.com/Azure/acs-engine/pkg/api"
"github.com/Azure/acs-engine/pkg/armhelpers"
"github.com/Azure/acs-engine/pkg/i18n"
)

const (
Expand All @@ -40,6 +42,7 @@ type deployCmd struct {
// derived
containerService *api.ContainerService
apiVersion string
locale *gotext.Locale

client armhelpers.ACSEngineClient
resourceGroup string
Expand Down Expand Up @@ -78,6 +81,11 @@ func newDeployCmd() *cobra.Command {
func (dc *deployCmd) validate(cmd *cobra.Command, args []string) {
var err error

dc.locale, err = i18n.LoadTranslations()
if err != nil {
log.Fatalf("error loading translation files: %s", err.Error())
}

if dc.apimodelPath == "" {
if len(args) > 0 {
dc.apimodelPath = args[0]
Expand All @@ -94,8 +102,13 @@ func (dc *deployCmd) validate(cmd *cobra.Command, args []string) {
log.Fatalf("specified api model does not exist (%s)", dc.apimodelPath)
}

apiloader := &api.Apiloader{
Translator: &i18n.Translator{
Locale: dc.locale,
},
}
// skip validating the model fields for now
dc.containerService, dc.apiVersion, err = api.LoadContainerServiceFromFile(dc.apimodelPath, false)
dc.containerService, dc.apiVersion, err = apiloader.LoadContainerServiceFromFile(dc.apimodelPath, false)
if err != nil {
log.Fatalf("error parsing the api model: %s", err.Error())
}
Expand All @@ -112,7 +125,7 @@ func (dc *deployCmd) validate(cmd *cobra.Command, args []string) {
// autofillApimodel calls log.Fatal() directly and does not return errors
autofillApimodel(dc)

_, _, err = revalidateApimodel(dc.containerService, dc.apiVersion)
_, _, err = revalidateApimodel(apiloader, dc.containerService, dc.apiVersion)
if err != nil {
log.Fatalf("Failed to validate the apimodel after populating values: %s", err)
}
Expand Down Expand Up @@ -162,7 +175,12 @@ func autofillApimodel(dc *deployCmd) {
if dc.containerService.Properties.LinuxProfile.SSH.PublicKeys == nil ||
len(dc.containerService.Properties.LinuxProfile.SSH.PublicKeys) == 0 ||
dc.containerService.Properties.LinuxProfile.SSH.PublicKeys[0].KeyData == "" {
_, publicKey, err := acsengine.CreateSaveSSH(dc.containerService.Properties.LinuxProfile.AdminUsername, dc.outputDirectory)
creator := &acsengine.SSHCreator{
Translator: &i18n.Translator{
Locale: dc.locale,
},
}
_, publicKey, err := creator.CreateSaveSSH(dc.containerService.Properties.LinuxProfile.AdminUsername, dc.outputDirectory)
if err != nil {
log.Fatal("Failed to generate SSH Key")
}
Expand Down Expand Up @@ -211,17 +229,23 @@ func autofillApimodel(dc *deployCmd) {
}
}

func revalidateApimodel(containerService *api.ContainerService, apiVersion string) (*api.ContainerService, string, error) {
func revalidateApimodel(apiloader *api.Apiloader, containerService *api.ContainerService, apiVersion string) (*api.ContainerService, string, error) {
// This isn't terribly elegant, but it's the easiest way to go for now w/o duplicating a bunch of code
rawVersionedAPIModel, err := api.SerializeContainerService(containerService, apiVersion)
rawVersionedAPIModel, err := apiloader.SerializeContainerService(containerService, apiVersion)
if err != nil {
return nil, "", err
}
return api.DeserializeContainerService(rawVersionedAPIModel, true)
return apiloader.DeserializeContainerService(rawVersionedAPIModel, true)
}

func (dc *deployCmd) run() error {
templateGenerator, err := acsengine.InitializeTemplateGenerator(dc.classicMode)
ctx := acsengine.Context{
Translator: &i18n.Translator{
Locale: dc.locale,
},
}

templateGenerator, err := acsengine.InitializeTemplateGenerator(ctx, dc.classicMode)
if err != nil {
log.Fatalln("failed to initialize template generator: %s", err.Error())
}
Expand All @@ -240,7 +264,12 @@ func (dc *deployCmd) run() error {
log.Fatalf("error pretty printing template parameters: %s \n", err.Error())
}

if err = acsengine.WriteTLSArtifacts(dc.containerService, dc.apiVersion, template, parametersFile, dc.outputDirectory, certsgenerated, dc.parametersOnly); err != nil {
writer := &acsengine.ArtifactWriter{
Translator: &i18n.Translator{
Locale: dc.locale,
},
}
if err = writer.WriteTLSArtifacts(dc.containerService, dc.apiVersion, template, parametersFile, dc.outputDirectory, certsgenerated, dc.parametersOnly); err != nil {
log.Fatalf("error writing artifacts: %s \n", err.Error())
}

Expand Down
8 changes: 6 additions & 2 deletions cmd/deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,12 @@ func TestAutofillApimodelAllowsPrespecifiedCreds(t *testing.T) {
}

func testAutodeployCredentialHandling(t *testing.T, useManagedIdentity bool, clientID, clientSecret string) {
apiloader := &api.Apiloader{
Translator: nil,
}

apimodel := getExampleAPIModel(useManagedIdentity, clientID, clientSecret)
cs, ver, err := api.DeserializeContainerService([]byte(apimodel), false)
cs, ver, err := apiloader.DeserializeContainerService([]byte(apimodel), false)
if err != nil {
t.Fatalf("unexpected error deserializing the example apimodel: %s", err)
}
Expand All @@ -73,7 +77,7 @@ func testAutodeployCredentialHandling(t *testing.T, useManagedIdentity bool, cli
// cleanup, since auto-populations creates dirs and saves the SSH private key that it might create
defer os.RemoveAll(deployCmd.outputDirectory)

cs, _, err = revalidateApimodel(cs, ver)
cs, _, err = revalidateApimodel(apiloader, cs, ver)
if err != nil {
log.Fatalf("unexpected error validating apimodel after populating defaults: %s", err)
}
Expand Down
29 changes: 26 additions & 3 deletions cmd/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import (

"github.com/Azure/acs-engine/pkg/acsengine"
"github.com/Azure/acs-engine/pkg/api"
"github.com/Azure/acs-engine/pkg/i18n"
log "github.com/Sirupsen/logrus"
"github.com/leonelquinteros/gotext"
"github.com/spf13/cobra"
)

Expand All @@ -29,6 +31,7 @@ type generateCmd struct {
// derived
containerService *api.ContainerService
apiVersion string
locale *gotext.Locale
}

func newGenerateCmd() *cobra.Command {
Expand Down Expand Up @@ -61,6 +64,11 @@ func (gc *generateCmd) validate(cmd *cobra.Command, args []string) {
var caKeyBytes []byte
var err error

gc.locale, err = i18n.LoadTranslations()
if err != nil {
log.Fatalf("error loading translation files: %s", err.Error())
}

if gc.apimodelPath == "" {
if len(args) > 0 {
gc.apimodelPath = args[0]
Expand All @@ -77,7 +85,12 @@ func (gc *generateCmd) validate(cmd *cobra.Command, args []string) {
log.Fatalf("specified api model does not exist (%s)", gc.apimodelPath)
}

gc.containerService, gc.apiVersion, err = api.LoadContainerServiceFromFile(gc.apimodelPath, true)
apiloader := &api.Apiloader{
Translator: &i18n.Translator{
Locale: gc.locale,
},
}
gc.containerService, gc.apiVersion, err = apiloader.LoadContainerServiceFromFile(gc.apimodelPath, true)
if err != nil {
log.Fatalf("error parsing the api model: %s", err.Error())
}
Expand Down Expand Up @@ -111,7 +124,12 @@ func (gc *generateCmd) validate(cmd *cobra.Command, args []string) {
func (gc *generateCmd) run() error {
log.Infoln("Generating assets...")

templateGenerator, err := acsengine.InitializeTemplateGenerator(gc.classicMode)
ctx := acsengine.Context{
Translator: &i18n.Translator{
Locale: gc.locale,
},
}
templateGenerator, err := acsengine.InitializeTemplateGenerator(ctx, gc.classicMode)
if err != nil {
log.Fatalln("failed to initialize template generator: %s", err.Error())
}
Expand All @@ -131,7 +149,12 @@ func (gc *generateCmd) run() error {
}
}

if err = acsengine.WriteTLSArtifacts(gc.containerService, gc.apiVersion, template, parameters, gc.outputDirectory, certsGenerated, gc.parametersOnly); err != nil {
writer := &acsengine.ArtifactWriter{
Translator: &i18n.Translator{
Locale: gc.locale,
},
}
if err = writer.WriteTLSArtifacts(gc.containerService, gc.apiVersion, template, parameters, gc.outputDirectory, certsGenerated, gc.parametersOnly); err != nil {
log.Fatalf("error writing artifacts: %s \n", err.Error())
}

Expand Down
25 changes: 23 additions & 2 deletions cmd/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import (

"github.com/Azure/acs-engine/pkg/api"
"github.com/Azure/acs-engine/pkg/armhelpers"
"github.com/Azure/acs-engine/pkg/i18n"
"github.com/Azure/acs-engine/pkg/operations/kubernetesupgrade"
"github.com/leonelquinteros/gotext"

log "github.com/Sirupsen/logrus"
"github.com/spf13/cobra"
Expand All @@ -35,6 +37,7 @@ type upgradeCmd struct {
upgradeContainerService *api.UpgradeContainerService
upgradeAPIVersion string
client armhelpers.ACSEngineClient
locale *gotext.Locale
nameSuffix string
}

Expand Down Expand Up @@ -65,6 +68,11 @@ func (uc *upgradeCmd) validate(cmd *cobra.Command, args []string) {

var err error

uc.locale, err = i18n.LoadTranslations()
if err != nil {
log.Fatalf("error loading translation files: %s", err.Error())
}

if uc.resourceGroupName == "" {
cmd.Usage()
log.Fatal("--resource-group must be specified")
Expand Down Expand Up @@ -92,7 +100,12 @@ func (uc *upgradeCmd) validate(cmd *cobra.Command, args []string) {
log.Fatalf("specified api model does not exist (%s)", apiModelPath)
}

uc.containerService, uc.apiVersion, err = api.LoadContainerServiceFromFile(apiModelPath, true)
apiloader := &api.Apiloader{
Translator: &i18n.Translator{
Locale: uc.locale,
},
}
uc.containerService, uc.apiVersion, err = apiloader.LoadContainerServiceFromFile(apiModelPath, true)
if err != nil {
log.Fatalf("error parsing the api model: %s", err.Error())
}
Expand All @@ -101,7 +114,12 @@ func (uc *upgradeCmd) validate(cmd *cobra.Command, args []string) {
log.Fatalf("specified upgrade model file does not exist (%s)", uc.upgradeModelFile)
}

uc.upgradeContainerService, uc.upgradeAPIVersion, err = api.LoadUpgradeContainerServiceFromFile(uc.upgradeModelFile)
upgradeapiloader := &api.UpgradeApiloader{
Translator: &i18n.Translator{
Locale: uc.locale,
},
}
uc.upgradeContainerService, uc.upgradeAPIVersion, err = upgradeapiloader.LoadUpgradeContainerServiceFromFile(uc.upgradeModelFile)
if err != nil {
log.Fatalf("error parsing the upgrade api model: %s", err.Error())
}
Expand Down Expand Up @@ -134,6 +152,9 @@ func (uc *upgradeCmd) run(cmd *cobra.Command, args []string) error {
uc.validate(cmd, args)

upgradeCluster := kubernetesupgrade.UpgradeCluster{
Translator: &i18n.Translator{
Locale: uc.locale,
},
Client: uc.client,
}

Expand Down
8 changes: 8 additions & 0 deletions glide.lock

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

2 changes: 2 additions & 0 deletions glide.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import:
- package: github.com/spf13/cobra
version: 4cdb38c072b86bf795d2c81de50784d9fdd6eb77
- package: github.com/spf13/pflag
- package: github.com/leonelquinteros/gotext
version: v1.1.1
version: e57e3eeb33f795204c1ca35f56c44f83227c6e66
- package: gopkg.in/go-playground/validator.v9
version: v9.4.0
Expand Down
Loading

0 comments on commit b41df8f

Please sign in to comment.