1// 2// Copyright (c) 2018, Joyent, Inc. All rights reserved. 3// 4// This Source Code Form is subject to the terms of the Mozilla Public 5// License, v. 2.0. If a copy of the MPL was not distributed with this 6// file, You can obtain one at http://mozilla.org/MPL/2.0/. 7// 8 9package main 10 11import ( 12 "context" 13 "fmt" 14 "io/ioutil" 15 "log" 16 "os" 17 "strconv" 18 19 "encoding/pem" 20 21 triton "github.com/joyent/triton-go" 22 "github.com/joyent/triton-go/authentication" 23 "github.com/joyent/triton-go/storage" 24) 25 26func main() { 27 keyID := os.Getenv("TRITON_KEY_ID") 28 accountName := os.Getenv("TRITON_ACCOUNT") 29 keyMaterial := os.Getenv("TRITON_KEY_MATERIAL") 30 userName := os.Getenv("TRITON_USER") 31 fileName := "foo.txt" 32 localPath := "/tmp/" + fileName 33 mantaPath := "/stor/bar/baz/" + fileName 34 35 var signer authentication.Signer 36 var err error 37 38 if keyMaterial == "" { 39 input := authentication.SSHAgentSignerInput{ 40 KeyID: keyID, 41 AccountName: accountName, 42 Username: userName, 43 } 44 signer, err = authentication.NewSSHAgentSigner(input) 45 if err != nil { 46 log.Fatalf("Error Creating SSH Agent Signer: %v", err) 47 } 48 } else { 49 var keyBytes []byte 50 if _, err = os.Stat(keyMaterial); err == nil { 51 keyBytes, err = ioutil.ReadFile(keyMaterial) 52 if err != nil { 53 log.Fatalf("Error reading key material from %s: %s", 54 keyMaterial, err) 55 } 56 block, _ := pem.Decode(keyBytes) 57 if block == nil { 58 log.Fatalf( 59 "Failed to read key material '%s': no key found", keyMaterial) 60 } 61 62 if block.Headers["Proc-Type"] == "4,ENCRYPTED" { 63 log.Fatalf( 64 "Failed to read key '%s': password protected keys are\n"+ 65 "not currently supported. Please decrypt the key prior to use.", keyMaterial) 66 } 67 68 } else { 69 keyBytes = []byte(keyMaterial) 70 } 71 72 input := authentication.PrivateKeySignerInput{ 73 KeyID: keyID, 74 PrivateKeyMaterial: keyBytes, 75 AccountName: accountName, 76 Username: userName, 77 } 78 signer, err = authentication.NewPrivateKeySigner(input) 79 if err != nil { 80 log.Fatalf("Error Creating SSH Private Key Signer: %v", err) 81 } 82 } 83 84 config := &triton.ClientConfig{ 85 MantaURL: os.Getenv("MANTA_URL"), 86 AccountName: accountName, 87 Username: userName, 88 Signers: []authentication.Signer{signer}, 89 } 90 91 client, err := storage.NewClient(config) 92 if err != nil { 93 log.Fatalf("NewClient: %v", err) 94 } 95 96 mpuBody := storage.CreateMpuBody{ 97 ObjectPath: mantaPath, 98 } 99 100 fooFile := []byte("this is only a test\n") 101 err = ioutil.WriteFile(localPath, fooFile, 0644) 102 if err != nil { 103 log.Fatalf("Failed to write temporary upload file " + localPath) 104 } 105 106 createMpuInput := &storage.CreateMpuInput{ 107 DurabilityLevel: 2, 108 Body: mpuBody, 109 ForceInsert: true, 110 } 111 112 // Create a multipart upload to use for further testing 113 fmt.Println("*** Creating new multipart upload ***") 114 response := &storage.CreateMpuOutput{} 115 response, err = client.Objects().CreateMultipartUpload(context.Background(), createMpuInput) 116 if err != nil { 117 log.Fatalf("storage.Objects.CreateMpu: %v", err) 118 } 119 fmt.Printf("Response Body\nid: %s\npartsDirectory: %s\n", response.Id, response.PartsDirectory) 120 fmt.Println("Successfully created MPU for " + localPath) 121 122 reader, err := os.Open(localPath) 123 if err != nil { 124 log.Fatalf("os.Open: %v", err) 125 } 126 defer reader.Close() 127 128 uploadPartInput := &storage.UploadPartInput{ 129 Id: response.Id, 130 PartNum: 0, 131 ObjectReader: reader, 132 } 133 134 fmt.Println("ObjectDirectorPath for UploadPartInput: " + response.PartsDirectory) 135 136 // Upload a single part 137 fmt.Println("\n*** Upload a single part to the previous multipart upload ***") 138 response2 := &storage.UploadPartOutput{} 139 response2, err = client.Objects().UploadPart(context.Background(), uploadPartInput) 140 if err != nil { 141 log.Fatalf("storage.Objects.UploadPart: %v", err) 142 } 143 fmt.Println("Successfully uploaded " + fileName + " part 0!") 144 145 var parts []string 146 fmt.Printf("Part: %s\n", response2.Part) 147 parts = append(parts, response2.Part) 148 commitBody := storage.CommitMpuBody{ 149 Parts: parts, 150 } 151 152 commitMpuInput := &storage.CommitMpuInput{ 153 Id: response.Id, 154 Body: commitBody, 155 } 156 157 // List parts 158 fmt.Println("\n*** List the parts of the current multipart upload ***") 159 listMpuInput := &storage.ListMpuPartsInput{ 160 Id: response.Id, 161 } 162 listPartsOutput, err := client.Objects().ListMultipartUploadParts(context.Background(), listMpuInput) 163 if err != nil { 164 log.Fatalf("storage.Objects.ListMultipartUploadParts: %v", err) 165 } 166 for _, value := range listPartsOutput.Parts { 167 fmt.Println("Etag: " + value.ETag + " PartNumber: " + strconv.Itoa(value.PartNumber) + " Size: " + strconv.FormatInt(value.Size, 10)) 168 } 169 fmt.Println("Successfully listed MPU parts!") 170 171 // Commit completed multipart upload 172 fmt.Println("\n*** Commit the completed multipart upload ***") 173 err = client.Objects().CommitMultipartUpload(context.Background(), commitMpuInput) 174 if err != nil { 175 log.Fatalf("storage.Objects.CommitMultipartUpload: %v", err) 176 } 177 fmt.Println("Successfully committed " + response.Id + "!") 178 179 getMpuInput := &storage.GetMpuInput{ 180 PartsDirectoryPath: response.PartsDirectory, 181 } 182 183 // Get the status of the completed multipart upload 184 fmt.Println("\n*** Get the status of the multipart upload ***") 185 response3 := &storage.GetMpuOutput{} 186 response3, err = client.Objects().GetMultipartUpload(context.Background(), getMpuInput) 187 if err != nil { 188 log.Fatalf("storage.Objects.GetMultipartUpload: %v", err) 189 } 190 fmt.Println("Successful get of " + response3.Id + " for targetObject: " + response3.TargetObject) 191 192 err = os.Remove(localPath) 193 if err != nil { 194 log.Fatalf("os.Remove: %v", err) 195 } 196 197 // Create a new multipart upload just to test abort 198 fmt.Println("\n*** Create a throwaway multipart upload ***") 199 response, err = client.Objects().CreateMultipartUpload(context.Background(), createMpuInput) 200 if err != nil { 201 log.Fatalf("storage.Objects.CreateMpu: %v", err) 202 } 203 fmt.Printf("Response Body\nid: %s\npartsDirectory: %s\n", response.Id, response.PartsDirectory) 204 fmt.Println("Successfully created MPU for " + localPath) 205 206 abortMpuInput := &storage.AbortMpuInput{ 207 PartsDirectoryPath: response.PartsDirectory, 208 } 209 210 // Abort multipart upload 211 fmt.Println("\n*** Abort the previous multipart upload ***") 212 err = client.Objects().AbortMultipartUpload(context.Background(), abortMpuInput) 213 if err != nil { 214 log.Fatalf("storage.Objects.AbortMultipartUpload: %v", err) 215 } 216 217 fmt.Println("Successfully aborted MPU") 218} 219