@@ -2156,3 +2156,284 @@ def run(self):
21562156 raise ModuleError ("No operating systems found matching the criteria" )
21572157
21582158 return {"changed" : False , "os_list" : os_list }
2159+
2160+
2161+ class ScRBSFlavorsInfo :
2162+ def __init__ (self , endpoint , token , location_id ):
2163+ self .api = ScApi (token , endpoint )
2164+ self .location_id = location_id
2165+
2166+ def run (self ):
2167+ return {
2168+ "changed" : False ,
2169+ "rbs_volume_flavors" : list (self .api .list_rbs_flavors (self .location_id )),
2170+ }
2171+
2172+
2173+ class ScRBSVolumeList :
2174+ def __init__ (self , endpoint , token , label_selector = None , search_pattern = None , location_id = None , location_code = None ):
2175+ self .api = ScApi (token , endpoint )
2176+ self .label_selector = label_selector
2177+ self .search_pattern = search_pattern
2178+ self .location_id = location_id
2179+ self .location_code = location_code
2180+
2181+ if not self .location_id and self .location_code :
2182+ self .location_code = self .location_code .upper ()
2183+ locations = self .api .list_locations (search_pattern = self .location_code )
2184+
2185+ for location in locations :
2186+ if location .get ("code" ) == self .location_code :
2187+ self .location_id = location .get ("id" )
2188+ break
2189+
2190+ if not self .location_id :
2191+ raise ModuleError (
2192+ f"Location with code '{ self .location_code } ' not found."
2193+ )
2194+
2195+ def run (self ):
2196+ volumes = list (self .api .list_rbs_volumes (self .label_selector , self .search_pattern , self .location_id ))
2197+ for volume in volumes :
2198+ volume_credentials = self .api .get_rbs_volume_credentials (volume ["id" ])
2199+ volume .update ({"username" : volume_credentials ["username" ], "password" : volume_credentials ["password" ]})
2200+ return {
2201+ "changed" : False ,
2202+ "rbs_volumes" : volumes ,
2203+ }
2204+
2205+
2206+ class scRBSVolumeCreateUpdateDelete :
2207+ def __init__ (
2208+ self ,
2209+ endpoint ,
2210+ token ,
2211+ name ,
2212+ location_id ,
2213+ location_code ,
2214+ flavor_id ,
2215+ flavor_name ,
2216+ size ,
2217+ labels ,
2218+ volume_id ,
2219+ wait ,
2220+ update_interval ,
2221+ checkmode
2222+ ):
2223+ self .api = ScApi (token , endpoint )
2224+ self .volume_id = volume_id
2225+ self .name = name
2226+ self .location_id = location_id
2227+ self .location_code = location_code
2228+ self .flavor_id = flavor_id
2229+ self .flavor_name = flavor_name
2230+ self .size = size
2231+ self .labels = labels
2232+ self .wait = wait
2233+ self .update_interval = update_interval
2234+ self .checkmode = checkmode
2235+
2236+ if not self .location_id and self .location_code :
2237+ self .location_code = self .location_code .upper ()
2238+ locations = self .api .list_locations (search_pattern = self .location_code )
2239+
2240+ for location in locations :
2241+ if location .get ("code" ) == self .location_code :
2242+ self .location_id = location .get ("id" )
2243+ break
2244+
2245+ if not self .location_id :
2246+ raise ModuleError (
2247+ f"Location with code '{ self .location_code } ' not found."
2248+ )
2249+
2250+ if not self .flavor_id and self .flavor_name :
2251+ flavors = self .api .list_rbs_flavors (location_id = self .location_id )
2252+
2253+ for flavor in flavors :
2254+ if flavor .get ("name" ) == self .flavor_name :
2255+ self .flavor_id = flavor .get ("id" )
2256+ break
2257+
2258+ if not self .flavor_id :
2259+ raise ModuleError (
2260+ f"Flavor with the name '{ self .flavor_name } ' not found."
2261+ )
2262+
2263+ def update_volume (self ):
2264+ volume = self .api .get_rbs_volume (self .volume_id )
2265+ result = {"changed" : False , "rbs_volume" : volume }
2266+ if any ([
2267+ self .name and self .name != volume .get ("name" ),
2268+ self .size and self .size != volume .get ("size" ),
2269+ self .labels and self .labels != volume .get ("labels" ),
2270+ ]):
2271+ if not self .checkmode :
2272+ updated_volume = self .api .update_rbs_volume (
2273+ self .volume_id ,
2274+ name = self .name ,
2275+ size = self .size ,
2276+ labels = self .labels ,
2277+ )
2278+ updated_volume = self .wait_for_active ()
2279+ result ["rbs_volume" ] = updated_volume
2280+ else :
2281+ result ["rbs_volume" ]["name" ] = self .name or volume .get ("name" )
2282+ result ["rbs_volume" ]["size" ] = self .size or volume .get ("size" )
2283+ result ["rbs_volume" ]["labels" ] = self .labels or volume .get ("labels" )
2284+ result ["changed" ] = True
2285+ return result
2286+ else :
2287+ result ["changed" ] = False
2288+ return result
2289+
2290+ def create_or_update_volume (self ):
2291+ result = {"changed" : False , "rbs_volume" : None }
2292+ existing_volume = self .api .get_rbs_volume_by_name (self .name )
2293+ if existing_volume :
2294+ if (self .location_id and self .location_id != existing_volume ["location_id" ]) or (self .flavor_id and self .flavor_id != existing_volume ["flavor_id" ]):
2295+ raise ModuleError (f"RBS volume with name '{ self .name } ' already exists. You cannot change its location or flavor." )
2296+ else :
2297+ self .volume_id = existing_volume ["id" ]
2298+ upd = self .update_volume ()
2299+ return upd
2300+ else :
2301+ if not (self .location_id and self .flavor_id and self .size ):
2302+ raise ModuleError (f"RBS volume with name '{ self .name } ' does not exist. "
2303+ "To create it, location_id (or location_code), flavor_id (or flavor_name) and size must be provided." )
2304+ if not self .checkmode :
2305+ response = self .api .create_rbs_volume (
2306+ name = self .name ,
2307+ location_id = self .location_id ,
2308+ flavor_id = self .flavor_id ,
2309+ size = self .size ,
2310+ labels = self .labels ,
2311+ )
2312+ self .volume_id = response .get ("id" )
2313+ new_volume = self .wait_for_active ()
2314+ result ["rbs_volume" ] = new_volume
2315+ else :
2316+ result ["rbs_volume" ] = {"id" : None ,
2317+ "name" : self .name ,
2318+ "location_id" : self .location_id ,
2319+ "location_code" : None ,
2320+ "flavor_id" : self .flavor_id ,
2321+ "size" : self .size ,
2322+ "labels" : self .labels ,
2323+ "status" : "creating" }
2324+ result ["changed" ] = True
2325+ return result
2326+
2327+ def delete_volume (self ):
2328+ no_volume = False
2329+ if self .name and not self .volume_id :
2330+ volume = self .api .get_rbs_volume_by_name (self .name )
2331+ if volume :
2332+ self .volume_id = volume ["id" ]
2333+ else :
2334+ no_volume = True
2335+ try :
2336+ volume = self .api .get_rbs_volume (self .volume_id )
2337+ except APIError404 :
2338+ no_volume = True
2339+ if not self .checkmode and not no_volume :
2340+ if volume ["status" ] != "removing" :
2341+ self .api .delete_rbs_volume (self .volume_id )
2342+ self .wait_for_disappearance ()
2343+ return {"changed" : not no_volume , "rbs_volume" : {}}
2344+
2345+ def wait_for_active (self ):
2346+ volume = self .api .get_rbs_volume (self .volume_id )
2347+ if self .wait == 0 :
2348+ return volume
2349+ start_time = time .time ()
2350+ while True :
2351+ if volume ["status" ] == "active" :
2352+ return volume
2353+ elapsed = time .time () - start_time
2354+ if elapsed > self .wait :
2355+ raise WaitError (
2356+ msg = f"Timeout waiting for RBS volume { self .volume_id } to become active after { elapsed :.2f} seconds." ,
2357+ timeout = elapsed ,
2358+ )
2359+ time .sleep (self .update_interval )
2360+ volume = self .api .get_rbs_volume (self .volume_id )
2361+
2362+ def wait_for_disappearance (self ):
2363+ if self .wait == 0 :
2364+ return
2365+ start_time = time .time ()
2366+ while True :
2367+ try :
2368+ self .api .get_rbs_volume (self .volume_id )
2369+ except APIError404 :
2370+ return []
2371+ elapsed = time .time () - start_time
2372+ if elapsed > self .wait :
2373+ raise WaitError (
2374+ msg = f"Timeout waiting for RBS volume { self .volume_id } to disappear after { elapsed :.2f} seconds." ,
2375+ timeout = elapsed ,
2376+ )
2377+ time .sleep (self .update_interval )
2378+
2379+
2380+ class ScRBSVolumeCredentialsInfo :
2381+ def __init__ (self , endpoint , token , volume_id , name ):
2382+ self .api = ScApi (token , endpoint )
2383+ self .volume_id = volume_id
2384+ self .name = name
2385+
2386+ def run (self ):
2387+ if self .name and not self .volume_id :
2388+ existing_volume = self .api .get_rbs_volume_by_name (self .name )
2389+ if existing_volume :
2390+ self .volume_id = existing_volume ["id" ]
2391+ else :
2392+ raise ModuleError (f"RBS volume with name '{ self .name } ' not found." )
2393+ rbs_volume_credentials = self .api .get_rbs_volume_credentials (self .volume_id )
2394+ return {
2395+ "changed" : False ,
2396+ "rbs_volume_credentials" : rbs_volume_credentials ,
2397+ }
2398+
2399+
2400+ class ScRBSVolumeCredentialsReset :
2401+ def __init__ (self , endpoint , token , wait , update_interval , checkmode , volume_id , name ):
2402+ self .api = ScApi (token , endpoint )
2403+ self .volume_id = volume_id
2404+ self .name = name
2405+ self .wait = wait
2406+ self .update_interval = update_interval
2407+ self .checkmode = checkmode
2408+
2409+ def run (self ):
2410+ if self .name and not self .volume_id :
2411+ existing_volume = self .api .get_rbs_volume_by_name (self .name )
2412+ if existing_volume :
2413+ self .volume_id = existing_volume ["id" ]
2414+ else :
2415+ raise ModuleError (f"RBS volume with name '{ self .name } ' not found." )
2416+ if not self .checkmode :
2417+ rbs_volume = self .api .reset_rbs_volume_credentials (self .volume_id )
2418+ if self .wait > 0 :
2419+ start_time = time .time ()
2420+ while True :
2421+ if rbs_volume ["status" ] == "active" :
2422+ break
2423+ elapsed = time .time () - start_time
2424+ if elapsed > self .wait :
2425+ raise WaitError (
2426+ msg = f"Timeout waiting for RBS volume { self .volume_id } to become active after { elapsed :.2f} seconds." ,
2427+ timeout = elapsed ,
2428+ )
2429+ time .sleep (self .update_interval )
2430+ rbs_volume = self .api .get_rbs_volume (self .volume_id )
2431+ rbs_volume_credentials = self .api .get_rbs_volume_credentials (self .volume_id )
2432+ return {
2433+ "changed" : True ,
2434+ "rbs_volume_credentials" : rbs_volume_credentials ,
2435+ }
2436+ return {
2437+ "changed" : True ,
2438+ "rbs_volume_credentials" : {},
2439+ }
0 commit comments