github.com/mmcquillan/packer@v1.1.1-0.20171009221028-c85cf0483a5d/builder/azure/arm/artifact.go (about)

     1  package arm
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"net/url"
     7  	"path"
     8  	"strings"
     9  )
    10  
    11  const (
    12  	BuilderId = "Azure.ResourceManagement.VMImage"
    13  )
    14  
    15  type Artifact struct {
    16  	// VHD
    17  	StorageAccountLocation string
    18  	OSDiskUri              string
    19  	TemplateUri            string
    20  	OSDiskUriReadOnlySas   string
    21  	TemplateUriReadOnlySas string
    22  
    23  	// Managed Image
    24  	ManagedImageResourceGroupName string
    25  	ManagedImageName              string
    26  	ManagedImageLocation          string
    27  }
    28  
    29  func NewManagedImageArtifact(resourceGroup, name, location string) (*Artifact, error) {
    30  	return &Artifact{
    31  		ManagedImageResourceGroupName: resourceGroup,
    32  		ManagedImageName:              name,
    33  		ManagedImageLocation:          location,
    34  	}, nil
    35  }
    36  
    37  func NewArtifact(template *CaptureTemplate, getSasUrl func(name string) string) (*Artifact, error) {
    38  	if template == nil {
    39  		return nil, fmt.Errorf("nil capture template")
    40  	}
    41  
    42  	if len(template.Resources) != 1 {
    43  		return nil, fmt.Errorf("malformed capture template, expected one resource")
    44  	}
    45  
    46  	vhdUri, err := url.Parse(template.Resources[0].Properties.StorageProfile.OSDisk.Image.Uri)
    47  	if err != nil {
    48  		return nil, err
    49  	}
    50  
    51  	templateUri, err := storageUriToTemplateUri(vhdUri)
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  
    56  	return &Artifact{
    57  		OSDiskUri:              vhdUri.String(),
    58  		OSDiskUriReadOnlySas:   getSasUrl(getStorageUrlPath(vhdUri)),
    59  		TemplateUri:            templateUri.String(),
    60  		TemplateUriReadOnlySas: getSasUrl(getStorageUrlPath(templateUri)),
    61  
    62  		StorageAccountLocation: template.Resources[0].Location,
    63  	}, nil
    64  }
    65  
    66  func getStorageUrlPath(u *url.URL) string {
    67  	parts := strings.Split(u.Path, "/")
    68  	return strings.Join(parts[3:], "/")
    69  }
    70  
    71  func storageUriToTemplateUri(su *url.URL) (*url.URL, error) {
    72  	// packer-osDisk.4085bb15-3644-4641-b9cd-f575918640b4.vhd -> 4085bb15-3644-4641-b9cd-f575918640b4
    73  	filename := path.Base(su.Path)
    74  	parts := strings.Split(filename, ".")
    75  
    76  	if len(parts) < 3 {
    77  		return nil, fmt.Errorf("malformed URL")
    78  	}
    79  
    80  	// packer-osDisk.4085bb15-3644-4641-b9cd-f575918640b4.vhd -> packer
    81  	prefixParts := strings.Split(parts[0], "-")
    82  	prefix := strings.Join(prefixParts[:len(prefixParts)-1], "-")
    83  
    84  	templateFilename := fmt.Sprintf("%s-vmTemplate.%s.json", prefix, parts[1])
    85  
    86  	// https://storage.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-osDisk.4085bb15-3644-4641-b9cd-f575918640b4.vhd"
    87  	//   ->
    88  	// https://storage.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-vmTemplate.4085bb15-3644-4641-b9cd-f575918640b4.json"
    89  	return url.Parse(strings.Replace(su.String(), filename, templateFilename, 1))
    90  }
    91  
    92  func (a *Artifact) isMangedImage() bool {
    93  	return a.ManagedImageResourceGroupName != ""
    94  }
    95  
    96  func (*Artifact) BuilderId() string {
    97  	return BuilderId
    98  }
    99  
   100  func (*Artifact) Files() []string {
   101  	return []string{}
   102  }
   103  
   104  func (a *Artifact) Id() string {
   105  	return a.OSDiskUri
   106  }
   107  
   108  func (a *Artifact) State(name string) interface{} {
   109  	switch name {
   110  	case "atlas.artifact.metadata":
   111  		return a.stateAtlasMetadata()
   112  	default:
   113  		return nil
   114  	}
   115  }
   116  
   117  func (a *Artifact) String() string {
   118  	var buf bytes.Buffer
   119  
   120  	buf.WriteString(fmt.Sprintf("%s:\n\n", a.BuilderId()))
   121  	if a.isMangedImage() {
   122  		buf.WriteString(fmt.Sprintf("ManagedImageResourceGroupName: %s\n", a.ManagedImageResourceGroupName))
   123  		buf.WriteString(fmt.Sprintf("ManagedImageName: %s\n", a.ManagedImageName))
   124  		buf.WriteString(fmt.Sprintf("ManagedImageLocation: %s\n", a.ManagedImageLocation))
   125  	} else {
   126  		buf.WriteString(fmt.Sprintf("StorageAccountLocation: %s\n", a.StorageAccountLocation))
   127  		buf.WriteString(fmt.Sprintf("OSDiskUri: %s\n", a.OSDiskUri))
   128  		buf.WriteString(fmt.Sprintf("OSDiskUriReadOnlySas: %s\n", a.OSDiskUriReadOnlySas))
   129  		buf.WriteString(fmt.Sprintf("TemplateUri: %s\n", a.TemplateUri))
   130  		buf.WriteString(fmt.Sprintf("TemplateUriReadOnlySas: %s\n", a.TemplateUriReadOnlySas))
   131  	}
   132  
   133  	return buf.String()
   134  }
   135  
   136  func (*Artifact) Destroy() error {
   137  	return nil
   138  }
   139  
   140  func (a *Artifact) stateAtlasMetadata() interface{} {
   141  	metadata := make(map[string]string)
   142  	metadata["StorageAccountLocation"] = a.StorageAccountLocation
   143  	metadata["OSDiskUri"] = a.OSDiskUri
   144  	metadata["OSDiskUriReadOnlySas"] = a.OSDiskUriReadOnlySas
   145  	metadata["TemplateUri"] = a.TemplateUri
   146  	metadata["TemplateUriReadOnlySas"] = a.TemplateUriReadOnlySas
   147  
   148  	return metadata
   149  }