зеркало из https://github.com/Azure/buffalo-azure.git
Коммит
16c74dff1d
|
@ -15,8 +15,8 @@
|
||||||
"services/resources/mgmt/2017-05-10/resources",
|
"services/resources/mgmt/2017-05-10/resources",
|
||||||
"version"
|
"version"
|
||||||
]
|
]
|
||||||
revision = "cd93ccfe0395e70031704ca68f14606588eec120"
|
revision = "7971189ecf5a584b9211f2527737f94bb979644e"
|
||||||
version = "v17.3.0"
|
version = "v17.4.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/Azure/go-autorest"
|
name = "github.com/Azure/go-autorest"
|
||||||
|
@ -28,8 +28,8 @@
|
||||||
"autorest/to",
|
"autorest/to",
|
||||||
"autorest/validation"
|
"autorest/validation"
|
||||||
]
|
]
|
||||||
revision = "76796dcb80ab6491bf22e344402023c081a7a282"
|
revision = "1f7cd6cfe0adea687ad44a512dfe76140f804318"
|
||||||
version = "v10.11.1"
|
version = "v10.12.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
@ -90,8 +90,17 @@
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/gobuffalo/envy"
|
name = "github.com/gobuffalo/envy"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "ef60bfc50c8f92d1ee64674d8ce7a48f1f67625e"
|
revision = "2d0f467653f3d961ce9ada4d32a230bdcb3bfe11"
|
||||||
version = "v1.6.2"
|
version = "v1.6.3"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/gobuffalo/fizz"
|
||||||
|
packages = [
|
||||||
|
".",
|
||||||
|
"translators"
|
||||||
|
]
|
||||||
|
revision = "25461ee937655cd1136523f6653d5bd15343cc48"
|
||||||
|
version = "v1.0.1"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/gobuffalo/makr"
|
name = "github.com/gobuffalo/makr"
|
||||||
|
@ -114,8 +123,8 @@
|
||||||
"parser",
|
"parser",
|
||||||
"token"
|
"token"
|
||||||
]
|
]
|
||||||
revision = "b0b0a05f963a529b49d835f868fa1e2b92f4b144"
|
revision = "2ec029f415ed9a8a1448a5bb389d79084d606035"
|
||||||
version = "v3.7.4"
|
version = "v3.7.7"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/gobuffalo/pop"
|
name = "github.com/gobuffalo/pop"
|
||||||
|
@ -123,12 +132,11 @@
|
||||||
".",
|
".",
|
||||||
"associations",
|
"associations",
|
||||||
"columns",
|
"columns",
|
||||||
"fizz",
|
"fix",
|
||||||
"fizz/translators",
|
|
||||||
"nulls"
|
"nulls"
|
||||||
]
|
]
|
||||||
revision = "9985012f32f5e36b1a10e9191ee460daac4a9bc7"
|
revision = "66130dbcd030ea900e35e45e03dd1a59577d2e99"
|
||||||
version = "v4.5.9"
|
version = "v4.5.12"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/gobuffalo/tags"
|
name = "github.com/gobuffalo/tags"
|
||||||
|
@ -137,8 +145,8 @@
|
||||||
"form",
|
"form",
|
||||||
"form/bootstrap"
|
"form/bootstrap"
|
||||||
]
|
]
|
||||||
revision = "82cd7696c84aba829b74e81814ff489b64e7b56a"
|
revision = "96c7cdfcadcb28eb1b42b9080ba7f93936ffc5c5"
|
||||||
version = "v2.0.5"
|
version = "v2.0.7"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/gobuffalo/uuid"
|
name = "github.com/gobuffalo/uuid"
|
||||||
|
@ -221,7 +229,7 @@
|
||||||
".",
|
".",
|
||||||
"reflectx"
|
"reflectx"
|
||||||
]
|
]
|
||||||
revision = "2aeb6a910c2b94f2d5eb53d9895d80e27264ec41"
|
revision = "0dae4fefe7c0e190f7b5a78dac28a1c82cc8d849"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/joho/godotenv"
|
name = "github.com/joho/godotenv"
|
||||||
|
@ -245,7 +253,6 @@
|
||||||
version = "v1.8.0"
|
version = "v1.8.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
|
||||||
name = "github.com/markbates/going"
|
name = "github.com/markbates/going"
|
||||||
packages = [
|
packages = [
|
||||||
"defaults",
|
"defaults",
|
||||||
|
@ -253,18 +260,19 @@
|
||||||
"wait"
|
"wait"
|
||||||
]
|
]
|
||||||
revision = "0576708c56cea02331f864fe6e157ac7841923e4"
|
revision = "0576708c56cea02331f864fe6e157ac7841923e4"
|
||||||
|
version = "v1.0.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
|
||||||
name = "github.com/markbates/grift"
|
name = "github.com/markbates/grift"
|
||||||
packages = ["grift"]
|
packages = ["grift"]
|
||||||
revision = "76f93617a788d350124f749acb3790276a436cc0"
|
revision = "76f93617a788d350124f749acb3790276a436cc0"
|
||||||
|
version = "v1.0.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
|
||||||
name = "github.com/markbates/inflect"
|
name = "github.com/markbates/inflect"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "dd7de90c06bca70f18136e59dec2270c19a401e7"
|
revision = "dd7de90c06bca70f18136e59dec2270c19a401e7"
|
||||||
|
version = "v1.0.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/markbates/refresh"
|
name = "github.com/markbates/refresh"
|
||||||
|
@ -293,17 +301,6 @@
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "48a63b6052f1f9373db9388a658da30c6ab53db1"
|
revision = "48a63b6052f1f9373db9388a658da30c6ab53db1"
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
name = "github.com/mattn/anko"
|
|
||||||
packages = [
|
|
||||||
"ast",
|
|
||||||
"core",
|
|
||||||
"parser",
|
|
||||||
"vm"
|
|
||||||
]
|
|
||||||
revision = "e9c5c0ca86cf129292c56ddbddc4fff027844d65"
|
|
||||||
version = "v0.0.4"
|
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/mattn/go-colorable"
|
name = "github.com/mattn/go-colorable"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
|
@ -319,14 +316,14 @@
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/mattn/go-sqlite3"
|
name = "github.com/mattn/go-sqlite3"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "323a32be5a2421b8c7087225079c6c900ec397cd"
|
revision = "25ecb14adfc7543176f7d85291ec7dba82c6f7e4"
|
||||||
version = "v1.7.0"
|
version = "v1.9.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/microcosm-cc/bluemonday"
|
name = "github.com/microcosm-cc/bluemonday"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "995366fdf961d03629cd17361bddd32745718e2c"
|
revision = "f0761eb8ed07c1cc892ef631b00c33463b9b6868"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
@ -494,7 +491,7 @@
|
||||||
"blowfish",
|
"blowfish",
|
||||||
"ssh/terminal"
|
"ssh/terminal"
|
||||||
]
|
]
|
||||||
revision = "8ac0e0d97ce45cd83d1d7243c060cb8461dda5e9"
|
revision = "a49355c7e3f8fe157a85be2f77e6e269a0f89602"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
@ -504,7 +501,7 @@
|
||||||
"html",
|
"html",
|
||||||
"html/atom"
|
"html/atom"
|
||||||
]
|
]
|
||||||
revision = "db08ff08e8622530d9ed3a0e8ac279f6d4c02196"
|
revision = "87b3feba568e144938625fc5d80ec92566c1a8fe"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
@ -519,7 +516,7 @@
|
||||||
"unix",
|
"unix",
|
||||||
"windows"
|
"windows"
|
||||||
]
|
]
|
||||||
revision = "bff228c7b664c5fce602223a05fb708fd8654986"
|
revision = "7138fd3d9dc8335c567ca206f4333fb75eb05d56"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "golang.org/x/text"
|
name = "golang.org/x/text"
|
||||||
|
@ -537,8 +534,8 @@
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "google.golang.org/appengine"
|
name = "google.golang.org/appengine"
|
||||||
packages = ["cloudsql"]
|
packages = ["cloudsql"]
|
||||||
revision = "150dc57a1b433e64154302bdc40b6bb8aefa313a"
|
revision = "b1f26356af11148e710935ed1ac8a7f5702c7612"
|
||||||
version = "v1.0.0"
|
version = "v1.1.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "gopkg.in/yaml.v2"
|
name = "gopkg.in/yaml.v2"
|
||||||
|
@ -549,6 +546,6 @@
|
||||||
[solve-meta]
|
[solve-meta]
|
||||||
analyzer-name = "dep"
|
analyzer-name = "dep"
|
||||||
analyzer-version = 1
|
analyzer-version = 1
|
||||||
inputs-digest = "b735a8f4099268006777df3205705fac3423a7666a61f92eeba515d365aac5b7"
|
inputs-digest = "0ca276e99bfba052cf9d07bc5e408c494fce5cc8b82106feec5601f108cd5b4d"
|
||||||
solver-name = "gps-cdcl"
|
solver-name = "gps-cdcl"
|
||||||
solver-version = 1
|
solver-version = 1
|
||||||
|
|
10
Gopkg.toml
10
Gopkg.toml
|
@ -27,11 +27,11 @@
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/gobuffalo/buffalo"
|
name = "github.com/gobuffalo/buffalo"
|
||||||
version = "0.11.0"
|
version = "~0.11.0"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/gobuffalo/uuid"
|
name = "github.com/gobuffalo/uuid"
|
||||||
version = "2.0.0"
|
version = "^2.0.0"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
@ -43,7 +43,11 @@
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/spf13/viper"
|
name = "github.com/spf13/viper"
|
||||||
version = "1.0.2"
|
version = "^1.0.2"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/joho/godotenv"
|
||||||
|
version = "^1.2.0"
|
||||||
|
|
||||||
[prune]
|
[prune]
|
||||||
go-tests = true
|
go-tests = true
|
||||||
|
|
166
cmd/provision.go
166
cmd/provision.go
|
@ -42,6 +42,7 @@ import (
|
||||||
"github.com/Azure/go-autorest/autorest/azure"
|
"github.com/Azure/go-autorest/autorest/azure"
|
||||||
"github.com/gobuffalo/buffalo/meta"
|
"github.com/gobuffalo/buffalo/meta"
|
||||||
"github.com/gobuffalo/pop"
|
"github.com/gobuffalo/pop"
|
||||||
|
"github.com/joho/godotenv"
|
||||||
"github.com/marstr/randname"
|
"github.com/marstr/randname"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
@ -108,7 +109,7 @@ const (
|
||||||
const (
|
const (
|
||||||
DatabaseAdminName = "db-admin"
|
DatabaseAdminName = "db-admin"
|
||||||
DatabaseAdminDefault = "buffaloAdmin"
|
DatabaseAdminDefault = "buffaloAdmin"
|
||||||
databaseAdminUsage = "The user handle of the administratr account "
|
databaseAdminUsage = "The user handle of the administrator account."
|
||||||
)
|
)
|
||||||
|
|
||||||
// These constants define a parameter which controls the password of the database provisioned. For marginal security,
|
// These constants define a parameter which controls the password of the database provisioned. For marginal security,
|
||||||
|
@ -119,6 +120,7 @@ const (
|
||||||
DatabasePasswordShorthand = "w"
|
DatabasePasswordShorthand = "w"
|
||||||
DatabasePasswordDefault = "<randomly generated>"
|
DatabasePasswordDefault = "<randomly generated>"
|
||||||
databasePasswordUsage = "The administrator password for the database created. It is recommended you read this from a file instead of typing it in from your terminal."
|
databasePasswordUsage = "The administrator password for the database created. It is recommended you read this from a file instead of typing it in from your terminal."
|
||||||
|
DatabasePasswordEnvVar = "BUFFALO_AZURE_DATABASE_PASSWORD"
|
||||||
)
|
)
|
||||||
|
|
||||||
// These constants define a parameter which allows control over the particular Azure cloud which should be used for
|
// These constants define a parameter which allows control over the particular Azure cloud which should be used for
|
||||||
|
@ -255,8 +257,9 @@ const (
|
||||||
|
|
||||||
// These constants define a parameter which toggles whether or not to save the template used for deployment to disk.
|
// These constants define a parameter which toggles whether or not to save the template used for deployment to disk.
|
||||||
const (
|
const (
|
||||||
SkipTemplateCacheName = "skip-template-cache"
|
SkipTemplateCacheName = "skip-template-cache"
|
||||||
skipTemplateCacheUsage = "After downloading the default template, do NOT save it in the working directory."
|
SkipTemplateCacheShorthand = "z"
|
||||||
|
skipTemplateCacheUsage = "After downloading the default template, do NOT save it in the working directory."
|
||||||
)
|
)
|
||||||
|
|
||||||
// These constants define a parameter which toggles whether or not to save the parameters used for deployment to disk.
|
// These constants define a parameter which toggles whether or not to save the parameters used for deployment to disk.
|
||||||
|
@ -273,6 +276,41 @@ const (
|
||||||
skipDeploymentUsage = "Do not create an Azure deployment, do just the meta tasks."
|
skipDeploymentUsage = "Do not create an Azure deployment, do just the meta tasks."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// These constants define a parameter which controls the Docker registry that will be searched for the image provided.
|
||||||
|
const (
|
||||||
|
DockerRegistryURLName = "docker-registry-url"
|
||||||
|
dockerRegistryURLUsage = "The URL for a private Docker Registry containing the image definition."
|
||||||
|
)
|
||||||
|
|
||||||
|
// These constants define a parameter which allows the username to be set for Docker authentication.
|
||||||
|
const (
|
||||||
|
DockerRegistryUsernameName = "docker-registry-username"
|
||||||
|
dockerRegistryUsernameUsage = "The user handle to allow access to a private docker registry."
|
||||||
|
)
|
||||||
|
|
||||||
|
// These constants define a parameter which allows the password to be set for Docker authentication.
|
||||||
|
const (
|
||||||
|
DockerRegistryPasswordName = "docker-registry-password"
|
||||||
|
dockerRegistryPasswordUsage = "The user password to allow access to a private docker registry."
|
||||||
|
)
|
||||||
|
|
||||||
|
// DockerAccess is an enum that contains either "private" or "public"
|
||||||
|
type DockerAccess string
|
||||||
|
|
||||||
|
// All (currently) possible value of DockerAccess
|
||||||
|
const (
|
||||||
|
DockerAccessPublic = "public"
|
||||||
|
DockerAccessPrivate = "private"
|
||||||
|
)
|
||||||
|
|
||||||
|
// These constants define a parameter which informs buffalo-azure whether the registry is public or
|
||||||
|
// private.
|
||||||
|
const (
|
||||||
|
DockerRegistryAccessName = "docker-registry-access"
|
||||||
|
DockerRegistryAccessDefault = DockerAccessPublic
|
||||||
|
dockerRegistryAccessUsage = "Specifies whether the Docker registry targeted is " + DockerAccessPublic + " or " + DockerAccessPrivate
|
||||||
|
)
|
||||||
|
|
||||||
var status *log.Logger
|
var status *log.Logger
|
||||||
var errLog = newFormattedLog(os.Stderr, "error")
|
var errLog = newFormattedLog(os.Stderr, "error")
|
||||||
var debugLog *log.Logger
|
var debugLog *log.Logger
|
||||||
|
@ -304,10 +342,15 @@ var provisionCmd = &cobra.Command{
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 45*time.Minute)
|
ctx, cancel := context.WithTimeout(context.Background(), 45*time.Minute)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
auth, err := getAuthorizer(ctx, subscriptionID, clientID, clientSecret, provisionConfig.GetString(TenantIDName))
|
var err error
|
||||||
if err != nil {
|
var auth autorest.Authorizer
|
||||||
errLog.Print("unable to authenticate: ", err)
|
|
||||||
return
|
if !provisionConfig.GetBool(SkipDeploymentName) {
|
||||||
|
auth, err = getAuthorizer(ctx, subscriptionID, clientID, clientSecret, provisionConfig.GetString(TenantIDName))
|
||||||
|
if err != nil {
|
||||||
|
errLog.Print("unable to authenticate: ", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
status.Print(TenantIDName+" selected: ", provisionConfig.GetString(TenantIDName))
|
status.Print(TenantIDName+" selected: ", provisionConfig.GetString(TenantIDName))
|
||||||
status.Print(SubscriptionName+" selected: ", subscriptionID)
|
status.Print(SubscriptionName+" selected: ", subscriptionID)
|
||||||
|
@ -317,34 +360,26 @@ var provisionCmd = &cobra.Command{
|
||||||
status.Println(DatabaseAdminName+" selected: ", databaseAdmin)
|
status.Println(DatabaseAdminName+" selected: ", databaseAdmin)
|
||||||
|
|
||||||
if usingDB, dbPassword := !strings.EqualFold(provisionConfig.GetString(DatabaseTypeName), "none"), provisionConfig.GetString(DatabasePasswordName); usingDB && dbPassword == DatabasePasswordDefault {
|
if usingDB, dbPassword := !strings.EqualFold(provisionConfig.GetString(DatabaseTypeName), "none"), provisionConfig.GetString(DatabasePasswordName); usingDB && dbPassword == DatabasePasswordDefault {
|
||||||
provisionConfig.Set(DatabasePasswordName, randname.GenerateWithPrefix("MSFT+Buffalo-", 20))
|
newPass := randname.GenerateWithPrefix("MSFT+Buffalo-", 20)
|
||||||
|
provisionConfig.Set(DatabasePasswordName, newPass)
|
||||||
status.Println("generated database password")
|
status.Println("generated database password")
|
||||||
|
var envMap map[string]string
|
||||||
|
const envFileLoc = "./.env"
|
||||||
|
if envMap, err = godotenv.Read(envFileLoc); err != nil {
|
||||||
|
envMap = make(map[string]string, 1)
|
||||||
|
}
|
||||||
|
envMap[DatabasePasswordEnvVar] = newPass
|
||||||
|
if err := godotenv.Write(envMap, envFileLoc); err == nil {
|
||||||
|
status.Printf("wrote database password to %q", envFileLoc)
|
||||||
|
} else {
|
||||||
|
errLog.Printf("unable to write database password to %q", envFileLoc)
|
||||||
|
}
|
||||||
} else if usingDB {
|
} else if usingDB {
|
||||||
status.Println("using provided password")
|
status.Println("using provided password")
|
||||||
}
|
}
|
||||||
|
|
||||||
status.Println(ImageName+" selected: ", image)
|
status.Println(ImageName+" selected: ", image)
|
||||||
|
|
||||||
groups := resources.NewGroupsClient(subscriptionID)
|
|
||||||
groups.Authorizer = auth
|
|
||||||
groups.AddToUserAgent(userAgent)
|
|
||||||
|
|
||||||
// Assert the presence of the specified Resource Group
|
|
||||||
rgName := provisionConfig.GetString(ResoureGroupName)
|
|
||||||
created, err := insertResourceGroup(ctx, groups, rgName, provisionConfig.GetString(LocationName))
|
|
||||||
if err != nil {
|
|
||||||
errLog.Printf("unable to fetch or create resource group %s: %v\n", rgName, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if created {
|
|
||||||
status.Println("created resource group: ", rgName)
|
|
||||||
} else {
|
|
||||||
status.Println("found resource group: ", rgName)
|
|
||||||
}
|
|
||||||
status.Println("site name selected: ", siteName)
|
|
||||||
|
|
||||||
pLink := portalLink(subscriptionID, rgName)
|
|
||||||
|
|
||||||
// Provision the necessary assets.
|
// Provision the necessary assets.
|
||||||
|
|
||||||
deployParams.Parameters["name"] = DeploymentParameter{siteName}
|
deployParams.Parameters["name"] = DeploymentParameter{siteName}
|
||||||
|
@ -353,6 +388,10 @@ var provisionCmd = &cobra.Command{
|
||||||
deployParams.Parameters["imageName"] = DeploymentParameter{image}
|
deployParams.Parameters["imageName"] = DeploymentParameter{image}
|
||||||
deployParams.Parameters["databaseAdministratorLogin"] = DeploymentParameter{databaseAdmin}
|
deployParams.Parameters["databaseAdministratorLogin"] = DeploymentParameter{databaseAdmin}
|
||||||
deployParams.Parameters["databaseAdministratorLoginPassword"] = DeploymentParameter{provisionConfig.GetString(DatabasePasswordName)}
|
deployParams.Parameters["databaseAdministratorLoginPassword"] = DeploymentParameter{provisionConfig.GetString(DatabasePasswordName)}
|
||||||
|
deployParams.Parameters["dockerRegistryAccess"] = DeploymentParameter{provisionConfig.GetString(DockerRegistryAccessName)}
|
||||||
|
deployParams.Parameters["dockerRegistryServerURL"] = DeploymentParameter{provisionConfig.GetString(DockerRegistryURLName)}
|
||||||
|
deployParams.Parameters["dockerRegistryServerUsername"] = DeploymentParameter{provisionConfig.GetString(DockerRegistryUsernameName)}
|
||||||
|
deployParams.Parameters["dockerRegistryServerPassword"] = DeploymentParameter{provisionConfig.GetString(DockerRegistryPasswordName)}
|
||||||
|
|
||||||
template, err := getDeploymentTemplate(ctx, templateLocation)
|
template, err := getDeploymentTemplate(ctx, templateLocation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -369,6 +408,27 @@ var provisionCmd = &cobra.Command{
|
||||||
} else {
|
} else {
|
||||||
go func(errOut chan<- error) {
|
go func(errOut chan<- error) {
|
||||||
defer close(errOut)
|
defer close(errOut)
|
||||||
|
groups := resources.NewGroupsClient(subscriptionID)
|
||||||
|
groups.Authorizer = auth
|
||||||
|
groups.AddToUserAgent(userAgent)
|
||||||
|
|
||||||
|
// Assert the presence of the specified Resource Group
|
||||||
|
rgName := provisionConfig.GetString(ResoureGroupName)
|
||||||
|
created, err := insertResourceGroup(ctx, groups, rgName, provisionConfig.GetString(LocationName))
|
||||||
|
if err != nil {
|
||||||
|
errLog.Printf("unable to fetch or create resource group %s: %v\n", rgName, err)
|
||||||
|
errOut <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if created {
|
||||||
|
status.Println("created resource group: ", rgName)
|
||||||
|
} else {
|
||||||
|
status.Println("found resource group: ", rgName)
|
||||||
|
}
|
||||||
|
status.Println("site name selected: ", siteName)
|
||||||
|
|
||||||
|
pLink := portalLink(subscriptionID, rgName)
|
||||||
|
|
||||||
status.Println("beginning deployment")
|
status.Println("beginning deployment")
|
||||||
if err := doDeployment(ctx, auth, subscriptionID, rgName, template); err == nil {
|
if err := doDeployment(ctx, auth, subscriptionID, rgName, template); err == nil {
|
||||||
fmt.Println("Check on your new Resource Group in the Azure Portal: ", pLink)
|
fmt.Println("Check on your new Resource Group in the Azure Portal: ", pLink)
|
||||||
|
@ -404,7 +464,7 @@ var provisionCmd = &cobra.Command{
|
||||||
if provisionConfig.GetBool(SkipParameterCacheName) {
|
if provisionConfig.GetBool(SkipParameterCacheName) {
|
||||||
close(parameterSaveResults)
|
close(parameterSaveResults)
|
||||||
} else {
|
} else {
|
||||||
go doCache(ctx, parameterSaveResults, stripDBPassword(deployParams), TemplateParametersDefault, "parameters")
|
go doCache(ctx, parameterSaveResults, stripPasswords(deployParams), TemplateParametersDefault, "parameters")
|
||||||
}
|
}
|
||||||
|
|
||||||
waitOnResults := func(ctx context.Context, results <-chan error) error {
|
waitOnResults := func(ctx context.Context, results <-chan error) error {
|
||||||
|
@ -480,7 +540,7 @@ var provisionCmd = &cobra.Command{
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func stripDBPassword(original *DeploymentParameters) (copy *DeploymentParameters) {
|
func stripPasswords(original *DeploymentParameters) (copy *DeploymentParameters) {
|
||||||
copy = NewDeploymentParameters()
|
copy = NewDeploymentParameters()
|
||||||
copy.Parameters = make(map[string]DeploymentParameter, len(original.Parameters))
|
copy.Parameters = make(map[string]DeploymentParameter, len(original.Parameters))
|
||||||
copy.ContentVersion = original.ContentVersion
|
copy.ContentVersion = original.ContentVersion
|
||||||
|
@ -490,6 +550,7 @@ func stripDBPassword(original *DeploymentParameters) (copy *DeploymentParameters
|
||||||
copy.Parameters[k] = v
|
copy.Parameters[k] = v
|
||||||
}
|
}
|
||||||
delete(copy.Parameters, "databaseAdministratorLoginPassword")
|
delete(copy.Parameters, "databaseAdministratorLoginPassword")
|
||||||
|
delete(copy.Parameters, "dockerRegistryServerPassword")
|
||||||
return copy
|
return copy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,6 +559,7 @@ func cache(ctx context.Context, contents interface{}, outputName string) error {
|
||||||
defer handle.Close()
|
defer handle.Close()
|
||||||
|
|
||||||
enc := json.NewEncoder(handle)
|
enc := json.NewEncoder(handle)
|
||||||
|
enc.SetIndent("", " ")
|
||||||
err = enc.Encode(contents)
|
err = enc.Encode(contents)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -824,6 +886,22 @@ func setDefaults(conf *viper.Viper, params *DeploymentParameters) {
|
||||||
if dbAdmin, ok := params.Parameters["databaseAdministratorLogin"]; ok {
|
if dbAdmin, ok := params.Parameters["databaseAdministratorLogin"]; ok {
|
||||||
conf.SetDefault(DatabaseAdminName, dbAdmin.Value)
|
conf.SetDefault(DatabaseAdminName, dbAdmin.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if dockerAccess, ok := params.Parameters["dockerRegistryAccess"]; ok {
|
||||||
|
conf.SetDefault(DockerRegistryAccessName, dockerAccess)
|
||||||
|
}
|
||||||
|
|
||||||
|
if dockerURL, ok := params.Parameters["dockerRegistryServerURL"]; ok {
|
||||||
|
conf.SetDefault(DockerRegistryURLName, dockerURL)
|
||||||
|
}
|
||||||
|
|
||||||
|
if dockerUsername, ok := params.Parameters["dockerRegistryServerUsername"]; ok {
|
||||||
|
conf.SetDefault(DockerRegistryUsernameName, dockerUsername)
|
||||||
|
}
|
||||||
|
|
||||||
|
if dockerPassword, ok := params.Parameters["dockerRegistryServerPassword"]; ok {
|
||||||
|
conf.SetDefault(DockerRegistryPasswordName, dockerPassword)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadFromParameterFile(paramFile string) (*DeploymentParameters, error) {
|
func loadFromParameterFile(paramFile string) (*DeploymentParameters, error) {
|
||||||
|
@ -844,6 +922,7 @@ func loadFromParameterFile(paramFile string) (*DeploymentParameters, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
const redactedMessage = "[redacted]"
|
||||||
var debugWriter io.Writer
|
var debugWriter io.Writer
|
||||||
if debug == "" {
|
if debug == "" {
|
||||||
debugWriter = ioutil.Discard
|
debugWriter = ioutil.Discard
|
||||||
|
@ -854,6 +933,8 @@ func init() {
|
||||||
|
|
||||||
azureCmd.AddCommand(provisionCmd)
|
azureCmd.AddCommand(provisionCmd)
|
||||||
|
|
||||||
|
godotenv.Load()
|
||||||
|
|
||||||
// Here you will define your flags and configuration settings.
|
// Here you will define your flags and configuration settings.
|
||||||
|
|
||||||
// Cobra supports Persistent Flags which will work for this command
|
// Cobra supports Persistent Flags which will work for this command
|
||||||
|
@ -870,6 +951,7 @@ func init() {
|
||||||
provisionConfig.BindEnv(TenantIDName, "AZURE_TENANT_ID", "AZ_TENANT_ID")
|
provisionConfig.BindEnv(TenantIDName, "AZURE_TENANT_ID", "AZ_TENANT_ID")
|
||||||
provisionConfig.BindEnv(EnvironmentName, "AZURE_ENVIRONMENT", "AZ_ENVIRONMENT")
|
provisionConfig.BindEnv(EnvironmentName, "AZURE_ENVIRONMENT", "AZ_ENVIRONMENT")
|
||||||
provisionConfig.BindEnv(ProfileName, "GO_ENV")
|
provisionConfig.BindEnv(ProfileName, "GO_ENV")
|
||||||
|
provisionConfig.BindEnv(DatabasePasswordName, DatabasePasswordEnvVar, "BUFFALO_AZURE_DB_PASSWORD", "BUFFALO_AZ_DATABASE_PASSWORD", "BUFFALO_AZ_DB_PASSWORD")
|
||||||
|
|
||||||
provisionConfig.SetDefault(ProfileName, "development")
|
provisionConfig.SetDefault(ProfileName, "development")
|
||||||
|
|
||||||
|
@ -888,6 +970,7 @@ func init() {
|
||||||
provisionConfig.SetDefault(LocationName, LocationDefaultText)
|
provisionConfig.SetDefault(LocationName, LocationDefaultText)
|
||||||
provisionConfig.SetDefault(SiteName, siteDefaultMessage)
|
provisionConfig.SetDefault(SiteName, siteDefaultMessage)
|
||||||
provisionConfig.SetDefault(TemplateParametersName, TemplateParametersDefault)
|
provisionConfig.SetDefault(TemplateParametersName, TemplateParametersDefault)
|
||||||
|
provisionConfig.SetDefault(DockerRegistryAccessName, DockerRegistryAccessDefault)
|
||||||
|
|
||||||
var sanitizedClientSecret string
|
var sanitizedClientSecret string
|
||||||
if rawSecret := provisionConfig.GetString(ClientSecretName); rawSecret != "" {
|
if rawSecret := provisionConfig.GetString(ClientSecretName); rawSecret != "" {
|
||||||
|
@ -895,7 +978,7 @@ func init() {
|
||||||
if len(rawSecret) > safeCharCount {
|
if len(rawSecret) > safeCharCount {
|
||||||
sanitizedClientSecret = fmt.Sprintf("...%s", rawSecret[len(rawSecret)-safeCharCount:])
|
sanitizedClientSecret = fmt.Sprintf("...%s", rawSecret[len(rawSecret)-safeCharCount:])
|
||||||
} else {
|
} else {
|
||||||
sanitizedClientSecret = "[key hidden]"
|
sanitizedClientSecret = redactedMessage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -912,6 +995,19 @@ func init() {
|
||||||
deployParams = NewDeploymentParameters()
|
deployParams = NewDeploymentParameters()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dbPassText := provisionConfig.GetString(DatabasePasswordName)
|
||||||
|
if dbPassText == "" {
|
||||||
|
dbPassText = DatabasePasswordDefault
|
||||||
|
provisionConfig.SetDefault(DatabasePasswordName, DatabasePasswordDefault)
|
||||||
|
} else {
|
||||||
|
dbPassText = redactedMessage
|
||||||
|
}
|
||||||
|
|
||||||
|
dockerPassText := provisionConfig.GetString(DockerRegistryPasswordName)
|
||||||
|
if dockerPassText != "" {
|
||||||
|
dockerPassText = redactedMessage
|
||||||
|
}
|
||||||
|
|
||||||
provisionCmd.Flags().StringP(ImageName, ImageShorthand, provisionConfig.GetString(ImageName), imageUsage)
|
provisionCmd.Flags().StringP(ImageName, ImageShorthand, provisionConfig.GetString(ImageName), imageUsage)
|
||||||
provisionCmd.Flags().StringP(TemplateName, TemplateShorthand, provisionConfig.GetString(TemplateName), templateUsage)
|
provisionCmd.Flags().StringP(TemplateName, TemplateShorthand, provisionConfig.GetString(TemplateName), templateUsage)
|
||||||
provisionCmd.Flags().StringP(SubscriptionName, SubscriptionShorthand, provisionConfig.GetString(SubscriptionName), subscriptionUsage)
|
provisionCmd.Flags().StringP(SubscriptionName, SubscriptionShorthand, provisionConfig.GetString(SubscriptionName), subscriptionUsage)
|
||||||
|
@ -926,12 +1022,16 @@ func init() {
|
||||||
provisionCmd.Flags().StringP(ResoureGroupName, ResourceGroupShorthand, provisionConfig.GetString(ResoureGroupName), resourceGroupUsage)
|
provisionCmd.Flags().StringP(ResoureGroupName, ResourceGroupShorthand, provisionConfig.GetString(ResoureGroupName), resourceGroupUsage)
|
||||||
provisionCmd.Flags().StringP(SiteName, SiteShorthand, provisionConfig.GetString(SiteName), siteUsage)
|
provisionCmd.Flags().StringP(SiteName, SiteShorthand, provisionConfig.GetString(SiteName), siteUsage)
|
||||||
provisionCmd.Flags().StringP(LocationName, LocationShorthand, provisionConfig.GetString(LocationName), locationUsage)
|
provisionCmd.Flags().StringP(LocationName, LocationShorthand, provisionConfig.GetString(LocationName), locationUsage)
|
||||||
provisionCmd.Flags().Bool(SkipTemplateCacheName, false, skipTemplateCacheUsage)
|
provisionCmd.Flags().BoolP(SkipTemplateCacheName, SkipTemplateCacheShorthand, false, skipTemplateCacheUsage)
|
||||||
provisionCmd.Flags().BoolP(SkipParameterCacheName, SkipParameterCacheShorthand, false, skipParameterCacheUsage)
|
provisionCmd.Flags().BoolP(SkipParameterCacheName, SkipParameterCacheShorthand, false, skipParameterCacheUsage)
|
||||||
provisionCmd.Flags().BoolP(SkipDeploymentName, SkipDeploymentShorthand, false, skipDeploymentUsage)
|
provisionCmd.Flags().BoolP(SkipDeploymentName, SkipDeploymentShorthand, false, skipDeploymentUsage)
|
||||||
provisionCmd.Flags().StringP(DatabasePasswordName, DatabasePasswordShorthand, DatabasePasswordDefault, databasePasswordUsage)
|
provisionCmd.Flags().StringP(DatabasePasswordName, DatabasePasswordShorthand, dbPassText, databasePasswordUsage)
|
||||||
provisionCmd.Flags().String(DatabaseAdminName, provisionConfig.GetString(DatabaseAdminName), databaseAdminUsage)
|
provisionCmd.Flags().String(DatabaseAdminName, provisionConfig.GetString(DatabaseAdminName), databaseAdminUsage)
|
||||||
provisionCmd.Flags().StringP(TemplateParametersName, TemplateParametersShorthand, provisionConfig.GetString(TemplateParametersName), templateParametersUsage)
|
provisionCmd.Flags().StringP(TemplateParametersName, TemplateParametersShorthand, provisionConfig.GetString(TemplateParametersName), templateParametersUsage)
|
||||||
|
provisionCmd.Flags().String(DockerRegistryAccessName, provisionConfig.GetString(DockerRegistryAccessName), dockerRegistryAccessUsage)
|
||||||
|
provisionCmd.Flags().String(DockerRegistryURLName, provisionConfig.GetString(DockerRegistryURLName), dockerRegistryURLUsage)
|
||||||
|
provisionCmd.Flags().String(DockerRegistryUsernameName, provisionConfig.GetString(DockerRegistryUsernameName), dockerRegistryUsernameUsage)
|
||||||
|
provisionCmd.Flags().String(DockerRegistryPasswordName, dockerPassText, dockerRegistryPasswordUsage)
|
||||||
|
|
||||||
provisionConfig.BindPFlags(provisionCmd.Flags())
|
provisionConfig.BindPFlags(provisionCmd.Flags())
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,234 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"go/ast"
|
||||||
|
"go/importer"
|
||||||
|
"go/parser"
|
||||||
|
"go/token"
|
||||||
|
"go/types"
|
||||||
|
"path"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PackageSpecifier is a string that represents the name that will be used to refer to
|
||||||
|
// exported functions and variables from a package.
|
||||||
|
type PackageSpecifier string
|
||||||
|
|
||||||
|
// PackagePath is a string that refers to the location of Go package.
|
||||||
|
type PackagePath string
|
||||||
|
|
||||||
|
// ImportBag captures all of the imports in a Go source file, and attempts
|
||||||
|
// to ease the process of working with them.
|
||||||
|
type ImportBag struct {
|
||||||
|
bySpec map[PackageSpecifier]PackagePath
|
||||||
|
blankIdent map[PackagePath]struct{}
|
||||||
|
localIdent map[PackagePath]struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewImportBag instantiates an empty ImportBag.
|
||||||
|
func NewImportBag() *ImportBag {
|
||||||
|
return &ImportBag{
|
||||||
|
bySpec: make(map[PackageSpecifier]PackagePath),
|
||||||
|
blankIdent: make(map[PackagePath]struct{}),
|
||||||
|
localIdent: make(map[PackagePath]struct{}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewImportBagFromFile reads a Go source file, finds all imports,
|
||||||
|
// and returns them as an instantiated ImportBag.
|
||||||
|
func NewImportBagFromFile(filepath string) (*ImportBag, error) {
|
||||||
|
f, err := parser.ParseFile(token.NewFileSet(), filepath, nil, parser.ImportsOnly)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ib := NewImportBag()
|
||||||
|
|
||||||
|
for _, spec := range f.Imports {
|
||||||
|
pkgPath := PackagePath(strings.Trim(spec.Path.Value, `"`))
|
||||||
|
if spec.Name == nil {
|
||||||
|
ib.AddImport(pkgPath)
|
||||||
|
} else {
|
||||||
|
ib.AddImportWithSpecifier(pkgPath, PackageSpecifier(spec.Name.Name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ib, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImport includes a package, and returns the name that was selected to
|
||||||
|
// be the specified for working with this path. It first attempts to use the
|
||||||
|
// package name as the specifier. Should that cause a conflict, it determines
|
||||||
|
// a unique name to be used as the specifier.
|
||||||
|
//
|
||||||
|
// If the path provided has already been imported, the existing name for it
|
||||||
|
// is returned, but err is non-nil.
|
||||||
|
func (ib *ImportBag) AddImport(pkgPath PackagePath) PackageSpecifier {
|
||||||
|
spec, err := FindSpecifier(pkgPath)
|
||||||
|
if err != nil {
|
||||||
|
spec = PackageSpecifier(path.Base(string(pkgPath)))
|
||||||
|
}
|
||||||
|
specLen := len(spec)
|
||||||
|
suffix := uint(1)
|
||||||
|
for {
|
||||||
|
err = ib.AddImportWithSpecifier(pkgPath, spec)
|
||||||
|
if err == nil {
|
||||||
|
break
|
||||||
|
} else if err != ErrDuplicateImport {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
spec = PackageSpecifier(fmt.Sprintf("%s%d", spec[:specLen], suffix))
|
||||||
|
suffix++
|
||||||
|
}
|
||||||
|
|
||||||
|
return spec
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrDuplicateImport is the error that will be returned when two packages are both requested
|
||||||
|
// to be imported using the same specifier.
|
||||||
|
var ErrDuplicateImport = errors.New("specifier already in use in ImportBag")
|
||||||
|
|
||||||
|
// ErrMultipleLocalImport is the error that will be returned when the same package has been imported
|
||||||
|
// to the specifer "." more than once.
|
||||||
|
var ErrMultipleLocalImport = errors.New("package already imported into the local namespace")
|
||||||
|
|
||||||
|
// AddImportWithSpecifier will add an import with a given name. If it would lead
|
||||||
|
// to conflicting package specifiers, it returns an error.
|
||||||
|
func (ib *ImportBag) AddImportWithSpecifier(pkgPath PackagePath, specifier PackageSpecifier) error {
|
||||||
|
if specifier == "_" {
|
||||||
|
ib.blankIdent[pkgPath] = struct{}{}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if specifier == "." {
|
||||||
|
if _, ok := ib.localIdent[pkgPath]; ok {
|
||||||
|
return ErrMultipleLocalImport
|
||||||
|
}
|
||||||
|
ib.localIdent[pkgPath] = struct{}{}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if impPath, ok := ib.bySpec[specifier]; ok && pkgPath != impPath {
|
||||||
|
return ErrDuplicateImport
|
||||||
|
}
|
||||||
|
|
||||||
|
ib.bySpec[specifier] = pkgPath
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindSpecifier finds the specifier assocatied with a particular package.
|
||||||
|
//
|
||||||
|
// If the package was not imported, the empty string and false are returned.
|
||||||
|
//
|
||||||
|
// If multiple specifiers are assigned to the package, one is returned at
|
||||||
|
// random.
|
||||||
|
//
|
||||||
|
// If the same package is imported with a named specifier, and the blank
|
||||||
|
// identifier, the name is returned.
|
||||||
|
func (ib ImportBag) FindSpecifier(pkgPath PackagePath) (PackageSpecifier, bool) {
|
||||||
|
for k, v := range ib.bySpec {
|
||||||
|
if v == pkgPath {
|
||||||
|
return k, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := ib.blankIdent[pkgPath]; ok {
|
||||||
|
return "_", true
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := ib.localIdent[pkgPath]; ok {
|
||||||
|
return ".", true
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
// List returns each import statement as a slice of strings sorted alphabetically by
|
||||||
|
// their import paths.
|
||||||
|
func (ib *ImportBag) List() []string {
|
||||||
|
specs := ib.ListAsImportSpec()
|
||||||
|
retval := make([]string, len(specs))
|
||||||
|
|
||||||
|
builder := bytes.NewBuffer([]byte{})
|
||||||
|
|
||||||
|
for i, s := range specs {
|
||||||
|
if s.Name != nil {
|
||||||
|
builder.WriteString(s.Name.Name)
|
||||||
|
builder.WriteRune(' ')
|
||||||
|
}
|
||||||
|
builder.WriteString(s.Path.Value)
|
||||||
|
retval[i] = builder.String()
|
||||||
|
builder.Reset()
|
||||||
|
}
|
||||||
|
return retval
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListAsImportSpec returns the imports from the ImportBag as a slice of ImportSpecs
|
||||||
|
// sorted alphabetically by their import paths.
|
||||||
|
func (ib *ImportBag) ListAsImportSpec() []*ast.ImportSpec {
|
||||||
|
retval := make([]*ast.ImportSpec, 0, len(ib.bySpec)+len(ib.localIdent)+len(ib.blankIdent))
|
||||||
|
|
||||||
|
getLit := func(pkgPath PackagePath) *ast.BasicLit {
|
||||||
|
return &ast.BasicLit{
|
||||||
|
Kind: token.STRING,
|
||||||
|
Value: fmt.Sprintf("%q", string(pkgPath)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range ib.bySpec {
|
||||||
|
var name *ast.Ident
|
||||||
|
|
||||||
|
if path.Base(string(v)) != string(k) {
|
||||||
|
name = ast.NewIdent(string(k))
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = append(retval, &ast.ImportSpec{
|
||||||
|
Name: name,
|
||||||
|
Path: getLit(v),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
for s := range ib.localIdent {
|
||||||
|
retval = append(retval, &ast.ImportSpec{
|
||||||
|
Name: ast.NewIdent("."),
|
||||||
|
Path: getLit(s),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
for s := range ib.blankIdent {
|
||||||
|
retval = append(retval, &ast.ImportSpec{
|
||||||
|
Name: ast.NewIdent("_"),
|
||||||
|
Path: getLit(s),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(retval, func(i, j int) bool {
|
||||||
|
return strings.Compare(retval[i].Path.Value, retval[j].Path.Value) < 0
|
||||||
|
})
|
||||||
|
|
||||||
|
return retval
|
||||||
|
}
|
||||||
|
|
||||||
|
var impFinder = importer.Default()
|
||||||
|
|
||||||
|
// FindSpecifier finds the name of a package by loading it in from GOPATH
|
||||||
|
// or a vendor folder.
|
||||||
|
func FindSpecifier(pkgPath PackagePath) (PackageSpecifier, error) {
|
||||||
|
var pkg *types.Package
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if cast, ok := impFinder.(types.ImporterFrom); ok {
|
||||||
|
pkg, err = cast.ImportFrom(string(pkgPath), "", 0)
|
||||||
|
} else {
|
||||||
|
pkg, err = impFinder.Import(string(pkgPath))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return PackageSpecifier(pkg.Name()), nil
|
||||||
|
}
|
|
@ -0,0 +1,144 @@
|
||||||
|
package common_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
. "github.com/Azure/buffalo-azure/generators/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestImportBag_AddImport_Unique(t *testing.T) {
|
||||||
|
testCases := [][]PackagePath{
|
||||||
|
{
|
||||||
|
"github.com/Azure/azure-sdk-for-go/services/eventgrid/2018-01-01/eventgrid",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"github.com/Azure/buffalo-azure/generators/common",
|
||||||
|
"github.com/Azure/buffalo-azure/sdk/eventgrid",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fmt",
|
||||||
|
"github.com/Azure/buffalo-azure/generators/common",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run("", func(t *testing.T) {
|
||||||
|
|
||||||
|
seen := map[PackageSpecifier]struct{}{}
|
||||||
|
subject := NewImportBag()
|
||||||
|
|
||||||
|
for _, pkgPath := range tc {
|
||||||
|
spec := subject.AddImport(pkgPath)
|
||||||
|
if _, ok := seen[spec]; ok {
|
||||||
|
t.Logf("duplicate spec returned")
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestImportBag_List(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
inputs []PackagePath
|
||||||
|
expected []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
inputs: []PackagePath{
|
||||||
|
"github.com/Azure/buffalo-azure/generators/common",
|
||||||
|
"github.com/Azure/azure-sdk-for-go/services/eventgrid/2018-01-01/eventgrid",
|
||||||
|
},
|
||||||
|
expected: []string{
|
||||||
|
`"github.com/Azure/azure-sdk-for-go/services/eventgrid/2018-01-01/eventgrid"`,
|
||||||
|
`"github.com/Azure/buffalo-azure/generators/common"`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputs: []PackagePath{
|
||||||
|
"github.com/Azure/buffalo-azure/sdk/eventgrid",
|
||||||
|
"github.com/Azure/azure-sdk-for-go/services/eventgrid/2018-01-01/eventgrid",
|
||||||
|
},
|
||||||
|
expected: []string{
|
||||||
|
`eventgrid1 "github.com/Azure/azure-sdk-for-go/services/eventgrid/2018-01-01/eventgrid"`,
|
||||||
|
`"github.com/Azure/buffalo-azure/sdk/eventgrid"`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputs: []PackagePath{
|
||||||
|
"github.com/Azure/buffalo-azure/sdk/eventgrid",
|
||||||
|
"github.com/Azure/azure-sdk-for-go/services/eventgrid/2018-01-01/eventgrid",
|
||||||
|
"github.com/Azure/buffalo-azure/generators/eventgrid",
|
||||||
|
},
|
||||||
|
expected: []string{
|
||||||
|
`eventgrid1 "github.com/Azure/azure-sdk-for-go/services/eventgrid/2018-01-01/eventgrid"`,
|
||||||
|
`eventgrid2 "github.com/Azure/buffalo-azure/generators/eventgrid"`,
|
||||||
|
`"github.com/Azure/buffalo-azure/sdk/eventgrid"`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputs: []PackagePath{
|
||||||
|
"github.com/Azure/buffalo-azure/sdk/eventgrid",
|
||||||
|
"github.com/Azure/buffalo-azure/sdk/eventgrid",
|
||||||
|
},
|
||||||
|
expected: []string{
|
||||||
|
`"github.com/Azure/buffalo-azure/sdk/eventgrid"`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run("", func(t *testing.T) {
|
||||||
|
subject := NewImportBag()
|
||||||
|
for _, i := range tc.inputs {
|
||||||
|
subject.AddImport(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
got := subject.List()
|
||||||
|
|
||||||
|
if len(got) != len(tc.expected) {
|
||||||
|
t.Logf("got: %d imports want: %d imports", len(got), len(tc.expected))
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, val := range tc.expected {
|
||||||
|
if got[i] != val {
|
||||||
|
t.Logf("at %d\n\tgot: %s\n\twant: %s", i, got[i], val)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestImportBag_NewImportBagFromFile(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
inputFile string
|
||||||
|
expected []string
|
||||||
|
}{
|
||||||
|
{"./testdata/main.go", []string{`"fmt"`, `_ "github.com/Azure/azure-sdk-for-go/services/eventgrid/2018-01-01/eventgrid"`}},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run("", func(t *testing.T) {
|
||||||
|
subject, err := NewImportBagFromFile(tc.inputFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
got := subject.List()
|
||||||
|
|
||||||
|
for i, imp := range tc.expected {
|
||||||
|
if imp != got[i] {
|
||||||
|
t.Logf("at: %d\n\tgot: %s\n\twant: %s", i, got[i], imp)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(got) != len(tc.expected) {
|
||||||
|
t.Logf("got: %d imports want: %d imports", len(got), len(tc.expected))
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
_ "github.com/Azure/azure-sdk-for-go/services/eventgrid/2018-01-01/eventgrid"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("Hello, world!!!")
|
||||||
|
}
|
|
@ -11,6 +11,8 @@ import (
|
||||||
"github.com/gobuffalo/buffalo/meta"
|
"github.com/gobuffalo/buffalo/meta"
|
||||||
"github.com/gobuffalo/makr"
|
"github.com/gobuffalo/makr"
|
||||||
"github.com/markbates/inflect"
|
"github.com/markbates/inflect"
|
||||||
|
|
||||||
|
"github.com/Azure/buffalo-azure/generators/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate go run ./builder/builder.go -o ./static_templates.go ./templates
|
//go:generate go run ./builder/builder.go -o ./static_templates.go ./templates
|
||||||
|
@ -26,15 +28,24 @@ func (eg *Generator) Run(app meta.App, name string, types map[string]reflect.Typ
|
||||||
type TypeMapping struct {
|
type TypeMapping struct {
|
||||||
Identifier string
|
Identifier string
|
||||||
inflect.Name
|
inflect.Name
|
||||||
PackageSpecifier string
|
PkgPath string
|
||||||
|
PkgSpec common.PackageSpecifier
|
||||||
}
|
}
|
||||||
flatTypes := make([]TypeMapping, 0, len(types))
|
flatTypes := make([]TypeMapping, 0, len(types))
|
||||||
|
|
||||||
|
ib := common.NewImportBag()
|
||||||
|
ib.AddImport("encoding/json")
|
||||||
|
ib.AddImport("errors")
|
||||||
|
ib.AddImport("net/http")
|
||||||
|
ib.AddImportWithSpecifier("github.com/Azure/buffalo-azure/sdk/eventgrid", "eg")
|
||||||
|
ib.AddImport("github.com/gobuffalo/buffalo")
|
||||||
|
|
||||||
for i, n := range types {
|
for i, n := range types {
|
||||||
flatTypes = append(flatTypes, TypeMapping{
|
flatTypes = append(flatTypes, TypeMapping{
|
||||||
Identifier: i,
|
Identifier: i,
|
||||||
PackageSpecifier: path.Base(n.PkgPath()),
|
PkgPath: n.PkgPath(),
|
||||||
Name: inflect.Name(n.Name()),
|
PkgSpec: ib.AddImport(common.PackagePath(n.PkgPath())),
|
||||||
|
Name: inflect.Name(n.Name()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,6 +71,7 @@ func (eg *Generator) Run(app meta.App, name string, types map[string]reflect.Typ
|
||||||
d := make(makr.Data)
|
d := make(makr.Data)
|
||||||
d["name"] = iName
|
d["name"] = iName
|
||||||
d["types"] = flatTypes
|
d["types"] = flatTypes
|
||||||
|
d["imports"] = ib.List()
|
||||||
|
|
||||||
return g.Run(app.Root, d)
|
return g.Run(app.Root, d)
|
||||||
}
|
}
|
||||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -1,22 +1,18 @@
|
||||||
package actions
|
package actions
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
{{ range $i := .imports }} {{$i}}
|
||||||
"errors"
|
{{ end }}
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/Azure/buffalo-azure/sdk/eventgrid"
|
|
||||||
"github.com/gobuffalo/buffalo"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// My{{$.name.Camel}}Subscriber gathers responds to all Requests sent to a particular endpoint.
|
// My{{$.name.Camel}}Subscriber gathers responds to all Requests sent to a particular endpoint.
|
||||||
type {{$.name.Camel}}Subscriber struct {
|
type {{$.name.Camel}}Subscriber struct {
|
||||||
eventgrid.Subscriber
|
eg.Subscriber
|
||||||
}
|
}
|
||||||
|
|
||||||
// New{{$.name.Camel}}Subscriber instantiates {{$.name.Camel}}Subscriber for use in a `buffalo.App`.
|
// New{{$.name.Camel}}Subscriber instantiates {{$.name.Camel}}Subscriber for use in a `buffalo.App`.
|
||||||
func New{{$.name.Camel}}Subscriber(parent eventgrid.Subscriber) (created *{{$.name.Camel}}Subscriber) {
|
func New{{$.name.Camel}}Subscriber(parent eg.Subscriber) (created *{{$.name.Camel}}Subscriber) {
|
||||||
dispatcher := eventgrid.NewTypeDispatchSubscriber(parent)
|
dispatcher := eg.NewTypeDispatchSubscriber(parent)
|
||||||
|
|
||||||
created = &{{$.name.Camel}}Subscriber{
|
created = &{{$.name.Camel}}Subscriber{
|
||||||
Subscriber: dispatcher,
|
Subscriber: dispatcher,
|
||||||
|
@ -25,15 +21,15 @@ func New{{$.name.Camel}}Subscriber(parent eventgrid.Subscriber) (created *{{$.na
|
||||||
{{ range $t := .types}}
|
{{ range $t := .types}}
|
||||||
dispatcher.Bind("{{$t.Identifier}}", created.Receive{{$t.Name.Camel}})
|
dispatcher.Bind("{{$t.Identifier}}", created.Receive{{$t.Name.Camel}})
|
||||||
{{end}}
|
{{end}}
|
||||||
dispatcher.Bind(eventgrid.EventTypeWildcard, created.ReceiveDefault)
|
dispatcher.Bind(eg.EventTypeWildcard, created.ReceiveDefault)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
{{ range $t := .types }}
|
{{ range $t := .types }}
|
||||||
// Receive{{$t.Name.Camel}} will respond to an `eventgrid.Event` carrying a serialized `{{$t.Name.Camel}}` as its payload.
|
// Receive{{$t.Name.Camel}} will respond to an `eventgrid.Event` carrying a serialized `{{$t.Name.Camel}}` as its payload.
|
||||||
func (s *{{$.name.Camel}}Subscriber) Receive{{$t.Name.Camel}}(c buffalo.Context, e eventgrid.Event) error {
|
func (s *{{$.name.Camel}}Subscriber) Receive{{$t.Name.Camel}}(c buffalo.Context, e eg.Event) error {
|
||||||
var payload {{$t.PackageSpecifier}}.{{$t.Name.Camel}}
|
var payload {{$t.PkgSpec}}.{{$t.Name.Camel}}
|
||||||
if err := json.Unmarshal(e.Data, &payload); err != nil {
|
if err := json.Unmarshal(e.Data, &payload); err != nil {
|
||||||
return c.Error(http.StatusBadRequest, errors.New("unable to unmarshal request data"))
|
return c.Error(http.StatusBadRequest, errors.New("unable to unmarshal request data"))
|
||||||
}
|
}
|
||||||
|
@ -44,6 +40,6 @@ func (s *{{$.name.Camel}}Subscriber) Receive{{$t.Name.Camel}}(c buffalo.Context,
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
// ReceiveDefault will respond to an `eventgrid.Event` carrying any EventType as its payload.
|
// ReceiveDefault will respond to an `eventgrid.Event` carrying any EventType as its payload.
|
||||||
func (s *{{$.name.Camel}}Subscriber) ReceiveDefault(c buffalo.Context, e eventgrid.Event) error {
|
func (s *{{$.name.Camel}}Subscriber) ReceiveDefault(c buffalo.Context, e eg.Event) error {
|
||||||
return c.Error(http.StatusInternalServerError, errors.New("not implemented"))
|
return c.Error(http.StatusInternalServerError, errors.New("not implemented"))
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
egdp "github.com/Azure/azure-sdk-for-go/services/eventgrid/2018-01-01/eventgrid"
|
||||||
|
"github.com/Azure/buffalo-azure/sdk/eventgrid"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Printf("%#v\n", eventgrid.TypeDispatchSubscriber{})
|
||||||
|
fmt.Printf("%#v\n", egdp.StorageBlobCreatedEventData{})
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче