Skip to content

Commit 224a318

Browse files
SCANPY-120 Use the new region URLs (#170)
1 parent 2fd5606 commit 224a318

File tree

3 files changed

+93
-22
lines changed

3 files changed

+93
-22
lines changed

src/pysonar_scanner/api.py

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,12 @@
3131
SONAR_REGION,
3232
Key,
3333
)
34-
from pysonar_scanner.exceptions import MissingKeyException, SonarQubeApiException
34+
from pysonar_scanner.exceptions import MissingKeyException, SonarQubeApiException, InconsistentConfiguration
3535
from pysonar_scanner.utils import Arch, Os, remove_trailing_slash
3636

37+
GLOBAL_SONARCLOUD_URL = "https://sonarcloud.io"
38+
US_SONARCLOUD_URL = "https://sonarqube.us"
39+
3740

3841
@dataclass(frozen=True)
3942
class SQVersion:
@@ -126,28 +129,45 @@ def to_api_configuration(config_dict: dict[Key, any]) -> ApiConfiguration:
126129

127130
def get_base_urls(config_dict: dict[Key, any]) -> BaseUrls:
128131
def is_sq_cloud_url(api_config: ApiConfiguration, sonar_host_url: str) -> bool:
129-
sq_cloud_url = api_config[SONAR_SCANNER_SONARCLOUD_URL] or "https://sonarcloud.io"
130-
return remove_trailing_slash(sonar_host_url) == remove_trailing_slash(sq_cloud_url)
132+
sq_cloud_url = api_config[SONAR_SCANNER_SONARCLOUD_URL] or GLOBAL_SONARCLOUD_URL
133+
return remove_trailing_slash(sonar_host_url) in [remove_trailing_slash(sq_cloud_url), US_SONARCLOUD_URL]
131134

132135
def is_blank(str) -> bool:
133136
return str.strip() == ""
134137

135-
def region_with_dot(region: str) -> str:
136-
return region + "." if not is_blank(region) else ""
137-
138138
api_config: ApiConfiguration = to_api_configuration(config_dict)
139139

140140
sonar_host_url = remove_trailing_slash(api_config[SONAR_HOST_URL])
141+
region = api_config[SONAR_REGION]
142+
if region and region != "us":
143+
raise InconsistentConfiguration(
144+
f"Invalid region '{region}'. Valid regions are: 'us'. "
145+
"Please check the 'sonar.region' property or the 'SONAR_REGION' environment variable."
146+
)
147+
if is_inconsistent_configuration(region, sonar_host_url):
148+
raise InconsistentConfiguration(
149+
"Inconsistent values for properties 'sonar.region' and 'sonar.host.url'. "
150+
+ "Please only specify one of the two properties."
151+
)
141152
if is_blank(sonar_host_url) or is_sq_cloud_url(api_config, sonar_host_url):
142-
region = region_with_dot(api_config[SONAR_REGION])
143-
sonar_host_url = api_config[SONAR_SCANNER_SONARCLOUD_URL] or f"https://{region}sonarcloud.io"
144-
api_base_url = api_config[SONAR_SCANNER_API_BASE_URL] or f"https://api.{region}sonarcloud.io"
153+
default_url = US_SONARCLOUD_URL if region == "us" else GLOBAL_SONARCLOUD_URL
154+
default_api_base_url = "https://api.sonarqube.us" if region == "us" else "https://api.sonarcloud.io"
155+
sonar_host_url = api_config[SONAR_SCANNER_SONARCLOUD_URL] or default_url
156+
api_base_url = api_config[SONAR_SCANNER_API_BASE_URL] or default_api_base_url
145157
return BaseUrls(base_url=sonar_host_url, api_base_url=api_base_url, is_sonar_qube_cloud=True)
146158
else:
147159
api_base_url = api_config[SONAR_SCANNER_API_BASE_URL] or f"{sonar_host_url}/api/v2"
148160
return BaseUrls(base_url=sonar_host_url, api_base_url=api_base_url, is_sonar_qube_cloud=False)
149161

150162

163+
def is_inconsistent_configuration(region, sonar_host_url):
164+
if not region or not sonar_host_url:
165+
return False
166+
if region == "us" and sonar_host_url.startswith(US_SONARCLOUD_URL):
167+
return False
168+
return True
169+
170+
151171
class BearerAuth(requests.auth.AuthBase):
152172
def __init__(self, token):
153173
self.token = token

src/pysonar_scanner/exceptions.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ class SQTooOldException(Exception):
3131
pass
3232

3333

34+
class InconsistentConfiguration(Exception):
35+
pass
36+
37+
3438
class ChecksumException(Exception):
3539
pass
3640

tests/unit/test_api.py

Lines changed: 60 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
SONAR_SCANNER_SONARCLOUD_URL,
3232
)
3333
from pysonar_scanner.api import SQVersion
34+
from pysonar_scanner.exceptions import InconsistentConfiguration
3435
from tests.unit import sq_api_utils
3536
from tests.unit.sq_api_utils import sq_api_mocker
3637

@@ -139,33 +140,29 @@ class TestCaseDict(TypedDict):
139140
base_url="https://sonarcloud.io", api_base_url="https://api.sonarcloud.io", is_sonar_qube_cloud=True
140141
),
141142
},
142-
# SQ:Cloud region tests
143+
# Region parameter
143144
{
144-
"name": "When region is set, use region in base urls",
145+
"name": "When region is set to US, use US base urls",
145146
"config": {
146-
SONAR_HOST_URL: "https://sonarcloud.io",
147+
SONAR_HOST_URL: "/",
147148
SONAR_SCANNER_SONARCLOUD_URL: "",
148149
SONAR_SCANNER_API_BASE_URL: "",
149150
SONAR_REGION: "us",
150151
},
151152
"expected": BaseUrls(
152-
base_url="https://us.sonarcloud.io",
153-
api_base_url="https://api.us.sonarcloud.io",
154-
is_sonar_qube_cloud=True,
153+
base_url="https://sonarqube.us", api_base_url="https://api.sonarqube.us", is_sonar_qube_cloud=True
155154
),
156155
},
157156
{
158-
"name": "Ignore region when sonarcloud_url and api_base_url is set",
157+
"name": "US region and US base url is fine",
159158
"config": {
160-
SONAR_HOST_URL: "https://custom-sq-cloud.io",
161-
SONAR_SCANNER_SONARCLOUD_URL: "https://custom-sq-cloud.io",
162-
SONAR_SCANNER_API_BASE_URL: "https://other-api.custom-sq-cloud.io",
159+
SONAR_HOST_URL: "https://sonarqube.us",
160+
SONAR_SCANNER_SONARCLOUD_URL: "",
161+
SONAR_SCANNER_API_BASE_URL: "",
163162
SONAR_REGION: "us",
164163
},
165164
"expected": BaseUrls(
166-
base_url="https://custom-sq-cloud.io",
167-
api_base_url="https://other-api.custom-sq-cloud.io",
168-
is_sonar_qube_cloud=True,
165+
base_url="https://sonarqube.us", api_base_url="https://api.sonarqube.us", is_sonar_qube_cloud=True
169166
),
170167
},
171168
# SQ:Server tests
@@ -204,6 +201,56 @@ class TestCaseDict(TypedDict):
204201
self.assertEqual(base_urls.is_sonar_qube_cloud, expected.is_sonar_qube_cloud)
205202
self.assertEqual(base_urls, expected)
206203

204+
def test_inconsistent_urls_raises_exception(self):
205+
class TestCaseDict(TypedDict):
206+
name: str
207+
config: dict[Key, any]
208+
expected: str
209+
210+
cases: list[TestCaseDict] = [
211+
{
212+
"name": "US region and global SQCloud URL",
213+
"config": {
214+
SONAR_HOST_URL: "https://sonarcloud.io",
215+
SONAR_SCANNER_SONARCLOUD_URL: "",
216+
SONAR_SCANNER_API_BASE_URL: "",
217+
SONAR_REGION: "us",
218+
},
219+
"expected": "Inconsistent values for properties 'sonar.region' and 'sonar.host.url'. "
220+
"Please only specify one of the two properties.",
221+
},
222+
{
223+
"name": "Region set with unknown SQCloud URL",
224+
"config": {
225+
SONAR_HOST_URL: "https://custom-sq-cloud.io",
226+
SONAR_SCANNER_SONARCLOUD_URL: "https://custom-sq-cloud.io",
227+
SONAR_SCANNER_API_BASE_URL: "https://other-api.custom-sq-cloud.io",
228+
SONAR_REGION: "us",
229+
},
230+
"expected": "Inconsistent values for properties 'sonar.region' and 'sonar.host.url'. "
231+
"Please only specify one of the two properties.",
232+
},
233+
{
234+
"name": "Unsupported region parameter",
235+
"config": {
236+
SONAR_HOST_URL: "",
237+
SONAR_SCANNER_SONARCLOUD_URL: "",
238+
SONAR_SCANNER_API_BASE_URL: "",
239+
SONAR_REGION: "fr",
240+
},
241+
"expected": "Invalid region 'fr'. Valid regions are: 'us'. "
242+
"Please check the 'sonar.region' property "
243+
"or the 'SONAR_REGION' environment variable.",
244+
},
245+
]
246+
247+
for case in cases:
248+
config = case["config"]
249+
expected = case["expected"]
250+
with self.subTest(case["name"], config=config, expected=expected):
251+
with self.assertRaises(InconsistentConfiguration, msg=expected):
252+
get_base_urls(config)
253+
207254

208255
class TestSonarQubeApiWithUnreachableSQServer(unittest.TestCase):
209256
def setUp(self):

0 commit comments

Comments
 (0)