Skip to content
This repository was archived by the owner on Aug 15, 2022. It is now read-only.
4 changes: 2 additions & 2 deletions docs/docs/choose-provider/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Every EC2 instance is built using an image. This image specifies the operating s
AWS VPC is a Virtual Network! It allows you to create an complete logical network infrastructure for your VMs. This opens up a world of possibilities for using multiple VMs together. If you don't require any special networking, Koding handles this automatically. However, if you want to create a custom network environment, you can configure it simply within your Stack.

- [**AWS Documentation**][16]
- [**Using IAM in your Stack**][17]
- [**Using VPC in your Stack**][17]
- [**Stack Reference**][18]

***
Expand Down Expand Up @@ -162,7 +162,7 @@ Monitor your instances for performance and uptime without resorting to third-par

## Microsoft Azure <a name="azure"></a>

# Coming Soon...
Coming Soon...

[1]: {{ site.url }}/docs/creating-an-aws-stack
[2]: {{ site.url }}/docs/terraform/providers/aws/
Expand Down
53 changes: 46 additions & 7 deletions go/src/koding/kites/kloud/provider/azure/azure.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func newMetadata(m *stack.Machine) interface{} {
}

if cred, ok := m.Credential.Credential.(*Cred); ok {
meta.Location = cred.Location
meta.Location = string(cred.Location)
}

return meta
Expand All @@ -81,14 +81,53 @@ type Subscription struct {
ID string `xml:"Id,attr"`
}

type (
StorageType string
LocationType string
)

var (
_ stack.Enumer = StorageType("")
_ stack.Enumer = LocationType("")
)

var (
Storages = []stack.Enum{
{Title: "Locally redundant storage (LRS)", Value: "Standard_LRS"},
{Title: "Zone-redundant storage (ZRS)", Value: "Standard_ZRS"},
{Title: "Geo-redundant storage (GRS)", Value: "Standard_GRS"},
{Title: "Read-access geo-redundant storage (RA-GRS)", Value: "Standard_RAGRS"},
{Title: "Premium Locally redundant storage (P_LRS)", Value: "Premium_LRS"},
}

Locations = []stack.Enum{
{Title: "East US", Value: "East US"},
{Title: "East US 2", Value: "East US 2"},
{Title: "West US", Value: "West US"},
{Title: "Central US", Value: "Central US"},
{Title: "South Central US", Value: "South Central US"},
{Title: "North Europe", Value: "North Europe"},
{Title: "West Europe", Value: "West Europe"},
{Title: "East Asia", Value: "East Asia"},
{Title: "Southeast Asia", Value: "Southeast Asia"},
{Title: "Japan East", Value: "Japan East"},
{Title: "Japan West", Value: "Japan West"},
{Title: "North Central US", Value: "North Central US"},
{Title: "Brazil South", Value: "Brazil South"},
}
)

func (StorageType) Enums() []stack.Enum { return Storages }
func (LocationType) Enums() []stack.Enum { return Locations }

// Cred represents jCredentialDatas.meta for "azure" provider.
type Cred struct {
PublishSettings string `json:"publish_settings" bson:"publish_settings" hcl:"publish_settings"` // required
SubscriptionID string `json:"subscription_id,omitempty" bson:"subscription_id,omitempty" hcl:"subscription_id"` // required if PublishSettings contains multiple subscriptions
Location string `json:"location,omitempty" bson:"location,omitempty" hcl:"location"` // by default "East US 2"
Storage string `json:"storage,omitempty" bson:"storage,omitempty" hcl:"storage"` // by default "Standard_LRS"
SSHKeyThumbprint string `json:"ssh_key_thumbprint,omitempty" bson:"ssh_key_thumbprint" hcl:"ssh_key_thumbprint"`
Password string `json:"password" bson:"password" hcl:"password"`
PublishSettings string `json:"publish_settings" bson:"publish_settings" hcl:"publish_settings"` // required
SubscriptionID string `json:"subscription_id,omitempty" bson:"subscription_id,omitempty" hcl:"subscription_id"` // required if PublishSettings contains multiple subscriptions
Location LocationType `json:"location,omitempty" bson:"location,omitempty" hcl:"location"` // by default "East US 2"
Storage StorageType `json:"storage,omitempty" bson:"storage,omitempty" hcl:"storage"` // by default "Standard_LRS"
SSHKeyThumbprint string `json:"ssh_key_thumbprint,omitempty" bson:"ssh_key_thumbprint" hcl:"ssh_key_thumbprint"`
Password string `json:"password" bson:"password" hcl:"password"`
}

var _ stack.Validator = (*Cred)(nil)
Expand Down
2 changes: 1 addition & 1 deletion go/src/koding/kites/kloud/provider/azure/stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func (s *Stack) BootstrapTemplates(c *stack.Credential) ([]*stack.Template, erro
cfg := &BootstrapConfig{
TeamSlug: s.BootstrapArg().GroupName,
HostedServiceName: "koding-hs-" + c.Identifier,
StorageType: cred.Storage,
StorageType: string(cred.Storage),
AddressSpace: boot.addressSpace(),
StorageServiceName: substringN(strings.ToLower("kodings"+c.Identifier), 24),
SecurityGroupName: "koding-sg-" + c.Identifier,
Expand Down
65 changes: 35 additions & 30 deletions go/src/koding/kites/kloud/provider/do/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,35 @@ type Bootstrap struct {
KeyFingerprint string `json:"key_fingerprint" bson:"key_fingerprint" hcl:"key_fingerprint"`
}

// Region represents a DigitalOcean region
type Region string
// RegionType represents a DigitalOcean region
type RegionType string

var _ stack.Enumer = RegionType("")

var Regions = []stack.Enum{
{Title: "Amsterdam 1", Value: "ams1"},
{Title: "Amsterdam 2", Value: "ams2"},
{Title: "Amsterdam 3", Value: "ams3"},
{Title: "Bangalore 1", Value: "blr1"},
{Title: "France 1", Value: "fra1"},
{Title: "London 1", Value: "lon1"},
{Title: "New York 1", Value: "nyc1"},
{Title: "New York 2", Value: "nyc2"},
{Title: "New York 3", Value: "nyc3"},
{Title: "San Francisco 1", Value: "sfo1"},
{Title: "San Francisco 2", Value: "sfo2"},
{Title: "Singapore 1", Value: "sgp1"},
{Title: "Toronto 1", Value: "tor1"},
}

func (RegionType) Enums() []stack.Enum { return Regions }

// Metadata represent the data that is stored on Koding's DB storage
type Metadata struct {
DropletID int `json:"droplet_id" bson:"droplet_id" hcl:"droplet_id"`
Region Region `json:"region" bson:"region" hcl:"region"`
Size string `json:"size" bson:"size" hcl:"size"`
Image string `json:"image" bson:"image" hcl:"image"`
DropletID int `json:"droplet_id" bson:"droplet_id" hcl:"droplet_id"`
Region RegionType `json:"region" bson:"region" hcl:"region"`
Size string `json:"size" bson:"size" hcl:"size"`
Image string `json:"image" bson:"image" hcl:"image"`
}

func newSchema() *provider.Schema {
Expand All @@ -83,7 +103,7 @@ func newMetadata(m *stack.Machine) interface{} {
meta := &Metadata{
Size: m.Attributes["size"],
Image: m.Attributes["image"],
Region: Region(m.Attributes["region"]),
Region: RegionType(m.Attributes["region"]),
}

if id, err := strconv.Atoi(m.Attributes["id"]); err == nil {
Expand Down Expand Up @@ -115,9 +135,8 @@ func (m *Metadata) Valid() error {
return errors.New("region cannot be empty")
}

if !m.Region.isValid() {
return fmt.Errorf("region %q is not valid. Valid regions can be one of the following: %v",
m.Region, validRegions)
if err := m.Region.Valid(); err != nil {
return err
}

if m.Image == "" {
Expand Down Expand Up @@ -148,26 +167,12 @@ func (b *Bootstrap) Valid() error {
return nil
}

// isValid checks whether the given region is valid or not
func (r Region) isValid() bool {
for _, validRegion := range validRegions {
if validRegion == string(r) {
return true
// Valid implements the stack.Validator interface.
func (r RegionType) Valid() error {
for _, region := range Regions {
if r == RegionType(region.Value.(string)) {
return nil
}
}
return false
}

// Enum implements the stack.Enumer interface
func (Region) Enum() []interface{} {
// TODO: check whether the valid regions have metadata listed as their
// features and only show those regions, because User Data is currently
// only available in regions with metadata listed in their features.
regions := make([]interface{}, len(validRegions))

for i, region := range validRegions {
regions[i] = region
}

return regions
return fmt.Errorf("region %q does not exist", r)
}
53 changes: 25 additions & 28 deletions go/src/koding/kites/kloud/provider/google/google.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,45 +31,42 @@ func init() {
provider.Register(p)
}

// Region represents google's geographical region code.
type Region string

var regions = []Region{
"asia-east1",
"europe-west1",
"us-central1",
"us-east1",
"us-west1",
// RegionType represents google's geographical region code.
type RegionType string

var _ stack.Enumer = RegionType("")

var Regions = []stack.Enum{
{Title: "Asia West 1", Value: "asia-east1"},
{Title: "Europte West 1", Value: "europe-west1"},
{Title: "US Central 1", Value: "us-central1"},
{Title: "US East 1", Value: "us-east1"},
{Title: "US West 1", Value: "us-west1"},
}

// Enum returns all available regions for "google" provider.
func (Region) Enum() (rs []interface{}) {
for _, region := range regions {
rs = append(rs, region)
}
return rs
}
func (RegionType) Enums() []stack.Enum { return Regions }

// Valid checks if stored region code is available in GCP.
func (r Region) Valid() error {
func (r RegionType) Valid() error {
if r == "" {
return fmt.Errorf("region name is not set")
}

for _, region := range regions {
if r == region {
for _, region := range Regions {
if r == RegionType(region.Value.(string)) {
return nil
}
}

return fmt.Errorf("unknown region name: %v", r)
return fmt.Errorf("region %q does not exist", r)
}

// Cred represents jCredentialDatas.meta for "google" provider.
type Cred struct {
Credentials string `json:"credentials" bson:"credentials" hcl:"credentials" kloud:",secret"`
Project string `json:"project" bson:"project" hcl:"project"`
Region Region `json:"region" bson:"region" hcl:"region"`
Credentials string `json:"credentials" bson:"credentials" hcl:"credentials" kloud:",secret"`
Project string `json:"project" bson:"project" hcl:"project"`
Region RegionType `json:"region" bson:"region" hcl:"region"`
}

var _ stack.Validator = (*Cred)(nil)
Expand Down Expand Up @@ -139,12 +136,12 @@ func (b *Bootstrap) Valid() error {
}

type Meta struct {
Name string `json:"name" bson:"name" hcl:"name"`
Region Region `json:"region" bson:"region" hcl:"region"`
Zone string `json:"zone" bson:"zone" hcl:"zone"`
Image string `json:"image" bson:"image" hcl:"image"`
StorageSize int `json:"storage_size" bson:"storage_size" hcl:"storage_size"`
MachineType string `json:"machine_type" bson:"machine_type" hcl:"machine_type"`
Name string `json:"name" bson:"name" hcl:"name"`
Region RegionType `json:"region" bson:"region" hcl:"region"`
Zone string `json:"zone" bson:"zone" hcl:"zone"`
Image string `json:"image" bson:"image" hcl:"image"`
StorageSize int `json:"storage_size" bson:"storage_size" hcl:"storage_size"`
MachineType string `json:"machine_type" bson:"machine_type" hcl:"machine_type"`
}

var _ stack.Validator = (*Meta)(nil)
Expand Down
39 changes: 36 additions & 3 deletions go/src/koding/kites/kloud/stack/credential.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,37 @@ type Enum struct {
Value interface{} `json:"value"`
}

// Enums is an enum list.
type Enums []Enum

// Contains gives true if enums contains the given value.
func (e Enums) Contains(value interface{}) bool {
for _, e := range e {
if e.Value == value {
return true
}
}
return false
}

// Values gives all enums' values.
func (e Enums) Values() []interface{} {
v := make([]interface{}, len(e))
for i := range e {
v[i] = e[i].Value
}
return v
}

// Titles gives all enums' titles.
func (e Enums) Titles() []string {
t := make([]string, len(e))
for i := range e {
t[i] = e[i].Title
}
return t
}

// Value represents a description of a single
// field within Bootstrap or Credential struct.
type Value struct {
Expand All @@ -56,7 +87,7 @@ type Value struct {
Label string `json:"label"`
Secret bool `json:"secret"`
ReadOnly bool `json:"readOnly"`
Values []Enum `json:"values,omitempty"`
Values Enums `json:"values,omitempty"`
}

// CredentialListRequest represents a request
Expand Down Expand Up @@ -204,8 +235,10 @@ type CredentialAddResponse struct {
func (k *Kloud) CredentialDescribe(r *kite.Request) (interface{}, error) {
var req CredentialDescribeRequest

if err := r.Args.One().Unmarshal(&req); err != nil {
return nil, err
if r.Args != nil {
if err := r.Args.One().Unmarshal(&req); err != nil {
return nil, err
}
}

// TODO: add support for reading the provider names by parsing
Expand Down
Loading