Skip to content

Commit 08822d4

Browse files
authored
test(generator/protobuf): add iam/v1 protos (#179)
Include the IAM protos to the Rust golden file sources. These both use external packages (`google.type`) and are used in the secretmanager service protos.
1 parent cf220b8 commit 08822d4

File tree

8 files changed

+798
-11
lines changed

8 files changed

+798
-11
lines changed

Cargo.lock

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ members = [
2121
"types",
2222
"gax",
2323
"generator/testdata/rust/openapi/golden",
24+
"generator/testdata/rust/gclient/golden/iam/v1",
2425
"generator/testdata/rust/gclient/golden/type",
2526
"generator/testdata/rust/gclient/golden/secretmanager",
2627
]

generator/cmd/main_test.go

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@ package main
1717
import (
1818
"errors"
1919
"flag"
20+
"fmt"
2021
"os"
2122
"os/exec"
2223
"path"
24+
"strings"
2325
"testing"
2426

2527
"github.com/googleapis/google-cloud-rust/generator/internal/genclient"
@@ -74,39 +76,59 @@ func TestRustFromProtobuf(t *testing.T) {
7476
)
7577

7678
type Config struct {
77-
Source string
78-
Name string
79+
Source string
80+
Name string
81+
ExtraOptions map[string]string
7982
}
8083

8184
configs := []Config{
82-
{
83-
Source: "../testdata/rust/gclient/protos",
84-
Name: "secretmanager",
85-
},
8685
{
8786
Source: "../testdata/googleapis/google/type",
8887
Name: "type",
8988
},
89+
{
90+
Source: "../testdata/googleapis/google/iam/v1",
91+
Name: "iam/v1",
92+
ExtraOptions: map[string]string{
93+
"package:gtype": "package=type-golden-gclient,path=../../type,source=google.type",
94+
},
95+
},
96+
{
97+
Source: "../testdata/rust/gclient/protos",
98+
Name: "secretmanager",
99+
ExtraOptions: map[string]string{
100+
"package:iam": "package=iam-v1-golden-gclient,path=../iam/v1,source=google.iam.v1",
101+
},
102+
},
90103
}
91104

92105
for _, config := range configs {
106+
depth := strings.Count(outDir, "/") + strings.Count(config.Name, "/") + 2
107+
toProjectRoot := ".."
108+
for range depth {
109+
toProjectRoot = path.Join(toProjectRoot, "..")
110+
}
93111
popts := &genclient.ParserOptions{
94112
Source: config.Source,
95113
Options: map[string]string{
96114
"googleapis-root": "../testdata/googleapis",
97115
"input-root": "../testdata",
98116
},
99117
}
118+
options := map[string]string{
119+
"package-name-override": strings.Replace(config.Name, "/", "-", -1) + "-golden-gclient",
120+
"package:gax_placeholder": fmt.Sprintf("package=types,path=%s/types,source=google.protobuf", toProjectRoot),
121+
"package:gax": fmt.Sprintf("package=gax,path=%s/gax", toProjectRoot),
122+
}
123+
for k, v := range config.ExtraOptions {
124+
options[k] = v
125+
}
100126
copts := &genclient.CodecOptions{
101127
Language: "rust",
102128
ProjectRoot: projectRoot,
103129
OutDir: path.Join(outDir, config.Name),
104130
TemplateDir: "../templates",
105-
Options: map[string]string{
106-
"package-name-override": config.Name + "-golden-gclient",
107-
"package:gax_placeholder": "package=types,path=../../../../../../types,source=google.protobuf",
108-
"package:gax": "package=gax,path=../../../../../../gax",
109-
},
131+
Options: options,
110132
}
111133
err := Generate("protobuf", popts, copts)
112134
if err != nil {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[package]
2+
name = "iam-v1-golden-gclient"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
serde = { version = "1.0.214", features = ["serde_derive"] }
8+
serde_with = "3.11.0"
9+
serde_json = "1.0.132"
10+
time = { version = "0.3.36", features = ["formatting", "parsing"] }
11+
reqwest = { version = "0.12.9", features = ["json"] }
12+
bytes = { version = "1.8.0", features = ["serde"] }
13+
gax = { path = "../../../../../../../gax", package = "gax" }
14+
gax_placeholder = { path = "../../../../../../../types", package = "types" }
15+
gtype = { path = "../../type", package = "type-golden-gclient" }
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# - Rust Client Library
2+
3+
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
#![allow(dead_code)]
2+
3+
use std::sync::Arc;
4+
5+
pub mod model;
6+
7+
#[derive(Clone, Debug)]
8+
pub struct Client {
9+
inner: Arc<ClientRef>,
10+
}
11+
12+
#[derive(Debug)]
13+
struct ClientRef {
14+
http_client: reqwest::Client,
15+
token: String,
16+
}
17+
18+
impl Client {
19+
pub fn new(tok: String) -> Self {
20+
let client = reqwest::Client::builder().build().unwrap();
21+
let inner = ClientRef {
22+
http_client: client,
23+
token: tok,
24+
};
25+
Self {
26+
inner: Arc::new(inner),
27+
}
28+
}
29+
30+
/// API Overview
31+
///
32+
///
33+
/// Manages Identity and Access Management (IAM) policies.
34+
///
35+
/// Any implementation of an API that offers access control features
36+
/// implements the google.iam.v1.IAMPolicy interface.
37+
///
38+
/// ## Data model
39+
///
40+
/// Access control is applied when a principal (user or service account), takes
41+
/// some action on a resource exposed by a service. Resources, identified by
42+
/// URI-like names, are the unit of access control specification. Service
43+
/// implementations can choose the granularity of access control and the
44+
/// supported permissions for their resources.
45+
/// For example one database service may allow access control to be
46+
/// specified only at the Table level, whereas another might allow access control
47+
/// to also be specified at the Column level.
48+
///
49+
/// ## Policy Structure
50+
///
51+
/// See google.iam.v1.Policy
52+
///
53+
/// This is intentionally not a CRUD style API because access control policies
54+
/// are created and deleted implicitly with the resources to which they are
55+
/// attached.
56+
pub fn iam_policy(&self) -> Iampolicy {
57+
Iampolicy {
58+
client: self.clone(),
59+
base_path: "https://iam-meta-api.googleapis.com/".to_string(),
60+
}
61+
}
62+
}
63+
64+
/// API Overview
65+
///
66+
///
67+
/// Manages Identity and Access Management (IAM) policies.
68+
///
69+
/// Any implementation of an API that offers access control features
70+
/// implements the google.iam.v1.IAMPolicy interface.
71+
///
72+
/// ## Data model
73+
///
74+
/// Access control is applied when a principal (user or service account), takes
75+
/// some action on a resource exposed by a service. Resources, identified by
76+
/// URI-like names, are the unit of access control specification. Service
77+
/// implementations can choose the granularity of access control and the
78+
/// supported permissions for their resources.
79+
/// For example one database service may allow access control to be
80+
/// specified only at the Table level, whereas another might allow access control
81+
/// to also be specified at the Column level.
82+
///
83+
/// ## Policy Structure
84+
///
85+
/// See google.iam.v1.Policy
86+
///
87+
/// This is intentionally not a CRUD style API because access control policies
88+
/// are created and deleted implicitly with the resources to which they are
89+
/// attached.
90+
#[derive(Debug)]
91+
pub struct Iampolicy {
92+
client: Client,
93+
base_path: String,
94+
}
95+
96+
impl Iampolicy {
97+
/// Sets the access control policy on the specified resource. Replaces any
98+
/// existing policy.
99+
///
100+
/// Can return `NOT_FOUND`, `INVALID_ARGUMENT`, and `PERMISSION_DENIED` errors.
101+
pub async fn set_iam_policy(
102+
&self,
103+
req: crate::model::SetIamPolicyRequest,
104+
) -> Result<crate::model::Policy, Box<dyn std::error::Error>> {
105+
let query_parameters = [None::<(&str, String)>; 0];
106+
let client = self.client.inner.clone();
107+
let res = client
108+
.http_client
109+
.post(format!(
110+
"{}/v1/{}:setIamPolicy",
111+
self.base_path, req.resource,
112+
))
113+
.query(&[("alt", "json")])
114+
.query(
115+
&query_parameters
116+
.into_iter()
117+
.flatten()
118+
.collect::<Vec<(&str, String)>>(),
119+
)
120+
.bearer_auth(&client.token)
121+
.json(&req)
122+
.send()
123+
.await?;
124+
if !res.status().is_success() {
125+
return Err(
126+
"sorry the api you are looking for is not available, please try again".into(),
127+
);
128+
}
129+
let response = res.json::<crate::model::Policy>().await?;
130+
Ok(response)
131+
}
132+
133+
/// Gets the access control policy for a resource.
134+
/// Returns an empty policy if the resource exists and does not have a policy
135+
/// set.
136+
pub async fn get_iam_policy(
137+
&self,
138+
req: crate::model::GetIamPolicyRequest,
139+
) -> Result<crate::model::Policy, Box<dyn std::error::Error>> {
140+
let query_parameters = [None::<(&str, String)>; 0];
141+
let client = self.client.inner.clone();
142+
let res = client
143+
.http_client
144+
.post(format!(
145+
"{}/v1/{}:getIamPolicy",
146+
self.base_path, req.resource,
147+
))
148+
.query(&[("alt", "json")])
149+
.query(
150+
&query_parameters
151+
.into_iter()
152+
.flatten()
153+
.collect::<Vec<(&str, String)>>(),
154+
)
155+
.bearer_auth(&client.token)
156+
.json(&req)
157+
.send()
158+
.await?;
159+
if !res.status().is_success() {
160+
return Err(
161+
"sorry the api you are looking for is not available, please try again".into(),
162+
);
163+
}
164+
let response = res.json::<crate::model::Policy>().await?;
165+
Ok(response)
166+
}
167+
168+
/// Returns permissions that a caller has on the specified resource.
169+
/// If the resource does not exist, this will return an empty set of
170+
/// permissions, not a `NOT_FOUND` error.
171+
///
172+
/// Note: This operation is designed to be used for building permission-aware
173+
/// UIs and command-line tools, not for authorization checking. This operation
174+
/// may "fail open" without warning.
175+
pub async fn test_iam_permissions(
176+
&self,
177+
req: crate::model::TestIamPermissionsRequest,
178+
) -> Result<crate::model::TestIamPermissionsResponse, Box<dyn std::error::Error>> {
179+
let query_parameters = [None::<(&str, String)>; 0];
180+
let client = self.client.inner.clone();
181+
let res = client
182+
.http_client
183+
.post(format!(
184+
"{}/v1/{}:testIamPermissions",
185+
self.base_path, req.resource,
186+
))
187+
.query(&[("alt", "json")])
188+
.query(
189+
&query_parameters
190+
.into_iter()
191+
.flatten()
192+
.collect::<Vec<(&str, String)>>(),
193+
)
194+
.bearer_auth(&client.token)
195+
.json(&req)
196+
.send()
197+
.await?;
198+
if !res.status().is_success() {
199+
return Err(
200+
"sorry the api you are looking for is not available, please try again".into(),
201+
);
202+
}
203+
let response = res
204+
.json::<crate::model::TestIamPermissionsResponse>()
205+
.await?;
206+
Ok(response)
207+
}
208+
}

0 commit comments

Comments
 (0)