Exemple #1
0
//CopyFileToS3 - Responsible for copying a file to S3
func (t *Task) CopyFileToS3() (err error) {
	start := time.Now()

	f := history.S3FileHistory{}
	f.Status = "error" //Changed at the end of the function if successful
	f.Bucket = rdpgs3.BucketName
	defer func() {
		f.Duration = int(time.Since(start).Seconds())
		insertErr := history.InsertS3History(f)
		if insertErr != nil {
			log.Error(fmt.Sprintf("tasks.CopyFileToS3 ! insertS3History erred : %s", err.Error()))
		}
	}()

	taskParams := []byte(t.Data)
	fm := S3FileMetadata{}
	err = json.Unmarshal(taskParams, &fm)
	if err != nil {
		log.Error(fmt.Sprintf("tasks.CopyFileToS3() json.Unmarshal() ! %s", err))
		return err
	}

	//Log results to backups.file_history
	f.Source = fm.Location
	f.Target = fm.Location
	f.DBName = fm.DBName
	f.Node = fm.Node
	creds := credentials.NewStaticCredentials(rdpgs3.AWSAccessKey, rdpgs3.AWSSecretKey, rdpgs3.Token)

	config := &aws.Config{
		Region:           &rdpgs3.AWSRegion,
		Endpoint:         &rdpgs3.Endpoint,
		S3ForcePathStyle: &rdpgs3.S3ForcePathStyle,
		Credentials:      creds,
	}

	s3client := s3.New(config)

	file, err := os.Open(fm.Location)
	if err != nil {
		log.Error(fmt.Sprintf("tasks.CopyFileToS3() Error attempting to open file %s ! %s", fm.Location, err))
		return err
	}

	defer file.Close()

	fileInfo, _ := file.Stat()
	f.Size = fileInfo.Size()
	f.FileName = fileInfo.Name()
	buffer := make([]byte, f.Size)
	file.Read(buffer)
	fileBytes := bytes.NewReader(buffer) // convert to io.ReadSeeker type
	fileType := http.DetectContentType(buffer)

	s3params := &s3.PutObjectInput{
		Bucket:        aws.String(rdpgs3.BucketName), // required
		Key:           aws.String(fm.Location),       // required
		ACL:           aws.String("public-read"),     //other values: http://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#CannedACL
		Body:          fileBytes,
		ContentLength: aws.Int64(f.Size),
		ContentType:   aws.String(fileType),
		Metadata: map[string]*string{
			"Key": aws.String("MetadataValue"), //required
		},
		// see more at http://godoc.org/github.com/aws/aws-sdk-go/service/s3#S3.PutObject
	}

	result, err := s3client.PutObject(s3params)
	log.Trace(fmt.Sprintf("tasks.CopyFileToS3() Copy file to S3 result > %s ", result))

	if err != nil {
		log.Error(fmt.Sprintf("tasks.CopyFileToS3() AWS General Error ! %s", err))
		if awsErr, ok := err.(awserr.Error); ok {
			// Generic AWS Error with Code, Message, and original error (if any)
			log.Error(fmt.Sprintf("tasks.CopyFileToS3() AWS Error %s !! %s ! %s", awsErr.Code(), awsErr.Message(), awsErr.OrigErr()))
			if reqErr, ok := err.(awserr.RequestFailure); ok {
				// A service error occurred
				log.Error(fmt.Sprintf("tasks.CopyFileToS3() AWS Service Error %s !!! %s !! %s ! %s", reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID()))
			}
		} else {
			// This case should never be hit, the SDK should always return an
			// error which satisfies the awserr.Error interface.
			log.Error(fmt.Sprintf("tasks.CopyFileToS3() General AWS Error %s ! ", err.Error()))
		}
	}

	return
}
//Base function for getting a file from S3 and putting it somewhere on the local filesystem.
func CopyFileFromS3(source, destination, bucket string) (err error) {
	start := time.Now()
	f := history.S3FileHistory{}
	f.Status = "error" //Changed at end if successful
	spl := strings.Split(source, "/")
	basename := spl[len(spl)-1]
	//Log results to backups.file_history
	f.Source = source
	f.Target = destination
	f.Node = globals.MyIP
	f.Bucket = bucket
	f.FileName = basename
	defer func() {
		f.Duration = int(time.Since(start).Seconds())
		insertErr := history.InsertS3History(f)
		if insertErr != nil {
			log.Error(fmt.Sprintf("utils/rdpgs3.CopyFileFromS3 ! InsertS3History erred : %s", err.Error()))
		}
	}()

	if !Configured {
		errorMessage := "utils/rdpgs3.CopyFileFromS3 ! S3 Credentials not configured for this deployment!"
		log.Error(errorMessage)
		return errors.New(errorMessage)
	}

	creds := credentials.NewStaticCredentials(AWSAccessKey, AWSSecretKey, Token)

	config := &aws.Config{
		Region:           &AWSRegion,
		Endpoint:         &Endpoint,
		S3ForcePathStyle: &S3ForcePathStyle,
		Credentials:      creds,
	}

	s3client := s3.New(config)

	params := &s3.GetObjectInput{
		Bucket: aws.String(bucket),
		Key:    aws.String(source),
	}
	resp, err := s3client.GetObject(params)
	if err != nil {
		// Print the error, cast err to awserr.Error to get the Code and
		// Message from an error.
		log.Error(fmt.Sprintf("tasks.StageRemoteRestore() AWS Error: ! %s", err.Error()))
		return
	}
	defer resp.Body.Close()

	pathArray := removeBlankSplit(strings.Split(destination, "/"))
	basefilename := pathArray[len(pathArray)-1]
	pathArray = pathArray[0 : len(pathArray)-1]
	if len(pathArray) == 0 {
		errorMessage := "utils/rdpgs3.CopyFileFromS3 ! Must specify destination path"
		log.Error(errorMessage)
		return errors.New(errorMessage)
	}
	folderPath := "/"
	for _, v := range pathArray {
		folderPath += (v + "/")
	}

	// make sure the folder exists before we create the file
	err = os.MkdirAll(folderPath, 0777)
	if err != nil {
		log.Error(fmt.Sprintf("utils/backup.CopyFileFromS3 ! Could not create target folder %s ! %s", folderPath, err))
		return err
	}

	downloadFile, err := os.Create(folderPath + basefilename)
	if err != nil {
		log.Error(fmt.Sprintf("utils/backup.CopyFileFromS3 ! attempting to create file error: ! %s", err))
		return err
	}

	defer downloadFile.Close()

	f.Size, err = io.Copy(downloadFile, resp.Body)

	if err != nil {
		log.Error(fmt.Sprintf("utils/backup.CopyFileFromS3 ! Failed to copy object to file ! %s", err))
		return err
	}

	f.Status = "ok"
	return err
}