func rotateFiles(fileMap KeyIDFileMap, keyStore keystore.RotateStorageKeyStore, zoneMode, dryRun bool) (ZoneRotateResult, error) {
	rotator, err := newRotator(keyStore, zoneMode)
	if err != nil {
		return nil, err
	}
	defer rotator.clearKeys()
	output := ZoneRotateResult{}
	for zoneID, paths := range fileMap {
		logger := log.WithField("Key ID", zoneID)
		binZoneID := []byte(zoneID)
		newPublicKey, err := rotator.getRotatedPublicKey(binZoneID)
		if err != nil {
			logger.WithError(err).Errorln("Can't rotate zone key")
			return nil, err
		}
		result := &ZoneRotateData{NewPublicKey: newPublicKey.Value}
		for _, path := range paths {
			fileLogger := logger.WithField("filepath", path)
			result.FilePaths = append(result.FilePaths, path)
			acraStruct, err := ioutil.ReadFile(path)
			if err != nil {
				fileLogger.WithError(err).Errorf("Can't read file %s", path)
				return nil, err
			}
			rotated, err := rotator.rotateAcrastruct(binZoneID, acraStruct)
			if err != nil {
				fileLogger.WithField("acrastruct", hex.EncodeToString(acraStruct)).WithError(err).Errorln("Can't rotate data")
				return nil, err
			}
			stat, err := os.Stat(path)
			if err != nil {
				fileLogger.WithError(err).Errorln("Can't get stat info about file to retrieve current file permissions")
				return nil, err
			}
			if !dryRun {
				if err := ioutil.WriteFile(path, rotated, stat.Mode()); err != nil {
					fileLogger.WithError(err).Errorln("Can't write rotated AcraStruct with zone")
					return nil, err
				}
			}
			fileLogger.Infof("Finish rotate file")
		}
		output[zoneID] = result
		logger.Infoln("Finish rotate zone")
	}
	if !dryRun {
		if err := rotator.saveRotatedKeys(); err != nil {
			log.WithError(err).Errorln("Can't save rotated keys")
		}
	}
	return output, nil
}
rotateFiles generate new key pair for each zone in KeyIDFileMap and re-encrypt all files encrypted with each zone
package main
import (
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"github.com/cossacklabs/acra/keystore"
	log "github.com/sirupsen/logrus"
)
func loadFileMap(path string) (KeyIDFileMap, error) {
	configData, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}
	return ParseConfig(configData)
}
type ZoneRotateData struct {
	NewPublicKey []byte   `json:"new_public_key"`
	FilePaths    []string `json:"file_paths"`
}
type ZoneRotateResult map[string]*ZoneRotateData