Skip to content

Commit

Permalink
Merge branch 'master' into cloud-suffix
Browse files Browse the repository at this point in the history
  • Loading branch information
jananivMS authored Apr 21, 2020
2 parents 20ea794 + 95c68bd commit 85c1bb1
Show file tree
Hide file tree
Showing 17 changed files with 372 additions and 91 deletions.
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,16 @@ This project maintains [releases of the Azure Service Operator](https://github.c
1. [Resource Group](/docs/resourcegroup/resourcegroup.md)
2. [EventHub](/docs/eventhub/eventhub.md)
3. [Azure SQL](/docs/azuresql/azuresql.md)
4. [Azure Keyvault](/docs/keyvault/keyvault.md)
5. [Azure Rediscache](/docs/rediscache/rediscache.md)
6. [Storage Account](/docs/storage/storageaccount.md)
7. [Blob container](/docs/storage/blobcontainer.md)
8. [Azure Database for PostgreSQL](/docs/postgresql/postgresql.md)
9. [Virtual Network](/docs/virtualnetwork/virtualnetwork.md)
10.[Application Insights](/docs/appinsights/appinsights.md)
11.[API Management](/docs/apimgmt/apimgmt.md)
12.[Cosmos DB](/docs/cosmosdb/cosmosdb.md)
4. [Azure Database for PostgreSQL](/docs/postgresql/postgresql.md)
5. [Azure Database for MySQL](/docs/mysql/mysql.md)
6. [Azure Keyvault](/docs/keyvault/keyvault.md)
7. [Azure Rediscache](/docs/rediscache/rediscache.md)
8. [Storage Account](/docs/storage/storageaccount.md)
9. [Blob container](/docs/storage/blobcontainer.md)
10. [Virtual Network](/docs/virtualnetwork/virtualnetwork.md)
11. [Application Insights](/docs/appinsights/appinsights.md)
12. [API Management](/docs/apimgmt/apimgmt.md)
13. [Cosmos DB](/docs/cosmosdb/cosmosdb.md)

For more information on deploying, troubleshooting & deleting resources, refer to [this](/docs/customresource.md) link

Expand Down
27 changes: 19 additions & 8 deletions api/v1alpha1/cosmosdb_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ type CosmosDBSpec struct {

// +kubebuilder:validation:MinLength=0

Location string `json:"location,omitempty"`
ResourceGroup string `json:"resourceGroup"`
Kind CosmosDBKind `json:"kind,omitempty"`
Properties CosmosDBProperties `json:"properties,omitempty"`
KeyVaultToStoreSecrets string `json:"keyVaultToStoreSecrets,omitempty"`
Location string `json:"location,omitempty"`
ResourceGroup string `json:"resourceGroup"`
Kind CosmosDBKind `json:"kind,omitempty"`
Properties CosmosDBProperties `json:"properties,omitempty"`
VirtualNetworkRules *[]CosmosDBVirtualNetworkRule `json:"virtualNetworkRules,omitempty"`
KeyVaultToStoreSecrets string `json:"keyVaultToStoreSecrets,omitempty"`
}

// CosmosDBKind enumerates the values for kind.
Expand All @@ -40,10 +41,12 @@ const (

// CosmosDBProperties the CosmosDBProperties of CosmosDB.
type CosmosDBProperties struct {
// CosmosDBDatabaseAccountOfferType - The offer type for the Cosmos DB database account.
// DatabaseAccountOfferType - The offer type for the Cosmos DB database account.
DatabaseAccountOfferType CosmosDBDatabaseAccountOfferType `json:"databaseAccountOfferType,omitempty"`
//Locations []CosmosDBLocation `json:"locations,omitempty"`
MongoDBVersion string `json:"mongoDBVersion,omitempty"`
// IsVirtualNetworkFilterEnabled - Flag to indicate whether to enable/disable Virtual Network ACL rules.
IsVirtualNetworkFilterEnabled bool `json:"isVirtualNetworkFilterEnabled,omitempty"`
EnableMultipleWriteLocations bool `json:"enableMultipleWriteLocations,omitempty"`
MongoDBVersion string `json:"mongoDBVersion,omitempty"`
}

// +kubebuilder:validation:Enum=Standard
Expand Down Expand Up @@ -84,6 +87,14 @@ type CosmosDBList struct {
Items []CosmosDB `json:"items"`
}

//CosmosDBVirtualNetworkRule virtual Network ACL Rule object
type CosmosDBVirtualNetworkRule struct {
// ID - Resource ID of a subnet, for example: /subscriptions/{subscriptionId}/resourceGroups/{groupName}/providers/Microsoft.Network/virtualNetworks/{virtualNetworkName}/subnets/{subnetName}.
SubnetID *string `json:"subnetID,omitempty"`
// IgnoreMissingVNetServiceEndpoint - Create firewall rule before the virtual network has vnet service endpoint enabled.
IgnoreMissingVNetServiceEndpoint *bool `json:"ignoreMissingVNetServiceEndpoint,omitempty"`
}

func init() {
SchemeBuilder.Register(&CosmosDB{}, &CosmosDBList{})
}
Expand Down
30 changes: 27 additions & 3 deletions api/v1alpha1/mysqlserver_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ type MySQLServerSpec struct {
Sku AzureDBsSQLSku `json:"sku,omitempty"`
ServerVersion ServerVersion `json:"serverVersion,omitempty"`
SSLEnforcement SslEnforcementEnum `json:"sslEnforcement,omitempty"`
CreateMode string `json:"createMode,omitempty"`
ReplicaProperties ReplicaProperties `json:"replicaProperties,omitempty"`
KeyVaultToStoreSecrets string `json:"keyVaultToStoreSecrets,omitempty"`
}

Expand All @@ -41,6 +43,10 @@ type MySQLServerList struct {
Items []MySQLServer `json:"items"`
}

type ReplicaProperties struct {
SourceServerId string `json:"sourceServerId,omitempty"`
}

func init() {
SchemeBuilder.Register(&MySQLServer{}, &MySQLServerList{})
}
Expand All @@ -55,14 +61,32 @@ func NewDefaultMySQLServer(name, resourceGroup, location string) *MySQLServer {
Location: location,
ResourceGroup: resourceGroup,
Sku: AzureDBsSQLSku{
Name: "B_Gen5_2",
Tier: SkuTier("Basic"),
Name: "GP_Gen5_4",
Tier: SkuTier("GeneralPurpose"),
Family: "Gen5",
Size: "51200",
Capacity: 2,
Capacity: 4,
},
ServerVersion: ServerVersion("8.0"),
SSLEnforcement: SslEnforcementEnumEnabled,
CreateMode: "Default",
},
}
}

func NewReplicaMySQLServer(name, resourceGroup, location string, sourceserverid string) *MySQLServer {
return &MySQLServer{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: "default",
},
Spec: MySQLServerSpec{
Location: location,
ResourceGroup: resourceGroup,
CreateMode: "Replica",
ReplicaProperties: ReplicaProperties{
SourceServerId: sourceserverid,
},
},
}
}
11 changes: 9 additions & 2 deletions config/samples/azure_v1alpha1_cosmosdb.yaml
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
apiVersion: azure.microsoft.com/v1alpha1
kind: CosmosDB
metadata:
name: cosmosdb-sample1908xyzkj
name: cosmosdb-sample-1
spec:
kind: GlobalDocumentDB
location: westus
resourceGroup: resourcegroup-azure-operators
properties:
databaseAccountOfferType: Standard
enableMultipleWriteLocations: false
# optionally set the mongoDBVersion to "3.2" or "3.6", if omitted the default is "3.2"
# NOTE: kind must be set to MongoDB for this to take effect
#mongoDBVersion: "3.6"

# Use the field below to optionally specify a different keyvault
#optional for network rule set
# isVirtualNetworkFilterEnabled: true
# virtualNetworkRules:
# - subnetId: /subscriptions/{subscription_id}/resourceGroups/{resourcegroup}/providers/Microsoft.Network/virtualNetworks/{vnet_name}/subnets/{subnet_name}
# ignoreMissingServiceEndpoint: false

# Use the field below to optionally specify a different keyvault
# to store the connectiong string secrets in
#keyVaultToStoreSecrets: asoSecretKeyVault
12 changes: 8 additions & 4 deletions config/samples/azure_v1alpha1_mysqlserver.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@ spec:
resourceGroup: resourcegroup-azure-operators
serverVersion: "8.0"
sslEnforcement: Enabled
minimalTLSVersion: TLS10 # Possible values include: 'TLS10', 'TLS11', 'TLS12', 'Disabled'
infrastructureEncryption: Enabled # Possible values include: Enabled, Disabled
createMode: Default # Possible values include: Default, Replica, PointInTimeRestore (not implemented), GeoRestore (not implemented)
sku:
name: B_Gen5_2
tier: Basic
family: Gen5
name: GP_Gen5_4 # tier + family + cores eg. - B_Gen4_1, GP_Gen5_4
tier: GeneralPurpose # possible values - 'Basic', 'GeneralPurpose', 'MemoryOptimized'
family: Gen5
size: "51200"
capacity: 2
capacity: 4

12 changes: 12 additions & 0 deletions config/samples/azure_v1alpha1_mysqlserver_replica.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: azure.microsoft.com/v1alpha1
kind: MySQLServer
metadata:
name: mysqlserver-replica
spec:
location: eastus2
resourceGroup: resourcegroup-azure-operators
createMode: Replica # Possible values include: Default, Replica, PointInTimeRestore (not implemented), GeoRestore (not implemented)
replicaProperties:
# sourceServer tier should be "GeneralPurpose" or higher for replica support
sourceServerId: /subscriptions/{SUBID}/resourceGroups/resourcegroup-azure-operators/providers/Microsoft.DBforMySQL/servers/mysqlserver-sample

7 changes: 7 additions & 0 deletions controllers/mysql_combined_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,18 @@ func TestMySQLHappyPath(t *testing.T) {
rgLocation := "eastus2"
rgName := tc.resourceGroupName
mySQLServerName := GenerateTestResourceNameWithRandom("mysql-srv", 10)
mySQLReplicaName := GenerateTestResourceNameWithRandom("mysql-rep", 10)

// Create the mySQLServer object and expect the Reconcile to be created
mySQLServerInstance := azurev1alpha1.NewDefaultMySQLServer(mySQLServerName, rgName, rgLocation)

RequireInstance(ctx, t, tc, mySQLServerInstance)

// Create a mySQL replica
mySQLReplicaInstance := azurev1alpha1.NewReplicaMySQLServer(mySQLReplicaName, rgName, rgLocation, mySQLServerInstance.Status.ResourceId)

EnsureInstance(ctx, t, tc, mySQLReplicaInstance)

mySQLDBName := GenerateTestResourceNameWithRandom("mysql-db", 10)

// Create the mySQLDB object and expect the Reconcile to be created
Expand Down Expand Up @@ -65,4 +71,5 @@ func TestMySQLHappyPath(t *testing.T) {
EnsureDelete(ctx, t, tc, ruleInstance)
EnsureDelete(ctx, t, tc, mySQLDBInstance)
EnsureDelete(ctx, t, tc, mySQLServerInstance)
EnsureDelete(ctx, t, tc, mySQLReplicaInstance)
}
60 changes: 60 additions & 0 deletions docs/mysql/mysql.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# MySQL Operator

## Resources Supported

The MySQL operator suite consists of the following operators.

1. MySQL server - Deploys an `Azure Database for MySQL server` given the Location, Resource group and other properties. This operator also helps creating read replicas for MySQL server.
2. MySQL database - Deploys a database under the given `Azure Database for MySQL server`
3. MySQL firewall rule - Deploys a firewall rule to allow access to the `Azure Database for MySQL server` from the specified IP range

### MySQL server

Here is a [sample YAML](/config/samples/azure_v1alpha1_mysqlserver.yaml) for the MySQL server.

The value for kind, `MySQLServer` is the Custom Resource Definition (CRD) name.
`mysqlserver-sample` is the name of the MySQL server resource that will be created.

The values under `spec` provide the values for the location where you want to create the server at and the Resource group in which you want to create it under. It also contains other values that are required to create the server like the `serverVersion`, `sslEnforcement` and the `sku` information.

Along with creating the MySQL server, this operator also generates the admin username and password for the MySQL server and stores it in a kube secret or keyvault (based on what is specified) with the same name as the MySQL server.

This secret contains the following fields.

- `fullyqualifiedservername` : Fully qualified name of the MySQL server such as mysqlserver.mysql.database.azure.com
- `mysqlservername` : MySQL server name
- `username` : Server admin
- `password` : Password for the server admin
- `fullyqualifiedusername` : Fully qualified user name that is required by some apps such as <username>@<mysqlserver>

For more information on where and how secrets are stored, look [here](/docs/secrets.md)

#### Read Replicas in Azure Database for MySQL

The MySQL server operator can also be used to create Read Replicas given the `sourceserverid` and the `location`.

The replica inherits all other properties including the admin username and password from the source server.

The operator reads the admin username and password for the source server from its secret (if available) and creates a secret with the same fields as described above for the replica.

For more information on read replicas, refer [here](https://docs.microsoft.com/en-us/azure/mysql/concepts-read-replicas)

### MySQL Database

Here is a [sample YAML](/config/samples/azure_v1alpha1_mysqldatabase.yaml) for MySQL database

Update the `resourcegroup` to where you want to provision the MySQL database. `server` is the name of the MySQL server where you want to create the database in.

### MySQL firewall rule

The MySQL firewall rule operator allows you to add a firewall rule to the MySQL server.

Here is a [sample YAML](/config/samples/azure_v1alpha1_mysqlfirewallrule.yaml) for MySQL firewall rule

The `server` indicates the MySQL server on which you want to configure the new MySQL firewall rule on and `resourceGroup` is the resource group of the MySQL server. The `startIpAddress` and `endIpAddress` indicate the IP range of sources to allow access to the server.

*Note*: When the `startIpAddress` and `endIpAddress` are 0.0.0.0, it denotes a special case that adds a firewall rule to allow all Azure services to access the server.

## Deploy, view and delete resources

You can follow the steps [here](/docs/customresource.md) to deploy, view and delete resources.
1 change: 1 addition & 0 deletions pkg/errhelp/errhelp.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func StripErrorIDs(err error) string {
patterns := []string{
"RequestID=",
"CorrelationId:\\s",
"Tracking ID: ",
}
reg := regexp.MustCompile(fmt.Sprintf(`(%s)\S+`, strings.Join(patterns, "|")))
return reg.ReplaceAllString(err.Error(), "")
Expand Down
8 changes: 4 additions & 4 deletions pkg/errhelp/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ const (
RequestDisallowedByPolicy = "RequestDisallowedByPolicy"
ServiceBusy = "ServiceBusy"
NameNotAvailable = "NameNotAvailable"

NetworkAclsValidationFailure = "NetworkAclsValidationFailure"

PublicIPIdleTimeoutIsOutOfRange = "PublicIPIdleTimeoutIsOutOfRange"
PublicIPIdleTimeoutIsOutOfRange = "PublicIPIdleTimeoutIsOutOfRange"
InvalidRequestContent = "InvalidRequestContent"
InternalServerError = "InternalServerError"
NetworkAclsValidationFailure = "NetworkAclsValidationFailure"
)

func NewAzureError(err error) error {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,6 @@ func (s *AzureSqlUserManager) Ensure(ctx context.Context, obj runtime.Object, op

err = s.GrantUserRoles(ctx, user, instance.Spec.Roles, db)
if err != nil {
fmt.Println(err)
instance.Status.Message = "GrantUserRoles failed"
return false, fmt.Errorf("GrantUserRoles failed")
}
Expand Down
27 changes: 21 additions & 6 deletions pkg/resourcemanager/cosmosdbs/cosmosdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,21 @@ func (*AzureCosmosDBManager) CreateOrUpdateCosmosDB(
cosmosDBName string,
location string,
kind v1alpha1.CosmosDBKind,
dbType v1alpha1.CosmosDBDatabaseAccountOfferType,
dbVersion string,
networkRule *[]v1alpha1.CosmosDBVirtualNetworkRule,
properties v1alpha1.CosmosDBProperties,
tags map[string]*string) (*documentdb.DatabaseAccount, error) {
cosmosDBClient, err := getCosmosDBClient()
if err != nil {
return nil, err
}

dbKind := documentdb.DatabaseAccountKind(kind)
sDBType := string(dbType)
sDBType := string(properties.DatabaseAccountOfferType)
bWriteLocal := bool(properties.EnableMultipleWriteLocations)
vnetEnabled := bool(properties.IsVirtualNetworkFilterEnabled)

var capabilities []documentdb.Capability
if dbKind == documentdb.MongoDB && dbVersion == "3.6" {
if dbKind == documentdb.MongoDB && properties.MongoDBVersion == "3.6" {
capabilities = []documentdb.Capability{
{Name: to.StringPtr("EnableMongo")},
}
Expand Down Expand Up @@ -84,6 +86,18 @@ func (*AzureCosmosDBManager) CreateOrUpdateCosmosDB(
locationsArray := []documentdb.Location{
locationObj,
}

vNetRulesSet := []documentdb.VirtualNetworkRule{}
if networkRule != nil {
for _, i := range *networkRule {
subnetID := i.SubnetID
ignoreEndpoint := i.IgnoreMissingVNetServiceEndpoint
vNetRulesSet = append(vNetRulesSet, documentdb.VirtualNetworkRule{
ID: subnetID,
IgnoreMissingVNetServiceEndpoint: ignoreEndpoint,
})
}
}
createUpdateParams := documentdb.DatabaseAccountCreateUpdateParameters{
Location: to.StringPtr(location),
Tags: tags,
Expand All @@ -93,8 +107,9 @@ func (*AzureCosmosDBManager) CreateOrUpdateCosmosDB(
ID: &cosmosDBName,
DatabaseAccountCreateUpdateProperties: &documentdb.DatabaseAccountCreateUpdateProperties{
DatabaseAccountOfferType: &sDBType,
EnableMultipleWriteLocations: to.BoolPtr(false),
IsVirtualNetworkFilterEnabled: to.BoolPtr(false),
IsVirtualNetworkFilterEnabled: &vnetEnabled,
VirtualNetworkRules: &vNetRulesSet,
EnableMultipleWriteLocations: &bWriteLocal,
Locations: &locationsArray,
Capabilities: &capabilities,
},
Expand Down
2 changes: 1 addition & 1 deletion pkg/resourcemanager/cosmosdbs/cosmosdb_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func NewAzureCosmosDBManager(secretClient secrets.SecretClient) *AzureCosmosDBMa
// CosmosDBManager client functions
type CosmosDBManager interface {
// CreateOrUpdateCosmosDB creates a new cosmos database account
CreateOrUpdateCosmosDB(ctx context.Context, groupName string, cosmosDBName string, location string, kind v1alpha1.CosmosDBKind, dbType v1alpha1.CosmosDBDatabaseAccountOfferType, dbVersion string, tags map[string]*string) (*documentdb.DatabaseAccount, error)
CreateOrUpdateCosmosDB(ctx context.Context, groupName string, cosmosDBName string, location string, kind v1alpha1.CosmosDBKind, networkRule *[]v1alpha1.CosmosDBVirtualNetworkRule, properties v1alpha1.CosmosDBProperties, tags map[string]*string) (*documentdb.DatabaseAccount, error)

// GetCosmosDB gets a cosmos database account
GetCosmosDB(ctx context.Context, groupName string, cosmosDBName string) (*documentdb.DatabaseAccount, error)
Expand Down
12 changes: 9 additions & 3 deletions pkg/resourcemanager/cosmosdbs/cosmosdb_reconcile.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,16 @@ func (m *AzureCosmosDBManager) Ensure(ctx context.Context, obj runtime.Object, o
groupName := instance.Spec.ResourceGroup
location := instance.Spec.Location
kind := instance.Spec.Kind
dbType := instance.Spec.Properties.DatabaseAccountOfferType
dbVersion := instance.Spec.Properties.MongoDBVersion
networkRule := instance.Spec.VirtualNetworkRules

db, err = m.CreateOrUpdateCosmosDB(ctx, groupName, accountName, location, kind, dbType, dbVersion, tags)
cosmosDBProperties := v1alpha1.CosmosDBProperties{
DatabaseAccountOfferType: instance.Spec.Properties.DatabaseAccountOfferType,
EnableMultipleWriteLocations: instance.Spec.Properties.EnableMultipleWriteLocations,
MongoDBVersion: instance.Spec.Properties.MongoDBVersion,
IsVirtualNetworkFilterEnabled: instance.Spec.Properties.IsVirtualNetworkFilterEnabled,
}

db, err = m.CreateOrUpdateCosmosDB(ctx, groupName, accountName, location, kind, networkRule, cosmosDBProperties, tags)
if err != nil {
azerr := errhelp.NewAzureErrorAzureError(err)
instance.Status.Message = err.Error()
Expand Down
Loading

0 comments on commit 85c1bb1

Please sign in to comment.