@@ -947,3 +947,117 @@ func (o *oracleOps) scaleDownToZeroThenScaleUp(instanceGroupName, instanceGroupI
947947
948948 return updateResp , nil
949949}
950+
951+ // Enumerate volumes that match given filters. Organize them into
952+ // sets identified by setIdentifier.
953+ // labels can be nil, setIdentifier can be empty string.
954+ func (o * oracleOps ) Enumerate (volumeIds []* string ,
955+ labels map [string ]string ,
956+ setIdentifier string ,
957+ ) (map [string ][]interface {}, error ) {
958+ sets := make (map [string ][]interface {})
959+ req := core.ListVolumesRequest {
960+ CompartmentId : common .String (o .compartmentID ),
961+ }
962+ resp , err := o .storage .ListVolumes (context .Background (), req )
963+ if err != nil {
964+ return nil , err
965+ }
966+ volIDsMap := map [string ]string {}
967+ for _ , volIds := range volumeIds {
968+ volIDsMap [* volIds ] = * volIds
969+ }
970+ for _ , vol := range resp .Items {
971+ _ , ok := volIDsMap [* vol .Id ]
972+ if ! ok {
973+ continue
974+ }
975+
976+ if o .deleted (vol ) {
977+ continue
978+ }
979+ // TODO: [PWX-26616] Check if SDK itself returns list of volumes
980+ // that have labels OR use volumeGroup for filtering
981+ if labels != nil && containsMap (vol .FreeformTags , labels ) {
982+ continue
983+ }
984+ if len (setIdentifier ) == 0 {
985+ cloudops .AddElementToMap (sets , vol , cloudops .SetIdentifierNone )
986+ } else {
987+ found := false
988+ for tagKey , tagValue := range vol .FreeformTags {
989+ if tagKey == setIdentifier {
990+ cloudops .AddElementToMap (sets , vol , tagValue )
991+ found = true
992+ break
993+ }
994+ }
995+ if ! found {
996+ cloudops .AddElementToMap (sets , vol , cloudops .SetIdentifierNone )
997+ }
998+ }
999+ }
1000+ return sets , nil
1001+ }
1002+
1003+ func containsMap (mainMap map [string ]string , subMap map [string ]string ) bool {
1004+ for k , v := range subMap {
1005+ value , ok := mainMap [k ]
1006+ if ! ok {
1007+ return false
1008+ }
1009+ if value != v {
1010+ return false
1011+ }
1012+ }
1013+ return true
1014+ }
1015+
1016+ func (o * oracleOps ) deleted (v core.Volume ) bool {
1017+ return v .LifecycleState == core .VolumeLifecycleStateTerminating ||
1018+ v .LifecycleState == core .VolumeLifecycleStateTerminated
1019+ }
1020+
1021+ // ApplyTags will apply given labels/tags on the given volume
1022+ func (o * oracleOps ) ApplyTags (volumeID string , labels map [string ]string ) error {
1023+ req := core.UpdateVolumeRequest {
1024+ VolumeId : common .String (volumeID ),
1025+ UpdateVolumeDetails : core.UpdateVolumeDetails {
1026+ FreeformTags : labels ,
1027+ },
1028+ }
1029+ resp , err := o .storage .UpdateVolume (context .Background (), req )
1030+ if err != nil {
1031+ logrus .Errorf ("failed to apply tag to %s. response: %v" , volumeID , resp )
1032+ }
1033+ return err
1034+ }
1035+
1036+ // Tags will list the existing labels/tags on the given volume
1037+ func (o * oracleOps ) Tags (volumeID string ) (map [string ]string , error ) {
1038+ vols , err := o .Inspect ([]* string {& volumeID })
1039+ if err != nil {
1040+ return nil , err
1041+ }
1042+ if len (vols ) != 1 {
1043+ return nil , fmt .Errorf ("incorrect number of volumes [%v] got for volume id: %v" ,
1044+ len (vols ), volumeID )
1045+ }
1046+ oracleVol , ok := vols [0 ].(* core.Volume )
1047+ if ! ok {
1048+ return nil , fmt .Errorf ("Invalid oracle volume" )
1049+ }
1050+ return oracleVol .FreeformTags , nil
1051+ }
1052+
1053+ // RemoveTags removes labels/tags from the given volume
1054+ func (o * oracleOps ) RemoveTags (volumeID string , labels map [string ]string ) error {
1055+ currentTags , err := o .Tags (volumeID )
1056+ if err != nil {
1057+ return nil
1058+ }
1059+ for key := range labels {
1060+ delete (currentTags , key )
1061+ }
1062+ return o .ApplyTags (volumeID , currentTags )
1063+ }
0 commit comments