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}