openstack/
cloud.rs

1// Copyright 2018-2019 Dmitry Tantsur <divius.inside@gmail.com>
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Cloud API.
16
17#[allow(unused_imports)]
18use futures::io::AsyncRead;
19#[allow(unused_imports)]
20use std::io;
21
22use super::auth::AuthType;
23#[cfg(feature = "baremetal")]
24use super::baremetal;
25#[cfg(feature = "block-storage")]
26use super::block_storage::{NewVolume, Volume, VolumeQuery};
27#[allow(unused_imports)]
28use super::common::{ContainerRef, FlavorRef, NetworkRef};
29#[cfg(feature = "compute")]
30use super::compute::{
31    Flavor, FlavorQuery, FlavorSummary, KeyPair, KeyPairQuery, NewKeyPair, NewServer, Server,
32    ServerQuery, ServerSummary,
33};
34#[cfg(feature = "image")]
35use super::image::{Image, ImageQuery};
36#[cfg(feature = "network")]
37use super::network::{
38    FloatingIp, FloatingIpQuery, Network, NetworkQuery, NewFloatingIp, NewNetwork, NewPort,
39    NewRouter, NewSubnet, Port, PortQuery, Router, RouterQuery, Subnet, SubnetQuery,
40};
41#[cfg(feature = "object-storage")]
42use super::object_storage::{Container, ContainerQuery, NewObject, Object, ObjectQuery};
43use super::session::Session;
44use super::{EndpointFilters, InterfaceType, Result};
45
46/// OpenStack cloud API.
47///
48/// Provides high-level API for working with OpenStack clouds.
49#[derive(Debug, Clone)]
50pub struct Cloud {
51    session: Session,
52}
53
54impl Cloud {
55    /// Create a new cloud object with a given authentication plugin.
56    ///
57    /// See [`auth` module](auth/index.html) for details on how to authenticate
58    /// against OpenStack clouds.
59    ///
60    /// # Example
61    ///
62    /// ```rust,no_run
63    /// async fn cloud() -> openstack::Result<openstack::Cloud> {
64    ///     let scope = openstack::auth::Scope::Project {
65    ///         project: openstack::IdOrName::from_name("project1"),
66    ///         domain: Some(openstack::IdOrName::from_name("Default")),
67    ///     };
68    ///     let auth = openstack::auth::Password::new(
69    ///             "https://cloud.example.com",
70    ///             "user1", "pa$$word", "Default")
71    ///         .expect("Invalid authentication URL")
72    ///         .with_scope(scope);
73    ///     openstack::Cloud::new(auth).await
74    /// }
75    /// ```
76    ///
77    /// # See Also
78    ///
79    /// * [from_config](#method.from_config) to create a Cloud from clouds.yaml
80    /// * [from_env](#method.from_env) to create a Cloud from environment variables
81    pub async fn new<Auth: AuthType + 'static>(auth_type: Auth) -> Result<Cloud> {
82        Ok(Cloud {
83            session: Session::new(auth_type).await?,
84        })
85    }
86
87    /// Create a new cloud object from a configuration file
88    ///
89    /// # Example
90    ///
91    /// ```rust,no_run
92    /// # async fn cloud_from_config() -> openstack::Result<()> {
93    /// let os = openstack::Cloud::from_config("cloud-1").await?;
94    /// # Ok(()) }
95    /// ```
96    pub async fn from_config<S: AsRef<str>>(cloud_name: S) -> Result<Cloud> {
97        Ok(Cloud {
98            session: Session::from_config(cloud_name).await?,
99        })
100    }
101
102    /// Create a new cloud object from environment variables.
103    ///
104    /// # Example
105    ///
106    /// ```rust,no_run
107    /// # async fn cloud_from_env() -> openstack::Result<()> {
108    /// let os = openstack::Cloud::from_env().await?;
109    /// # Ok(()) }
110    /// ```
111    pub async fn from_env() -> Result<Cloud> {
112        Ok(Cloud {
113            session: Session::from_env().await?,
114        })
115    }
116
117    /// Endpoint filters for this cloud.
118    #[inline]
119    pub fn endpoint_filters(&self) -> &EndpointFilters {
120        self.session.endpoint_filters()
121    }
122
123    /// Modify endpoint filters for this cloud.
124    ///
125    /// # Example
126    ///
127    /// ```rust,no_run
128    /// async fn cloud_from_env() -> openstack::Result<openstack::Cloud> {
129    ///     let mut cloud = openstack::Cloud::from_env().await?;
130    ///     {
131    ///         let mut filters = cloud.endpoint_filters_mut();
132    ///         filters.set_region("internal-1");
133    ///         // Give priority to internal endpoints.
134    ///         filters.set_interfaces(&[
135    ///             openstack::InterfaceType::Internal,
136    ///             openstack::InterfaceType::Public,
137    ///         ][..])
138    ///     }
139    ///     Ok(cloud)
140    /// }
141    /// ```
142    ///
143    /// Removes cached endpoint information and detaches this object from a shared `Session`.
144    pub fn endpoint_filters_mut(&mut self) -> &mut EndpointFilters {
145        self.session.endpoint_filters_mut()
146    }
147
148    /// Convert this cloud into one using the given endpoint interface.
149    ///
150    /// # Example
151    ///
152    /// ```rust,no_run
153    /// async fn cloud_from_env() -> openstack::Result<openstack::Cloud> {
154    ///     openstack::Cloud::from_env().await
155    ///         .map(|os| os.with_endpoint_interface(openstack::InterfaceType::Internal))
156    /// }
157    /// ```
158    ///
159    /// Removes cached endpoint information and detaches this object from a shared `Session`.
160    pub fn with_endpoint_interface(mut self, endpoint_interface: InterfaceType) -> Cloud {
161        self.session.set_endpoint_interface(endpoint_interface);
162        self
163    }
164
165    /// Convert this cloud into one using the given endpoint filters.
166    ///
167    /// Removes cached endpoint information and detaches this object from a shared `Session`.
168    #[inline]
169    pub fn with_endpoint_filters(mut self, endpoint_filters: EndpointFilters) -> Cloud {
170        *self.endpoint_filters_mut() = endpoint_filters;
171        self
172    }
173
174    /// Refresh this `Cloud` object (renew token, refetch service catalog, etc).
175    pub async fn refresh(&mut self) -> Result<()> {
176        self.session.refresh().await
177    }
178
179    /// Create a new container.
180    ///
181    /// If the container already exists, this call returns successfully.
182    #[cfg(feature = "object-storage")]
183    pub async fn create_container<Id: AsRef<str>>(&self, name: Id) -> Result<Container> {
184        Container::create(self.session.clone(), name).await
185    }
186
187    /// Create a new object.
188    #[cfg(feature = "object-storage")]
189    pub async fn create_object<C, Id, R>(&self, container: C, name: Id, body: R) -> Result<Object>
190    where
191        C: Into<ContainerRef>,
192        Id: AsRef<str>,
193        R: AsyncRead + Send + Sync + 'static,
194    {
195        Object::create(self.session.clone(), container, name, body).await
196    }
197
198    /// Build a query against node list.
199    ///
200    /// The returned object is a builder that should be used to construct
201    /// the query.
202    #[cfg(feature = "baremetal")]
203    #[inline]
204    pub fn find_baremetal_nodes(&self) -> baremetal::NodeQuery {
205        baremetal::NodeQuery::new(self.session.clone())
206    }
207
208    /// Build a query against container list.
209    ///
210    /// The returned object is a builder that should be used to construct
211    /// the query.
212    #[cfg(feature = "object-storage")]
213    #[inline]
214    pub fn find_containers(&self) -> ContainerQuery {
215        ContainerQuery::new(self.session.clone())
216    }
217
218    /// Build a query against object list.
219    ///
220    /// The returned object is a builder that should be used to construct
221    /// the query.
222    #[cfg(feature = "object-storage")]
223    pub fn find_objects<C>(&self, container: C) -> ObjectQuery
224    where
225        C: Into<ContainerRef>,
226    {
227        ObjectQuery::new(self.session.clone(), container)
228    }
229
230    /// Build a query against flavor list.
231    ///
232    /// The returned object is a builder that should be used to construct
233    /// the query.
234    #[cfg(feature = "compute")]
235    pub fn find_flavors(&self) -> FlavorQuery {
236        FlavorQuery::new(self.session.clone())
237    }
238
239    /// Build a query against floating IP list.
240    ///
241    /// The returned object is a builder that should be used to construct
242    /// the query.
243    #[cfg(feature = "network")]
244    pub fn find_floating_ips(&self) -> FloatingIpQuery {
245        FloatingIpQuery::new(self.session.clone())
246    }
247
248    /// Build a query against image list.
249    ///
250    /// The returned object is a builder that should be used to construct
251    /// the query.
252    #[cfg(feature = "image")]
253    pub fn find_images(&self) -> ImageQuery {
254        ImageQuery::new(self.session.clone())
255    }
256
257    /// Build a query against key pairs list.
258    ///
259    /// The returned object is a builder that should be used to construct
260    /// the query.
261    #[cfg(feature = "compute")]
262    pub fn find_keypairs(&self) -> KeyPairQuery {
263        KeyPairQuery::new(self.session.clone())
264    }
265
266    /// Build a query against network list.
267    ///
268    /// The returned object is a builder that should be used to construct
269    /// the query.
270    #[cfg(feature = "network")]
271    pub fn find_networks(&self) -> NetworkQuery {
272        NetworkQuery::new(self.session.clone())
273    }
274
275    /// Build a query against port list.
276    ///
277    /// The returned object is a builder that should be used to construct
278    /// the query.
279    #[cfg(feature = "network")]
280    pub fn find_ports(&self) -> PortQuery {
281        PortQuery::new(self.session.clone())
282    }
283
284    /// Build a query against router list.
285    ///
286    /// The returned object is a builder that should be used to construct
287    /// the query.
288    #[cfg(feature = "network")]
289    pub fn find_routers(&self) -> RouterQuery {
290        RouterQuery::new(self.session.clone())
291    }
292
293    /// Build a query against server list.
294    ///
295    /// The returned object is a builder that should be used to construct
296    /// the query.
297    ///
298    /// # Example
299    ///
300    /// Sorting servers by `access_ip_v4` and getting first 5 results:
301    ///
302    /// ```rust,no_run
303    /// use openstack;
304    ///
305    /// # async fn async_wrapper() {
306    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
307    /// let sorting = openstack::compute::ServerSortKey::AccessIpv4;
308    /// let server_list = os.find_servers()
309    ///     .sort_by(openstack::Sort::Asc(sorting)).with_limit(5)
310    ///     .all().await.expect("Unable to fetch servers");
311    /// # }
312    /// ```
313    #[cfg(feature = "compute")]
314    pub fn find_servers(&self) -> ServerQuery {
315        ServerQuery::new(self.session.clone())
316    }
317
318    /// Build a query against subnet list.
319    ///
320    /// The returned object is a builder that should be used to construct
321    /// the query.
322    #[cfg(feature = "network")]
323    pub fn find_subnets(&self) -> SubnetQuery {
324        SubnetQuery::new(self.session.clone())
325    }
326
327    /// Build a query against volume list.
328    ///
329    /// The returned object is a builder that should be used to construct
330    /// the query.
331    #[cfg(feature = "block-storage")]
332    pub fn find_volumes(&self) -> VolumeQuery {
333        VolumeQuery::new(self.session.clone())
334    }
335
336    /// Get bare metal node by its name or UUID.
337    #[cfg(feature = "baremetal")]
338    pub async fn get_baremetal_node<Id: AsRef<str>>(
339        &self,
340        id_or_name: Id,
341    ) -> Result<baremetal::Node> {
342        baremetal::Node::load(self.session.clone(), id_or_name).await
343    }
344
345    /// Get object container metadata by its name.
346    ///
347    /// # Example
348    ///
349    /// ```rust,no_run
350    /// use openstack;
351    ///
352    /// # async fn async_wrapper() {
353    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
354    /// let ctr = os.get_container("www").await.expect("Unable to get a container");
355    /// # }
356    /// ```
357    #[cfg(feature = "object-storage")]
358    pub async fn get_container<Id: AsRef<str>>(&self, name: Id) -> Result<Container> {
359        Container::load(self.session.clone(), name).await
360    }
361
362    /// Get object metadata by its name.
363    ///
364    /// # Example
365    ///
366    /// ```rust,no_run
367    /// use openstack;
368    ///
369    /// # async fn async_wrapper() {
370    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
371    /// let obj = os.get_object("www", "/foo/bar").await.expect("Unable to get an object");
372    /// # }
373    /// ```
374    #[cfg(feature = "object-storage")]
375    pub async fn get_object<C, Id>(&self, container: C, name: Id) -> Result<Object>
376    where
377        C: Into<ContainerRef>,
378        Id: AsRef<str>,
379    {
380        Object::load(self.session.clone(), container, name).await
381    }
382
383    /// Find a flavor by its name or ID.
384    ///
385    /// # Example
386    ///
387    /// ```rust,no_run
388    /// use openstack;
389    ///
390    /// # async fn async_wrapper() {
391    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
392    /// let server = os.get_flavor("m1.medium").await.expect("Unable to get a flavor");
393    /// # }
394    /// ```
395    #[cfg(feature = "compute")]
396    pub async fn get_flavor<Id: AsRef<str>>(&self, id_or_name: Id) -> Result<Flavor> {
397        Flavor::load(self.session.clone(), id_or_name).await
398    }
399
400    /// Find a floating IP by its ID.
401    ///
402    /// # Example
403    ///
404    /// ```rust,no_run
405    /// use openstack;
406    ///
407    /// # async fn async_wrapper() {
408    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
409    /// let server = os.get_floating_ip("031e08c7-2ca7-4c0b-9923-030c8d946ba4")
410    ///     .await
411    ///     .expect("Unable to get a floating IP");
412    /// # }
413    /// ```
414    #[cfg(feature = "network")]
415    pub async fn get_floating_ip<Id: AsRef<str>>(&self, id: Id) -> Result<FloatingIp> {
416        FloatingIp::load(self.session.clone(), id).await
417    }
418
419    /// Find an image by its name or ID.
420    ///
421    /// # Example
422    ///
423    /// ```rust,no_run
424    /// use openstack;
425    ///
426    /// # async fn async_wrapper() {
427    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
428    /// let server = os.get_image("centos7").await.expect("Unable to get a image");
429    /// # }
430    /// ```
431    #[cfg(feature = "image")]
432    pub async fn get_image<Id: AsRef<str>>(&self, id_or_name: Id) -> Result<Image> {
433        Image::new(self.session.clone(), id_or_name).await
434    }
435
436    /// Find a key pair by its name or ID.
437    ///
438    /// # Example
439    ///
440    /// ```rust,no_run
441    /// use openstack;
442    ///
443    /// # async fn async_wrapper() {
444    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
445    /// let server = os.get_keypair("default").await.expect("Unable to get a key pair");
446    /// # }
447    /// ```
448    #[cfg(feature = "compute")]
449    pub async fn get_keypair<Id: AsRef<str>>(&self, name: Id) -> Result<KeyPair> {
450        KeyPair::new(self.session.clone(), name).await
451    }
452
453    /// Find an network by its name or ID.
454    ///
455    /// # Example
456    ///
457    /// ```rust,no_run
458    /// use openstack;
459    ///
460    /// # async fn async_wrapper() {
461    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
462    /// let server = os.get_network("centos7").await.expect("Unable to get a network");
463    /// # }
464    /// ```
465    #[cfg(feature = "network")]
466    pub async fn get_network<Id: AsRef<str>>(&self, id_or_name: Id) -> Result<Network> {
467        Network::load(self.session.clone(), id_or_name).await
468    }
469
470    /// Find an port by its name or ID.
471    ///
472    /// # Example
473    ///
474    /// ```rust,no_run
475    /// use openstack;
476    ///
477    /// # async fn async_wrapper() {
478    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
479    /// let server = os.get_port("4d9c1710-fa02-49f9-8218-291024ef4140")
480    ///     .await
481    ///     .expect("Unable to get a port");
482    /// # }
483    /// ```
484    #[cfg(feature = "network")]
485    pub async fn get_port<Id: AsRef<str>>(&self, id_or_name: Id) -> Result<Port> {
486        Port::load(self.session.clone(), id_or_name).await
487    }
488
489    /// Find a router by its name or ID.
490    ///
491    /// # Example
492    ///
493    /// ```rust,no_run
494    /// use openstack;
495    ///
496    /// # async fn async_wrapper() {
497    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
498    /// let router = os.get_router("router_name").await.expect("Unable to get a router");
499    /// # }
500    /// ```
501    #[cfg(feature = "network")]
502    pub async fn get_router<Id: AsRef<str>>(&self, id_or_name: Id) -> Result<Router> {
503        Router::load(self.session.clone(), id_or_name).await
504    }
505
506    /// Find a server by its name or ID.
507    ///
508    /// # Example
509    ///
510    /// ```rust,no_run
511    /// use openstack;
512    ///
513    /// # async fn async_wrapper() {
514    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
515    /// let server = os.get_server("8a1c355b-2e1e-440a-8aa8-f272df72bc32")
516    ///     .await
517    ///     .expect("Unable to get a server");
518    /// # }
519    /// ```
520    #[cfg(feature = "compute")]
521    pub async fn get_server<Id: AsRef<str>>(&self, id_or_name: Id) -> Result<Server> {
522        Server::load(self.session.clone(), id_or_name).await
523    }
524
525    /// Find an subnet by its name or ID.
526    ///
527    /// # Example
528    ///
529    /// ```rust,no_run
530    /// use openstack;
531    ///
532    /// # async fn async_wrapper() {
533    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
534    /// let server = os.get_subnet("private-subnet")
535    ///     .await
536    ///     .expect("Unable to get a subnet");
537    /// # }
538    /// ```
539    #[cfg(feature = "network")]
540    pub async fn get_subnet<Id: AsRef<str>>(&self, id_or_name: Id) -> Result<Subnet> {
541        Subnet::load(self.session.clone(), id_or_name).await
542    }
543
544    /// Find an volume by its name or ID.
545    ///
546    /// # Example
547    ///
548    /// ```rust,no_run
549    /// use openstack;
550    ///
551    /// # async fn async_wrapper() {
552    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
553    /// let volume = os.get_volume("my-first-volume").await.expect("Unable to get a volume");
554    /// # }
555    /// ```
556    #[cfg(feature = "block-storage")]
557    pub async fn get_volume<Id: AsRef<str>>(&self, id_or_name: Id) -> Result<Volume> {
558        Volume::new(self.session.clone(), id_or_name).await
559    }
560
561    /// List all baremetal nodes.
562    ///
563    /// This call can yield a lot of results, use the
564    /// [find_baremetal_nodes](#method.find_baremetal_nodes) call to limit the number of
565    /// baremetal nodes to receive.
566    ///
567    /// # Example
568    ///
569    /// ```rust,no_run
570    /// use openstack;
571    ///
572    /// # async fn async_wrapper() {
573    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
574    /// let server_list = os.list_baremetal_nodes().await.expect("Unable to fetch nodes");
575    /// # }
576    /// ```
577    #[cfg(feature = "baremetal")]
578    pub async fn list_baremetal_nodes(&self) -> Result<Vec<baremetal::NodeSummary>> {
579        self.find_baremetal_nodes().all().await
580    }
581
582    /// List all containers.
583    ///
584    /// This call can yield a lot of results, use the
585    /// [find_containers](#method.find_containers) call to limit the number of
586    /// containers to receive.
587    ///
588    /// # Example
589    ///
590    /// ```rust,no_run
591    /// use openstack;
592    ///
593    /// # async fn async_wrapper() {
594    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
595    /// let server_list = os.list_containers().await.expect("Unable to fetch containers");
596    /// # }
597    /// ```
598    #[cfg(feature = "object-storage")]
599    pub async fn list_containers(&self) -> Result<Vec<Container>> {
600        self.find_containers().all().await
601    }
602
603    /// List all objects.
604    ///
605    /// This call can yield a lot of results, use the
606    /// [find_objects](#method.find_objects) call to limit the number of
607    /// objects to receive.
608    ///
609    /// # Example
610    ///
611    /// ```rust,no_run
612    /// use openstack;
613    ///
614    /// # async fn async_wrapper() {
615    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
616    /// let server_list = os.list_objects("www").await.expect("Unable to fetch objects");
617    /// # }
618    /// ```
619    #[cfg(feature = "object-storage")]
620    pub async fn list_objects<C>(&self, container: C) -> Result<Vec<Object>>
621    where
622        C: Into<ContainerRef>,
623    {
624        self.find_objects(container).all().await
625    }
626
627    /// List all flavors.
628    ///
629    /// This call can yield a lot of results, use the
630    /// [find_flavors](#method.find_flavors) call to limit the number of
631    /// flavors to receive.
632    ///
633    /// # Example
634    ///
635    /// ```rust,no_run
636    /// use openstack;
637    ///
638    /// # async fn async_wrapper() {
639    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
640    /// let server_list = os.list_flavors().await.expect("Unable to fetch flavors");
641    /// # }
642    /// ```
643    #[cfg(feature = "compute")]
644    pub async fn list_flavors(&self) -> Result<Vec<FlavorSummary>> {
645        self.find_flavors().all().await
646    }
647
648    /// List all floating IPs
649    ///
650    /// This call can yield a lot of results, use the
651    /// [find_floating_ips](#method.find_floating_ips) call to limit the number of
652    /// networks to receive.
653    ///
654    /// # Example
655    ///
656    /// ```rust,no_run
657    /// use openstack;
658    ///
659    /// # async fn async_wrapper() {
660    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
661    /// let server_list = os.list_floating_ips().await.expect("Unable to fetch floating IPs");
662    /// # }
663    /// ```
664    #[cfg(feature = "network")]
665    pub async fn list_floating_ips(&self) -> Result<Vec<FloatingIp>> {
666        self.find_floating_ips().all().await
667    }
668
669    /// List all images.
670    ///
671    /// This call can yield a lot of results, use the
672    /// [find_images](#method.find_images) call to limit the number of
673    /// images to receive.
674    ///
675    /// # Example
676    ///
677    /// ```rust,no_run
678    /// use openstack;
679    ///
680    /// # async fn async_wrapper() {
681    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
682    /// let server_list = os.list_images().await.expect("Unable to fetch images");
683    /// # }
684    /// ```
685    #[cfg(feature = "image")]
686    pub async fn list_images(&self) -> Result<Vec<Image>> {
687        self.find_images().all().await
688    }
689
690    /// List all key pairs.
691    ///
692    /// # Example
693    ///
694    /// ```rust,no_run
695    /// use openstack;
696    ///
697    /// # async fn async_wrapper() {
698    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
699    /// let result = os.list_keypairs().await.expect("Unable to fetch key pairs");
700    /// # }
701    /// ```
702    #[cfg(feature = "compute")]
703    pub async fn list_keypairs(&self) -> Result<Vec<KeyPair>> {
704        self.find_keypairs().all().await
705    }
706
707    /// List all networks.
708    ///
709    /// This call can yield a lot of results, use the
710    /// [find_networks](#method.find_networks) call to limit the number of
711    /// networks to receive.
712    ///
713    /// # Example
714    ///
715    /// ```rust,no_run
716    /// use openstack;
717    ///
718    /// # async fn async_wrapper() {
719    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
720    /// let server_list = os.list_networks().await.expect("Unable to fetch networks");
721    /// # }
722    /// ```
723    #[cfg(feature = "network")]
724    pub async fn list_networks(&self) -> Result<Vec<Network>> {
725        self.find_networks().all().await
726    }
727
728    /// List all ports.
729    ///
730    /// This call can yield a lot of results, use the
731    /// [find_ports](#method.find_ports) call to limit the number of
732    /// ports to receive.
733    ///
734    /// # Example
735    ///
736    /// ```rust,no_run
737    /// use openstack;
738    ///
739    /// # async fn async_wrapper() {
740    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
741    /// let server_list = os.list_ports().await.expect("Unable to fetch ports");
742    /// # }
743    /// ```
744    #[cfg(feature = "network")]
745    pub async fn list_ports(&self) -> Result<Vec<Port>> {
746        self.find_ports().all().await
747    }
748
749    /// List all routers.
750    ///
751    /// This call can yield a lot of results, use the
752    /// [find_routers](#method.find_routers) call to limit the number of
753    /// routers to receive.
754    ///
755    /// # Example
756    ///
757    /// ```rust,no_run
758    /// use openstack;
759    ///
760    /// # async fn async_wrapper() {
761    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
762    /// let router_list = os.list_routers().await.expect("Unable to fetch routers");
763    /// # }
764    /// ```
765    #[cfg(feature = "network")]
766    pub async fn list_routers(&self) -> Result<Vec<Router>> {
767        self.find_routers().all().await
768    }
769
770    /// List all servers.
771    ///
772    /// This call can yield a lot of results, use the
773    /// [find_servers](#method.find_servers) call to limit the number of
774    /// servers to receive.
775    ///
776    /// # Example
777    ///
778    /// ```rust,no_run
779    /// use openstack;
780    ///
781    /// # async fn async_wrapper() {
782    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
783    /// let server_list = os.list_servers().await.expect("Unable to fetch servers");
784    /// # }
785    /// ```
786    #[cfg(feature = "compute")]
787    pub async fn list_servers(&self) -> Result<Vec<ServerSummary>> {
788        self.find_servers().all().await
789    }
790
791    /// List all subnets.
792    ///
793    /// This call can yield a lot of results, use the
794    /// [find_subnets](#method.find_subnets) call to limit the number of
795    /// subnets to receive.
796    ///
797    /// # Example
798    ///
799    /// ```rust,no_run
800    /// use openstack;
801    ///
802    /// # async fn async_wrapper() {
803    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
804    /// let server_list = os.list_subnets().await.expect("Unable to fetch subnets");
805    /// # }
806    /// ```
807    #[cfg(feature = "network")]
808    pub async fn list_subnets(&self) -> Result<Vec<Subnet>> {
809        self.find_subnets().all().await
810    }
811
812    /// List all volumes.
813    #[cfg(feature = "block-storage")]
814    pub async fn list_volumes(&self) -> Result<Vec<Volume>> {
815        self.find_volumes().all().await
816    }
817
818    /// Prepare a new object for creation.
819    ///
820    /// This call returns a `NewObject` object, which is a builder
821    /// to create object in object storage.
822    #[cfg(feature = "object-storage")]
823    pub fn new_object<C, O, B>(&self, container: C, object: O, body: B) -> NewObject<B>
824    where
825        C: Into<ContainerRef>,
826        O: Into<String>,
827        B: AsyncRead + Sync + Send + 'static,
828    {
829        NewObject::new(self.session.clone(), container.into(), object.into(), body)
830    }
831
832    /// Prepare a new floating IP for creation.
833    ///
834    /// This call returns a `NewFloatingIp` object, which is a builder
835    /// to populate floating IP fields.
836    #[cfg(feature = "network")]
837    pub fn new_floating_ip<N>(&self, floating_network: N) -> NewFloatingIp
838    where
839        N: Into<NetworkRef>,
840    {
841        NewFloatingIp::new(self.session.clone(), floating_network.into())
842    }
843
844    /// Prepare a new key pair for creation.
845    ///
846    /// This call returns a `NewKeyPair` object, which is a builder to populate
847    /// key pair fields.
848    #[cfg(feature = "compute")]
849    pub fn new_keypair<S>(&self, name: S) -> NewKeyPair
850    where
851        S: Into<String>,
852    {
853        NewKeyPair::new(self.session.clone(), name.into())
854    }
855
856    /// Prepare a new network for creation.
857    ///
858    /// This call returns a `NewNetwork` object, which is a builder to populate
859    /// network fields.
860    #[cfg(feature = "network")]
861    pub fn new_network(&self) -> NewNetwork {
862        NewNetwork::new(self.session.clone())
863    }
864
865    /// Prepare a new port for creation.
866    ///
867    /// This call returns a `NewPort` object, which is a builder to populate
868    /// port fields.
869    #[cfg(feature = "network")]
870    pub fn new_port<N>(&self, network: N) -> NewPort
871    where
872        N: Into<NetworkRef>,
873    {
874        NewPort::new(self.session.clone(), network.into())
875    }
876
877    /// Prepare a new router for creation.
878    ///
879    /// This call returns a `NewRouter` object, which is a builder to populate
880    /// router fields.
881    #[cfg(feature = "network")]
882    pub fn new_router(&self) -> NewRouter {
883        NewRouter::new(self.session.clone())
884    }
885
886    /// Prepare a new server for creation.
887    ///
888    /// This call returns a `NewServer` object, which is a builder to populate
889    /// server fields.
890    #[cfg(feature = "compute")]
891    pub fn new_server<S, F>(&self, name: S, flavor: F) -> NewServer
892    where
893        S: Into<String>,
894        F: Into<FlavorRef>,
895    {
896        NewServer::new(self.session.clone(), name.into(), flavor.into())
897    }
898
899    /// Prepare a new volume for creation.
900    ///
901    /// This call returns a `NewVolume` object, which is a builder to populate
902    /// volume fields.
903    #[cfg(feature = "block-storage")]
904    pub fn new_volume<U>(&self, size: U) -> NewVolume
905    where
906        U: Into<u64>,
907    {
908        NewVolume::new(self.session.clone(), size.into())
909    }
910
911    /// Prepare a new subnet for creation.
912    ///
913    /// This call returns a `NewSubnet` object, which is a builder to populate
914    /// subnet fields.
915    ///
916    /// # Example
917    ///
918    /// ```rust,no_run
919    /// extern crate ipnet;
920    /// extern crate openstack;
921    /// use std::net;
922    ///
923    /// # async fn async_wrapper() {
924    /// let os = openstack::Cloud::from_env().await.expect("Unable to authenticate");
925    /// let cidr = ipnet::Ipv4Net::new(net::Ipv4Addr::new(192, 168, 1, 0), 24)
926    ///     .unwrap().into();
927    /// let new_subnet = os.new_subnet("private-net", cidr)
928    ///     .with_name("private-subnet")
929    ///     .create().await.expect("Unable to create subnet");
930    /// # }
931    /// ```
932    #[cfg(feature = "network")]
933    pub fn new_subnet<N>(&self, network: N, cidr: ipnet::IpNet) -> NewSubnet
934    where
935        N: Into<NetworkRef>,
936    {
937        NewSubnet::new(self.session.clone(), network.into(), cidr)
938    }
939}
940
941impl From<Session> for Cloud {
942    fn from(value: Session) -> Cloud {
943        Cloud { session: value }
944    }
945}