func ToStorageAccountCreate(s *StorageAccountSpec) storage.AccountCreateParameters {
	if s == nil {
		return storage.AccountCreateParameters{}
	}
	acp := storage.AccountCreateParameters{
		Kind:     s.Kind,
		Location: toStringPtr(s.Location),
		Sku:      toStorageSku(s.Sku),
		Tags:     *to.StringMapPtr(s.Tags),
	}
	if v := s.StorageAccountSpecProperties; v != nil {
		acp.AccountPropertiesCreateParameters = toStorageAccountCreateProperties(v)
	}
	if v := s.Identity; v != nil {
		acp.Identity = toStorageIdentity(v)
	}
	return acp
}
ToStorageAccountCreate from StorageAccountSpec
package v1alpha3
import (
	"encoding/json"
	"github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2017-06-01/storage"
	"github.com/Azure/go-autorest/autorest/date"
	"github.com/Azure/go-autorest/autorest/to"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type CustomDomain struct {
	Name string `json:"name,omitempty"`
	UseSubDomainName bool `json:"useSubDomainName,omitempty"`
}
func newCustomDomain(d *storage.CustomDomain) *CustomDomain {
	if d == nil {
		return nil
	}
	return &CustomDomain{
		Name:             to.String(d.Name),
		UseSubDomainName: to.Bool(d.UseSubDomainName),
	}
}
func toStorageCustomDomain(c *CustomDomain) *storage.CustomDomain {
	if c == nil {
		return nil
	}
	return &storage.CustomDomain{
		Name:             toStringPtr(c.Name),
		UseSubDomainName: to.BoolPtr(c.UseSubDomainName),
	}
}
type EnabledEncryptionServices struct {
	Blob bool `json:"blob,omitempty"`
	File bool `json:"file,omitempty"`
}
func newEnabledEncryptionServices(s *storage.EncryptionServices) *EnabledEncryptionServices {
	if s == nil {
		return nil
	}
	b := func(s *storage.EncryptionService) bool {
		return s != nil && s.Enabled != nil && *s.Enabled
	}
	return &EnabledEncryptionServices{
		Blob: b(s.Blob),
		File: b(s.File),
	}
}
func toStorageEncryptedServices(s *EnabledEncryptionServices) *storage.EncryptionServices {
	return &storage.EncryptionServices{
		Blob: &storage.EncryptionService{Enabled: to.BoolPtr(s.Blob)},
		File: &storage.EncryptionService{Enabled: to.BoolPtr(s.File)},
	}
}
type Encryption struct {
	Services *EnabledEncryptionServices `json:"services,omitempty"`
	KeySource storage.KeySource `json:"keySource,omitempty"`
	KeyVaultProperties *KeyVaultProperties `json:"keyvaultproperties,omitempty"`
}
func newEncryption(s *storage.Encryption) *Encryption {
	if s == nil {
		return nil
	}
	return &Encryption{
		Services:           newEnabledEncryptionServices(s.Services),
		KeySource:          s.KeySource,
		KeyVaultProperties: newKeyVaultProperties(s.KeyVaultProperties),
	}
}
func toStorageEncryption(e *Encryption) *storage.Encryption {
	if e == nil {
		return nil
	}
	return &storage.Encryption{
		Services:           toStorageEncryptedServices(e.Services),
		KeySource:          e.KeySource,
		KeyVaultProperties: toStorageKeyVaultProperties(e.KeyVaultProperties),
	}
}
type Endpoints struct {
	Blob string `json:"blob,omitempty"`
	Queue string `json:"queue,omitempty"`
	Table string `json:"table,omitempty"`
	File string `json:"file,omitempty"`
}
func newEndpoints(ep *storage.Endpoints) *Endpoints {
	if ep == nil {
		return nil
	}
	return &Endpoints{
		Blob:  to.String(ep.Blob),
		Queue: to.String(ep.Queue),
		Table: to.String(ep.Table),
		File:  to.String(ep.File),
	}
}
type Identity struct {
	PrincipalID string `json:"principalId,omitempty"`
	TenantID string `json:"tenantId,omitempty"`
	Type string `json:"type,omitempty"`
}
func newIdentity(s *storage.Identity) *Identity {
	if s == nil {
		return nil
	}
	return &Identity{
		PrincipalID: to.String(s.PrincipalID),
		TenantID:    to.String(s.TenantID),
		Type:        to.String(s.Type),
	}
}
func toStorageIdentity(i *Identity) *storage.Identity {
	if i == nil {
		return nil
	}
	return &storage.Identity{
		PrincipalID: toStringPtr(i.PrincipalID),
		TenantID:    toStringPtr(i.TenantID),
		Type:        toStringPtr(i.Type),
	}
}
type IPRule struct {
	IPAddressOrRange string `json:"value,omitempty"`
	Action storage.Action `json:"action,omitempty"`
}
func newIPRule(r storage.IPRule) IPRule {
	return IPRule{
		IPAddressOrRange: to.String(r.IPAddressOrRange),
		Action:           r.Action,
	}
}
func toStorageIPRule(r IPRule) storage.IPRule {
	return storage.IPRule{
		IPAddressOrRange: toStringPtr(r.IPAddressOrRange),
		Action:           r.Action,
	}
}
type KeyVaultProperties struct {
	KeyName string `json:"keyname,omitempty"`
	KeyVersion string `json:"keyversion,omitempty"`
	KeyVaultURI string `json:"keyvaulturi,omitempty"`
}
func newKeyVaultProperties(p *storage.KeyVaultProperties) *KeyVaultProperties {
	if p == nil {
		return nil
	}
	return &KeyVaultProperties{
		KeyName:     to.String(p.KeyName),
		KeyVersion:  to.String(p.KeyVersion),
		KeyVaultURI: to.String(p.KeyVaultURI),
	}
}
func toStorageKeyVaultProperties(p *KeyVaultProperties) *storage.KeyVaultProperties {
	if p == nil {
		return nil
	}
	return &storage.KeyVaultProperties{
		KeyName:     toStringPtr(p.KeyName),
		KeyVersion:  toStringPtr(p.KeyVersion),
		KeyVaultURI: toStringPtr(p.KeyVaultURI),
	}
}
type NetworkRuleSet struct {
	Bypass storage.Bypass `json:"bypass,omitempty"`
	VirtualNetworkRules []VirtualNetworkRule `json:"virtualNetworkRules,omitempty"`
	IPRules []IPRule `json:"ipRules,omitempty"`
	DefaultAction storage.DefaultAction `json:"defaultAction,omitempty"`
}
func newNetworkRuleSet(s *storage.NetworkRuleSet) *NetworkRuleSet {
	if s == nil {
		return nil
	}
	var networkRules []VirtualNetworkRule
	if s.VirtualNetworkRules != nil {
		networkRules = make([]VirtualNetworkRule, len(*s.VirtualNetworkRules))
		for i, v := range *s.VirtualNetworkRules {
			networkRules[i] = newVirtualNetworkRule(v)
		}
	}
	var ipRules []IPRule
	if s.IPRules != nil {
		ipRules = make([]IPRule, len(*s.IPRules))
		for i, v := range *s.IPRules {
			ipRules[i] = newIPRule(v)
		}
	}
	return &NetworkRuleSet{
		Bypass:              s.Bypass,
		VirtualNetworkRules: networkRules,
		IPRules:             ipRules,
		DefaultAction:       s.DefaultAction,
	}
}
func toStorageNetworkRuleSet(n *NetworkRuleSet) *storage.NetworkRuleSet {
	if n == nil {
		return nil
	}
	var networkRules *[]storage.VirtualNetworkRule
	if l := len(n.VirtualNetworkRules); l > 0 {
		nr := make([]storage.VirtualNetworkRule, l)
		for i, v := range n.VirtualNetworkRules {
			nr[i] = toStorageVirtualNetworkRule(v)
		}
		networkRules = &nr
	}
	var ipRules *[]storage.IPRule
	if l := len(n.IPRules); l > 0 {
		ir := make([]storage.IPRule, len(n.IPRules))
		for i, v := range n.IPRules {
			ir[i] = toStorageIPRule(v)
		}
		ipRules = &ir
	}
	return &storage.NetworkRuleSet{
		Bypass:              n.Bypass,
		DefaultAction:       n.DefaultAction,
		IPRules:             ipRules,
		VirtualNetworkRules: networkRules,
	}
}
type skuCapability struct {
	Name string `json:"name,omitempty"`
	Value string `json:"value,omitempty"`
}
func newSkuCapability(s storage.SKUCapability) skuCapability {
	return skuCapability{
		Name:  to.String(s.Name),
		Value: to.String(s.Value),
	}
}
func toStorageSkuCapability(s skuCapability) storage.SKUCapability {
	return storage.SKUCapability{
		Name:  toStringPtr(s.Name),
		Value: toStringPtr(s.Value),
	}
}
type Sku struct {
	Capabilities []skuCapability `json:"capabilities,omitempty"`
	Kind storage.Kind `json:"kind,omitempty"`
	Locations []string `json:"locations,omitempty"`
	Name storage.SkuName `json:"name"`
	ResourceType string `json:"resourceType,omitempty"`
	Tier storage.SkuTier `json:"tier,omitempty"`
}
func newSku(s *storage.Sku) *Sku {
	if s == nil {
		return nil
	}
	var capabilities []skuCapability
	if s.Capabilities != nil {
		capabilities = make([]skuCapability, len(*s.Capabilities))
		for i, v := range *s.Capabilities {
			capabilities[i] = newSkuCapability(v)
		}
	}
	return &Sku{
		Capabilities: capabilities,
		Kind:         s.Kind,
		Locations:    to.StringSlice(s.Locations),
		Name:         s.Name,
		ResourceType: to.String(s.ResourceType),
		Tier:         s.Tier,
	}
}
func toStorageSku(s *Sku) *storage.Sku {
	if s == nil {
		return nil
	}
	var capabilities *[]storage.SKUCapability
	if len(s.Capabilities) > 0 {
		cbp := make([]storage.SKUCapability, len(s.Capabilities))
		for i, v := range s.Capabilities {
			cbp[i] = toStorageSkuCapability(v)
		}
		capabilities = &cbp
	}
	var locations *[]string
	if len(s.Locations) > 0 {
		locations = to.StringSlicePtr(s.Locations)
	}
	return &storage.Sku{
		Capabilities: capabilities,
		Kind:         s.Kind,
		Locations:    locations,
		Name:         s.Name,
		ResourceType: toStringPtr(s.ResourceType),
		Tier:         s.Tier,
	}
}
type VirtualNetworkRule struct {
	VirtualNetworkResourceID string `json:"id,omitempty"`
	Action storage.Action `json:"action,omitempty"`
}
func newVirtualNetworkRule(s storage.VirtualNetworkRule) VirtualNetworkRule {
	return VirtualNetworkRule{
		VirtualNetworkResourceID: to.String(s.VirtualNetworkResourceID),
		Action:                   s.Action,
	}
}
func toStorageVirtualNetworkRule(v VirtualNetworkRule) storage.VirtualNetworkRule {
	return storage.VirtualNetworkRule{
		VirtualNetworkResourceID: toStringPtr(v.VirtualNetworkResourceID),
		Action:                   v.Action,
	}
}
type StorageAccountSpecProperties struct {
	AccessTier storage.AccessTier `json:"accessTier,omitempty"`
	CustomDomain *CustomDomain `json:"customDomain,omitempty"`
	EnableHTTPSTrafficOnly bool `json:"supportsHttpsTrafficOnly,omitempty"`
	Encryption *Encryption `json:"encryption,omitempty"`
	NetworkRuleSet *NetworkRuleSet `json:"networkAcls,omitempty"`
}
func newStorageAccountSpecProperties(p *storage.AccountProperties) *StorageAccountSpecProperties {
	if p == nil {
		return nil
	}
	return &StorageAccountSpecProperties{
		AccessTier:             p.AccessTier,
		CustomDomain:           newCustomDomain(p.CustomDomain),
		EnableHTTPSTrafficOnly: to.Bool(p.EnableHTTPSTrafficOnly),
		Encryption:             newEncryption(p.Encryption),
		NetworkRuleSet:         newNetworkRuleSet(p.NetworkRuleSet),
	}
}
func toStorageAccountCreateProperties(s *StorageAccountSpecProperties) *storage.AccountPropertiesCreateParameters {
	if s == nil {
		return nil
	}
	return &storage.AccountPropertiesCreateParameters{
		AccessTier:             s.AccessTier,
		CustomDomain:           toStorageCustomDomain(s.CustomDomain),
		EnableHTTPSTrafficOnly: to.BoolPtr(s.EnableHTTPSTrafficOnly),
		Encryption:             toStorageEncryption(s.Encryption),
		NetworkRuleSet:         toStorageNetworkRuleSet(s.NetworkRuleSet),
	}
}
func toStorageAccountUpdateProperties(s *StorageAccountSpecProperties) *storage.AccountPropertiesUpdateParameters {
	if s == nil {
		return nil
	}
	return &storage.AccountPropertiesUpdateParameters{
		AccessTier:             s.AccessTier,
		CustomDomain:           toStorageCustomDomain(s.CustomDomain),
		EnableHTTPSTrafficOnly: to.BoolPtr(s.EnableHTTPSTrafficOnly),
		Encryption:             toStorageEncryption(s.Encryption),
		NetworkRuleSet:         toStorageNetworkRuleSet(s.NetworkRuleSet),
	}
}
type StorageAccountStatusProperties struct {
	CreationTime *metav1.Time `json:"creationTime,omitempty"`
	LastGeoFailoverTime *metav1.Time `json:"lastGeoFailoverTime,omitempty"`
	PrimaryEndpoints *Endpoints `json:"primaryEndpoints,omitempty"`
	PrimaryLocation string `json:"primaryLocation,omitempty"`
	ProvisioningState storage.ProvisioningState `json:"provisioningState,omitempty"`
	SecondaryEndpoints *Endpoints `json:"secondaryEndpoints,omitempty"`
	SecondaryLocation string `json:"secondaryLocation,omitempty"`
	StatusOfPrimary storage.AccountStatus `json:"statusOfPrimary,omitempty"`
	StatusOfSecondary storage.AccountStatus `json:"statusOfSecondary,omitempty"`
}
func newStorageAccountStatusProperties(s *storage.AccountProperties) *StorageAccountStatusProperties {
	if s == nil {
		return nil
	}
	tf := func(dt *date.Time) *metav1.Time {
		if dt == nil {
			return nil
		}
		return &metav1.Time{Time: dt.Time}
	}
	return &StorageAccountStatusProperties{
		CreationTime:        tf(s.CreationTime),
		LastGeoFailoverTime: tf(s.LastGeoFailoverTime),
		PrimaryEndpoints:    newEndpoints(s.PrimaryEndpoints),
		PrimaryLocation:     to.String(s.PrimaryLocation),
		ProvisioningState:   s.ProvisioningState,
		SecondaryEndpoints:  newEndpoints(s.SecondaryEndpoints),
		SecondaryLocation:   to.String(s.SecondaryLocation),
		StatusOfPrimary:     s.StatusOfPrimary,
		StatusOfSecondary:   s.StatusOfSecondary,
	}
}
type StorageAccountSpec struct {
	Identity *Identity `json:"identity,omitempty"`
	Kind storage.Kind `json:"kind"`
	Location string `json:"location"`
	Sku *Sku `json:"sku"`
	*StorageAccountSpecProperties `json:"properties,omitempty"`
	Tags map[string]string `json:"tags,omitempty"`
}
func NewStorageAccountSpec(a *storage.Account) *StorageAccountSpec {
	if a == nil {
		return nil
	}
	return &StorageAccountSpec{
		Identity:                     newIdentity(a.Identity),
		Kind:                         a.Kind,
		Location:                     to.String(a.Location),
		Sku:                          newSku(a.Sku),
		StorageAccountSpecProperties: newStorageAccountSpecProperties(a.AccountProperties),
		Tags:                         to.StringMap(a.Tags),
	}
}
func parseStorageAccountSpec(s string) *StorageAccountSpec {
	sas := &StorageAccountSpec{}
	_ = json.Unmarshal([]byte(s), sas)
	return sas
}