Skip to content

Commit

Permalink
Merge pull request #45 from nikitajoshi1/feature-770-Snaphot-Policy
Browse files Browse the repository at this point in the history
Implement the Snapshot Policy APIs
  • Loading branch information
tssushma authored May 15, 2023
2 parents 234fe4f + 3abe029 commit 83c6740
Show file tree
Hide file tree
Showing 7 changed files with 792 additions and 2 deletions.
12 changes: 12 additions & 0 deletions interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -381,4 +381,16 @@ type Pmax interface {
GetStorageGroupMigration(ctx context.Context, localSymID string) (*types.MigrationStorageGroups, error)
// GetStorageGroupMigrationByID returns migration details for a storage group
GetStorageGroupMigrationByID(ctx context.Context, localSymID, storageGroupID string) (*types.MigrationSession, error)

// GetSnapshotPolicy returns a SnapshotPolicy given the Symmetrix ID and SnapshotPolicy ID (which is really a name).
GetSnapshotPolicy(ctx context.Context, symID string, snapshotPolicyID string) (*types.SnapshotPolicy, error)
// GetSnapshotPolicyList returns all the SnapshotPolicy names given the Symmetrix ID
GetSnapshotPolicyList(ctx context.Context, symID string) (*types.SnapshotPolicyList, error)
// DeleteSnapshotPolicy deletes a SnapshotPolicy entry.
DeleteSnapshotPolicy(ctx context.Context, symID string, snapshotPolicyID string) error
// CreateSnapshotPolicy creates a Snapshot policy and returns a types.SnapshotPolicy.
CreateSnapshotPolicy(ctx context.Context, symID string, snapshotPolicyID string, interval string, offsetMins int32, complianceCountWarn int64,
complianceCountCritical int64, optionalPayload map[string]interface{}) (*types.SnapshotPolicy, error)
// UpdateSnapshotPolicy is a general method to update a SnapshotPolicy (PUT operation) based on the action using a UpdateSnapshotPolicyPayload.
UpdateSnapshotPolicy(ctx context.Context, symID string, action string, snapshotPolicyID string, optionalPayload map[string]interface{}) error
}
161 changes: 161 additions & 0 deletions inttest/pmax_replication_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -953,3 +953,164 @@ func TestGetLocalOnlineRDFDirs(t *testing.T) {
}
fmt.Printf("Local Online RDF Dirs fetched successfully: %v\n", rdfGrpInfo)
}

func TestCreateSnapshotPolicy(t *testing.T) {

if client == nil {
err := getClient()
if err != nil {
t.Error(err)
return
}
}
localSnapshotPolicyDetails := &types.LocalSnapshotPolicyDetails{
Secure: false,
SnapshotCount: 24,
}

optionalPayload := make(map[string]interface{})
optionalPayload["localSnapshotPolicyDetails"] = localSnapshotPolicyDetails

targets, err := client.CreateSnapshotPolicy(context.TODO(), symmetrixID, "WeeklyDefaultnewTest", "1 Hour", 10, 2, 2, optionalPayload)
if err != nil {
t.Error("Error Creating snapshot policy" + err.Error())
return
}
fmt.Printf("Created snapshot policy: %v\n", targets.SnapshotPolicyName)
}

func TestGetSnapshotPolicy(t *testing.T) {

if client == nil {
err := getClient()
if err != nil {
t.Error(err)
return
}
}

targets, err := client.GetSnapshotPolicy(context.TODO(), symmetrixID, "WeeklyDefaultnewTest")
if err != nil {
t.Error("Error calling GetSnapshotPolicy " + err.Error())
return
}
fmt.Printf("Snapshot Policy name: %v\n", targets.SnapshotPolicyName)
}

func TestUpdateSnapshotPolicyForModify(t *testing.T) {

if client == nil {
err := getClient()
if err != nil {
t.Error(err)
return
}
}
modifySnapshotPolicyParam := &types.ModifySnapshotPolicyParam{
SnapshotPolicyName: "WeeklyDefaultnewTest1",
IntervalMinutes: 60,
OffsetMins: 10,
}

optionalPayload := make(map[string]interface{})
optionalPayload["modify"] = modifySnapshotPolicyParam

error := client.UpdateSnapshotPolicy(context.TODO(), symmetrixID, "Modify", "WeeklyDefaultnewTest", optionalPayload)
if error != nil {
t.Error("Error Updating snapshot policy " + error.Error())
return
}
fmt.Printf("Updated Snapshot Policy: Modify")
}

func TestUpdateSnapshotPolicyForAddStorageGroup(t *testing.T) {

if client == nil {
err := getClient()
if err != nil {
t.Error(err)
return
}
}
snapshotPolicySgName := "test-snapshot-policy-sg"
// Create a storage group
_, err := createStorageGroup(symmetrixID, snapshotPolicySgName, "None", defaultServiceLevel, false, nil)
if err != nil {
fmt.Println(err.Error())
return
}

associateStorageGroupParam := &types.AssociateStorageGroupParam{
StorageGroupName: []string{snapshotPolicySgName},
}

optionalPayload := make(map[string]interface{})
optionalPayload["associateStorageGroupParam"] = associateStorageGroupParam

error := client.UpdateSnapshotPolicy(context.TODO(), symmetrixID, "AssociateToStorageGroups", "WeeklyDefaultnewTest1", optionalPayload)
if error != nil {
t.Error("Error Updating snapshot policy " + error.Error())
deleteStorageGroup(symmetrixID, snapshotPolicySgName)
return
}
fmt.Printf("Updated Snapshot Policy: AssociateToStorageGroups")
}
func TestUpdateSnapshotPolicyForRemoveStorageGroup(t *testing.T) {

if client == nil {
err := getClient()
if err != nil {
t.Error(err)
return
}
}
snapshotPolicySgName := "test-snapshot-policy-sg"
disassociateStorageGroupParam := &types.DisassociateStorageGroupParam{
StorageGroupName: []string{snapshotPolicySgName},
}

optionalPayload := make(map[string]interface{})
optionalPayload["disassociateStorageGroupParam"] = disassociateStorageGroupParam

error := client.UpdateSnapshotPolicy(context.TODO(), symmetrixID, "DisassociateFromStorageGroups", "WeeklyDefaultnewTest1", optionalPayload)
if error != nil {
t.Error("Error Updating snapshot policy " + error.Error())
return
}
fmt.Printf("Updated Snapshot Policy: DisassociateFromStorageGroups")
}

func TestGetSnapshotPolicyList(t *testing.T) {

if client == nil {
err := getClient()
if err != nil {
t.Error(err)
return
}
}
targets, err := client.GetSnapshotPolicyList(context.TODO(), symmetrixID)
if err != nil {
t.Error("Error calling GetSnapshotPolicyList " + err.Error())
return
}
fmt.Printf("Snapshot Policy names: %v\n", targets.SnapshotPolicyIds)
}

func TestDeleteSnapshotPolicy(t *testing.T) {

if client == nil {
err := getClient()
if err != nil {
t.Error(err)
return
}
}

error := client.DeleteSnapshotPolicy(context.TODO(), symmetrixID, "WeeklyDefaultnewTest1")
if error != nil {
t.Error("Error Deleting Snapshot Policy " + error.Error())
return
}
fmt.Printf("Deleted snapshot policy")
}
118 changes: 117 additions & 1 deletion mock/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,15 @@ var InducedErrors struct {
GetLocalRDFPortDetailsError bool
CreateRDFGroupError bool
GetStorageGroupSnapshotError bool
DeleteStorageGroupSnapshotError bool
GetStorageGroupSnapshotSnapError bool
GetStorageGroupSnapshotSnapDetailError bool
GetStorageGroupSnapshotSnapModifyError bool
GetSnapshotPolicyError bool
GetSnapshotPolicyListError bool
CreateSnapshotPolicyError bool
ModifySnapshotPolicyError bool
DeleteSnapshotPolicyError bool
}

// hasError checks to see if the specified error (via pointer)
Expand Down Expand Up @@ -326,6 +332,11 @@ func Reset() {
InducedErrors.GetLocalRDFPortDetailsError = false
InducedErrors.CreateRDFGroupError = false
InducedErrors.GetStorageGroupSnapshotSnapDetailError = false
InducedErrors.GetSnapshotPolicyError = false
InducedErrors.GetSnapshotPolicyListError = false
InducedErrors.CreateSnapshotPolicyError = false
InducedErrors.ModifySnapshotPolicyError = false
InducedErrors.DeleteSnapshotPolicyError = false
Data.JSONDir = "mock"
Data.VolumeIDToIdentifier = make(map[string]string)
Data.VolumeIDToSize = make(map[string]int)
Expand Down Expand Up @@ -528,6 +539,10 @@ func getRouter() http.Handler {
router.HandleFunc(PREFIXNOVERSION+"/performance/StorageGroup/keys", handleStorageGroupPerfKeys)
router.HandleFunc(PREFIXNOVERSION+"/performance/Array/keys", handleArrayPerfKeys)

//Snapshot Policy
router.HandleFunc(PREFIX+"/replication/symmetrix/{symid}/snapshot_policy/{snapshotPolicyId}", handleGetSnapshotPolicy)
router.HandleFunc(PREFIX+"/replication/symmetrix/{symid}/snapshot_policy", handleCreateSnapshotPolicy)

mockRouter = router
return router
}
Expand All @@ -536,7 +551,7 @@ func getRouter() http.Handler {
// PUT /replication/symmetrix/{symid}/storagegroup/{StorageGroupId}/snapshot/{snapshotId}/snapid/{snapID}
// DELETE /replication/symmetrix/{symid}/storagegroup/{StorageGroupId}/snapshot/{snapshotId}/snapid/{snapID}
func handleGetStorageGroupSnapshotsSnapsDetails(w http.ResponseWriter, r *http.Request) {
fmt.Printf("HANDLING GET STORAGE GROUPS SNAPs Details!!!! \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n")

if r.Method != http.MethodGet && r.Method != http.MethodPut && r.Method != http.MethodDelete {
writeError(w, "Method not allowed", http.StatusMethodNotAllowed)
return
Expand All @@ -549,6 +564,10 @@ func handleGetStorageGroupSnapshotsSnapsDetails(w http.ResponseWriter, r *http.R
writeError(w, "Could not get StorageGroup Snapshots Snap Ids: induced error", http.StatusBadRequest)
return
}
if InducedErrors.DeleteStorageGroupSnapshotError {
writeError(w, "Could not delete StorageGroup Snapshots Snap Ids: induced error", http.StatusBadRequest)
return
}
if r.Method == http.MethodGet {
sgCreateSnap := &types.StorageGroupSnap{
Name: "sg_1_snap",
Expand Down Expand Up @@ -628,6 +647,103 @@ func handleGetStorageGroupSnapshots(w http.ResponseWriter, r *http.Request) {
}
}

// GET /replication/symmetrix/{symid}/snapshot_policy/{snapshotPolicyId}
// PUT /replication/symmetrix/{symid}/snapshot_policy/{snapshotPolicyId}
// DELETE /replication/symmetrix/{symid}/snapshot_policy/{snapshotPolicyId}
func handleGetSnapshotPolicy(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet && r.Method != http.MethodPut && r.Method != http.MethodDelete {
writeError(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
if InducedErrors.GetSnapshotPolicyError {
writeError(w, "Could not get Snapshot Policy : induced error", http.StatusBadRequest)
return
}
if InducedErrors.ModifySnapshotPolicyError {
writeError(w, "Could not update Snapshot Policy : induced error", http.StatusBadRequest)
return
}
if InducedErrors.DeleteSnapshotPolicyError {
writeError(w, "Could not delete Snapshot Policy : induced error", http.StatusBadRequest)
return
}
if r.Method == http.MethodGet {

snapPolicy := &types.SnapshotPolicy{
SymmetrixID: "000197902572",
SnapshotPolicyName: "WeeklyDefault",
SnapshotCount: 13,
IntervalMinutes: 10080,
OffsetMinutes: 10074,
Suspended: false,
Secure: false,
LastTimeUsed: "23:53:15 Sun, 07 May 2023 +0000",
StorageGroupCount: 1,
ComplianceCountWarning: 10,
Type: "local",
}
writeJSON(w, snapPolicy)
}
if r.Method == http.MethodPut {
snapPolicy := &types.SnapshotPolicy{
SymmetrixID: "000197902572",
SnapshotPolicyName: "WeeklyDefault",
SnapshotCount: 13,
IntervalMinutes: 10080,
OffsetMinutes: 10074,
Suspended: false,
Secure: false,
LastTimeUsed: "23:53:15 Sun, 07 May 2023 +0000",
StorageGroupCount: 1,
ComplianceCountWarning: 10,
Type: "local",
}
writeJSON(w, snapPolicy)
}
}

// POST /replication/symmetrix/{symid}/snapshot_policy
// GET /replication/symmetrix/{symid}/snapshot_policy
func handleCreateSnapshotPolicy(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet && r.Method != http.MethodPost {
writeError(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
if InducedErrors.CreateSnapshotPolicyError {
writeError(w, "Could not Create Snapshot Policy : induced error", http.StatusBadRequest)
return
}
if InducedErrors.GetSnapshotPolicyListError {
writeError(w, "Could not get Snapshot Policy List: induced error", http.StatusBadRequest)
return
}

if r.Method == http.MethodGet {
ids := []string{"Test123", "Test345"}
snapPolicyList := &types.SnapshotPolicyList{
SnapshotPolicyIds: ids,
}
writeJSON(w, snapPolicyList)
}
if r.Method == http.MethodPost {

snapPolicy := &types.SnapshotPolicy{
SymmetrixID: "000197902572",
SnapshotPolicyName: "WeeklyDefault",
SnapshotCount: 13,
IntervalMinutes: 10080,
OffsetMinutes: 10074,
Suspended: false,
Secure: false,
LastTimeUsed: "23:53:15 Sun, 07 May 2023 +0000",
StorageGroupCount: 1,
ComplianceCountWarning: 10,
Type: "local",
}
writeJSON(w, snapPolicy)
}
}

// GET univmax/restapi/100/replication/symmetrix/{symID}/rdf_director/{dir}/port?online=true
// GET univmax/restapi/100/replication/symmetrix/{symID}/rdf_director/{dir}/port/{port}
func handleRDFPort(w http.ResponseWriter, r *http.Request) {
Expand Down
Loading

0 comments on commit 83c6740

Please sign in to comment.