libre-devops-helpers 0.4.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (256) hide show
  1. libre_devops_helpers-0.4.1/.dockerignore +12 -0
  2. libre_devops_helpers-0.4.1/.github/ISSUE_TEMPLATE/bug_report.md +42 -0
  3. libre_devops_helpers-0.4.1/.github/ISSUE_TEMPLATE/config.yml +5 -0
  4. libre_devops_helpers-0.4.1/.github/ISSUE_TEMPLATE/feature_request.md +28 -0
  5. libre_devops_helpers-0.4.1/.github/dependabot.yml +68 -0
  6. libre_devops_helpers-0.4.1/.github/pull_request_template.md +34 -0
  7. libre_devops_helpers-0.4.1/.github/workflows/badges.yml +83 -0
  8. libre_devops_helpers-0.4.1/.github/workflows/ci.yml +235 -0
  9. libre_devops_helpers-0.4.1/.github/workflows/codeql.yml +46 -0
  10. libre_devops_helpers-0.4.1/.github/workflows/container.yml +312 -0
  11. libre_devops_helpers-0.4.1/.github/workflows/dependency-review.yml +27 -0
  12. libre_devops_helpers-0.4.1/.github/workflows/release.yml +102 -0
  13. libre_devops_helpers-0.4.1/.gitignore +218 -0
  14. libre_devops_helpers-0.4.1/.gitleaks.toml +15 -0
  15. libre_devops_helpers-0.4.1/CHANGELOG.md +268 -0
  16. libre_devops_helpers-0.4.1/CONTRIBUTING.md +86 -0
  17. libre_devops_helpers-0.4.1/Containerfile +91 -0
  18. libre_devops_helpers-0.4.1/LICENSE +21 -0
  19. libre_devops_helpers-0.4.1/PKG-INFO +153 -0
  20. libre_devops_helpers-0.4.1/README.md +121 -0
  21. libre_devops_helpers-0.4.1/SECURITY.md +117 -0
  22. libre_devops_helpers-0.4.1/brand.toml +9 -0
  23. libre_devops_helpers-0.4.1/container/azure-cli/pyproject.toml +28 -0
  24. libre_devops_helpers-0.4.1/container/azure-cli/uv.lock +2411 -0
  25. libre_devops_helpers-0.4.1/docs/README.md +33 -0
  26. libre_devops_helpers-0.4.1/docs/authentication.md +125 -0
  27. libre_devops_helpers-0.4.1/docs/azure.md +61 -0
  28. libre_devops_helpers-0.4.1/docs/configuration.md +182 -0
  29. libre_devops_helpers-0.4.1/docs/containers.md +73 -0
  30. libre_devops_helpers-0.4.1/docs/defender.md +57 -0
  31. libre_devops_helpers-0.4.1/docs/development.md +85 -0
  32. libre_devops_helpers-0.4.1/docs/devices.md +52 -0
  33. libre_devops_helpers-0.4.1/docs/entra.md +45 -0
  34. libre_devops_helpers-0.4.1/docs/graph.md +36 -0
  35. libre_devops_helpers-0.4.1/docs/library.md +48 -0
  36. libre_devops_helpers-0.4.1/docs/logic-apps.md +42 -0
  37. libre_devops_helpers-0.4.1/docs/permissions.md +45 -0
  38. libre_devops_helpers-0.4.1/docs/pim.md +25 -0
  39. libre_devops_helpers-0.4.1/docs/rebranding.md +32 -0
  40. libre_devops_helpers-0.4.1/docs/servicenow.md +80 -0
  41. libre_devops_helpers-0.4.1/justfile +173 -0
  42. libre_devops_helpers-0.4.1/pyproject.toml +119 -0
  43. libre_devops_helpers-0.4.1/scripts/image_tags.py +75 -0
  44. libre_devops_helpers-0.4.1/scripts/rebrand.py +257 -0
  45. libre_devops_helpers-0.4.1/src/libre_devops_helpers/__init__.py +23 -0
  46. libre_devops_helpers-0.4.1/src/libre_devops_helpers/__main__.py +5 -0
  47. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/__init__.py +5 -0
  48. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/app.py +147 -0
  49. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/commands/__init__.py +1 -0
  50. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/commands/automation.py +321 -0
  51. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/commands/az.py +93 -0
  52. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/commands/azure.py +258 -0
  53. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/commands/config.py +54 -0
  54. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/commands/devices.py +548 -0
  55. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/commands/entra.py +554 -0
  56. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/commands/graph.py +358 -0
  57. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/commands/incidents.py +420 -0
  58. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/commands/intune.py +79 -0
  59. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/commands/keyvault.py +142 -0
  60. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/commands/logicapp.py +489 -0
  61. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/commands/logs.py +69 -0
  62. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/commands/pim.py +381 -0
  63. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/commands/pretty.py +141 -0
  64. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/commands/profiles.py +153 -0
  65. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/commands/snow.py +268 -0
  66. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/commands/token.py +222 -0
  67. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/commands/welcome.py +43 -0
  68. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/commands/xdr.py +353 -0
  69. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/exits.py +12 -0
  70. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/options.py +146 -0
  71. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/render.py +360 -0
  72. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/runtime.py +348 -0
  73. libre_devops_helpers-0.4.1/src/libre_devops_helpers/cli/servicenow_runtime.py +170 -0
  74. libre_devops_helpers-0.4.1/src/libre_devops_helpers/core/__init__.py +94 -0
  75. libre_devops_helpers-0.4.1/src/libre_devops_helpers/core/auth.py +103 -0
  76. libre_devops_helpers-0.4.1/src/libre_devops_helpers/core/brand.py +67 -0
  77. libre_devops_helpers-0.4.1/src/libre_devops_helpers/core/browser.py +21 -0
  78. libre_devops_helpers-0.4.1/src/libre_devops_helpers/core/config.py +159 -0
  79. libre_devops_helpers-0.4.1/src/libre_devops_helpers/core/dpapi.py +60 -0
  80. libre_devops_helpers-0.4.1/src/libre_devops_helpers/core/errors.py +90 -0
  81. libre_devops_helpers-0.4.1/src/libre_devops_helpers/core/http.py +412 -0
  82. libre_devops_helpers-0.4.1/src/libre_devops_helpers/core/inputs.py +193 -0
  83. libre_devops_helpers-0.4.1/src/libre_devops_helpers/core/log.py +246 -0
  84. libre_devops_helpers-0.4.1/src/libre_devops_helpers/core/poll.py +88 -0
  85. libre_devops_helpers-0.4.1/src/libre_devops_helpers/core/process.py +106 -0
  86. libre_devops_helpers-0.4.1/src/libre_devops_helpers/core/sheets.py +330 -0
  87. libre_devops_helpers-0.4.1/src/libre_devops_helpers/core/tables.py +49 -0
  88. libre_devops_helpers-0.4.1/src/libre_devops_helpers/core/timewindow.py +127 -0
  89. libre_devops_helpers-0.4.1/src/libre_devops_helpers/core/token_store.py +266 -0
  90. libre_devops_helpers-0.4.1/src/libre_devops_helpers/core/util.py +120 -0
  91. libre_devops_helpers-0.4.1/src/libre_devops_helpers/core/yaml_text.py +142 -0
  92. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/__init__.py +94 -0
  93. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/auth/__init__.py +43 -0
  94. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/auth/azure_cli.py +91 -0
  95. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/auth/delegated.py +391 -0
  96. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/auth/entra.py +241 -0
  97. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/auth/factory.py +114 -0
  98. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/auth/lapse.py +42 -0
  99. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/auth/managed_identity.py +84 -0
  100. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/automation/__init__.py +24 -0
  101. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/automation/client.py +241 -0
  102. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/automation/models.py +131 -0
  103. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/azcli/__init__.py +27 -0
  104. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/azcli/client.py +81 -0
  105. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/azcli/context.py +95 -0
  106. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/azure/__init__.py +34 -0
  107. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/azure/client.py +260 -0
  108. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/azure/models.py +198 -0
  109. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/clouds.py +83 -0
  110. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/config.py +244 -0
  111. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/devices/__init__.py +45 -0
  112. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/devices/antivirus.py +149 -0
  113. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/devices/check.py +286 -0
  114. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/devices/inspect.py +146 -0
  115. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/devices/models.py +148 -0
  116. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/entra/__init__.py +41 -0
  117. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/entra/client.py +422 -0
  118. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/entra/models.py +334 -0
  119. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/entra/permissions.py +51 -0
  120. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/graph/__init__.py +38 -0
  121. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/graph/client.py +292 -0
  122. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/incidents/__init__.py +51 -0
  123. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/incidents/client.py +217 -0
  124. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/incidents/models.py +165 -0
  125. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/incidents/permissions.py +15 -0
  126. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/intune/__init__.py +18 -0
  127. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/intune/client.py +94 -0
  128. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/intune/models.py +63 -0
  129. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/intune/permissions.py +16 -0
  130. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/keyvault/__init__.py +34 -0
  131. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/keyvault/client.py +185 -0
  132. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/loganalytics/__init__.py +17 -0
  133. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/loganalytics/client.py +117 -0
  134. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/logicapps/__init__.py +79 -0
  135. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/logicapps/checks.py +432 -0
  136. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/logicapps/client.py +162 -0
  137. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/logicapps/document.py +202 -0
  138. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/pim/__init__.py +39 -0
  139. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/pim/azure.py +238 -0
  140. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/pim/entra.py +294 -0
  141. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/pim/models.py +93 -0
  142. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/pim/permissions.py +98 -0
  143. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/pim/rules.py +70 -0
  144. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/process.py +70 -0
  145. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/resources.py +137 -0
  146. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/tokens.py +269 -0
  147. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/xdr/__init__.py +33 -0
  148. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/xdr/client.py +246 -0
  149. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/xdr/models.py +181 -0
  150. libre_devops_helpers-0.4.1/src/libre_devops_helpers/microsoft/xdr/permissions.py +24 -0
  151. libre_devops_helpers-0.4.1/src/libre_devops_helpers/py.typed +0 -0
  152. libre_devops_helpers-0.4.1/src/libre_devops_helpers/servicenow/__init__.py +50 -0
  153. libre_devops_helpers-0.4.1/src/libre_devops_helpers/servicenow/auth.py +409 -0
  154. libre_devops_helpers-0.4.1/src/libre_devops_helpers/servicenow/config.py +261 -0
  155. libre_devops_helpers-0.4.1/src/libre_devops_helpers/servicenow/instance/__init__.py +32 -0
  156. libre_devops_helpers-0.4.1/src/libre_devops_helpers/servicenow/instance/client.py +91 -0
  157. libre_devops_helpers-0.4.1/src/libre_devops_helpers/servicenow/instance/models.py +131 -0
  158. libre_devops_helpers-0.4.1/src/libre_devops_helpers/servicenow/roles.py +23 -0
  159. libre_devops_helpers-0.4.1/src/libre_devops_helpers/servicenow/tables.py +133 -0
  160. libre_devops_helpers-0.4.1/tests/cli/commands/test_automation.py +96 -0
  161. libre_devops_helpers-0.4.1/tests/cli/commands/test_az.py +59 -0
  162. libre_devops_helpers-0.4.1/tests/cli/commands/test_azure.py +120 -0
  163. libre_devops_helpers-0.4.1/tests/cli/commands/test_config.py +18 -0
  164. libre_devops_helpers-0.4.1/tests/cli/commands/test_devices.py +166 -0
  165. libre_devops_helpers-0.4.1/tests/cli/commands/test_entra.py +231 -0
  166. libre_devops_helpers-0.4.1/tests/cli/commands/test_graph.py +186 -0
  167. libre_devops_helpers-0.4.1/tests/cli/commands/test_incidents.py +168 -0
  168. libre_devops_helpers-0.4.1/tests/cli/commands/test_intune.py +46 -0
  169. libre_devops_helpers-0.4.1/tests/cli/commands/test_keyvault.py +44 -0
  170. libre_devops_helpers-0.4.1/tests/cli/commands/test_logicapp.py +192 -0
  171. libre_devops_helpers-0.4.1/tests/cli/commands/test_logs.py +11 -0
  172. libre_devops_helpers-0.4.1/tests/cli/commands/test_pim.py +228 -0
  173. libre_devops_helpers-0.4.1/tests/cli/commands/test_pretty.py +90 -0
  174. libre_devops_helpers-0.4.1/tests/cli/commands/test_profiles.py +106 -0
  175. libre_devops_helpers-0.4.1/tests/cli/commands/test_snow.py +168 -0
  176. libre_devops_helpers-0.4.1/tests/cli/commands/test_token.py +86 -0
  177. libre_devops_helpers-0.4.1/tests/cli/commands/test_welcome.py +19 -0
  178. libre_devops_helpers-0.4.1/tests/cli/commands/test_xdr.py +185 -0
  179. libre_devops_helpers-0.4.1/tests/cli/conftest.py +22 -0
  180. libre_devops_helpers-0.4.1/tests/cli/test_app.py +114 -0
  181. libre_devops_helpers-0.4.1/tests/cli/test_options.py +56 -0
  182. libre_devops_helpers-0.4.1/tests/cli/test_render.py +128 -0
  183. libre_devops_helpers-0.4.1/tests/cli/test_runtime.py +152 -0
  184. libre_devops_helpers-0.4.1/tests/cli/test_servicenow_runtime.py +55 -0
  185. libre_devops_helpers-0.4.1/tests/conftest.py +22 -0
  186. libre_devops_helpers-0.4.1/tests/core/test_auth.py +73 -0
  187. libre_devops_helpers-0.4.1/tests/core/test_browser.py +18 -0
  188. libre_devops_helpers-0.4.1/tests/core/test_config.py +59 -0
  189. libre_devops_helpers-0.4.1/tests/core/test_dpapi.py +22 -0
  190. libre_devops_helpers-0.4.1/tests/core/test_http.py +293 -0
  191. libre_devops_helpers-0.4.1/tests/core/test_inputs.py +173 -0
  192. libre_devops_helpers-0.4.1/tests/core/test_log.py +176 -0
  193. libre_devops_helpers-0.4.1/tests/core/test_poll.py +74 -0
  194. libre_devops_helpers-0.4.1/tests/core/test_process.py +76 -0
  195. libre_devops_helpers-0.4.1/tests/core/test_sheets.py +240 -0
  196. libre_devops_helpers-0.4.1/tests/core/test_timewindow.py +102 -0
  197. libre_devops_helpers-0.4.1/tests/core/test_token_store.py +206 -0
  198. libre_devops_helpers-0.4.1/tests/core/test_util.py +95 -0
  199. libre_devops_helpers-0.4.1/tests/core/test_yaml_text.py +138 -0
  200. libre_devops_helpers-0.4.1/tests/fakes/__init__.py +5 -0
  201. libre_devops_helpers-0.4.1/tests/fakes/automation.py +133 -0
  202. libre_devops_helpers-0.4.1/tests/fakes/azcli.py +86 -0
  203. libre_devops_helpers-0.4.1/tests/fakes/clock.py +16 -0
  204. libre_devops_helpers-0.4.1/tests/fakes/devices.py +123 -0
  205. libre_devops_helpers-0.4.1/tests/fakes/http.py +87 -0
  206. libre_devops_helpers-0.4.1/tests/fakes/ids.py +11 -0
  207. libre_devops_helpers-0.4.1/tests/fakes/incidents.py +52 -0
  208. libre_devops_helpers-0.4.1/tests/fakes/logicapps.py +139 -0
  209. libre_devops_helpers-0.4.1/tests/fakes/pim.py +35 -0
  210. libre_devops_helpers-0.4.1/tests/fakes/process.py +21 -0
  211. libre_devops_helpers-0.4.1/tests/fakes/servicenow.py +240 -0
  212. libre_devops_helpers-0.4.1/tests/fakes/tenant.py +238 -0
  213. libre_devops_helpers-0.4.1/tests/fakes/tokens.py +49 -0
  214. libre_devops_helpers-0.4.1/tests/fakes/workbooks.py +104 -0
  215. libre_devops_helpers-0.4.1/tests/microsoft/auth/test_azure_cli.py +102 -0
  216. libre_devops_helpers-0.4.1/tests/microsoft/auth/test_delegated.py +360 -0
  217. libre_devops_helpers-0.4.1/tests/microsoft/auth/test_entra.py +195 -0
  218. libre_devops_helpers-0.4.1/tests/microsoft/auth/test_factory.py +68 -0
  219. libre_devops_helpers-0.4.1/tests/microsoft/auth/test_lapse.py +36 -0
  220. libre_devops_helpers-0.4.1/tests/microsoft/auth/test_managed_identity.py +45 -0
  221. libre_devops_helpers-0.4.1/tests/microsoft/automation/test_client.py +100 -0
  222. libre_devops_helpers-0.4.1/tests/microsoft/azcli/test_client.py +36 -0
  223. libre_devops_helpers-0.4.1/tests/microsoft/azcli/test_context.py +89 -0
  224. libre_devops_helpers-0.4.1/tests/microsoft/azure/test_client.py +170 -0
  225. libre_devops_helpers-0.4.1/tests/microsoft/devices/test_antivirus.py +96 -0
  226. libre_devops_helpers-0.4.1/tests/microsoft/devices/test_check.py +336 -0
  227. libre_devops_helpers-0.4.1/tests/microsoft/devices/test_inspect.py +70 -0
  228. libre_devops_helpers-0.4.1/tests/microsoft/entra/test_client.py +290 -0
  229. libre_devops_helpers-0.4.1/tests/microsoft/graph/test_client.py +222 -0
  230. libre_devops_helpers-0.4.1/tests/microsoft/incidents/test_client.py +199 -0
  231. libre_devops_helpers-0.4.1/tests/microsoft/intune/test_client.py +58 -0
  232. libre_devops_helpers-0.4.1/tests/microsoft/keyvault/test_client.py +86 -0
  233. libre_devops_helpers-0.4.1/tests/microsoft/loganalytics/test_client.py +61 -0
  234. libre_devops_helpers-0.4.1/tests/microsoft/logicapps/test_checks.py +290 -0
  235. libre_devops_helpers-0.4.1/tests/microsoft/logicapps/test_client.py +118 -0
  236. libre_devops_helpers-0.4.1/tests/microsoft/logicapps/test_document.py +110 -0
  237. libre_devops_helpers-0.4.1/tests/microsoft/pim/test_azure.py +122 -0
  238. libre_devops_helpers-0.4.1/tests/microsoft/pim/test_entra.py +170 -0
  239. libre_devops_helpers-0.4.1/tests/microsoft/pim/test_rules.py +11 -0
  240. libre_devops_helpers-0.4.1/tests/microsoft/test_clouds.py +47 -0
  241. libre_devops_helpers-0.4.1/tests/microsoft/test_config.py +112 -0
  242. libre_devops_helpers-0.4.1/tests/microsoft/test_process.py +66 -0
  243. libre_devops_helpers-0.4.1/tests/microsoft/test_tokens.py +130 -0
  244. libre_devops_helpers-0.4.1/tests/microsoft/xdr/test_client.py +181 -0
  245. libre_devops_helpers-0.4.1/tests/project/test_containerfile.py +27 -0
  246. libre_devops_helpers-0.4.1/tests/project/test_docs.py +144 -0
  247. libre_devops_helpers-0.4.1/tests/project/test_image_tags.py +75 -0
  248. libre_devops_helpers-0.4.1/tests/project/test_layout.py +46 -0
  249. libre_devops_helpers-0.4.1/tests/project/test_package_surface.py +152 -0
  250. libre_devops_helpers-0.4.1/tests/project/test_rebrand.py +149 -0
  251. libre_devops_helpers-0.4.1/tests/servicenow/instance/test_client.py +84 -0
  252. libre_devops_helpers-0.4.1/tests/servicenow/test_auth.py +281 -0
  253. libre_devops_helpers-0.4.1/tests/servicenow/test_config.py +125 -0
  254. libre_devops_helpers-0.4.1/tests/servicenow/test_roles.py +8 -0
  255. libre_devops_helpers-0.4.1/tests/servicenow/test_tables.py +62 -0
  256. libre_devops_helpers-0.4.1/uv.lock +895 -0
@@ -0,0 +1,12 @@
1
+ # The build context for the Containerfile: podman and docker both read this file. Only
2
+ # what the Containerfile copies is let in, so secrets and local environments stay out.
3
+ *
4
+ !pyproject.toml
5
+ !uv.lock
6
+ !README.md
7
+ !LICENSE
8
+ !src/
9
+ !container/azure-cli/pyproject.toml
10
+ !container/azure-cli/uv.lock
11
+ **/__pycache__
12
+ **/*.pyc
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: Bug report
3
+ about: Report something in ldo that is broken or not working as expected
4
+ title: "[Bug]: "
5
+ labels: bug
6
+ assignees: ""
7
+ ---
8
+
9
+ <!-- Never paste an access token, tenant id, subscription id or real device name here.
10
+ Replace them with placeholders such as <tenant-id> or web01.example.com. -->
11
+
12
+ ## Description
13
+
14
+ A clear description of what is broken or not working as expected.
15
+
16
+ ## Steps to Reproduce
17
+
18
+ 1. Run `ldo ...`
19
+ 2. Observe the issue
20
+
21
+ ## Expected Behaviour
22
+
23
+ What should have happened?
24
+
25
+ ## Actual Behaviour
26
+
27
+ What actually happened? Include the error and hint lines, and the exit code.
28
+
29
+ ## Environment
30
+
31
+ - ldo version (`ldo --version`):
32
+ - Azure CLI version (`az version`):
33
+ - Python version:
34
+ - OS:
35
+
36
+ ## Debug Output
37
+
38
+ If useful, run the command again with `-vv` and paste the relevant lines, with any ids redacted.
39
+
40
+ ## Additional Context
41
+
42
+ Anything else useful.
@@ -0,0 +1,5 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: Report a security vulnerability
4
+ url: https://github.com/libre-devops/python-helpers/security/advisories/new
5
+ about: Please report vulnerabilities privately, not as a public issue.
@@ -0,0 +1,28 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an enhancement or new command for ldo
4
+ title: "[Feature]: "
5
+ labels: enhancement
6
+ assignees: ""
7
+ ---
8
+
9
+ ## Summary
10
+
11
+ Describe the feature or improvement.
12
+
13
+ ## Problem Statement
14
+
15
+ What problem does this solve, or what need does it address?
16
+
17
+ ## Proposed Solution
18
+
19
+ What would you like to see implemented? If it calls a new Microsoft API, say which one and
20
+ which permissions it needs.
21
+
22
+ ## Alternatives Considered
23
+
24
+ Any other approaches you have thought of?
25
+
26
+ ## Additional Context
27
+
28
+ Links, example output, or other relevant information.
@@ -0,0 +1,68 @@
1
+ version: 2
2
+ updates:
3
+ # uv - pyproject.toml and uv.lock at the repository root. Minor and patch are
4
+ # grouped into one PR per week; majors get individual PRs so they can be
5
+ # reviewed separately.
6
+ - package-ecosystem: uv
7
+ directory: /
8
+ schedule:
9
+ interval: weekly
10
+ day: monday
11
+ time: "06:00"
12
+ timezone: Europe/London
13
+ groups:
14
+ minor-and-patch:
15
+ patterns: ["*"]
16
+ update-types: [minor, patch]
17
+ open-pull-requests-limit: 5
18
+ labels:
19
+ - dependencies
20
+
21
+ # GitHub Actions - group all updates together. Dependabot keeps the SHA pin
22
+ # and its version comment in step for setup-uv.
23
+ - package-ecosystem: github-actions
24
+ directory: /
25
+ schedule:
26
+ interval: weekly
27
+ day: monday
28
+ time: "06:00"
29
+ timezone: Europe/London
30
+ groups:
31
+ actions:
32
+ patterns: ["*"]
33
+ open-pull-requests-limit: 3
34
+ labels:
35
+ - dependencies
36
+ - github-actions
37
+
38
+ # Container base images (Containerfile). Dependabot moves the pinned digests when the
39
+ # python and uv images are rebuilt upstream, and proposes new Python versions; the
40
+ # weekly container workflow patches Debian packages in between.
41
+ - package-ecosystem: docker
42
+ directory: /
43
+ schedule:
44
+ interval: weekly
45
+ day: monday
46
+ time: "06:00"
47
+ timezone: Europe/London
48
+ groups:
49
+ base-images:
50
+ patterns: ["*"]
51
+ open-pull-requests-limit: 3
52
+ labels:
53
+ - dependencies
54
+
55
+ # The Azure CLI in the "az" image, locked in its own project.
56
+ - package-ecosystem: uv
57
+ directory: /container/azure-cli
58
+ schedule:
59
+ interval: weekly
60
+ day: monday
61
+ time: "06:00"
62
+ timezone: Europe/London
63
+ groups:
64
+ azure-cli:
65
+ patterns: ["*"]
66
+ open-pull-requests-limit: 3
67
+ labels:
68
+ - dependencies
@@ -0,0 +1,34 @@
1
+ ## Summary
2
+
3
+ Brief description of the change.
4
+
5
+ ## Type of Change
6
+
7
+ - [ ] Bug fix
8
+ - [ ] New feature or command
9
+ - [ ] Enhancement / improvement
10
+ - [ ] Documentation update
11
+ - [ ] Refactor
12
+ - [ ] CI / pipeline change
13
+ - [ ] Dependency update
14
+
15
+ ## Testing
16
+
17
+ Describe how this was tested.
18
+
19
+ - [ ] `just ci` passes locally (lint, format check, tests with coverage, Python 3.11, audit, build)
20
+ - [ ] New behaviour is covered by tests that use the fakes, not the network or a real `az`
21
+ - [ ] Tests sit in the directory that mirrors the code under test
22
+ - [ ] If the Containerfile or its inputs changed: `just image`, `just image-slim` and
23
+ `just image-scan` pass
24
+ - [ ] Manually run against a real tenant (say which commands)
25
+ - [ ] GitHub Actions pipeline passed
26
+
27
+ ## Checklist
28
+
29
+ - [ ] Code follows project conventions (see CONTRIBUTING.md)
30
+ - [ ] `docs/` updated for any new command, option or exit code (and the README's table for a new group)
31
+ - [ ] CHANGELOG.md updated
32
+ - [ ] No tokens, tenant ids, subscription ids or real host names included (gitleaks checks)
33
+ - [ ] No hard-coded tool names; they come from `core/brand.py` (the rebrand test checks)
34
+ - [ ] Changes are scoped appropriately
@@ -0,0 +1,83 @@
1
+ name: Badges
2
+
3
+ # Publishes the README's coverage badge. After 'Lint and Test' passes on a push to main,
4
+ # the coverage total it wrote (a shields.io endpoint file) is committed to the 'badges'
5
+ # branch, which holds nothing else; the README reads it through img.shields.io/endpoint.
6
+ # No third-party service is involved. This is a workflow of its own because the release
7
+ # calls ci.yml with read-only permissions, and a job there cannot ask for more.
8
+ on:
9
+ workflow_run:
10
+ workflows: ["Lint and Test"]
11
+ types: [completed]
12
+ branches: [main]
13
+
14
+ permissions:
15
+ contents: read
16
+
17
+ concurrency:
18
+ group: badges
19
+ cancel-in-progress: false
20
+
21
+ jobs:
22
+ coverage:
23
+ name: Coverage badge
24
+ # Only a passing run from a push to this repository's main: never a pull request.
25
+ if: >-
26
+ github.event.workflow_run.conclusion == 'success' &&
27
+ github.event.workflow_run.event == 'push' &&
28
+ github.event.workflow_run.head_branch == 'main' &&
29
+ github.event.workflow_run.head_repository.full_name == github.repository
30
+ runs-on: ubuntu-latest
31
+ timeout-minutes: 5
32
+ permissions:
33
+ # Pushing to the badges branch, and reading the triggering run's artifact.
34
+ contents: write
35
+ actions: read
36
+
37
+ steps:
38
+ - name: Fetch the badge
39
+ uses: actions/download-artifact@v8
40
+ with:
41
+ name: coverage-badge
42
+ run-id: ${{ github.event.workflow_run.id }}
43
+ github-token: ${{ github.token }}
44
+
45
+ # The file is published as it is, so check it is exactly the shape expected.
46
+ - name: Check the badge
47
+ run: |
48
+ python3 - <<'PY'
49
+ import json
50
+ import re
51
+
52
+ with open("coverage-badge.json", encoding="utf-8") as handle:
53
+ badge = json.load(handle)
54
+ assert set(badge) == {"schemaVersion", "label", "message", "color"}, badge
55
+ assert badge["schemaVersion"] == 1 and badge["label"] == "coverage", badge
56
+ assert re.fullmatch(r"\d{1,3}\.\d%", badge["message"]), badge
57
+ assert badge["color"] in {"brightgreen", "green", "yellow", "red"}, badge
58
+ PY
59
+
60
+ - name: Publish to the badges branch
61
+ env:
62
+ GH_TOKEN: ${{ github.token }}
63
+ SHA: ${{ github.event.workflow_run.head_sha }}
64
+ run: |
65
+ set -euo pipefail
66
+ remote="https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"
67
+ if git ls-remote --exit-code --heads "$remote" badges > /dev/null; then
68
+ git clone --quiet --depth 1 --branch badges "$remote" "$RUNNER_TEMP/badges"
69
+ else
70
+ git init --quiet --initial-branch badges "$RUNNER_TEMP/badges"
71
+ git -C "$RUNNER_TEMP/badges" remote add origin "$remote"
72
+ fi
73
+ cp coverage-badge.json "$RUNNER_TEMP/badges/coverage.json"
74
+ cd "$RUNNER_TEMP/badges"
75
+ git config user.name "github-actions[bot]"
76
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
77
+ git add coverage.json
78
+ if git diff --cached --quiet; then
79
+ echo "coverage unchanged"
80
+ exit 0
81
+ fi
82
+ git commit --quiet --message "Coverage $(python3 -c 'import json; print(json.load(open("coverage.json"))["message"])') at ${SHA:0:7}"
83
+ git push --quiet origin badges
@@ -0,0 +1,235 @@
1
+ name: Lint and Test
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+ workflow_dispatch:
9
+ # The release workflow calls this one, so the gate a release passes is this exact job
10
+ # set rather than a copy of it that can drift.
11
+ workflow_call:
12
+
13
+ permissions:
14
+ contents: read
15
+
16
+ concurrency:
17
+ # github.workflow is the calling workflow's name under workflow_call, so a release and a
18
+ # push to main land in their own groups and do not cancel each other.
19
+ group: ci-${{ github.workflow }}-${{ github.ref }}
20
+ cancel-in-progress: true
21
+
22
+ env:
23
+ GITLEAKS_VERSION: 8.30.1
24
+ # From the release's checksums file. Dependabot cannot update a pinned download, so bump
25
+ # both together when moving to a new gitleaks release.
26
+ GITLEAKS_SHA256: 551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb
27
+ PIP_AUDIT_VERSION: 2.10.1
28
+
29
+ jobs:
30
+ secrets:
31
+ name: Secret scan (gitleaks)
32
+ runs-on: ubuntu-latest
33
+ timeout-minutes: 10
34
+
35
+ steps:
36
+ - name: Checkout (full history)
37
+ uses: actions/checkout@v7
38
+ with:
39
+ # Every commit, so a secret added and later removed is still found.
40
+ fetch-depth: 0
41
+
42
+ - name: Install gitleaks
43
+ run: |
44
+ archive="gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz"
45
+ curl -sSfL -o "$RUNNER_TEMP/$archive" \
46
+ "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/$archive"
47
+ echo "${GITLEAKS_SHA256} $RUNNER_TEMP/$archive" | sha256sum -c -
48
+ tar -xzf "$RUNNER_TEMP/$archive" -C "$RUNNER_TEMP" gitleaks
49
+
50
+ - name: Scan every commit
51
+ run: '"$RUNNER_TEMP/gitleaks" git --config .gitleaks.toml --redact --verbose .'
52
+
53
+ lint:
54
+ name: Lint and format check
55
+ runs-on: ubuntu-latest
56
+ timeout-minutes: 10
57
+
58
+ steps:
59
+ - name: Checkout
60
+ uses: actions/checkout@v7
61
+
62
+ - name: Set up uv
63
+ uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
64
+ with:
65
+ enable-cache: true
66
+
67
+ # --locked fails the job when uv.lock is out of step with pyproject.toml.
68
+ - name: Install
69
+ run: uv sync --locked
70
+
71
+ - name: Lint
72
+ run: uv run ruff check --output-format=github src tests scripts
73
+
74
+ # Check only: formatting is fixed locally with 'just fmt', never in CI.
75
+ - name: Format check
76
+ run: uv run ruff format --check src tests scripts
77
+
78
+ audit:
79
+ name: Dependency audit (pip-audit)
80
+ runs-on: ubuntu-latest
81
+ timeout-minutes: 10
82
+
83
+ steps:
84
+ - name: Checkout
85
+ uses: actions/checkout@v7
86
+
87
+ - name: Set up uv
88
+ uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
89
+
90
+ # The locked, hashed dependency tree, runtime and dev, exactly as CI installs it.
91
+ - name: Audit the locked dependencies for known vulnerabilities
92
+ run: |
93
+ uv export --frozen --all-extras --format requirements-txt --no-emit-project \
94
+ --output-file "$RUNNER_TEMP/requirements.txt"
95
+ uvx "pip-audit==${PIP_AUDIT_VERSION}" --strict --disable-pip --require-hashes \
96
+ --requirement "$RUNNER_TEMP/requirements.txt"
97
+
98
+ test:
99
+ name: Test (Python ${{ matrix.python-version }}, ${{ matrix.os }})
100
+ runs-on: ${{ matrix.os }}
101
+ timeout-minutes: 15
102
+
103
+ strategy:
104
+ fail-fast: false
105
+ matrix:
106
+ os: [ubuntu-latest]
107
+ python-version: ["3.11", "3.12", "3.13", "3.14"]
108
+ # The config path and file permission handling differ on Windows and macOS,
109
+ # so run the suite there too, on one Python version.
110
+ include:
111
+ - os: windows-latest
112
+ python-version: "3.13"
113
+ - os: macos-latest
114
+ python-version: "3.13"
115
+
116
+ env:
117
+ UV_PYTHON: ${{ matrix.python-version }}
118
+
119
+ steps:
120
+ - name: Checkout
121
+ uses: actions/checkout@v7
122
+
123
+ - name: Set up uv
124
+ uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
125
+ with:
126
+ enable-cache: true
127
+
128
+ - name: Install
129
+ run: uv sync --locked
130
+
131
+ # Includes the rebrand test, which renames a copy of the repository and runs its
132
+ # whole suite, so 'just rebrand' is proven on every platform.
133
+ - name: Test
134
+ run: uv run pytest
135
+
136
+ # Line and branch coverage on one platform, so the number is the same on every run.
137
+ # The floor (fail_under) lives in pyproject.toml, beside the rest of the coverage config.
138
+ coverage:
139
+ name: Coverage
140
+ runs-on: ubuntu-latest
141
+ timeout-minutes: 15
142
+
143
+ steps:
144
+ - name: Checkout
145
+ uses: actions/checkout@v7
146
+
147
+ - name: Set up uv
148
+ uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
149
+ with:
150
+ enable-cache: true
151
+
152
+ - name: Install
153
+ run: uv sync --locked
154
+
155
+ - name: Test with coverage
156
+ run: uv run pytest --cov --cov-report=term-missing --cov-report=xml
157
+
158
+ - name: Summarise
159
+ if: always()
160
+ shell: bash
161
+ run: |
162
+ if [ -f .coverage ]; then
163
+ {
164
+ echo "## Coverage"
165
+ echo
166
+ uv run coverage report --format=markdown --fail-under=0
167
+ } >> "$GITHUB_STEP_SUMMARY"
168
+ fi
169
+
170
+ - name: Keep the report
171
+ if: always()
172
+ uses: actions/upload-artifact@v7
173
+ with:
174
+ name: coverage
175
+ path: coverage.xml
176
+ if-no-files-found: ignore
177
+ retention-days: 14
178
+
179
+ # The total as a shields.io endpoint; badges.yml publishes it for the README badge
180
+ # after a push to main.
181
+ - name: Write the coverage badge
182
+ shell: bash
183
+ run: |
184
+ total="$(uv run coverage report --format=total --precision=1 --fail-under=0)"
185
+ python3 - "$total" > coverage-badge.json <<'PY'
186
+ import json
187
+ import sys
188
+
189
+ total = float(sys.argv[1])
190
+ colour = next(c for floor, c in ((90, "brightgreen"), (80, "green"), (70, "yellow"), (0, "red")) if total >= floor)
191
+ print(json.dumps({"schemaVersion": 1, "label": "coverage", "message": f"{total:.1f}%", "color": colour}))
192
+ PY
193
+ cat coverage-badge.json
194
+
195
+ - name: Keep the badge
196
+ uses: actions/upload-artifact@v7
197
+ with:
198
+ name: coverage-badge
199
+ path: coverage-badge.json
200
+ if-no-files-found: error
201
+ retention-days: 14
202
+
203
+ build:
204
+ name: Build
205
+ runs-on: ubuntu-latest
206
+ timeout-minutes: 10
207
+ needs: [secrets, lint, audit, test, coverage]
208
+
209
+ steps:
210
+ - name: Checkout
211
+ uses: actions/checkout@v7
212
+
213
+ - name: Set up uv
214
+ uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
215
+
216
+ - name: Build the sdist and wheel
217
+ run: uv build
218
+
219
+ # Proves the wheel installs cleanly and the entry point resolves outside the source tree.
220
+ - name: Smoke test the wheel
221
+ shell: bash
222
+ run: |
223
+ uv venv "$RUNNER_TEMP/smoke"
224
+ uv pip install --python "$RUNNER_TEMP/smoke" dist/*.whl
225
+ "$RUNNER_TEMP/smoke/bin/ldo" --version
226
+ "$RUNNER_TEMP/smoke/bin/ldo" --help > /dev/null
227
+
228
+ # Built once here; a release publishes these exact files rather than rebuilding.
229
+ - name: Keep the build
230
+ uses: actions/upload-artifact@v7
231
+ with:
232
+ name: dist
233
+ path: dist/
234
+ if-no-files-found: error
235
+ retention-days: 14
@@ -0,0 +1,46 @@
1
+ name: CodeQL
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+ schedule:
9
+ # Weekly full scan, Monday 03:00 UTC
10
+ - cron: '0 3 * * 1'
11
+
12
+ permissions:
13
+ contents: read
14
+ security-events: write
15
+ actions: read
16
+
17
+ jobs:
18
+ analyse:
19
+ name: Analyse (${{ matrix.language }})
20
+ runs-on: ubuntu-latest
21
+ timeout-minutes: 20
22
+
23
+ strategy:
24
+ fail-fast: false
25
+ matrix:
26
+ # python: the package under src/ and the tests
27
+ # actions: the workflows themselves
28
+ language: [python, actions]
29
+
30
+ steps:
31
+ - name: Checkout
32
+ uses: actions/checkout@v7
33
+
34
+ # Neither language is compiled, so there is nothing to build before analysis.
35
+ - name: Initialise CodeQL
36
+ uses: github/codeql-action/init@v4
37
+ with:
38
+ languages: ${{ matrix.language }}
39
+ build-mode: none
40
+ # security-and-quality catches both vulnerability patterns and bad practices
41
+ queries: security-and-quality
42
+
43
+ - name: Perform CodeQL analysis
44
+ uses: github/codeql-action/analyze@v4
45
+ with:
46
+ category: /language:${{ matrix.language }}