pax_global_header00006660000000000000000000000064147777333140014532gustar00rootroot0000000000000052 comment=af84137069fbb2170051e7d370a55f59f856a7a9 osconfig-20250416.02/000077500000000000000000000000001477773331400140265ustar00rootroot00000000000000osconfig-20250416.02/.github/000077500000000000000000000000001477773331400153665ustar00rootroot00000000000000osconfig-20250416.02/.github/dependabot.yml000066400000000000000000000002711477773331400202160ustar00rootroot00000000000000version: 2 updates: - package-ecosystem: "gomod" directory: "/" labels: - "dependencies" schedule: interval: "daily" allow: - dependency-type: "all" osconfig-20250416.02/.github/workflows/000077500000000000000000000000001477773331400174235ustar00rootroot00000000000000osconfig-20250416.02/.github/workflows/codeql.yml000066400000000000000000000103761477773331400214240ustar00rootroot00000000000000# For most projects, this workflow file will not need changing; you simply need # to commit it to your repository. # # You may wish to alter this file to override the set of languages analyzed, # or to provide custom queries or build logic. # # ******** NOTE ******** # We have attempted to detect the languages in your repository. Please check # the `language` matrix defined below to confirm you have the correct set of # supported CodeQL languages. # name: "CodeQL" on: push: branches: [ "master" ] pull_request: branches: [ "master" ] schedule: - cron: '45 4 * * 1' jobs: analyze: name: Analyze (${{ matrix.language }}) # Runner size impacts CodeQL analysis time. To learn more, please see: # - https://gh.io/recommended-hardware-resources-for-running-codeql # - https://gh.io/supported-runners-and-hardware-resources # - https://gh.io/using-larger-runners (GitHub.com only) # Consider using larger runners or machines with greater resources for possible analysis time improvements. runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} permissions: # required for all workflows security-events: write # required to fetch internal or private CodeQL packs packages: read # only required for workflows in private repositories actions: read contents: read strategy: fail-fast: false matrix: include: - language: go build-mode: autobuild # CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' # Use `c-cpp` to analyze code written in C, C++ or both # Use 'java-kotlin' to analyze code written in Java, Kotlin or both # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis, # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning. # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages steps: - name: Checkout repository uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} # If you wish to specify custom queries, you can do so here or in a config file. # By default, queries listed here will override any specified in a config file. # Prefix the list here with "+" to use these queries and those in the config file. # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs # queries: security-extended,security-and-quality # If the analyze step fails for one of the languages you are analyzing with # "We were unable to automatically build your code", modify the matrix above # to set the build mode to "manual" for that language. Then modify this step # to build your code. # â„šī¸ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - if: matrix.build-mode == 'manual' run: | echo 'If you are using a "manual" build mode for one or more of the' \ 'languages you are analyzing, replace this with the commands to build' \ 'your code, for example:' echo ' make bootstrap' echo ' make release' exit 1 - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 with: category: "/language:${{matrix.language}}" osconfig-20250416.02/90-google-osconfig-agent.preset000066400000000000000000000000441477773331400216530ustar00rootroot00000000000000enable google-osconfig-agent.serviceosconfig-20250416.02/CONTRIBUTING.md000066400000000000000000000061001477773331400162540ustar00rootroot00000000000000# How to become a contributor and submit your own code ## Contributor License Agreements We'd love to accept your sample apps and patches! Before we can take them, we have to jump a couple of legal hurdles. Please fill out either the individual or corporate Contributor License Agreement (CLA). * If you are an individual writing original source code and you're sure you own the intellectual property, then you'll need to sign an [individual CLA] (https://developers.google.com/open-source/cla/individual). * If you work for a company that wants to allow you to contribute your work, then you'll need to sign a [corporate CLA] (https://developers.google.com/open-source/cla/corporate). Follow either of the two links above to access the appropriate CLA and instructions for how to sign and return it. Once we receive it, we'll be able to accept your pull requests. ## Contributing a patch 1. Submit an issue describing your proposed change to the repo in question. 1. The repo owner will respond to your issue promptly. 1. If your proposed change is accepted, and you haven't already done so, sign a Contributor License Agreement (see details above). 1. Fork the desired repo, develop and test your code changes. 1. Ensure that your code adheres to the existing style in the sample to which you are contributing. Refer to the [Google Cloud Platform Samples Style Guide] (https://github.com/GoogleCloudPlatform/Template/wiki/style.html) for the recommended coding standards for this organization. 1. Ensure that your code has an appropriate set of unit tests which all pass. 1. Submit a pull request. ## Contributing a new sample App 1. Submit an issue to the `GoogleCloudPlatform/Template` repo describing your proposed sample app. 1. The Template repo owner will respond to your enhancement issue promptly. Instructional value is the top priority when evaluating new app proposals for this collection of repos. 1. If your proposal is accepted, and you haven't already done so, sign a Contributor License Agreement (see details above). 1. Create your own repo for your app following this naming convention: * {product}-{app-name}-{language} * products: appengine, compute, storage, bigquery, prediction, cloudsql * example: appengine-guestbook-python * For multi-product apps, concatenate the primary products, like this: compute-appengine-demo-suite-python. * For multi-language apps, concatenate the primary languages like this: appengine-sockets-python-java-go. 1. Clone the `README.md`, `CONTRIB.md` and `LICENSE` files from the GoogleCloudPlatform/Template repo. 1. Ensure that your code adheres to the existing style in the sample to which you are contributing. Refer to the [Google Cloud Platform Samples Style Guide] (https://github.com/GoogleCloudPlatform/Template/wiki/style.html) for the recommended coding standards for this organization. 1. Ensure that your code has an appropriate set of unit tests which all pass. 1. Submit a request to fork your repo in GoogleCloudPlatform organization via your proposal issue. osconfig-20250416.02/LICENSE000066400000000000000000000261351477773331400150420ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. osconfig-20250416.02/OWNERS000066400000000000000000000003011477773331400147600ustar00rootroot00000000000000# This file enables automatic assignment of PR reviewers. # See the OWNERS docs at https://go.k8s.io/owners approvers: - burov - ekremenetskii - paulinakania - savija-tv - zoltak-g osconfig-20250416.02/README.md000066400000000000000000000012121477773331400153010ustar00rootroot00000000000000# Google OS Config Agent. This repository contains the OS Config agent and associated end to end tests. The OS Config agent currently supports the following three main features: - [OS inventory management](https://cloud.google.com/compute/docs/instances/os-inventory-management) - [Patch](https://cloud.google.com/compute/docs/os-patch-management) - [OS policies](https://cloud.google.com/compute/docs/os-config-management) For instructions on how to install the OS Config agent on a [Compute Engine](https://cloud.google.com/compute) VM instance, see [Install the OS Config agent](https://cloud.google.com/compute/docs/manage-os#agent-install). osconfig-20250416.02/THIRD_PARTY_LICENSES/000077500000000000000000000000001477773331400171445ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/cloud.google.com/000077500000000000000000000000001477773331400223025ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/cloud.google.com/go/000077500000000000000000000000001477773331400227075ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/cloud.google.com/go/LICENSE000066400000000000000000000261361477773331400237240ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. osconfig-20250416.02/THIRD_PARTY_LICENSES/cloud.google.com/go/logging/000077500000000000000000000000001477773331400243355ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/cloud.google.com/go/logging/LICENSE000066400000000000000000000261361477773331400253520ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. osconfig-20250416.02/THIRD_PARTY_LICENSES/cloud.google.com/go/osconfig/000077500000000000000000000000001477773331400245165ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/cloud.google.com/go/osconfig/agentendpoint/000077500000000000000000000000001477773331400273555ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/cloud.google.com/go/osconfig/agentendpoint/apiv1/000077500000000000000000000000001477773331400303755ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/cloud.google.com/go/osconfig/agentendpoint/apiv1/LICENSE000066400000000000000000000261361477773331400314120ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. osconfig-20250416.02/THIRD_PARTY_LICENSES/cloud.google.com/go/storage/000077500000000000000000000000001477773331400243535ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/cloud.google.com/go/storage/LICENSE000066400000000000000000000261361477773331400253700ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. osconfig-20250416.02/THIRD_PARTY_LICENSES/cos.googlesource.com/000077500000000000000000000000001477773331400232015ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/cos.googlesource.com/cos/000077500000000000000000000000001477773331400237655ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/cos.googlesource.com/cos/tools.git/000077500000000000000000000000001477773331400257075ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/cos.googlesource.com/cos/tools.git/src/000077500000000000000000000000001477773331400264765ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/cos.googlesource.com/cos/tools.git/src/pkg/000077500000000000000000000000001477773331400272575ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/cos.googlesource.com/cos/tools.git/src/pkg/LICENSE000066400000000000000000000010501477773331400302600ustar00rootroot00000000000000Copyright 2020 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/000077500000000000000000000000001477773331400212035ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/GoogleCloudPlatform/000077500000000000000000000000001477773331400251135ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/GoogleCloudPlatform/guest-logging-go/000077500000000000000000000000001477773331400302715ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/GoogleCloudPlatform/guest-logging-go/logger/000077500000000000000000000000001477773331400315505ustar00rootroot00000000000000LICENSE000066400000000000000000000261351477773331400325050ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/GoogleCloudPlatform/guest-logging-go/logger Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/GoogleCloudPlatform/osconfig/000077500000000000000000000000001477773331400267225ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/GoogleCloudPlatform/osconfig/LICENSE000066400000000000000000000261351477773331400277360ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/golang/000077500000000000000000000000001477773331400224525ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/golang/glog/000077500000000000000000000000001477773331400234025ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/golang/glog/LICENSE000066400000000000000000000240411477773331400244100ustar00rootroot00000000000000Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/golang/groupcache/000077500000000000000000000000001477773331400245725ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/golang/groupcache/lru/000077500000000000000000000000001477773331400253745ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/golang/groupcache/lru/LICENSE000066400000000000000000000240411477773331400264020ustar00rootroot00000000000000Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/golang/mock/000077500000000000000000000000001477773331400234035ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/golang/mock/gomock/000077500000000000000000000000001477773331400246625ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/golang/mock/gomock/LICENSE000066400000000000000000000261361477773331400256770ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/golang/protobuf/000077500000000000000000000000001477773331400243125ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/golang/protobuf/LICENSE000066400000000000000000000027101477773331400253170ustar00rootroot00000000000000Copyright 2010 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/google/000077500000000000000000000000001477773331400224575ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/google/go-cmp/000077500000000000000000000000001477773331400236415ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/google/go-cmp/cmp/000077500000000000000000000000001477773331400244205ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/google/go-cmp/cmp/LICENSE000066400000000000000000000027071477773331400254330ustar00rootroot00000000000000Copyright (c) 2017 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/googleapis/000077500000000000000000000000001477773331400233345ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/googleapis/gax-go/000077500000000000000000000000001477773331400245165ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/googleapis/gax-go/v2/000077500000000000000000000000001477773331400250455ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/googleapis/gax-go/v2/LICENSE000066400000000000000000000026771477773331400260660ustar00rootroot00000000000000Copyright 2016, Google Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/julienschmidt/000077500000000000000000000000001477773331400240455ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/julienschmidt/httprouter/000077500000000000000000000000001477773331400262655ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/julienschmidt/httprouter/LICENSE000066400000000000000000000027621477773331400273010ustar00rootroot00000000000000BSD 3-Clause License Copyright (c) 2013, Julien Schmidt All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/pkg/000077500000000000000000000000001477773331400217645ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/pkg/errors/000077500000000000000000000000001477773331400233005ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/pkg/errors/LICENSE000066400000000000000000000024401477773331400243050ustar00rootroot00000000000000Copyright (c) 2015, Dave Cheney All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/sirupsen/000077500000000000000000000000001477773331400230535ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/sirupsen/logrus/000077500000000000000000000000001477773331400243665ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/sirupsen/logrus/LICENSE000066400000000000000000000020721477773331400253740ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2014 Simon Eskildsen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/tarm/000077500000000000000000000000001477773331400221465ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/tarm/serial/000077500000000000000000000000001477773331400234255ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/tarm/serial/LICENSE000066400000000000000000000027071477773331400244400ustar00rootroot00000000000000Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/ulikunitz/000077500000000000000000000000001477773331400232415ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/ulikunitz/xz/000077500000000000000000000000001477773331400237025ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/github.com/ulikunitz/xz/LICENSE000066400000000000000000000026471477773331400247200ustar00rootroot00000000000000Copyright (c) 2014-2021 Ulrich Kunitz All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * My name, Ulrich Kunitz, may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. osconfig-20250416.02/THIRD_PARTY_LICENSES/go.chromium.org/000077500000000000000000000000001477773331400221615ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/go.chromium.org/luci/000077500000000000000000000000001477773331400231155ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/go.chromium.org/luci/LICENSE000066400000000000000000000261231477773331400241260ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2014 The LUCI Authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. osconfig-20250416.02/THIRD_PARTY_LICENSES/go.opencensus.io/000077500000000000000000000000001477773331400223405ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/go.opencensus.io/LICENSE000066400000000000000000000261351477773331400233540ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.osconfig-20250416.02/THIRD_PARTY_LICENSES/golang.org/000077500000000000000000000000001477773331400212015ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/golang.org/x/000077500000000000000000000000001477773331400214505ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/golang.org/x/crypto/000077500000000000000000000000001477773331400227705ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/golang.org/x/crypto/LICENSE000066400000000000000000000027071477773331400240030ustar00rootroot00000000000000Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. osconfig-20250416.02/THIRD_PARTY_LICENSES/golang.org/x/net/000077500000000000000000000000001477773331400222365ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/golang.org/x/net/LICENSE000066400000000000000000000027071477773331400232510ustar00rootroot00000000000000Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. osconfig-20250416.02/THIRD_PARTY_LICENSES/golang.org/x/oauth2/000077500000000000000000000000001477773331400226525ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/golang.org/x/oauth2/LICENSE000066400000000000000000000027071477773331400236650ustar00rootroot00000000000000Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. osconfig-20250416.02/THIRD_PARTY_LICENSES/golang.org/x/sync/000077500000000000000000000000001477773331400224245ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/golang.org/x/sync/semaphore/000077500000000000000000000000001477773331400244075ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/golang.org/x/sync/semaphore/LICENSE000066400000000000000000000027071477773331400254220ustar00rootroot00000000000000Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. osconfig-20250416.02/THIRD_PARTY_LICENSES/golang.org/x/sys/000077500000000000000000000000001477773331400222665ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/golang.org/x/sys/LICENSE000066400000000000000000000027071477773331400233010ustar00rootroot00000000000000Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. osconfig-20250416.02/THIRD_PARTY_LICENSES/golang.org/x/text/000077500000000000000000000000001477773331400224345ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/golang.org/x/text/LICENSE000066400000000000000000000027071477773331400234470ustar00rootroot00000000000000Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. osconfig-20250416.02/THIRD_PARTY_LICENSES/google.golang.org/000077500000000000000000000000001477773331400224545ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/google.golang.org/api/000077500000000000000000000000001477773331400232255ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/google.golang.org/api/LICENSE000066400000000000000000000027031477773331400242340ustar00rootroot00000000000000Copyright (c) 2011 Google Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. osconfig-20250416.02/THIRD_PARTY_LICENSES/google.golang.org/api/internal/000077500000000000000000000000001477773331400250415ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/google.golang.org/api/internal/third_party/000077500000000000000000000000001477773331400273725ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/google.golang.org/api/internal/third_party/uritemplates/000077500000000000000000000000001477773331400321105ustar00rootroot00000000000000LICENSE000066400000000000000000000027061477773331400330430ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/google.golang.org/api/internal/third_party/uritemplatesCopyright (c) 2013 Joshua Tacoma. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. osconfig-20250416.02/THIRD_PARTY_LICENSES/google.golang.org/genproto/000077500000000000000000000000001477773331400243115ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/google.golang.org/genproto/LICENSE000066400000000000000000000261361477773331400253260ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. osconfig-20250416.02/THIRD_PARTY_LICENSES/google.golang.org/grpc/000077500000000000000000000000001477773331400234075ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/google.golang.org/grpc/LICENSE000066400000000000000000000261361477773331400244240ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. osconfig-20250416.02/THIRD_PARTY_LICENSES/google.golang.org/protobuf/000077500000000000000000000000001477773331400243145ustar00rootroot00000000000000osconfig-20250416.02/THIRD_PARTY_LICENSES/google.golang.org/protobuf/LICENSE000066400000000000000000000027071477773331400253270ustar00rootroot00000000000000Copyright (c) 2018 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. osconfig-20250416.02/agentconfig/000077500000000000000000000000001477773331400163125ustar00rootroot00000000000000osconfig-20250416.02/agentconfig/agentconfig.go000066400000000000000000000531311477773331400211300ustar00rootroot00000000000000// Copyright 2018 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package agentconfig stores and retrieves configuration settings for the OS Config agent. package agentconfig import ( "context" "crypto/sha256" "encoding/json" "flag" "fmt" "io/ioutil" "net" "net/http" "net/url" "os" "path/filepath" "runtime" "strconv" "strings" "sync" "time" "cloud.google.com/go/compute/metadata" "github.com/GoogleCloudPlatform/osconfig/clog" "golang.org/x/oauth2/jws" ) const ( // metadataIP is the documented metadata server IP address. metadataIP = "169.254.169.254" // metadataHostEnv is the environment variable specifying the // GCE metadata hostname. metadataHostEnv = "GCE_METADATA_HOST" // InstanceMetadata is the compute metadata URL. InstanceMetadata = "http://metadata.google.internal/computeMetadata/v1/instance" // IdentityTokenPath is the instance identity token path. IdentityTokenPath = "instance/service-accounts/default/identity?audience=osconfig.googleapis.com&format=full" // ReportURL is the guest attributes endpoint. ReportURL = InstanceMetadata + "/guest-attributes" googetRepoDir = "C:/ProgramData/GooGet/repos" googetRepoFilePath = googetRepoDir + "/google_osconfig_managed.repo" zypperRepoDir = "/etc/zypp/repos.d" zypperRepoFilePath = zypperRepoDir + "/google_osconfig_managed.repo" yumRepoDir = "/etc/yum.repos.d" yumRepoFilePath = yumRepoDir + "/google_osconfig_managed.repo" aptRepoDir = "/etc/apt/sources.list.d" aptRepoFilePath = aptRepoDir + "/google_osconfig_managed.list" prodEndpoint = "{zone}-osconfig.googleapis.com.:443" osInventoryEnabledDefault = false guestPoliciesEnabledDefault = false taskNotificationEnabledDefault = false debugEnabledDefault = false oldConfigDirLinux = "/etc/osconfig" cacheDirLinux = "/var/lib/google_osconfig_agent" windowsCacheDir = `Google\OSConfig` taskStateFileLinux = cacheDirLinux + "/osconfig_task.state" oldTaskStateFileLinux = oldConfigDirLinux + "/osconfig_task.state" oldCacheDirWindows = `C:\Program Files\Google\OSConfig` oldTaskStateFileWindows = oldCacheDirWindows + "\\osconfig_task.state" restartFileLinux = cacheDirLinux + "/osconfig_agent_restart_required" oldRestartFileLinux = oldConfigDirLinux + "/osconfig_agent_restart_required" osConfigPollIntervalDefault = 10 osConfigMetadataPollTimeout = 60 ) var ( endpoint = flag.String("endpoint", prodEndpoint, "osconfig endpoint override") debug = flag.Bool("debug", false, "set debug log verbosity") stdout = flag.Bool("stdout", false, "log to stdout") disableLocalLogging = flag.Bool("disable_local_logging", false, "disable logging using event log or syslog") agentConfig = &config{} agentConfigMx sync.RWMutex version string lEtag = &lastEtag{Etag: "0"} // Current supported capabilites for this agent. // These are matched server side to what tasks this agent can // perform. capabilities = []string{"PATCH_GA", "GUEST_POLICY_BETA", "CONFIG_V1"} osConfigWatchConfigTimeout = 10 * time.Minute defaultClient = &http.Client{ Transport: &http.Transport{ Dial: (&net.Dialer{ Timeout: 2 * time.Second, KeepAlive: 30 * time.Second, }).Dial, }, } freeOSMemory = strings.ToLower(os.Getenv("OSCONFIG_FREE_OS_MEMORY")) disableInventoryWrite = strings.ToLower(os.Getenv("OSCONFIG_DISABLE_INVENTORY_WRITE")) ) type config struct { aptRepoFilePath string instanceName string instanceZone string projectID string svcEndpoint string googetRepoFilePath string zypperRepoFilePath string yumRepoFilePath string instanceID string numericProjectID int64 osConfigPollInterval int debugEnabled bool taskNotificationEnabled bool guestPoliciesEnabled bool osInventoryEnabled bool guestAttributesEnabled bool } func (c *config) parseFeatures(features string, enabled bool) { for _, f := range strings.Split(features, ",") { f = strings.ToLower(strings.TrimSpace(f)) switch f { case "tasks", "ospatch": // ospatch is the legacy flag c.taskNotificationEnabled = enabled case "guestpolicies", "ospackage": // ospackage is the legacy flag c.guestPoliciesEnabled = enabled case "osinventory": c.osInventoryEnabled = enabled } } } func (c *config) asSha256() string { h := sha256.New() h.Write([]byte(fmt.Sprintf("%v", c))) return fmt.Sprintf("%x", h.Sum(nil)) } func getAgentConfig() config { agentConfigMx.RLock() defer agentConfigMx.RUnlock() return *agentConfig } type lastEtag struct { Etag string mu sync.RWMutex } func (e *lastEtag) set(etag string) { e.mu.Lock() defer e.mu.Unlock() e.Etag = etag } func (e *lastEtag) get() string { e.mu.RLock() defer e.mu.RUnlock() return e.Etag } func parseBool(s string) bool { enabled, err := strconv.ParseBool(s) if err != nil { // Bad entry returns as not enabled. return false } return enabled } type metadataJSON struct { Instance instanceJSON Project projectJSON } type instanceJSON struct { Attributes attributesJSON ID *json.Number Zone string Name string } type projectJSON struct { Attributes attributesJSON ProjectID string NumericProjectID int64 } type attributesJSON struct { PollIntervalOld *json.Number `json:"os-config-poll-interval"` PollInterval *json.Number `json:"osconfig-poll-interval"` InventoryEnabledOld string `json:"os-inventory-enabled"` InventoryEnabled string `json:"enable-os-inventory"` PreReleaseFeaturesOld string `json:"os-config-enabled-prerelease-features"` PreReleaseFeatures string `json:"osconfig-enabled-prerelease-features"` DebugEnabledOld string `json:"enable-os-config-debug"` LogLevel string `json:"osconfig-log-level"` OSConfigEndpointOld string `json:"os-config-endpoint"` OSConfigEndpoint string `json:"osconfig-endpoint"` OSConfigEnabled string `json:"enable-osconfig"` DisabledFeatures string `json:"osconfig-disabled-features"` EnableGuestAttributes string `json:"enable-guest-attributes"` } func createConfigFromMetadata(md metadataJSON) *config { old := getAgentConfig() c := &config{ osInventoryEnabled: osInventoryEnabledDefault, guestPoliciesEnabled: guestPoliciesEnabledDefault, taskNotificationEnabled: taskNotificationEnabledDefault, debugEnabled: debugEnabledDefault, svcEndpoint: prodEndpoint, osConfigPollInterval: osConfigPollIntervalDefault, googetRepoFilePath: googetRepoFilePath, zypperRepoFilePath: zypperRepoFilePath, yumRepoFilePath: yumRepoFilePath, aptRepoFilePath: aptRepoFilePath, projectID: old.projectID, numericProjectID: old.numericProjectID, instanceZone: old.instanceZone, instanceName: old.instanceName, instanceID: old.instanceID, } if md.Project.ProjectID != "" { c.projectID = md.Project.ProjectID } if md.Project.NumericProjectID != 0 { c.numericProjectID = md.Project.NumericProjectID } if md.Instance.Zone != "" { c.instanceZone = md.Instance.Zone } if md.Instance.Name != "" { c.instanceName = md.Instance.Name } if md.Instance.ID != nil { c.instanceID = md.Instance.ID.String() } // Check project first then instance as instance metadata overrides project. switch { case md.Project.Attributes.InventoryEnabled != "": c.osInventoryEnabled = parseBool(md.Project.Attributes.InventoryEnabled) case md.Project.Attributes.InventoryEnabledOld != "": c.osInventoryEnabled = parseBool(md.Project.Attributes.InventoryEnabledOld) } c.parseFeatures(md.Project.Attributes.PreReleaseFeaturesOld, true) c.parseFeatures(md.Project.Attributes.PreReleaseFeatures, true) if md.Project.Attributes.OSConfigEnabled != "" { e := parseBool(md.Project.Attributes.OSConfigEnabled) c.taskNotificationEnabled = e c.guestPoliciesEnabled = e c.osInventoryEnabled = e } c.parseFeatures(md.Project.Attributes.DisabledFeatures, false) switch { case md.Instance.Attributes.InventoryEnabled != "": c.osInventoryEnabled = parseBool(md.Instance.Attributes.InventoryEnabled) case md.Instance.Attributes.InventoryEnabledOld != "": c.osInventoryEnabled = parseBool(md.Instance.Attributes.InventoryEnabledOld) } c.parseFeatures(md.Instance.Attributes.PreReleaseFeaturesOld, true) c.parseFeatures(md.Instance.Attributes.PreReleaseFeatures, true) if md.Instance.Attributes.OSConfigEnabled != "" { e := parseBool(md.Instance.Attributes.OSConfigEnabled) c.taskNotificationEnabled = e c.guestPoliciesEnabled = e c.osInventoryEnabled = e } c.parseFeatures(md.Instance.Attributes.DisabledFeatures, false) switch { case md.Project.Attributes.PollInterval != nil: if val, err := md.Project.Attributes.PollInterval.Int64(); err == nil { c.osConfigPollInterval = int(val) } case md.Project.Attributes.PollIntervalOld != nil: if val, err := md.Project.Attributes.PollIntervalOld.Int64(); err == nil { c.osConfigPollInterval = int(val) } } switch { case md.Instance.Attributes.PollInterval != nil: if val, err := md.Instance.Attributes.PollInterval.Int64(); err == nil { c.osConfigPollInterval = int(val) } case md.Instance.Attributes.PollIntervalOld != nil: if val, err := md.Instance.Attributes.PollInterval.Int64(); err == nil { c.osConfigPollInterval = int(val) } } switch { case md.Project.Attributes.DebugEnabledOld != "": c.debugEnabled = parseBool(md.Project.Attributes.DebugEnabledOld) case md.Instance.Attributes.DebugEnabledOld != "": c.debugEnabled = parseBool(md.Instance.Attributes.DebugEnabledOld) } switch strings.ToLower(md.Project.Attributes.LogLevel) { case "debug": c.debugEnabled = true case "info": c.debugEnabled = false } switch strings.ToLower(md.Instance.Attributes.LogLevel) { case "debug": c.debugEnabled = true case "info": c.debugEnabled = false } if md.Project.Attributes.EnableGuestAttributes != "" { c.guestAttributesEnabled = parseBool(md.Project.Attributes.EnableGuestAttributes) } if md.Instance.Attributes.EnableGuestAttributes != "" { c.guestAttributesEnabled = parseBool(md.Instance.Attributes.EnableGuestAttributes) } // Flags take precedence over metadata. if *debug { c.debugEnabled = true } setSVCEndpoint(md, c) return c } func setSVCEndpoint(md metadataJSON, c *config) { switch { case *endpoint != prodEndpoint: c.svcEndpoint = *endpoint case md.Instance.Attributes.OSConfigEndpoint != "": c.svcEndpoint = md.Instance.Attributes.OSConfigEndpoint case md.Instance.Attributes.OSConfigEndpointOld != "": c.svcEndpoint = md.Instance.Attributes.OSConfigEndpointOld case md.Project.Attributes.OSConfigEndpoint != "": c.svcEndpoint = md.Project.Attributes.OSConfigEndpoint case md.Project.Attributes.OSConfigEndpointOld != "": c.svcEndpoint = md.Project.Attributes.OSConfigEndpointOld } // Example instanceZone: projects/123456/zones/us-west1-b parts := strings.Split(c.instanceZone, "/") zone := parts[len(parts)-1] c.svcEndpoint = strings.ReplaceAll(c.svcEndpoint, "{zone}", zone) } func formatMetadataError(err error) error { if urlErr, ok := err.(*url.Error); ok { if _, ok := urlErr.Err.(*net.DNSError); ok { return fmt.Errorf("DNS error when requesting metadata, check DNS settings and ensure metadata.google.internal is setup in your hosts file: %w", err) } if _, ok := urlErr.Err.(*net.OpError); ok { return fmt.Errorf("network error when requesting metadata, make sure your instance has an active network and can reach the metadata server: %w", err) } } return err } func getMetadata(suffix string) ([]byte, string, error) { host := os.Getenv(metadataHostEnv) if host == "" { // Using 169.254.169.254 instead of "metadata" here because Go // binaries built with the "netgo" tag and without cgo won't // know the search suffix for "metadata" is // ".google.internal", and this IP address is documented as // being stable anyway. host = metadataIP } computeMetadataURL := "http://" + host + "/computeMetadata/v1/" + suffix req, err := http.NewRequest("GET", computeMetadataURL, nil) if err != nil { return nil, "", err } req.Header.Add("Metadata-Flavor", "Google") resp, err := defaultClient.Do(req) if err != nil { return nil, "", err } defer resp.Body.Close() if resp.StatusCode == http.StatusNotFound { return nil, "", err } if resp.StatusCode != http.StatusOK { return nil, "", err } all, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, "", err } return all, resp.Header.Get("Etag"), nil } // GetCacheDirWindows returns the folder for the temp files location on Windows. func GetCacheDirWindows() string { cacheDir, dirErr := os.UserCacheDir() if dirErr != nil { cacheDir = os.TempDir() } return filepath.Join(cacheDir, windowsCacheDir) } // WatchConfig looks for changes in metadata keys. Upon receiving successful response, // it create a new agent config. func WatchConfig(ctx context.Context) error { var md []byte var webError error // Max watch time, after this WatchConfig will return. timeout := time.After(osConfigWatchConfigTimeout) // Min watch loop time. loopTicker := time.NewTicker(5 * time.Second) defer loopTicker.Stop() eTag := lEtag.get() webErrorCount := 0 unmarshalErrorCount := 0 for { md, eTag, webError = getMetadata(fmt.Sprintf("?recursive=true&alt=json&wait_for_change=true&last_etag=%s&timeout_sec=%d", lEtag.get(), osConfigMetadataPollTimeout)) if webError == nil && eTag != lEtag.get() { var metadataConfig metadataJSON if err := json.Unmarshal(md, &metadataConfig); err != nil { // Try up to three times (with 5s sleep) to get and unmarshal metadata. // Most unmarshal errors are transient read issues with the metadata server // so we should retry without logging the error. if unmarshalErrorCount >= 3 { return err } unmarshalErrorCount++ select { case <-timeout: return err case <-ctx.Done(): return nil case <-loopTicker.C: continue } } unmarshalErrorCount = 0 lEtag.set(eTag) newAgentConfig := createConfigFromMetadata(metadataConfig) agentConfigMx.Lock() if agentConfig.asSha256() != newAgentConfig.asSha256() { agentConfig = newAgentConfig agentConfigMx.Unlock() break } agentConfigMx.Unlock() } // Try up to 12 times (60s) to wait for slow network initialization, after // that resort to using defaults and returning the error. if webError != nil { if webErrorCount == 12 { return formatMetadataError(webError) } webErrorCount++ } select { case <-timeout: return webError case <-ctx.Done(): return nil case <-loopTicker.C: continue } } return webError } // LogFeatures logs the osconfig feature status. func LogFeatures(ctx context.Context) { clog.Infof(ctx, "OSConfig enabled features status:{GuestPolicies: %t, OSInventory: %t, PatchManagement: %t}.", GuestPoliciesEnabled(), OSInventoryEnabled(), TaskNotificationEnabled()) } // SvcPollInterval returns the frequency to poll the service. func SvcPollInterval() time.Duration { return time.Duration(getAgentConfig().osConfigPollInterval) * time.Minute } // SerialLogPort is the serial port to log to. func SerialLogPort() string { if runtime.GOOS == "windows" { return "COM1" } // Don't write directly to the serial port on Linux as syslog already writes there. return "" } // Debug sets the debug log verbosity. func Debug() bool { return *debug || getAgentConfig().debugEnabled } // Stdout flag. func Stdout() bool { return *stdout } // DisableLocalLogging flag. func DisableLocalLogging() bool { return *disableLocalLogging } // SvcEndpoint is the OS Config service endpoint. func SvcEndpoint() string { return getAgentConfig().svcEndpoint } // ZypperRepoDir is the location of the zypper repo files. func ZypperRepoDir() string { return zypperRepoDir } // ZypperRepoFormat is the format of the zypper repo files. func ZypperRepoFormat() string { return filepath.Join(zypperRepoDir, "osconfig_managed_%s.repo") } // ZypperRepoFilePath is the location where the zypper repo file will be created. func ZypperRepoFilePath() string { return getAgentConfig().zypperRepoFilePath } // YumRepoDir is the location of the yum repo files. func YumRepoDir() string { return yumRepoDir } // YumRepoFormat is the format of the yum repo files. func YumRepoFormat() string { return filepath.Join(yumRepoDir, "osconfig_managed_%s.repo") } // YumRepoFilePath is the location where the yum repo file will be created. func YumRepoFilePath() string { return getAgentConfig().yumRepoFilePath } // AptRepoDir is the location of the apt repo files. func AptRepoDir() string { return aptRepoDir } // AptRepoFormat is the format of the apt repo files. func AptRepoFormat() string { return filepath.Join(aptRepoDir, "osconfig_managed_%s.list") } // AptRepoFilePath is the location where the apt repo file will be created. func AptRepoFilePath() string { return getAgentConfig().aptRepoFilePath } // GooGetRepoDir is the location of the googet repo files. func GooGetRepoDir() string { return googetRepoDir } // GooGetRepoFormat is the format of the googet repo files. func GooGetRepoFormat() string { return filepath.Join(googetRepoDir, "osconfig_managed_%s.repo") } // GooGetRepoFilePath is the location where the googet repo file will be created. func GooGetRepoFilePath() string { return getAgentConfig().googetRepoFilePath } // OSInventoryEnabled indicates whether OSInventory should be enabled. func OSInventoryEnabled() bool { return getAgentConfig().osInventoryEnabled } // GuestPoliciesEnabled indicates whether GuestPolicies should be enabled. func GuestPoliciesEnabled() bool { return getAgentConfig().guestPoliciesEnabled } // TaskNotificationEnabled indicates whether TaskNotification should be enabled. func TaskNotificationEnabled() bool { return getAgentConfig().taskNotificationEnabled } // Instance is the URI of the instance the agent is running on. func Instance() string { // Zone contains 'projects/project-id/zones' as a prefix. return fmt.Sprintf("%s/instances/%s", Zone(), Name()) } // NumericProjectID is the numeric project ID of the instance. func NumericProjectID() int64 { return getAgentConfig().numericProjectID } // ProjectID is the project ID of the instance. func ProjectID() string { return getAgentConfig().projectID } // Zone is the zone the instance is running in. func Zone() string { return getAgentConfig().instanceZone } // Name is the instance name. func Name() string { return getAgentConfig().instanceName } // ID is the instance id. func ID() string { return getAgentConfig().instanceID } // GuestAttributesEnabled is a boolean flag that signal that guest attributes feature is enabled. func GuestAttributesEnabled() bool { return getAgentConfig().guestAttributesEnabled } type idToken struct { exp *time.Time raw string sync.Mutex } func (t *idToken) get() error { data, err := metadata.Get(IdentityTokenPath) if err != nil { return fmt.Errorf("error getting token from metadata: %w", err) } cs, err := jws.Decode(data) if err != nil { return err } t.raw = data exp := time.Unix(cs.Exp, 0) t.exp = &exp return nil } var identity idToken // IDToken is the instance id token. func IDToken() (string, error) { identity.Lock() defer identity.Unlock() // Rerequest token if expiry is within 10 minutes. if identity.exp == nil || time.Now().After(identity.exp.Add(-10*time.Minute)) { if err := identity.get(); err != nil { return "", err } } return identity.raw, nil } // Version is the agent version. func Version() string { return version } // SetVersion sets the agent version. func SetVersion(v string) { version = v } // Capabilities returns the agents capabilities. func Capabilities() []string { return capabilities } // TaskStateFile is the location of the task state file. func TaskStateFile() string { if runtime.GOOS == "windows" { return filepath.Join(GetCacheDirWindows(), "osconfig_task.state") } return taskStateFileLinux } // OldTaskStateFile is the location of the task state file. func OldTaskStateFile() string { if runtime.GOOS == "windows" { return oldTaskStateFileWindows } return oldTaskStateFileLinux } // RestartFile is the location of the restart required file. func RestartFile() string { if runtime.GOOS == "windows" { return filepath.Join( GetCacheDirWindows(), "osconfig_agent_restart_required") } return restartFileLinux } // OldRestartFile is the location of the restart required file. func OldRestartFile() string { return oldRestartFileLinux } // CacheDir is the location of the cache directory. func CacheDir() string { if runtime.GOOS == "windows" { return GetCacheDirWindows() } return cacheDirLinux } // UserAgent for creating http/grpc clients. func UserAgent() string { return "google-osconfig-agent/" + Version() } // DisableInventoryWrite returns true if the DisableInventoryWrite setting is set. func DisableInventoryWrite() bool { return strings.EqualFold(disableInventoryWrite, "true") || disableInventoryWrite == "1" } // FreeOSMemory returns true if the FreeOSMemory setting is set. func FreeOSMemory() bool { return strings.EqualFold(freeOSMemory, "true") || freeOSMemory == "1" } osconfig-20250416.02/agentconfig/agentconfig_test.go000066400000000000000000000204571477773331400221740ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package agentconfig import ( "context" "fmt" "net/http" "net/http/httptest" "os" "path/filepath" "reflect" "runtime" "strings" "testing" "time" ) func TestWatchConfig(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, `{"project":{"numericProjectID":12345,"projectId":"projectId","attributes":{"osconfig-endpoint":"bad!!1","enable-os-inventory":"false"}},"instance":{"id":12345,"name":"name","zone":"zone","attributes":{"osconfig-endpoint":"SvcEndpoint","enable-os-inventory":"1","enable-os-config-debug":"true","osconfig-enabled-prerelease-features":"ospackage,ospatch", "osconfig-poll-interval":"3"}}}`) })) defer ts.Close() if err := os.Setenv("GCE_METADATA_HOST", strings.Trim(ts.URL, "http://")); err != nil { t.Fatalf("Error running os.Setenv: %v", err) } if err := WatchConfig(context.Background()); err != nil { t.Fatalf("Error running WatchConfig: %v", err) } testsString := []struct { desc string op func() string want string }{ {"SvcEndpoint", SvcEndpoint, "SvcEndpoint"}, {"Instance", Instance, "zone/instances/name"}, {"ID", ID, "12345"}, {"ProjectID", ProjectID, "projectId"}, {"Zone", Zone, "zone"}, {"Name", Name, "name"}, } for _, tt := range testsString { if tt.op() != tt.want { t.Errorf("%q: got(%q) != want(%q)", tt.desc, tt.op(), tt.want) } } testsBool := []struct { desc string op func() bool want bool }{ {"osinventory should be enabled (proj disabled, inst enabled)", OSInventoryEnabled, true}, {"taskNotification should be enabled (inst enabled)", TaskNotificationEnabled, true}, {"guestpolicies should be enabled (proj enabled)", GuestPoliciesEnabled, true}, {"debugenabled should be true (proj disabled, inst enabled)", Debug, true}, } for _, tt := range testsBool { if tt.op() != tt.want { t.Errorf("%q: got(%t) != want(%t)", tt.desc, tt.op(), tt.want) } } if SvcPollInterval().Minutes() != float64(3) { t.Errorf("Default poll interval: got(%f) != want(%d)", SvcPollInterval().Minutes(), 3) } if NumericProjectID() != 12345 { t.Errorf("NumericProjectID: got(%v) != want(%d)", NumericProjectID(), 12345) } if Instance() != "zone/instances/name" { t.Errorf("zone: got(%s) != want(%s)", Instance(), "zone/instances/name") } } func TestSetConfigEnabled(t *testing.T) { var request int ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch request { case 0: w.Header().Set("Etag", "etag-0") fmt.Fprintln(w, `{"project":{"attributes":{"enable-osconfig":"false"}},"instance":{"attributes":{"enable-osconfig":"false"}}}`) case 1: w.Header().Set("Etag", "etag-1") fmt.Fprintln(w, `{"project":{"attributes":{"enable-osconfig":"false"}},"instance":{"attributes":{"enable-osconfig":"true"}}}`) case 2: w.Header().Set("Etag", "etag-2") fmt.Fprintln(w, `{"project":{"attributes":{"enable-osconfig":"false"}},"instance":{"attributes":{"enable-osconfig":"false"}}}`) case 3: w.Header().Set("Etag", "etag-3") fmt.Fprintln(w, `{"project":{"attributes":{"enable-osconfig":"true","osconfig-disabled-features":"osinventory"}}}`) } })) defer ts.Close() if err := os.Setenv("GCE_METADATA_HOST", strings.Trim(ts.URL, "http://")); err != nil { t.Fatalf("Error running os.Setenv: %v", err) } for i, want := range []bool{false, true, false} { request = i if err := WatchConfig(context.Background()); err != nil { t.Fatalf("Error running SetConfig: %v", err) } testsBool := []struct { desc string op func() bool }{ {"OSInventoryEnabled", OSInventoryEnabled}, {"TaskNotificationEnabled", TaskNotificationEnabled}, {"GuestPoliciesEnabled", GuestPoliciesEnabled}, } for _, tt := range testsBool { if tt.op() != want { t.Errorf("Request %d: %s: got(%t) != want(%t)", request, tt.desc, tt.op(), want) } } } request = 3 if err := WatchConfig(context.Background()); err != nil { t.Fatalf("Error running SetConfig: %v", err) } testsBool := []struct { desc string op func() bool want bool }{ {"OSInventoryEnabled", OSInventoryEnabled, false}, {"TaskNotificationEnabled", TaskNotificationEnabled, true}, {"GuestPoliciesEnabled", GuestPoliciesEnabled, true}, } for _, tt := range testsBool { if tt.op() != tt.want { t.Errorf("%s: got(%t) != want(%t)", tt.desc, tt.op(), tt.want) } } } func TestSetConfigDefaultValues(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Etag", "sample-etag") // we always get zone value in instance metadata. fmt.Fprintln(w, `{"instance": {"zone": "fake-zone"}}`) })) defer ts.Close() if err := os.Setenv("GCE_METADATA_HOST", strings.Trim(ts.URL, "http://")); err != nil { t.Fatalf("Error running os.Setenv: %v", err) } if err := WatchConfig(context.Background()); err != nil { t.Fatalf("Error running SetConfig: %v", err) } testsString := []struct { op func() string want string }{ {AptRepoFilePath, aptRepoFilePath}, {YumRepoFilePath, yumRepoFilePath}, {ZypperRepoFilePath, zypperRepoFilePath}, {GooGetRepoFilePath, googetRepoFilePath}, } for _, tt := range testsString { if tt.op() != tt.want { f := filepath.Base(runtime.FuncForPC(reflect.ValueOf(tt.op).Pointer()).Name()) t.Errorf("%q: got(%q) != want(%q)", f, tt.op(), tt.want) } } testsBool := []struct { op func() bool want bool }{ {OSInventoryEnabled, osInventoryEnabledDefault}, {TaskNotificationEnabled, taskNotificationEnabledDefault}, {GuestPoliciesEnabled, guestPoliciesEnabledDefault}, {Debug, debugEnabledDefault}, } for _, tt := range testsBool { if tt.op() != tt.want { f := filepath.Base(runtime.FuncForPC(reflect.ValueOf(tt.op).Pointer()).Name()) t.Errorf("%q: got(%t) != want(%t)", f, tt.op(), tt.want) } } if SvcPollInterval().Minutes() != float64(osConfigPollIntervalDefault) { t.Errorf("Default poll interval: got(%f) != want(%d)", SvcPollInterval().Minutes(), osConfigPollIntervalDefault) } expectedEndpoint := "fake-zone-osconfig.googleapis.com.:443" if SvcEndpoint() != expectedEndpoint { t.Errorf("Default endpoint: got(%s) != want(%s)", SvcEndpoint(), expectedEndpoint) } } func TestVersion(t *testing.T) { if Version() != "" { t.Errorf("Unexpected version %q, want \"\"", Version()) } var v = "1" SetVersion(v) if Version() != v { t.Errorf("Unexpected version %q, want %q", Version(), v) } } func TestSvcEndpoint(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Etag", "sametag") // we always get zone value in instance metadata. fmt.Fprintln(w, `{"instance": {"id": 12345,"name": "name","zone": "fakezone","attributes": {"osconfig-endpoint": "{zone}-dev.osconfig.googleapis.com"}}}`) })) defer ts.Close() if err := os.Setenv("GCE_METADATA_HOST", strings.Trim(ts.URL, "http://")); err != nil { t.Fatalf("Error running os.Setenv: %v", err) } if err := WatchConfig(context.Background()); err != nil { t.Fatalf("Error running SetConfig: %v", err) } expectedSvcEndpoint := "fakezone-dev.osconfig.googleapis.com" if SvcEndpoint() != expectedSvcEndpoint { t.Errorf("Default endpoint: got(%s) != want(%s)", SvcEndpoint(), expectedSvcEndpoint) } } func TestSetConfigError(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { })) defer ts.Close() if err := os.Setenv("GCE_METADATA_HOST", strings.Trim(ts.URL, "http://")); err != nil { t.Fatalf("Error running os.Setenv: %v", err) } osConfigWatchConfigTimeout = 1 * time.Millisecond if err := WatchConfig(context.Background()); err == nil || !strings.Contains(err.Error(), "unexpected end of JSON input") { t.Errorf("Unexpected output %+v", err) } } osconfig-20250416.02/agentendpoint/000077500000000000000000000000001477773331400166655ustar00rootroot00000000000000osconfig-20250416.02/agentendpoint/agentendpoint.go000066400000000000000000000312731477773331400220610ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package agentendpoint connects to the osconfig agentendpoint api. package agentendpoint import ( "context" "errors" "fmt" "io" "sync" "time" "cloud.google.com/go/compute/metadata" agentendpoint "cloud.google.com/go/osconfig/agentendpoint/apiv1" "github.com/GoogleCloudPlatform/osconfig/agentconfig" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/osinfo" "github.com/GoogleCloudPlatform/osconfig/retryutil" "github.com/GoogleCloudPlatform/osconfig/tasker" "google.golang.org/api/option" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/keepalive" "google.golang.org/grpc/status" "cloud.google.com/go/osconfig/agentendpoint/apiv1/agentendpointpb" ) const apiRetrySec = 600 var ( errServerCancel = errors.New("task canceled by server") errServiceNotEnabled = errors.New("service is not enabled for this project") errResourceExhausted = errors.New("ResourceExhausted") taskStateFile = agentconfig.TaskStateFile() oldTaskStateFile = agentconfig.OldTaskStateFile() sameStateTimeWindow = -5 * time.Second ) // Client is a an agentendpoint client. type Client struct { raw *agentendpoint.Client cancel context.CancelFunc noti chan struct{} closed bool mx sync.Mutex } // NewClient a new agentendpoint Client. func NewClient(ctx context.Context) (*Client, error) { keepAliveConf := keepalive.ClientParameters{ Time: 100 * time.Second, Timeout: 5 * time.Second, PermitWithoutStream: true, } opts := []option.ClientOption{ // Do not use oauth. option.WithoutAuthentication(), // Because we disabled Auth we need to specifically enable TLS. option.WithGRPCDialOption(grpc.WithTransportCredentials(credentials.NewTLS(nil))), option.WithGRPCDialOption(grpc.WithKeepaliveParams(keepAliveConf)), option.WithEndpoint(agentconfig.SvcEndpoint()), option.WithUserAgent(agentconfig.UserAgent()), } clog.Debugf(ctx, "Creating new agentendpoint client.") c, err := agentendpoint.NewClient(ctx, opts...) if err != nil { return nil, err } return &Client{raw: c, noti: make(chan struct{}, 1)}, nil } // Close cancels WaitForTaskNotification and closes the underlying ClientConn. func (c *Client) Close() error { // Lock so nothing can use the client while we are closing. c.mx.Lock() if c.cancel != nil { c.cancel() } c.closed = true return c.raw.Close() } // Closed reports whether the Client has been closed. func (c *Client) Closed() bool { return c.closed } // RegisterAgent calls RegisterAgent discarding the response. func (c *Client) RegisterAgent(ctx context.Context) error { token, err := agentconfig.IDToken() if err != nil { return err } oi := &osinfo.OSInfo{} if agentconfig.OSInventoryEnabled() { oi, err = osinfo.Get() if err != nil { // Log the error but still call RegisterAgent (fields will be empty). clog.Errorf(ctx, "osinfo.Get() error: %v", err) } } req := &agentendpointpb.RegisterAgentRequest{ AgentVersion: agentconfig.Version(), SupportedCapabilities: agentconfig.Capabilities(), OsLongName: oi.LongName, OsShortName: oi.ShortName, OsVersion: oi.Version, OsArchitecture: oi.Architecture, } req.InstanceIdToken = "" clog.DebugRPC(ctx, "RegisterAgent", req, nil) req.InstanceIdToken = token var resp *agentendpointpb.RegisterAgentResponse err = retryutil.RetryAPICall(ctx, apiRetrySec*time.Second, "RegisterAgent", func() error { resp, err = c.raw.RegisterAgent(ctx, req) return err }) clog.DebugRPC(ctx, "RegisterAgent", nil, resp) return err } // reportInventory calls ReportInventory with the provided inventory. func (c *Client) reportInventory(ctx context.Context, inventory *agentendpointpb.Inventory, reportFull bool) (*agentendpointpb.ReportInventoryResponse, error) { token, err := agentconfig.IDToken() if err != nil { return nil, err } checksum, err := computeStableFingerprint(ctx, inventory) if err != nil { return nil, fmt.Errorf("unable to compute hash, err: %w", err) } req := &agentendpointpb.ReportInventoryRequest{InventoryChecksum: checksum} if reportFull { req = &agentendpointpb.ReportInventoryRequest{InventoryChecksum: checksum, Inventory: inventory} } req.InstanceIdToken = "" clog.DebugRPC(ctx, "ReportInventory", req, nil) req.InstanceIdToken = token resp, err := c.raw.ReportInventory(ctx, req) clog.DebugRPC(ctx, "ReportInventory", nil, resp) return resp, err } func (c *Client) startNextTask(ctx context.Context) (res *agentendpointpb.StartNextTaskResponse, err error) { token, err := agentconfig.IDToken() if err != nil { return nil, err } req := &agentendpointpb.StartNextTaskRequest{} req.InstanceIdToken = "" clog.DebugRPC(ctx, "StartNextTask", req, nil) req.InstanceIdToken = token err = retryutil.RetryAPICall(ctx, apiRetrySec*time.Second, "StartNextTask", func() error { res, err = c.raw.StartNextTask(ctx, req) return err }) clog.DebugRPC(ctx, "StartNextTask", nil, res) if err != nil { return nil, fmt.Errorf("error calling StartNextTask: %w", err) } return res, nil } func (c *Client) reportTaskProgress(ctx context.Context, req *agentendpointpb.ReportTaskProgressRequest) (res *agentendpointpb.ReportTaskProgressResponse, err error) { token, err := agentconfig.IDToken() if err != nil { return nil, err } req.InstanceIdToken = "" clog.DebugRPC(ctx, "ReportTaskProgress", req, nil) req.InstanceIdToken = token err = retryutil.RetryAPICall(ctx, apiRetrySec*time.Second, "ReportTaskProgress", func() error { res, err = c.raw.ReportTaskProgress(ctx, req) return err }) clog.DebugRPC(ctx, "ReportTaskProgress", nil, res) if err != nil { return nil, fmt.Errorf("error calling ReportTaskProgress: %w", err) } return res, nil } func (c *Client) reportTaskComplete(ctx context.Context, req *agentendpointpb.ReportTaskCompleteRequest) error { token, err := agentconfig.IDToken() if err != nil { return err } req.InstanceIdToken = "" clog.DebugRPC(ctx, "ReportTaskComplete", req, nil) req.InstanceIdToken = token var res *agentendpointpb.ReportTaskCompleteResponse err = retryutil.RetryAPICall(ctx, apiRetrySec*time.Second, "ReportTaskComplete", func() error { res, err = c.raw.ReportTaskComplete(ctx, req) return err }) clog.DebugRPC(ctx, "ReportTaskComplete", nil, res) if err != nil { return fmt.Errorf("error calling ReportTaskComplete: %w", err) } return nil } func (c *Client) runTask(ctx context.Context) { clog.Debugf(ctx, "Beginning run task loop.") for { res, err := c.startNextTask(ctx) if err != nil { clog.Errorf(ctx, "Error running StartNextTask, cannot continue: %v", err) return } task := res.GetTask() if task == nil { clog.Debugf(ctx, "No task to run, ending run task loop.") return } clog.Debugf(ctx, "Received task: %s.", task.GetTaskType()) ctx := clog.WithLabels(ctx, map[string]string{"task_type": task.GetTaskType().String()}) switch task.GetTaskType() { case agentendpointpb.TaskType_APPLY_PATCHES: if err := c.RunApplyPatches(ctx, task); err != nil { clog.Errorf(ctx, "Error running TaskType_APPLY_PATCHES: %v", err) } case agentendpointpb.TaskType_EXEC_STEP_TASK: if err := c.RunExecStep(ctx, task); err != nil { clog.Errorf(ctx, "Error running TaskType_EXEC_STEP_TASK: %v", err) } case agentendpointpb.TaskType_APPLY_CONFIG_TASK: if err := c.RunApplyConfig(ctx, task); err != nil { clog.Errorf(ctx, "Error running TaskType_APPLY_CONFIG_TASK: %v", err) } default: clog.Errorf(ctx, "Unknown task type: %v", task.GetTaskType()) } } } func (c *Client) handleStream(ctx context.Context, stream agentendpointpb.AgentEndpointService_ReceiveTaskNotificationClient) error { for { clog.Debugf(ctx, "Waiting on ReceiveTaskNotification stream Recv().") if _, err := stream.Recv(); err != nil { // Return on any stream error, even a close, the caller will simply // reconnect the stream as needed. return err } clog.Debugf(ctx, "Received task notification.") // Only queue up one notifcation at a time. We should only ever // have one active task being worked on and one in the queue. select { case <-ctx.Done(): // We have been canceled. return nil case c.noti <- struct{}{}: tasker.Enqueue(ctx, "TaskNotification", func() { // We lock so that this task will complete before the client can get canceled. c.mx.Lock() defer c.mx.Unlock() select { case <-ctx.Done(): // We have been canceled. default: // Take this task off the notification queue so another can be // queued up. <-c.noti c.runTask(ctx) } }) default: // Ignore the notificaction as we already have one queued. } } } func (c *Client) receiveTaskNotification(ctx context.Context) (agentendpointpb.AgentEndpointService_ReceiveTaskNotificationClient, error) { token, err := agentconfig.IDToken() if err != nil { return nil, fmt.Errorf("error fetching Instance IDToken: %w", err) } req := &agentendpointpb.ReceiveTaskNotificationRequest{ AgentVersion: agentconfig.Version(), } req.InstanceIdToken = "" clog.DebugRPC(ctx, "ReceiveTaskNotification", req, nil) req.InstanceIdToken = token resp, err := c.raw.ReceiveTaskNotification(ctx, req) return resp, err } func (c *Client) loadTaskFromState(ctx context.Context) error { st, err := loadState(taskStateFile) if err != nil { return fmt.Errorf("loadState error: %w", err) } if st != nil && st.PatchTask != nil { st.PatchTask.client = c st.PatchTask.state = st tasker.Enqueue(ctx, "PatchRun", func() { st.PatchTask.run(ctx) }) } return nil } func (c *Client) waitForTask(ctx context.Context) error { stream, err := c.receiveTaskNotification(ctx) if err != nil { return err } err = c.handleStream(ctx, stream) if err == io.EOF { // Server closed the stream indication we should reconnect. return nil } if s, ok := status.FromError(err); ok { switch s.Code() { case codes.PermissionDenied: // Service is not enabled for this project. return errServiceNotEnabled case codes.ResourceExhausted: return errResourceExhausted } } return err } // WaitForTaskNotification waits for and acts on any task notification until the Client is closed. // Multiple calls to WaitForTaskNotification will not create new watchers. func (c *Client) WaitForTaskNotification(ctx context.Context) { c.mx.Lock() defer c.mx.Unlock() if c.cancel != nil { // WaitForTaskNotification is already running on this client. return } clog.Debugf(ctx, "Running WaitForTaskNotification") ctx, c.cancel = context.WithCancel(ctx) clog.Debugf(ctx, "Checking local state file for saved task.") if err := c.loadTaskFromState(ctx); err != nil { clog.Errorf(ctx, "%v", err.Error()) } clog.Debugf(ctx, "Setting up ReceiveTaskNotification stream watcher.") go func() { var resourceExhausted int var errs int var sleep time.Duration for { select { case <-ctx.Done(): // We have been canceled. clog.Debugf(ctx, "Disabling WaitForTaskNotification") return default: } if err := c.waitForTask(ctx); err != nil { if errors.Is(err, errServiceNotEnabled) { // Service is disabled, close this client and return. clog.Warningf(ctx, "OSConfig Service is disabled.") c.Close() return } var ndr *metadata.NotDefinedError if errors.As(err, &ndr) { // No service account setup for this instance, close this client and return. clog.Warningf(ctx, "No service account set for instance.") c.Close() return } if errors.Is(err, errResourceExhausted) { resourceExhausted++ sleep = retryutil.RetrySleep(resourceExhausted, 5) } else { // Retry any other errors with a modest backoff. Only retry up to 10 // times, at that point return, the client will be recreated during the next // cycle. errs++ clog.Warningf(ctx, "Error waiting for task (attempt %d of 10): %v", errs, err) resourceExhausted = 0 if errs >= 10 { c.Close() return } sleep = retryutil.RetrySleep(errs, 0) } time.Sleep(sleep) continue } errs = 0 } }() } osconfig-20250416.02/agentendpoint/agentendpoint_beta.go000066400000000000000000000067701477773331400230600ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package agentendpoint import ( "context" "fmt" "sync" "time" agentendpoint "cloud.google.com/go/osconfig/agentendpoint/apiv1beta" "github.com/GoogleCloudPlatform/osconfig/agentconfig" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/osinfo" "github.com/GoogleCloudPlatform/osconfig/pretty" "github.com/GoogleCloudPlatform/osconfig/retryutil" "google.golang.org/api/option" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "cloud.google.com/go/osconfig/agentendpoint/apiv1beta/agentendpointpb" ) // BetaClient is a an agentendpoint client. type BetaClient struct { raw *agentendpoint.Client cancel context.CancelFunc noti chan struct{} closed bool mx sync.Mutex } // NewBetaClient a new agentendpoint Client. func NewBetaClient(ctx context.Context) (*BetaClient, error) { opts := []option.ClientOption{ option.WithoutAuthentication(), // Do not use oauth. option.WithGRPCDialOption(grpc.WithTransportCredentials(credentials.NewTLS(nil))), // Because we disabled Auth we need to specifically enable TLS. option.WithEndpoint(agentconfig.SvcEndpoint()), option.WithUserAgent(agentconfig.UserAgent()), } clog.Debugf(ctx, "Creating new agentendpoint beta client.") c, err := agentendpoint.NewClient(ctx, opts...) if err != nil { return nil, err } return &BetaClient{raw: c, noti: make(chan struct{}, 1)}, nil } // Close cancels WaitForTaskNotification and closes the underlying ClientConn. func (c *BetaClient) Close() error { // Lock so nothing can use the client while we are closing. c.mx.Lock() if c.cancel != nil { c.cancel() } c.closed = true return c.raw.Close() } // Closed reports whether the Client has been closed. func (c *BetaClient) Closed() bool { return c.closed } // LookupEffectiveGuestPolicies calls the agentendpoint service LookupEffectiveGuestPolicies. func (c *BetaClient) LookupEffectiveGuestPolicies(ctx context.Context) (res *agentendpointpb.EffectiveGuestPolicy, err error) { info, err := osinfo.Get() if err != nil { return nil, err } req := &agentendpointpb.LookupEffectiveGuestPolicyRequest{ OsShortName: info.ShortName, OsVersion: info.Version, OsArchitecture: info.Architecture, } token, err := agentconfig.IDToken() if err != nil { return nil, err } clog.Debugf(ctx, "Calling LookupEffectiveGuestPolicies with request:\n%s", pretty.Format(req)) req.InstanceIdToken = token // Only retry up to 30s for LookupEffectiveGuestPolicies in order to not hang up local configs. if err := retryutil.RetryAPICall(ctx, 30*time.Second, "LookupEffectiveGuestPolicies", func() error { res, err = c.raw.LookupEffectiveGuestPolicy(ctx, req) if err != nil { return err } clog.Debugf(ctx, "LookupEffectiveGuestPolicies response:\n%s", pretty.Format(res)) return nil }); err != nil { return nil, fmt.Errorf("error calling LookupEffectiveGuestPolicies: %w", err) } return res, nil } osconfig-20250416.02/agentendpoint/agentendpoint_test.go000066400000000000000000000262601477773331400231200ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package agentendpoint import ( "context" "crypto/rand" "crypto/rsa" "errors" "fmt" "io" "io/ioutil" "log" "net" "net/http" "net/http/httptest" "os" "path/filepath" "strings" "testing" "time" agentendpoint "cloud.google.com/go/osconfig/agentendpoint/apiv1" "github.com/GoogleCloudPlatform/guest-logging-go/logger" "golang.org/x/oauth2/jws" "google.golang.org/api/option" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/grpc/test/bufconn" "cloud.google.com/go/osconfig/agentendpoint/apiv1/agentendpointpb" ) var testIDToken string func TestMain(m *testing.M) { cs := &jws.ClaimSet{ Exp: time.Now().Add(1 * time.Hour).Unix(), } key, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { fmt.Printf("Error creating rsa key: %v", err) os.Exit(1) } testIDToken, err = jws.Encode(nil, cs, key) if err != nil { fmt.Printf("Error creating jwt token: %v", err) os.Exit(1) } ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, testIDToken) })) if err := os.Setenv("GCE_METADATA_HOST", strings.Trim(ts.URL, "http://")); err != nil { fmt.Printf("Error running os.Setenv: %v", err) os.Exit(1) } opts := logger.LogOpts{LoggerName: "OSConfigAgent", Debug: true, Writers: []io.Writer{os.Stdout}} logger.Init(context.Background(), opts) out := m.Run() ts.Close() os.Exit(out) } const bufSize = 1024 * 1024 type testClient struct { client *Client s *grpc.Server } func (c *testClient) close() { c.client.Close() c.s.Stop() } func newTestClient(ctx context.Context, srv agentendpointpb.AgentEndpointServiceServer) (*testClient, error) { lis := bufconn.Listen(bufSize) s := grpc.NewServer() agentendpointpb.RegisterAgentEndpointServiceServer(s, srv) go func() { if err := s.Serve(lis); err != nil { log.Fatalf("Server exited with error: %v", err) } }() var bufDialer = func(string, time.Duration) (net.Conn, error) { return lis.Dial() } conn, err := grpc.DialContext(ctx, "bufnet", grpc.WithDialer(bufDialer), grpc.WithInsecure()) if err != nil { return nil, err } client, err := agentendpoint.NewClient(ctx, option.WithGRPCConn(conn)) if err != nil { return nil, err } return &testClient{ client: &Client{raw: client, noti: make(chan struct{}, 1)}, s: s, }, nil } type agentEndpointServiceTestServer struct { streamClose chan struct{} streamSend chan struct{} permissionError chan struct{} taskStart bool execTaskProgress bool patchTaskProgress bool applyConfigTaskProgress bool execTaskComplete bool patchTaskComplete bool applyConfigTaskComplete bool runTaskIDs []string } func newAgentEndpointServiceTestServer() *agentEndpointServiceTestServer { return &agentEndpointServiceTestServer{ streamClose: make(chan struct{}, 1), streamSend: make(chan struct{}, 1), permissionError: make(chan struct{}, 1), } } func (s *agentEndpointServiceTestServer) ReceiveTaskNotification(req *agentendpointpb.ReceiveTaskNotificationRequest, srv agentendpointpb.AgentEndpointService_ReceiveTaskNotificationServer) error { for { select { case <-s.streamClose: return nil case <-s.streamSend: srv.Send(&agentendpointpb.ReceiveTaskNotificationResponse{}) case <-s.permissionError: return status.Errorf(codes.PermissionDenied, "") } } } func (s *agentEndpointServiceTestServer) StartNextTask(ctx context.Context, req *agentendpointpb.StartNextTaskRequest) (*agentendpointpb.StartNextTaskResponse, error) { // We first return an TaskType_EXEC_STEP_TASK, then TaskType_APPLY_PATCHES, then TaskType_APPLY_CONFIG_TASK. // After all tasks complete, we return nothing signalling the end to tasks. s.taskStart = true switch { case s.applyConfigTaskComplete && s.execTaskComplete && s.patchTaskComplete: return &agentendpointpb.StartNextTaskResponse{}, nil case !s.execTaskComplete: return &agentendpointpb.StartNextTaskResponse{Task: &agentendpointpb.Task{TaskType: agentendpointpb.TaskType_EXEC_STEP_TASK, TaskId: "TaskType_EXEC_STEP_TASK"}}, nil case !s.patchTaskComplete: return &agentendpointpb.StartNextTaskResponse{Task: &agentendpointpb.Task{TaskType: agentendpointpb.TaskType_APPLY_PATCHES, TaskId: "TaskType_APPLY_PATCHES"}}, nil case !s.applyConfigTaskComplete: return &agentendpointpb.StartNextTaskResponse{Task: &agentendpointpb.Task{TaskType: agentendpointpb.TaskType_APPLY_CONFIG_TASK, TaskId: "TaskType_APPLY_CONFIG_TASK"}}, nil default: return &agentendpointpb.StartNextTaskResponse{}, status.Errorf(codes.Unimplemented, "unexpected start next task") } } func (s *agentEndpointServiceTestServer) ReportTaskProgress(ctx context.Context, req *agentendpointpb.ReportTaskProgressRequest) (*agentendpointpb.ReportTaskProgressResponse, error) { // Simply record and send STOP. switch req.GetTaskType() { case agentendpointpb.TaskType_EXEC_STEP_TASK: s.execTaskProgress = true case agentendpointpb.TaskType_APPLY_PATCHES: s.patchTaskProgress = true case agentendpointpb.TaskType_APPLY_CONFIG_TASK: s.applyConfigTaskProgress = true default: return &agentendpointpb.ReportTaskProgressResponse{}, status.Errorf(codes.Unimplemented, "task type %q not implemented", req.GetTaskType()) } return &agentendpointpb.ReportTaskProgressResponse{TaskDirective: agentendpointpb.TaskDirective_STOP}, nil } func (s *agentEndpointServiceTestServer) ReportTaskComplete(ctx context.Context, req *agentendpointpb.ReportTaskCompleteRequest) (*agentendpointpb.ReportTaskCompleteResponse, error) { // Record what task types we have seen, when the complete is called for TaskType_APPLY_CONFIG_TASK, close the stream. s.runTaskIDs = append(s.runTaskIDs, req.GetTaskId()) switch req.GetTaskType() { case agentendpointpb.TaskType_EXEC_STEP_TASK: s.execTaskComplete = true case agentendpointpb.TaskType_APPLY_PATCHES: s.patchTaskComplete = true case agentendpointpb.TaskType_APPLY_CONFIG_TASK: s.applyConfigTaskComplete = true default: return &agentendpointpb.ReportTaskCompleteResponse{}, status.Errorf(codes.Unimplemented, "task type %q not implemented", req.GetTaskType()) } if s.execTaskComplete && s.patchTaskComplete && s.applyConfigTaskComplete { s.streamClose <- struct{}{} } return &agentendpointpb.ReportTaskCompleteResponse{}, nil } func (*agentEndpointServiceTestServer) RegisterAgent(ctx context.Context, req *agentendpointpb.RegisterAgentRequest) (*agentendpointpb.RegisterAgentResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method RegisterAgent not implemented") } func (*agentEndpointServiceTestServer) ReportInventory(ctx context.Context, req *agentendpointpb.ReportInventoryRequest) (*agentendpointpb.ReportInventoryResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ReportInventory not implemented") } func TestWaitForTask(t *testing.T) { ctx := context.Background() srv := newAgentEndpointServiceTestServer() tc, err := newTestClient(ctx, srv) if err != nil { t.Fatal(err) } defer tc.close() td, err := ioutil.TempDir(os.TempDir(), "") if err != nil { t.Fatalf("error creating temp dir: %v", err) } defer os.RemoveAll(td) taskStateFile = filepath.Join(td, "testState") // Stream recieve. srv.streamSend <- struct{}{} if err := tc.client.waitForTask(ctx); err != nil { t.Errorf("did not expect error from a closed stream: %v", err) } if !srv.execTaskProgress { t.Error("expected ReportTaskProgress for TaskType_EXEC_STEP_TASK to have been called") } if !srv.execTaskComplete { t.Error("expected ReportTaskComplete for TaskType_EXEC_STEP_TASK to have been called") } if !srv.patchTaskProgress { t.Error("expected ReportTaskProgress for TaskType_APPLY_PATCHES to have been called") } if !srv.patchTaskComplete { t.Error("expected ReportTaskComplete for TaskType_APPLY_PATCHES to have been called") } if !srv.applyConfigTaskProgress { t.Error("expected ReportTaskProgress for TaskType_APPLY_CONFIG_TASK to have been called") } if !srv.applyConfigTaskComplete { t.Error("expected ReportTaskComplete for TaskType_APPLY_CONFIG_TASK to have been called") } } func TestWaitForTaskErrors(t *testing.T) { ctx := context.Background() srv := newAgentEndpointServiceTestServer() tc, err := newTestClient(ctx, srv) if err != nil { t.Fatal(err) } // errServiceNotEnabled from PermissionDenied error. srv.permissionError <- struct{}{} if err := tc.client.waitForTask(ctx); !errors.Is(err, errServiceNotEnabled) { t.Errorf("did not get expected errServiceNotEnabled, got: %v", err) } // No error from a closed stream. srv.streamClose <- struct{}{} if err := tc.client.waitForTask(ctx); err != nil { t.Errorf("did not expect error from a closed stream: %v", err) } } func TestLoadPatchTaskFromState(t *testing.T) { ctx := context.Background() srv := newAgentEndpointServiceTestServer() tc, err := newTestClient(ctx, srv) if err != nil { t.Fatal(err) } defer tc.close() td, err := ioutil.TempDir(os.TempDir(), "") if err != nil { t.Fatalf("error creating temp dir: %v", err) } defer os.RemoveAll(td) taskStateFile = filepath.Join(td, "testState") srv.streamSend <- struct{}{} // No state. if err := tc.client.loadTaskFromState(ctx); err != nil { t.Error(err) } if srv.taskStart { t.Error("expected ReportTaskStart to not have been called") } // Bad state. if err := ioutil.WriteFile(taskStateFile, []byte("bad"), 0600); err != nil { t.Fatal(err) } if err := tc.client.loadTaskFromState(ctx); err == nil { t.Error("expected error from loadTaskFromState") } // Existing task. taskID := "foo" if err := ioutil.WriteFile(taskStateFile, []byte(fmt.Sprintf(`{"PatchTask":{"TaskID":"%s", "PatchStep": "%s"}}`, taskID, patching)), 0600); err != nil { t.Fatal(err) } if err := tc.client.loadTaskFromState(ctx); err != nil { t.Fatal(err) } srv.execTaskComplete = true srv.applyConfigTaskComplete = true // Launch another patch task, this should run AFTER the task loaded from state file if err := tc.client.waitForTask(ctx); err != nil { t.Errorf("did not expect error from a closed stream: %v", err) } if srv.taskStart { t.Error("did not expect ReportTaskStart to have been called") } if !srv.patchTaskProgress { t.Error("expected ReportTaskProgress for TaskType_APPLY_PATCHES to have been called") } if !srv.patchTaskComplete { t.Error("expected ReportTaskComplete for TaskType_APPLY_PATCHES to have been called") } if len(srv.runTaskIDs) != 1 { t.Fatalf("expected srv.runTaskIDs to have a length of 1, not %d", len(srv.runTaskIDs)) } if srv.runTaskIDs[0] != taskID { t.Errorf("first entry in runTaskIDs does not match taskID, %q, %q", srv.runTaskIDs, taskID) } } osconfig-20250416.02/agentendpoint/config_task.go000066400000000000000000000451021477773331400215050ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package agentendpoint import ( "context" "fmt" "os" "path/filepath" "time" "github.com/GoogleCloudPlatform/osconfig/agentconfig" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/config" "github.com/GoogleCloudPlatform/osconfig/pretty" "cloud.google.com/go/osconfig/agentendpoint/apiv1/agentendpointpb" ) // This is the maximum size in bytes of the OSPolicyResourceConfigStep ErrorMessage field. // Any message longer than this will be truncated to at max this length. const maxErrorMessage = 512 var newResource = func(r *agentendpointpb.OSPolicy_Resource) *resource { return &resource{resourceIface: resourceIface(&config.OSPolicyResource{OSPolicy_Resource: r})} } var repoFormats = []string{agentconfig.AptRepoFormat(), agentconfig.YumRepoFormat(), agentconfig.ZypperRepoFormat(), agentconfig.GooGetRepoFormat()} type configTask struct { StartedAt time.Time `json:",omitempty"` client *Client lastProgressState map[agentendpointpb.ApplyConfigTaskProgress_State]time.Time Task *applyConfigTask policies map[string]*policy TaskID string results []*agentendpointpb.ApplyConfigTaskOutput_OSPolicyResult managedResources []*config.ManagedResources } type applyConfigTask struct { *agentendpointpb.ApplyConfigTask } type policy struct { resources map[string]*resource } type resource struct { resourceIface needsPostCheck bool validateOrCheckError bool } type resourceIface interface { Validate(context.Context) error CheckState(context.Context) error EnforceState(context.Context) error PopulateOutput(*agentendpointpb.OSPolicyResourceCompliance) error Cleanup(context.Context) error InDesiredState() bool ManagedResources() *config.ManagedResources } func (c *configTask) reportCompletedState(ctx context.Context, errMsg string, state agentendpointpb.ApplyConfigTaskOutput_State) error { req := &agentendpointpb.ReportTaskCompleteRequest{ TaskId: c.TaskID, TaskType: agentendpointpb.TaskType_APPLY_CONFIG_TASK, ErrorMessage: errMsg, Output: &agentendpointpb.ReportTaskCompleteRequest_ApplyConfigTaskOutput{ ApplyConfigTaskOutput: &agentendpointpb.ApplyConfigTaskOutput{State: state, OsPolicyResults: c.results}, }, } if err := c.client.reportTaskComplete(ctx, req); err != nil { return fmt.Errorf("error reporting completed state: %v", err) } return nil } func (c *configTask) handleErrorState(ctx context.Context, msg string, err error) error { if err == errServerCancel { clog.Infof(ctx, "Cancelling config run: %v", errServerCancel) return c.reportCompletedState(ctx, errServerCancel.Error(), agentendpointpb.ApplyConfigTaskOutput_CANCELLED) } msg = fmt.Sprintf("%s: %v", msg, err) clog.Errorf(ctx, "%v", msg) return c.reportCompletedState(ctx, msg, agentendpointpb.ApplyConfigTaskOutput_FAILED) } func (c *configTask) reportContinuingState(ctx context.Context, configState agentendpointpb.ApplyConfigTaskProgress_State) error { st, ok := c.lastProgressState[configState] if ok && st.After(time.Now().Add(sameStateTimeWindow)) { // Don't resend the same state more than once every 5s. return nil } req := &agentendpointpb.ReportTaskProgressRequest{ TaskId: c.TaskID, TaskType: agentendpointpb.TaskType_APPLY_CONFIG_TASK, Progress: &agentendpointpb.ReportTaskProgressRequest_ApplyConfigTaskProgress{ ApplyConfigTaskProgress: &agentendpointpb.ApplyConfigTaskProgress{State: configState}, }, } res, err := c.client.reportTaskProgress(ctx, req) if err != nil { return fmt.Errorf("error reporting task progress %s: %v", configState, err) } if res.GetTaskDirective() == agentendpointpb.TaskDirective_STOP { return errServerCancel } if c.lastProgressState == nil { c.lastProgressState = make(map[agentendpointpb.ApplyConfigTaskProgress_State]time.Time) } c.lastProgressState[configState] = time.Now() return nil } // detectPolicyConflicts checks for managed resource conflicts between a proposed // OSPolicyResource and all other OSPolcyResources up to this point, adding to the // current set of ManagedResources. func detectPolicyConflicts(proposed, current *config.ManagedResources) error { // TODO: implement return nil } func truncateMessage(msg string, size int) string { cut := size / 2 if len(msg) > size { return msg[:size-(cut+3)] + "..." + msg[len(msg)-cut:] } return msg } func validateConfigResource(ctx context.Context, res *resource, policyMR *config.ManagedResources, rCompliance *agentendpointpb.OSPolicyResourceCompliance, configResource *agentendpointpb.OSPolicy_Resource) (hasError bool) { ctx = clog.WithLabels(ctx, map[string]string{"resource_id": configResource.GetId()}) clog.Debugf(ctx, "Running step 'validate' on resource %q.", configResource.GetId()) var errMessage string outcome := agentendpointpb.OSPolicyResourceConfigStep_SUCCEEDED if err := res.Validate(ctx); err != nil { outcome = agentendpointpb.OSPolicyResourceConfigStep_FAILED hasError = true errMessage = truncateMessage(fmt.Sprintf("Validate: resource %q error: %v", configResource.GetId(), err), maxErrorMessage) clog.Errorf(ctx, "%v", errMessage) } else { // Detect any resource conflicts within this policy. if err := detectPolicyConflicts(res.ManagedResources(), policyMR); err != nil { outcome = agentendpointpb.OSPolicyResourceConfigStep_FAILED hasError = true errMessage = truncateMessage(fmt.Sprintf("Validate: resource conflict in policy: %v", err), maxErrorMessage) clog.Errorf(ctx, "%v", errMessage) } else { clog.Infof(ctx, "Validate: resource %q validation successful.", configResource.GetId()) } } rCompliance.ConfigSteps = append(rCompliance.GetConfigSteps(), &agentendpointpb.OSPolicyResourceConfigStep{ Type: agentendpointpb.OSPolicyResourceConfigStep_VALIDATION, Outcome: outcome, ErrorMessage: errMessage, }) rCompliance.State = agentendpointpb.OSPolicyComplianceState_UNKNOWN return hasError } func checkConfigResourceState(ctx context.Context, res *resource, rCompliance *agentendpointpb.OSPolicyResourceCompliance, configResource *agentendpointpb.OSPolicy_Resource) (hasError bool) { ctx = clog.WithLabels(ctx, map[string]string{"resource_id": configResource.GetId()}) clog.Debugf(ctx, "Running step 'check state' on resource %q.", configResource.GetId()) var errMessage string outcome := agentendpointpb.OSPolicyResourceConfigStep_SUCCEEDED state := agentendpointpb.OSPolicyComplianceState_UNKNOWN err := res.CheckState(ctx) if err != nil { outcome = agentendpointpb.OSPolicyResourceConfigStep_FAILED hasError = true errMessage = truncateMessage(fmt.Sprintf("Check state: resource %q error: %v", configResource.GetId(), err), maxErrorMessage) clog.Errorf(ctx, "%v", errMessage) } else if res.InDesiredState() { state = agentendpointpb.OSPolicyComplianceState_COMPLIANT } else { state = agentendpointpb.OSPolicyComplianceState_NON_COMPLIANT } rCompliance.ConfigSteps = append(rCompliance.GetConfigSteps(), &agentendpointpb.OSPolicyResourceConfigStep{ Type: agentendpointpb.OSPolicyResourceConfigStep_DESIRED_STATE_CHECK, Outcome: outcome, ErrorMessage: errMessage, }) clog.Infof(ctx, "Check state: resource %q state is %s.", configResource.GetId(), state) rCompliance.State = state return hasError } func enforceConfigResourceState(ctx context.Context, res *resource, rCompliance *agentendpointpb.OSPolicyResourceCompliance, configResource *agentendpointpb.OSPolicy_Resource) (enforcementActionTaken, hasError bool) { ctx = clog.WithLabels(ctx, map[string]string{"resource_id": configResource.GetId()}) clog.Debugf(ctx, "Running step 'enforce state' on resource %q.", configResource.GetId()) // Only enforce resources that need it. if res.InDesiredState() { clog.Debugf(ctx, "Enforce state: No enforcement required for %q.", configResource.GetId()) return false, false } var errMessage string outcome := agentendpointpb.OSPolicyResourceConfigStep_SUCCEEDED err := res.EnforceState(ctx) if err != nil { outcome = agentendpointpb.OSPolicyResourceConfigStep_FAILED hasError = true errMessage = truncateMessage(fmt.Sprintf("Enforce state: resource %q error: %v", configResource.GetId(), err), maxErrorMessage) clog.Errorf(ctx, "%v", errMessage) } else { clog.Infof(ctx, "Enforce state: resource %q enforcement successful.", configResource.GetId()) } rCompliance.ConfigSteps = append(rCompliance.GetConfigSteps(), &agentendpointpb.OSPolicyResourceConfigStep{ Type: agentendpointpb.OSPolicyResourceConfigStep_DESIRED_STATE_ENFORCEMENT, Outcome: outcome, ErrorMessage: errMessage, }) // Resource is always in an unknown state after enforcement is run. // A COMPLIANT state will only happen after a post check. rCompliance.State = agentendpointpb.OSPolicyComplianceState_UNKNOWN return true, hasError } func postCheckConfigResourceState(ctx context.Context, res *resource, rCompliance *agentendpointpb.OSPolicyResourceCompliance, configResource *agentendpointpb.OSPolicy_Resource) { ctx = clog.WithLabels(ctx, map[string]string{"resource_id": configResource.GetId()}) clog.Debugf(ctx, "Running step 'check state post enforcement' on resource %q.", configResource.GetId()) if !res.needsPostCheck { clog.Debugf(ctx, "Check state post enforcement: no post check required for %q.", configResource.GetId()) return } var errMessage string outcome := agentendpointpb.OSPolicyResourceConfigStep_SUCCEEDED state := agentendpointpb.OSPolicyComplianceState_UNKNOWN err := res.CheckState(ctx) if err != nil { outcome = agentendpointpb.OSPolicyResourceConfigStep_FAILED errMessage = truncateMessage(fmt.Sprintf("Check state post enforcement: resource %q error: %v", configResource.GetId(), err), maxErrorMessage) clog.Errorf(ctx, "%v", errMessage) } else if res.InDesiredState() { state = agentendpointpb.OSPolicyComplianceState_COMPLIANT } else { state = agentendpointpb.OSPolicyComplianceState_NON_COMPLIANT } rCompliance.ConfigSteps = append(rCompliance.GetConfigSteps(), &agentendpointpb.OSPolicyResourceConfigStep{ Type: agentendpointpb.OSPolicyResourceConfigStep_DESIRED_STATE_CHECK_POST_ENFORCEMENT, Outcome: outcome, ErrorMessage: errMessage, }) clog.Infof(ctx, "Check state post enforcement: resource %q state is %s.", configResource.GetId(), state) rCompliance.State = state } func (c *configTask) postCheckState(ctx context.Context) { // Actually run post check state (for policies that do not have a previous error). // No prepopulate run for post check as we will always check every resource. for i, osPolicy := range c.Task.GetOsPolicies() { ctx := clog.WithLabels(ctx, map[string]string{"os_policy_assignment": osPolicy.GetOsPolicyAssignment(), "os_policy_id": osPolicy.GetId()}) plcy, ok := c.policies[osPolicy.GetId()] // This should not happen in the normal code flow since we only run postCheckState after // all policies have been evaluated. if !ok { clog.Errorf(ctx, "Unexpected Error: policy entry for %q is empty.", osPolicy.GetId()) continue } pResult := c.results[i] for i, configResource := range osPolicy.GetResources() { res, ok := plcy.resources[configResource.GetId()] // This should only happen if there was a previous resource with a validate or check state error. if !ok || res == nil { continue } rCompliance := pResult.GetOsPolicyResourceCompliances()[i] postCheckConfigResourceState(ctx, res, rCompliance, configResource) clog.Infof(ctx, "Policy %q resource %q state: %s", osPolicy.GetId(), configResource.GetId(), rCompliance.GetState()) } } return } func (c *configTask) generateBaseResults() { c.results = make([]*agentendpointpb.ApplyConfigTaskOutput_OSPolicyResult, len(c.Task.GetOsPolicies())) for i, p := range c.Task.GetOsPolicies() { pResult := &agentendpointpb.ApplyConfigTaskOutput_OSPolicyResult{ OsPolicyId: p.GetId(), OsPolicyAssignment: p.GetOsPolicyAssignment(), OsPolicyResourceCompliances: make([]*agentendpointpb.OSPolicyResourceCompliance, len(p.GetResources())), } c.results[i] = pResult for i, r := range p.GetResources() { pResult.GetOsPolicyResourceCompliances()[i] = &agentendpointpb.OSPolicyResourceCompliance{ OsPolicyResourceId: r.GetId(), } } } } func removeFileIfNoMatch(a string, s []string) error { for _, b := range s { if a == b { return nil } } return os.Remove(a) } func (c *configTask) cleanupRepos(ctx context.Context) { var managedRepos []string for _, managedResource := range c.managedResources { if managedResource == nil { continue } for _, managedRepo := range managedResource.Repositories { managedRepos = append(managedRepos, managedRepo.RepoFilePath) } } for _, format := range repoFormats { matches, err := filepath.Glob(fmt.Sprintf(format, "*")) if err != nil { clog.Errorf(ctx, "Error globing directory: %v", err) } for _, match := range matches { if err := removeFileIfNoMatch(match, managedRepos); err != nil { clog.Errorf(ctx, "Error cleaning up old repo: %v", err) } } } } func (c *configTask) cleanup(ctx context.Context) { // Skip repo clean-up, as there is no clear way how to find full list of repos, // repos might be distributed across many tasks and there is no source of truth to find full list. //c.cleanupRepos(ctx) // Cleanup any policy specific resources. for _, osPolicy := range c.Task.GetOsPolicies() { ctx := clog.WithLabels(ctx, map[string]string{"os_policy_assignment": osPolicy.GetOsPolicyAssignment(), "os_policy_id": osPolicy.GetId()}) plcy := c.policies[osPolicy.GetId()] for _, configResource := range osPolicy.GetResources() { ctx := clog.WithLabels(ctx, map[string]string{"resource_id": configResource.GetId()}) res, ok := plcy.resources[configResource.GetId()] if !ok || res == nil { continue } if err := res.Cleanup(ctx); err != nil { clog.Warningf(ctx, "Error running resource cleanup:%v", err) } } } } func (c *configTask) run(ctx context.Context) error { clog.Infof(ctx, "Beginning ApplyConfigTask.") clog.Debugf(ctx, "ApplyConfigTask:\n%s", pretty.Format(c.Task.ApplyConfigTask)) c.StartedAt = time.Now() rcsErrMsg := "Error reporting continuing state" if err := c.reportContinuingState(ctx, agentendpointpb.ApplyConfigTaskProgress_STARTED); err != nil { return c.handleErrorState(ctx, rcsErrMsg, err) } if len(c.Task.GetOsPolicies()) == 0 { clog.Infof(ctx, "No OSPolicies to apply.") return c.reportCompletedState(ctx, "", agentendpointpb.ApplyConfigTaskOutput_SUCCEEDED) } // We need to generate base results first thing, each execution step // just adds on. c.generateBaseResults() defer c.cleanup(ctx) if err := c.reportContinuingState(ctx, agentendpointpb.ApplyConfigTaskProgress_APPLYING_CONFIG); err != nil { return c.handleErrorState(ctx, rcsErrMsg, err) } c.policies = map[string]*policy{} for i, osPolicy := range c.Task.GetOsPolicies() { ctx := clog.WithLabels(ctx, map[string]string{"os_policy_assignment": osPolicy.GetOsPolicyAssignment(), "os_policy_id": osPolicy.GetId()}) clog.Infof(ctx, "Executing policy %q", osPolicy.GetId()) pResult := c.results[i] plcy := &policy{resources: map[string]*resource{}} c.policies[osPolicy.GetId()] = plcy var policyMR *config.ManagedResources var validateOnly bool if osPolicy.GetMode() == agentendpointpb.OSPolicy_VALIDATION { clog.Infof(ctx, "Policy running in VALIDATION mode, not running enforcement action for any resources.") validateOnly = true } for i, configResource := range osPolicy.GetResources() { rCompliance := pResult.GetOsPolicyResourceCompliances()[i] plcy.resources[configResource.GetId()] = newResource(configResource) res := plcy.resources[configResource.GetId()] if hasError := validateConfigResource(ctx, res, policyMR, rCompliance, configResource); hasError { res.validateOrCheckError = true break } if hasError := checkConfigResourceState(ctx, res, rCompliance, configResource); hasError { res.validateOrCheckError = true break } // Skip enforcement actions in VALIDATION mode. if validateOnly { continue } // Only errors in validate and check state constitute a serious error, // for enforce if any action is taken we still want to run post check. // We do however stop further execution of this polcy on enforce error. enforcementActionTaken, hasError := enforceConfigResourceState(ctx, res, rCompliance, configResource) if enforcementActionTaken { // On any change we trigger post check for all previous resouces, // even if there was an error. c.markPostCheckRequired() } // Still record output even if there was an error during enforcement. res.PopulateOutput(rCompliance) // Errors from enforcement are not classified as "serious" becasue we want post check to run for this resource. if hasError { break } } c.managedResources = append(c.managedResources, policyMR) } // Run any post checks that we need to. c.postCheckState(ctx) if err := c.reportCompletedState(ctx, "", agentendpointpb.ApplyConfigTaskOutput_SUCCEEDED); err != nil { return err } clog.Infof(ctx, "Successfully completed ApplyConfigTask") return nil } // Mark all resources that have already completed as "needs post check". func (c *configTask) markPostCheckRequired() { for _, osPolicy := range c.Task.GetOsPolicies() { plcy, ok := c.policies[osPolicy.GetId()] // This policy entry may not have been created yet by the loop in run(). if !ok { continue } for _, configResource := range osPolicy.GetResources() { res, ok := plcy.resources[configResource.GetId()] // This resource entry may not have been created yet is this polciy is in mid-run. // We take no actions for resources that had a failure with validation or precheck. if !ok || res == nil || res.validateOrCheckError { continue } res.needsPostCheck = true } } } // RunApplyConfig runs an ApplyConfigTask. func (c *Client) RunApplyConfig(ctx context.Context, task *agentendpointpb.Task) error { ctx = clog.WithLabels(ctx, task.GetServiceLabels()) e := &configTask{ TaskID: task.GetTaskId(), client: c, Task: &applyConfigTask{task.GetApplyConfigTask()}, } return e.run(ctx) } osconfig-20250416.02/agentendpoint/config_task_test.go000066400000000000000000000357111477773331400225510ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package agentendpoint import ( "context" "errors" "fmt" "io/ioutil" "path/filepath" "reflect" "testing" "github.com/GoogleCloudPlatform/osconfig/config" "github.com/google/go-cmp/cmp" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/testing/protocmp" "cloud.google.com/go/osconfig/agentendpoint/apiv1/agentendpointpb" ) var errTest = errors.New("this is a test error") type testResource struct { inDesiredState bool steps int } func (r *testResource) InDesiredState() bool { return r.inDesiredState } func (r *testResource) Cleanup(ctx context.Context) error { return nil } func (r *testResource) Validate(ctx context.Context) error { if r.steps == 0 { return errTest } return nil } func (r *testResource) CheckState(ctx context.Context) error { if r.steps == 1 { return errTest } if r.steps == 3 && r.inDesiredState { return errTest } return nil } func (r *testResource) EnforceState(ctx context.Context) error { if r.steps == 2 { return errTest } r.inDesiredState = true return nil } func (r *testResource) ManagedResources() *config.ManagedResources { return nil } func (r *testResource) PopulateOutput(rCompliance *agentendpointpb.OSPolicyResourceCompliance) error { return nil } type agentEndpointServiceConfigTestServer struct { lastReportTaskCompleteRequest *agentendpointpb.ReportTaskCompleteRequest progressError chan struct{} progressCancel chan struct{} } func (*agentEndpointServiceConfigTestServer) ReceiveTaskNotification(req *agentendpointpb.ReceiveTaskNotificationRequest, srv agentendpointpb.AgentEndpointService_ReceiveTaskNotificationServer) error { return status.Errorf(codes.Unimplemented, "method ReceiveTaskNotification not implemented") } func (*agentEndpointServiceConfigTestServer) StartNextTask(ctx context.Context, req *agentendpointpb.StartNextTaskRequest) (*agentendpointpb.StartNextTaskResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method StartNextTask not implemented") } func (s *agentEndpointServiceConfigTestServer) ReportTaskProgress(ctx context.Context, req *agentendpointpb.ReportTaskProgressRequest) (*agentendpointpb.ReportTaskProgressResponse, error) { select { case s.progressError <- struct{}{}: default: return nil, status.Errorf(codes.Unimplemented, "") } select { case s.progressCancel <- struct{}{}: default: return &agentendpointpb.ReportTaskProgressResponse{TaskDirective: agentendpointpb.TaskDirective_STOP}, nil } return &agentendpointpb.ReportTaskProgressResponse{TaskDirective: agentendpointpb.TaskDirective_CONTINUE}, nil } func (s *agentEndpointServiceConfigTestServer) ReportTaskComplete(ctx context.Context, req *agentendpointpb.ReportTaskCompleteRequest) (*agentendpointpb.ReportTaskCompleteResponse, error) { s.lastReportTaskCompleteRequest = req return &agentendpointpb.ReportTaskCompleteResponse{}, nil } func (*agentEndpointServiceConfigTestServer) RegisterAgent(ctx context.Context, req *agentendpointpb.RegisterAgentRequest) (*agentendpointpb.RegisterAgentResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method RegisterAgent not implemented") } func (*agentEndpointServiceConfigTestServer) ReportInventory(ctx context.Context, req *agentendpointpb.ReportInventoryRequest) (*agentendpointpb.ReportInventoryResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ReportInventory not implemented") } func configOutputGen(msg string, st agentendpointpb.ApplyConfigTaskOutput_State, results []*agentendpointpb.ApplyConfigTaskOutput_OSPolicyResult) *agentendpointpb.ReportTaskCompleteRequest { return &agentendpointpb.ReportTaskCompleteRequest{ TaskType: agentendpointpb.TaskType_APPLY_CONFIG_TASK, ErrorMessage: msg, Output: &agentendpointpb.ReportTaskCompleteRequest_ApplyConfigTaskOutput{ ApplyConfigTaskOutput: &agentendpointpb.ApplyConfigTaskOutput{State: st, OsPolicyResults: results}, }, InstanceIdToken: testIDToken, } } func genTestResource(id string) *agentendpointpb.OSPolicy_Resource { return &agentendpointpb.OSPolicy_Resource{ Id: id, } } func genTestResourceCompliance(id string, steps int, inDesiredState bool) *agentendpointpb.OSPolicyResourceCompliance { // TODO: test various types of executions. ret := &agentendpointpb.OSPolicyResourceCompliance{ OsPolicyResourceId: id, } // Validation if steps > 0 { outcome := agentendpointpb.OSPolicyResourceConfigStep_FAILED state := agentendpointpb.OSPolicyComplianceState_UNKNOWN errMsg := `Validate: resource "r1" error: ` + errTest.Error() if steps > 1 { outcome = agentendpointpb.OSPolicyResourceConfigStep_SUCCEEDED errMsg = "" } ret.ConfigSteps = append(ret.GetConfigSteps(), &agentendpointpb.OSPolicyResourceConfigStep{ Type: agentendpointpb.OSPolicyResourceConfigStep_VALIDATION, Outcome: outcome, ErrorMessage: errMsg, }) ret.State = state } // DesiredStateCheck if steps > 1 { outcome := agentendpointpb.OSPolicyResourceConfigStep_SUCCEEDED state := agentendpointpb.OSPolicyComplianceState_NON_COMPLIANT errMsg := "" if steps == 2 && !inDesiredState { outcome = agentendpointpb.OSPolicyResourceConfigStep_FAILED state = agentendpointpb.OSPolicyComplianceState_UNKNOWN errMsg = `Check state: resource "r1" error: ` + errTest.Error() } else if inDesiredState { state = agentendpointpb.OSPolicyComplianceState_COMPLIANT } ret.ConfigSteps = append(ret.GetConfigSteps(), &agentendpointpb.OSPolicyResourceConfigStep{ Type: agentendpointpb.OSPolicyResourceConfigStep_DESIRED_STATE_CHECK, Outcome: outcome, ErrorMessage: errMsg, }) ret.State = state } // EnforceDesiredState if steps > 2 { outcome := agentendpointpb.OSPolicyResourceConfigStep_FAILED state := agentendpointpb.OSPolicyComplianceState_UNKNOWN errMsg := `Enforce state: resource "r1" error: ` + errTest.Error() if steps > 3 { outcome = agentendpointpb.OSPolicyResourceConfigStep_SUCCEEDED errMsg = "" } ret.ConfigSteps = append(ret.GetConfigSteps(), &agentendpointpb.OSPolicyResourceConfigStep{ Type: agentendpointpb.OSPolicyResourceConfigStep_DESIRED_STATE_ENFORCEMENT, Outcome: outcome, ErrorMessage: errMsg, }) ret.State = state } // DesiredStateCheckPostEnforcement if steps > 2 { outcome := agentendpointpb.OSPolicyResourceConfigStep_SUCCEEDED state := agentendpointpb.OSPolicyComplianceState_NON_COMPLIANT errMsg := "" if steps == 4 { outcome = agentendpointpb.OSPolicyResourceConfigStep_FAILED state = agentendpointpb.OSPolicyComplianceState_UNKNOWN errMsg = `Check state post enforcement: resource "r1" error: ` + errTest.Error() } else if steps == 5 { state = agentendpointpb.OSPolicyComplianceState_COMPLIANT } ret.ConfigSteps = append(ret.GetConfigSteps(), &agentendpointpb.OSPolicyResourceConfigStep{ Type: agentendpointpb.OSPolicyResourceConfigStep_DESIRED_STATE_CHECK_POST_ENFORCEMENT, Outcome: outcome, ErrorMessage: errMsg, }) ret.State = state } return ret } func genTestPolicy(id string) *agentendpointpb.ApplyConfigTask_OSPolicy { return &agentendpointpb.ApplyConfigTask_OSPolicy{ Id: id, Mode: agentendpointpb.OSPolicy_ENFORCEMENT, Resources: []*agentendpointpb.OSPolicy_Resource{ genTestResource("r1"), }, } } func genTestPolicyResult(id string, steps int, inDesiredState bool) *agentendpointpb.ApplyConfigTaskOutput_OSPolicyResult { return &agentendpointpb.ApplyConfigTaskOutput_OSPolicyResult{ OsPolicyId: id, OsPolicyResourceCompliances: []*agentendpointpb.OSPolicyResourceCompliance{ genTestResourceCompliance("r1", steps, inDesiredState), }, } } func TestRunApplyConfig(t *testing.T) { ctx := context.Background() sameStateTimeWindow = 0 res := &testResource{} newResource = func(r *agentendpointpb.OSPolicy_Resource) *resource { return &resource{resourceIface: resourceIface(res)} } testConfig := &agentendpointpb.ApplyConfigTask{ OsPolicies: []*agentendpointpb.ApplyConfigTask_OSPolicy{ genTestPolicy("p1"), }, } tests := []struct { name string wantComReq *agentendpointpb.ReportTaskCompleteRequest step *agentendpointpb.ApplyConfigTask callsBeforeCancel int callsBeforeErr int stepsBeforeErr int startInDesiredState bool }{ // Normal cases: { "InDesiredState", configOutputGen("", agentendpointpb.ApplyConfigTaskOutput_SUCCEEDED, []*agentendpointpb.ApplyConfigTaskOutput_OSPolicyResult{ genTestPolicyResult("p1", 2, true), }, ), testConfig, 5, 5, 5, true, }, { "ValidationMode", configOutputGen("", agentendpointpb.ApplyConfigTaskOutput_SUCCEEDED, []*agentendpointpb.ApplyConfigTaskOutput_OSPolicyResult{ { OsPolicyId: "p1", OsPolicyResourceCompliances: []*agentendpointpb.OSPolicyResourceCompliance{ { State: agentendpointpb.OSPolicyComplianceState_NON_COMPLIANT, OsPolicyResourceId: "r1", ConfigSteps: []*agentendpointpb.OSPolicyResourceConfigStep{ { Type: agentendpointpb.OSPolicyResourceConfigStep_VALIDATION, Outcome: agentendpointpb.OSPolicyResourceConfigStep_SUCCEEDED, }, { Type: agentendpointpb.OSPolicyResourceConfigStep_DESIRED_STATE_CHECK, Outcome: agentendpointpb.OSPolicyResourceConfigStep_SUCCEEDED, }, }, }, }, }, }, ), &agentendpointpb.ApplyConfigTask{ OsPolicies: []*agentendpointpb.ApplyConfigTask_OSPolicy{ { Id: "p1", Mode: agentendpointpb.OSPolicy_VALIDATION, Resources: []*agentendpointpb.OSPolicy_Resource{ genTestResource("r1"), }, }, }, }, 5, 5, 5, false, }, { "EnforceDesiredState", configOutputGen("", agentendpointpb.ApplyConfigTaskOutput_SUCCEEDED, []*agentendpointpb.ApplyConfigTaskOutput_OSPolicyResult{ genTestPolicyResult("p1", 5, false), }, ), testConfig, 5, 5, 5, false, }, { "NilPolicies", configOutputGen("", agentendpointpb.ApplyConfigTaskOutput_SUCCEEDED, []*agentendpointpb.ApplyConfigTaskOutput_OSPolicyResult{}), &agentendpointpb.ApplyConfigTask{OsPolicies: nil}, 5, 5, 5, false, }, { "NoPolicies", configOutputGen("", agentendpointpb.ApplyConfigTaskOutput_SUCCEEDED, []*agentendpointpb.ApplyConfigTaskOutput_OSPolicyResult{}), &agentendpointpb.ApplyConfigTask{OsPolicies: nil}, 5, 5, 5, false, }, // Step error cases { "ValidateError", configOutputGen("", agentendpointpb.ApplyConfigTaskOutput_SUCCEEDED, []*agentendpointpb.ApplyConfigTaskOutput_OSPolicyResult{ genTestPolicyResult("p1", 1, false), }, ), testConfig, 5, 5, 0, false, }, { "CheckStateError", configOutputGen("", agentendpointpb.ApplyConfigTaskOutput_SUCCEEDED, []*agentendpointpb.ApplyConfigTaskOutput_OSPolicyResult{ genTestPolicyResult("p1", 2, false), }, ), testConfig, 5, 5, 1, false, }, { "EnforceError", configOutputGen("", agentendpointpb.ApplyConfigTaskOutput_SUCCEEDED, []*agentendpointpb.ApplyConfigTaskOutput_OSPolicyResult{ genTestPolicyResult("p1", 3, false), }, ), testConfig, 5, 5, 2, false, }, { "PostCheckError", configOutputGen("", agentendpointpb.ApplyConfigTaskOutput_SUCCEEDED, []*agentendpointpb.ApplyConfigTaskOutput_OSPolicyResult{ genTestPolicyResult("p1", 4, false), }, ), testConfig, 5, 5, 3, false, }, // Cases where task is canceled by server at various points. { "CancelAfterSTARTED", // No results generated. configOutputGen(errServerCancel.Error(), agentendpointpb.ApplyConfigTaskOutput_CANCELLED, []*agentendpointpb.ApplyConfigTaskOutput_OSPolicyResult{}), testConfig, 0, 5, 5, false, }, // Cases where task has task level error. { "ErrorReportingSTARTED", // No results configOutputGen(`Error reporting continuing state: error reporting task progress STARTED: error calling ReportTaskProgress: code: "Unimplemented", message: "", details: []`, agentendpointpb.ApplyConfigTaskOutput_FAILED, []*agentendpointpb.ApplyConfigTaskOutput_OSPolicyResult{}), testConfig, 5, 0, 5, false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { srv := &agentEndpointServiceConfigTestServer{ progressError: make(chan struct{}, tt.callsBeforeErr), progressCancel: make(chan struct{}, tt.callsBeforeCancel), } tc, err := newTestClient(ctx, srv) if err != nil { t.Fatal(err) } defer tc.close() res.inDesiredState = tt.startInDesiredState res.steps = tt.stepsBeforeErr if err := tc.client.RunApplyConfig(ctx, &agentendpointpb.Task{TaskDetails: &agentendpointpb.Task_ApplyConfigTask{ApplyConfigTask: tt.step}}); err != nil { t.Fatal(err) } if diff := cmp.Diff(tt.wantComReq, srv.lastReportTaskCompleteRequest, protocmp.Transform()); diff != "" { t.Fatalf("ReportTaskCompleteRequest mismatch (-want +got):\n%s", diff) } }) } } func TestCleanupRepos(t *testing.T) { ctx := context.Background() tmpDir, err := ioutil.TempDir("", "") if err != nil { t.Fatal(err) } repoFormats = []string{filepath.Join(tmpDir, "some_repo_%s.repo"), filepath.Join(tmpDir, "some/other_repo_%s.repo")} want := []string{filepath.Join(tmpDir, "some_repo.repo"), filepath.Join(tmpDir, fmt.Sprintf("some_repo_%s.repo", "123456"))} task := &configTask{} task.managedResources = []*config.ManagedResources{{Repositories: []config.ManagedRepository{{RepoFilePath: want[1]}}}} // Create the repos. if err := ioutil.WriteFile(want[0], nil, 0644); err != nil { t.Fatal(err) } if err := ioutil.WriteFile(want[1], nil, 0644); err != nil { t.Fatal(err) } if err := ioutil.WriteFile(filepath.Join(tmpDir, fmt.Sprintf("some_repo_%s.repo", "do_not_want")), nil, 0644); err != nil { t.Fatal(err) } task.cleanupRepos(ctx) got, err := filepath.Glob(tmpDir + "/*") if !reflect.DeepEqual(want, got) { t.Errorf("want != got: want: %q, got:%q", want, got) } } func TestTruncateMessage(t *testing.T) { tests := []struct { name string message string want string length int }{ {"less than length", "test", "test", 5}, {"equal to length", "test", "test", 4}, {"greater than length", "this is a longer message", "this i... message", 17}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := truncateMessage(tt.message, tt.length) if got != tt.want { t.Errorf("%s: got (%q) != want (%q)", tt.name, got, tt.want) } }) } } osconfig-20250416.02/agentendpoint/exec_task.go000066400000000000000000000167551477773331400212000ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package agentendpoint import ( "context" "errors" "fmt" "os" "os/exec" "path" "path/filepath" "runtime" "time" "cloud.google.com/go/storage" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/external" "github.com/GoogleCloudPlatform/osconfig/util" "cloud.google.com/go/osconfig/agentendpoint/apiv1/agentendpointpb" ) var ( winRoot = os.Getenv("SystemRoot") sh = "/bin/sh" winPowershell string winCmd string winPowershellArgs = []string{"-NonInteractive", "-NoProfile", "-ExecutionPolicy", "Bypass"} goos = runtime.GOOS errLinuxPowerShell = errors.New("interpreter POWERSHELL cannot be used on non-Windows system") errWinNoInt = fmt.Errorf("an interpreter value of `SHELL` or `POWERSHELL` must be set for files ran on Windows systems") ) func init() { if winRoot == "" { winRoot = `C:\Windows` } winPowershell = filepath.Join(winRoot, `System32\WindowsPowerShell\v1.0\PowerShell.exe`) winCmd = filepath.Join(winRoot, `System32\cmd.exe`) } var run = func(cmd *exec.Cmd) ([]byte, error) { return cmd.CombinedOutput() } func getGCSObject(ctx context.Context, bkt, obj string, gen int64) (string, error) { cl, err := storage.NewClient(ctx) if err != nil { return "", fmt.Errorf("error creating gcs client: %v", err) } defer cl.Close() reader, err := external.FetchGCSObject(ctx, cl, bkt, obj, gen) if err != nil { return "", fmt.Errorf("error fetching GCS object: %v", err) } defer reader.Close() clog.Debugf(ctx, "Fetched GCS object bucket %s object %s generation number %d", bkt, obj, gen) localPath := filepath.Join(os.TempDir(), path.Base(obj)) if _, err := util.AtomicWriteFileStream(reader, "", localPath, 0755); err != nil { return "", fmt.Errorf("error downloading GCS object: %s", err) } clog.Debugf(ctx, "Downloaded to local path %s", localPath) return localPath, nil } func executeCommand(ctx context.Context, path string, args []string) (int32, error) { clog.Debugf(ctx, "Running command %s with args %s", path, args) cmd := exec.Command(path, args...) out, err := run(cmd) var exitCode int32 if cmd.ProcessState != nil { exitCode = int32(cmd.ProcessState.ExitCode()) clog.Infof(ctx, "Command exit code: %d, out:\n%s", exitCode, out) } if err != nil { if _, ok := err.(*exec.ExitError); !ok { return -1, err } } return exitCode, nil } type execTask struct { StartedAt time.Time `json:",omitempty"` client *Client Task *execStepTask TaskID string } type execStepTask struct { *agentendpointpb.ExecStepTask } func (e *execTask) reportCompletedState(ctx context.Context, errMsg string, output *agentendpointpb.ReportTaskCompleteRequest_ExecStepTaskOutput) error { req := &agentendpointpb.ReportTaskCompleteRequest{ TaskId: e.TaskID, TaskType: agentendpointpb.TaskType_EXEC_STEP_TASK, ErrorMessage: errMsg, Output: output, } if err := e.client.reportTaskComplete(ctx, req); err != nil { return fmt.Errorf("error reporting completed state: %v", err) } return nil } func (e *execTask) run(ctx context.Context) error { clog.Infof(ctx, "Beginning ExecStepTask") e.StartedAt = time.Now() req := &agentendpointpb.ReportTaskProgressRequest{ TaskId: e.TaskID, TaskType: agentendpointpb.TaskType_EXEC_STEP_TASK, Progress: &agentendpointpb.ReportTaskProgressRequest_ExecStepTaskProgress{ ExecStepTaskProgress: &agentendpointpb.ExecStepTaskProgress{State: agentendpointpb.ExecStepTaskProgress_STARTED}, }, } res, err := e.client.reportTaskProgress(ctx, req) if err != nil { return fmt.Errorf("error reporting state %s: %v", agentendpointpb.ExecStepTaskProgress_STARTED, err) } if res.GetTaskDirective() == agentendpointpb.TaskDirective_STOP { return e.reportCompletedState(ctx, errServerCancel.Error(), &agentendpointpb.ReportTaskCompleteRequest_ExecStepTaskOutput{ ExecStepTaskOutput: &agentendpointpb.ExecStepTaskOutput{State: agentendpointpb.ExecStepTaskOutput_CANCELLED}, }) } stepConfig := e.Task.GetExecStep().GetLinuxExecStepConfig() if goos == "windows" { stepConfig = e.Task.GetExecStep().GetWindowsExecStepConfig() } if stepConfig == nil { // The given ExecTask does not apply to this OS. return e.reportCompletedState(ctx, "", &agentendpointpb.ReportTaskCompleteRequest_ExecStepTaskOutput{ ExecStepTaskOutput: &agentendpointpb.ExecStepTaskOutput{ State: agentendpointpb.ExecStepTaskOutput_COMPLETED, ExitCode: 0, }, }) } localPath := stepConfig.GetLocalPath() if gcsObject := stepConfig.GetGcsObject(); gcsObject != nil { var err error localPath, err = getGCSObject(ctx, gcsObject.GetBucket(), gcsObject.GetObject(), gcsObject.GetGenerationNumber()) if err != nil { msg := fmt.Sprintf("Error downloading GCS object: %v", err) clog.Errorf(ctx, "%v", msg) return e.reportCompletedState(ctx, msg, &agentendpointpb.ReportTaskCompleteRequest_ExecStepTaskOutput{ ExecStepTaskOutput: &agentendpointpb.ExecStepTaskOutput{ State: agentendpointpb.ExecStepTaskOutput_COMPLETED, ExitCode: -1, }, }) } defer func() { if err := os.Remove(localPath); err != nil { clog.Errorf(ctx, "error removing downloaded file %s", err) } }() } exitCode := int32(-1) switch stepConfig.GetInterpreter() { case agentendpointpb.ExecStepConfig_INTERPRETER_UNSPECIFIED: if goos == "windows" { err = errWinNoInt } else { exitCode, err = executeCommand(ctx, localPath, nil) } case agentendpointpb.ExecStepConfig_SHELL: if goos == "windows" { exitCode, err = executeCommand(ctx, winCmd, []string{"/c", localPath}) } else { exitCode, err = executeCommand(ctx, sh, []string{localPath}) } case agentendpointpb.ExecStepConfig_POWERSHELL: if goos == "windows" { exitCode, err = executeCommand(ctx, winPowershell, append(winPowershellArgs, "-File", localPath)) } else { err = errLinuxPowerShell } default: err = fmt.Errorf("invalid interpreter %q", stepConfig.GetInterpreter()) } if err != nil { msg := fmt.Sprintf("Error running ExecStepTask: %v", err) clog.Errorf(ctx, "%v", msg) return e.reportCompletedState(ctx, msg, &agentendpointpb.ReportTaskCompleteRequest_ExecStepTaskOutput{ ExecStepTaskOutput: &agentendpointpb.ExecStepTaskOutput{ State: agentendpointpb.ExecStepTaskOutput_COMPLETED, ExitCode: exitCode, }, }) } if err := e.reportCompletedState(ctx, "", &agentendpointpb.ReportTaskCompleteRequest_ExecStepTaskOutput{ ExecStepTaskOutput: &agentendpointpb.ExecStepTaskOutput{ State: agentendpointpb.ExecStepTaskOutput_COMPLETED, ExitCode: exitCode, }, }); err != nil { return err } clog.Infof(ctx, "Successfully completed ApplyConfigTask") return nil } // RunExecStep runs an ExecStepTask. func (c *Client) RunExecStep(ctx context.Context, task *agentendpointpb.Task) error { ctx = clog.WithLabels(ctx, task.GetServiceLabels()) e := &execTask{ TaskID: task.GetTaskId(), client: c, Task: &execStepTask{task.GetExecStepTask()}, } return e.run(ctx) } osconfig-20250416.02/agentendpoint/exec_task_test.go000066400000000000000000000202561477773331400222260ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package agentendpoint import ( "context" "os/exec" "testing" "github.com/google/go-cmp/cmp" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/testing/protocmp" "cloud.google.com/go/osconfig/agentendpoint/apiv1/agentendpointpb" ) type agentEndpointServiceExecTestServer struct { lastReportTaskCompleteRequest *agentendpointpb.ReportTaskCompleteRequest } func (*agentEndpointServiceExecTestServer) ReceiveTaskNotification(req *agentendpointpb.ReceiveTaskNotificationRequest, srv agentendpointpb.AgentEndpointService_ReceiveTaskNotificationServer) error { return status.Errorf(codes.Unimplemented, "method ReceiveTaskNotification not implemented") } func (*agentEndpointServiceExecTestServer) StartNextTask(ctx context.Context, req *agentendpointpb.StartNextTaskRequest) (*agentendpointpb.StartNextTaskResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method StartNextTask not implemented") } func (*agentEndpointServiceExecTestServer) ReportTaskProgress(ctx context.Context, req *agentendpointpb.ReportTaskProgressRequest) (*agentendpointpb.ReportTaskProgressResponse, error) { return &agentendpointpb.ReportTaskProgressResponse{}, nil } func (s *agentEndpointServiceExecTestServer) ReportTaskComplete(ctx context.Context, req *agentendpointpb.ReportTaskCompleteRequest) (*agentendpointpb.ReportTaskCompleteResponse, error) { s.lastReportTaskCompleteRequest = req return &agentendpointpb.ReportTaskCompleteResponse{}, nil } func (*agentEndpointServiceExecTestServer) RegisterAgent(ctx context.Context, req *agentendpointpb.RegisterAgentRequest) (*agentendpointpb.RegisterAgentResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method RegisterAgent not implemented") } func (*agentEndpointServiceExecTestServer) ReportInventory(ctx context.Context, req *agentendpointpb.ReportInventoryRequest) (*agentendpointpb.ReportInventoryResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ReportInventory not implemented") } func outputGen(id string, msg string, st agentendpointpb.ExecStepTaskOutput_State, exitCode int32) *agentendpointpb.ReportTaskCompleteRequest { if msg != "" { msg = "Error running ExecStepTask: " + msg } return &agentendpointpb.ReportTaskCompleteRequest{ TaskId: id, TaskType: agentendpointpb.TaskType_EXEC_STEP_TASK, ErrorMessage: msg, Output: &agentendpointpb.ReportTaskCompleteRequest_ExecStepTaskOutput{ ExecStepTaskOutput: &agentendpointpb.ExecStepTaskOutput{State: st, ExitCode: exitCode}, }, InstanceIdToken: testIDToken, } } func TestRunExecStep(t *testing.T) { ctx := context.Background() srv := &agentEndpointServiceExecTestServer{} tc, err := newTestClient(ctx, srv) if err != nil { t.Fatal(err) } defer tc.close() tests := []struct { name string goos string wantComReq *agentendpointpb.ReportTaskCompleteRequest wantPath string wantArgs []string step *agentendpointpb.ExecStep }{ // Matching script and OS. {"LinuxExec", "linux", outputGen("", "", agentendpointpb.ExecStepTaskOutput_COMPLETED, 0), "foo", []string{"foo"}, &agentendpointpb.ExecStep{LinuxExecStepConfig: &agentendpointpb.ExecStepConfig{Executable: &agentendpointpb.ExecStepConfig_LocalPath{LocalPath: "foo"}}}}, {"LinuxShell", "linux", outputGen("", "", agentendpointpb.ExecStepTaskOutput_COMPLETED, 0), sh, []string{sh, "foo"}, &agentendpointpb.ExecStep{LinuxExecStepConfig: &agentendpointpb.ExecStepConfig{Executable: &agentendpointpb.ExecStepConfig_LocalPath{LocalPath: "foo"}, Interpreter: agentendpointpb.ExecStepConfig_SHELL}}}, {"LinuxPowerShell", "linux", outputGen("", errLinuxPowerShell.Error(), agentendpointpb.ExecStepTaskOutput_COMPLETED, -1), "", nil, &agentendpointpb.ExecStep{LinuxExecStepConfig: &agentendpointpb.ExecStepConfig{Executable: &agentendpointpb.ExecStepConfig_LocalPath{LocalPath: "foo"}, Interpreter: agentendpointpb.ExecStepConfig_POWERSHELL}}}, {"WinExec", "windows", outputGen("", errWinNoInt.Error(), agentendpointpb.ExecStepTaskOutput_COMPLETED, -1), "", nil, &agentendpointpb.ExecStep{WindowsExecStepConfig: &agentendpointpb.ExecStepConfig{Executable: &agentendpointpb.ExecStepConfig_LocalPath{LocalPath: "foo"}}}}, {"WinShell", "windows", outputGen("", "", agentendpointpb.ExecStepTaskOutput_COMPLETED, 0), winCmd, []string{winCmd, "/c", "foo"}, &agentendpointpb.ExecStep{WindowsExecStepConfig: &agentendpointpb.ExecStepConfig{Executable: &agentendpointpb.ExecStepConfig_LocalPath{LocalPath: "foo"}, Interpreter: agentendpointpb.ExecStepConfig_SHELL}}}, {"WinPowerShell", "windows", outputGen("", "", agentendpointpb.ExecStepTaskOutput_COMPLETED, 0), winPowershell, []string{winPowershell, "-NonInteractive", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "foo"}, &agentendpointpb.ExecStep{WindowsExecStepConfig: &agentendpointpb.ExecStepConfig{Executable: &agentendpointpb.ExecStepConfig_LocalPath{LocalPath: "foo"}, Interpreter: agentendpointpb.ExecStepConfig_POWERSHELL}}}, // Mismatched script and OS. {"LinuxExec", "windows", outputGen("", "", agentendpointpb.ExecStepTaskOutput_COMPLETED, 0), "", nil, &agentendpointpb.ExecStep{LinuxExecStepConfig: &agentendpointpb.ExecStepConfig{Executable: &agentendpointpb.ExecStepConfig_LocalPath{LocalPath: "foo"}}}}, {"LinuxShell", "windows", outputGen("", "", agentendpointpb.ExecStepTaskOutput_COMPLETED, 0), "", nil, &agentendpointpb.ExecStep{LinuxExecStepConfig: &agentendpointpb.ExecStepConfig{Executable: &agentendpointpb.ExecStepConfig_LocalPath{LocalPath: "foo"}, Interpreter: agentendpointpb.ExecStepConfig_SHELL}}}, {"LinuxPowerShell", "windows", outputGen("", "", agentendpointpb.ExecStepTaskOutput_COMPLETED, 0), "", nil, &agentendpointpb.ExecStep{LinuxExecStepConfig: &agentendpointpb.ExecStepConfig{Executable: &agentendpointpb.ExecStepConfig_LocalPath{LocalPath: "foo"}, Interpreter: agentendpointpb.ExecStepConfig_POWERSHELL}}}, {"WinExec", "linux", outputGen("", "", agentendpointpb.ExecStepTaskOutput_COMPLETED, 0), "", nil, &agentendpointpb.ExecStep{WindowsExecStepConfig: &agentendpointpb.ExecStepConfig{Executable: &agentendpointpb.ExecStepConfig_LocalPath{LocalPath: "foo"}}}}, {"WinShell", "linux", outputGen("", "", agentendpointpb.ExecStepTaskOutput_COMPLETED, 0), "", nil, &agentendpointpb.ExecStep{WindowsExecStepConfig: &agentendpointpb.ExecStepConfig{Executable: &agentendpointpb.ExecStepConfig_LocalPath{LocalPath: "foo"}, Interpreter: agentendpointpb.ExecStepConfig_SHELL}}}, {"WinPowerShell", "linux", outputGen("", "", agentendpointpb.ExecStepTaskOutput_COMPLETED, 0), "", nil, &agentendpointpb.ExecStep{WindowsExecStepConfig: &agentendpointpb.ExecStepConfig{Executable: &agentendpointpb.ExecStepConfig_LocalPath{LocalPath: "foo"}, Interpreter: agentendpointpb.ExecStepConfig_POWERSHELL}}}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { var gotPath string var gotArgs []string run = func(cmd *exec.Cmd) ([]byte, error) { gotPath = cmd.Path gotArgs = cmd.Args return nil, nil } goos = tt.goos if err := tc.client.RunExecStep(ctx, &agentendpointpb.Task{TaskDetails: &agentendpointpb.Task_ExecStepTask{ExecStepTask: &agentendpointpb.ExecStepTask{ExecStep: tt.step}}}); err != nil { t.Fatal(err) } if diff := cmp.Diff(tt.wantComReq, srv.lastReportTaskCompleteRequest, protocmp.Transform()); diff != "" { t.Fatalf("ReportTaskCompleteRequest mismatch (-want +got):\n%s", diff) } if gotPath != tt.wantPath { t.Errorf("did not get expected path, want: %q, got: %q", tt.wantPath, gotPath) } if diff := cmp.Diff(tt.wantArgs, gotArgs); diff != "" { t.Fatalf("did not get expected args (-want +got):\n%s", diff) } }) } } osconfig-20250416.02/agentendpoint/inventory.go000066400000000000000000000330041477773331400212510ustar00rootroot00000000000000package agentendpoint import ( "bytes" "context" "crypto/sha256" "encoding/hex" "fmt" "io" "reflect" "sort" "strings" "time" "github.com/GoogleCloudPlatform/osconfig/agentconfig" "github.com/GoogleCloudPlatform/osconfig/attributes" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/inventory" "github.com/GoogleCloudPlatform/osconfig/packages" "github.com/GoogleCloudPlatform/osconfig/retryutil" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" "cloud.google.com/go/osconfig/agentendpoint/apiv1/agentendpointpb" datepb "google.golang.org/genproto/googleapis/type/date" ) const ( inventoryURL = agentconfig.ReportURL + "/guestInventory" ) // ReportInventory writes inventory to guest attributes and reports it to agent endpoint. func (c *Client) ReportInventory(ctx context.Context) { state := inventory.Get(ctx) if agentconfig.GuestAttributesEnabled() && !agentconfig.DisableInventoryWrite() { clog.Infof(ctx, "Writing inventory to guest attributes") write(ctx, state, inventoryURL) } c.report(ctx, state) } func write(ctx context.Context, state *inventory.InstanceInventory, url string) { clog.Debugf(ctx, "Writing instance inventory to guest attributes.") e := reflect.ValueOf(state).Elem() t := e.Type() for i := 0; i < e.NumField(); i++ { f := e.Field(i) u := fmt.Sprintf("%s/%s", url, t.Field(i).Name) switch f.Kind() { case reflect.String: clog.Debugf(ctx, "postAttribute %s: %+v", u, f) if err := attributes.PostAttribute(u, strings.NewReader(f.String())); err != nil { clog.Errorf(ctx, "postAttribute error: %v", err) } case reflect.Ptr: switch reflect.Indirect(f).Kind() { case reflect.Struct: clog.Debugf(ctx, "postAttributeCompressed %s", u) if err := attributes.PostAttributeCompressed(u, f.Interface()); err != nil { clog.Errorf(ctx, "postAttributeCompressed error: %v", err) } } } } } func (c *Client) report(ctx context.Context, state *inventory.InstanceInventory) { clog.Debugf(ctx, "Reporting instance inventory to agent endpoint.") inventory := formatInventory(ctx, state) reportFull := false var res *agentendpointpb.ReportInventoryResponse var err error f := func() error { res, err = c.reportInventory(ctx, inventory, reportFull) if err != nil { return err } return nil } if err = retryutil.RetryAPICall(ctx, apiRetrySec*time.Second, "ReportInventory", f); err != nil { clog.Errorf(ctx, "Error reporting inventory checksum: %v", err) return } if res.GetReportFullInventory() { reportFull = true if err = retryutil.RetryAPICall(ctx, apiRetrySec*time.Second, "ReportInventory", f); err != nil { clog.Errorf(ctx, "Error reporting full inventory: %v", err) return } } } func formatInventory(ctx context.Context, state *inventory.InstanceInventory) *agentendpointpb.Inventory { osInfo := &agentendpointpb.Inventory_OsInfo{ Hostname: state.Hostname, LongName: state.LongName, ShortName: state.ShortName, Version: state.Version, Architecture: state.Architecture, KernelVersion: state.KernelVersion, KernelRelease: state.KernelRelease, OsconfigAgentVersion: state.OSConfigAgentVersion, } installedPackages := formatPackages(ctx, state.InstalledPackages, state.ShortName) availablePackages := formatPackages(ctx, state.PackageUpdates, state.ShortName) return &agentendpointpb.Inventory{OsInfo: osInfo, InstalledPackages: installedPackages, AvailablePackages: availablePackages} } func formatPackages(ctx context.Context, pkgs *packages.Packages, shortName string) []*agentendpointpb.Inventory_SoftwarePackage { var softwarePackages []*agentendpointpb.Inventory_SoftwarePackage if pkgs == nil { return softwarePackages } if pkgs.Apt != nil { temp := make([]*agentendpointpb.Inventory_SoftwarePackage, len(pkgs.Apt)) for i, pkg := range pkgs.Apt { temp[i] = &agentendpointpb.Inventory_SoftwarePackage{ Details: formatAptPackage(pkg), } } softwarePackages = append(softwarePackages, temp...) } if pkgs.Deb != nil { temp := make([]*agentendpointpb.Inventory_SoftwarePackage, len(pkgs.Deb)) for i, pkg := range pkgs.Deb { temp[i] = &agentendpointpb.Inventory_SoftwarePackage{ Details: formatAptPackage(pkg), } } softwarePackages = append(softwarePackages, temp...) } if pkgs.GooGet != nil { temp := make([]*agentendpointpb.Inventory_SoftwarePackage, len(pkgs.GooGet)) for i, pkg := range pkgs.GooGet { temp[i] = &agentendpointpb.Inventory_SoftwarePackage{ Details: formatGooGetPackage(pkg), } } softwarePackages = append(softwarePackages, temp...) } if pkgs.Yum != nil { temp := make([]*agentendpointpb.Inventory_SoftwarePackage, len(pkgs.Yum)) for i, pkg := range pkgs.Yum { temp[i] = &agentendpointpb.Inventory_SoftwarePackage{ Details: formatYumPackage(pkg), } } softwarePackages = append(softwarePackages, temp...) } if pkgs.Zypper != nil { temp := make([]*agentendpointpb.Inventory_SoftwarePackage, len(pkgs.Zypper)) for i, pkg := range pkgs.Zypper { temp[i] = &agentendpointpb.Inventory_SoftwarePackage{ Details: formatZypperPackage(pkg), } } softwarePackages = append(softwarePackages, temp...) } if pkgs.Rpm != nil { temp := make([]*agentendpointpb.Inventory_SoftwarePackage, len(pkgs.Rpm)) if packages.YumExists || !packages.ZypperExists { for i, pkg := range pkgs.Rpm { temp[i] = &agentendpointpb.Inventory_SoftwarePackage{ Details: formatYumPackage(pkg), } } } else { for i, pkg := range pkgs.Rpm { temp[i] = &agentendpointpb.Inventory_SoftwarePackage{ Details: formatZypperPackage(pkg), } } } softwarePackages = append(softwarePackages, temp...) } if pkgs.ZypperPatches != nil { temp := make([]*agentendpointpb.Inventory_SoftwarePackage, len(pkgs.ZypperPatches)) for i, pkg := range pkgs.ZypperPatches { temp[i] = &agentendpointpb.Inventory_SoftwarePackage{ Details: formatZypperPatch(pkg), } } softwarePackages = append(softwarePackages, temp...) } if pkgs.WUA != nil { temp := make([]*agentendpointpb.Inventory_SoftwarePackage, len(pkgs.WUA)) for i, pkg := range pkgs.WUA { temp[i] = &agentendpointpb.Inventory_SoftwarePackage{ Details: formatWUAPackage(pkg), } } softwarePackages = append(softwarePackages, temp...) } if pkgs.QFE != nil { temp := make([]*agentendpointpb.Inventory_SoftwarePackage, len(pkgs.QFE)) for i, pkg := range pkgs.QFE { temp[i] = &agentendpointpb.Inventory_SoftwarePackage{ Details: formatQFEPackage(ctx, pkg), } } softwarePackages = append(softwarePackages, temp...) } if pkgs.COS != nil { temp := make([]*agentendpointpb.Inventory_SoftwarePackage, len(pkgs.COS)) for i, pkg := range pkgs.COS { temp[i] = &agentendpointpb.Inventory_SoftwarePackage{ Details: formatCOSPackage(pkg), } } softwarePackages = append(softwarePackages, temp...) } if pkgs.WindowsApplication != nil { temp := make([]*agentendpointpb.Inventory_SoftwarePackage, len(pkgs.WindowsApplication)) for i, pkg := range pkgs.WindowsApplication { temp[i] = &agentendpointpb.Inventory_SoftwarePackage{ Details: formatWindowsApplication(pkg), } } softwarePackages = append(softwarePackages, temp...) } // Ignore Pip and Gem packages. return softwarePackages } func formatAptPackage(pkg *packages.PkgInfo) *agentendpointpb.Inventory_SoftwarePackage_AptPackage { fPkg := &agentendpointpb.Inventory_SoftwarePackage_AptPackage{ AptPackage: &agentendpointpb.Inventory_VersionedPackage{ PackageName: pkg.Name, Architecture: pkg.Arch, Version: pkg.Version, }, } // for some of the APT packages source package might be available. if pkg.Source.Name != "" { fPkg.AptPackage.Source = &agentendpointpb.Inventory_VersionedPackage_Source{ Name: pkg.Source.Name, Version: pkg.Source.Version, } } return fPkg } func formatCOSPackage(pkg *packages.PkgInfo) *agentendpointpb.Inventory_SoftwarePackage_CosPackage { return &agentendpointpb.Inventory_SoftwarePackage_CosPackage{ CosPackage: &agentendpointpb.Inventory_VersionedPackage{ PackageName: pkg.Name, Architecture: pkg.Arch, Version: pkg.Version, }} } func formatGooGetPackage(pkg *packages.PkgInfo) *agentendpointpb.Inventory_SoftwarePackage_GoogetPackage { return &agentendpointpb.Inventory_SoftwarePackage_GoogetPackage{ GoogetPackage: &agentendpointpb.Inventory_VersionedPackage{ PackageName: pkg.Name, Architecture: pkg.Arch, Version: pkg.Version, }} } func formatYumPackage(pkg *packages.PkgInfo) *agentendpointpb.Inventory_SoftwarePackage_YumPackage { fPkg := &agentendpointpb.Inventory_SoftwarePackage_YumPackage{ YumPackage: &agentendpointpb.Inventory_VersionedPackage{ PackageName: pkg.Name, Architecture: pkg.Arch, Version: pkg.Version, }, } // for some of the YUM packages source package might be available. if pkg.Source.Name != "" { fPkg.YumPackage.Source = &agentendpointpb.Inventory_VersionedPackage_Source{ Name: pkg.Source.Name, Version: pkg.Source.Version, } } return fPkg } func formatZypperPackage(pkg *packages.PkgInfo) *agentendpointpb.Inventory_SoftwarePackage_ZypperPackage { return &agentendpointpb.Inventory_SoftwarePackage_ZypperPackage{ ZypperPackage: &agentendpointpb.Inventory_VersionedPackage{ PackageName: pkg.Name, Architecture: pkg.Arch, Version: pkg.Version}} } func formatZypperPatch(pkg *packages.ZypperPatch) *agentendpointpb.Inventory_SoftwarePackage_ZypperPatch { return &agentendpointpb.Inventory_SoftwarePackage_ZypperPatch{ ZypperPatch: &agentendpointpb.Inventory_ZypperPatch{ PatchName: pkg.Name, Category: pkg.Category, Severity: pkg.Severity, Summary: pkg.Summary, }} } func formatWUAPackage(pkg *packages.WUAPackage) *agentendpointpb.Inventory_SoftwarePackage_WuaPackage { var categories []*agentendpointpb.Inventory_WindowsUpdatePackage_WindowsUpdateCategory for idx, category := range pkg.Categories { categories = append(categories, &agentendpointpb.Inventory_WindowsUpdatePackage_WindowsUpdateCategory{ Id: pkg.CategoryIDs[idx], Name: category, }) } return &agentendpointpb.Inventory_SoftwarePackage_WuaPackage{ WuaPackage: &agentendpointpb.Inventory_WindowsUpdatePackage{ Title: pkg.Title, Description: pkg.Description, Categories: categories, KbArticleIds: pkg.KBArticleIDs, SupportUrl: pkg.SupportURL, MoreInfoUrls: pkg.MoreInfoURLs, UpdateId: pkg.UpdateID, RevisionNumber: pkg.RevisionNumber, LastDeploymentChangeTime: timestamppb.New(pkg.LastDeploymentChangeTime), }} } func formatQFEPackage(ctx context.Context, pkg *packages.QFEPackage) *agentendpointpb.Inventory_SoftwarePackage_QfePackage { installedTime, err := time.Parse("1/2/2006", pkg.InstalledOn) if err != nil { clog.Warningf(ctx, "Error parsing QFE InstalledOn date: %v", err) } return &agentendpointpb.Inventory_SoftwarePackage_QfePackage{ QfePackage: &agentendpointpb.Inventory_WindowsQuickFixEngineeringPackage{ Caption: pkg.Caption, Description: pkg.Description, HotFixId: pkg.HotFixID, InstallTime: timestamppb.New(installedTime), }} } func formatWindowsApplication(pkg *packages.WindowsApplication) *agentendpointpb.Inventory_SoftwarePackage_WindowsApplication { d := datepb.Date{} // We have to check if date is zero. // Because zero value of time has Year, Month, Day equal to 1 if !pkg.InstallDate.IsZero() { d = datepb.Date{ Year: int32(pkg.InstallDate.Year()), Month: int32(pkg.InstallDate.Month()), Day: int32(pkg.InstallDate.Day()), } } return &agentendpointpb.Inventory_SoftwarePackage_WindowsApplication{ WindowsApplication: &agentendpointpb.Inventory_WindowsApplication{ DisplayName: pkg.DisplayName, DisplayVersion: pkg.DisplayVersion, Publisher: pkg.Publisher, InstallDate: &d, HelpLink: pkg.HelpLink, }} } func computeFingerprint(ctx context.Context, inventory *agentendpointpb.Inventory) (string, error) { fingerprint := sha256.New() b, err := proto.Marshal(inventory) if err != nil { return "", err } io.Copy(fingerprint, bytes.NewReader(b)) return hex.EncodeToString(fingerprint.Sum(nil)), nil } func computeStableFingerprint(ctx context.Context, inventory *agentendpointpb.Inventory) (string, error) { fingerprint := sha256.New() b, err := proto.Marshal(inventory.GetOsInfo()) if err != nil { return "", err } io.Copy(fingerprint, bytes.NewReader(b)) installedPackages := inventory.GetInstalledPackages() availablePackages := inventory.GetAvailablePackages() entries := make([]string, 0, len(installedPackages)+len(availablePackages)) for _, pkg := range installedPackages { entries = append(entries, fingerprintForPackage(pkg)) } for _, pkg := range availablePackages { entries = append(entries, fingerprintForPackage(pkg)) } sort.Strings(entries) for _, entry := range entries { if _, err := io.WriteString(fingerprint, entry); err != nil { return "", err } } return hex.EncodeToString(fingerprint.Sum(nil)), nil } func fingerprintForPackage(pkg *agentendpointpb.Inventory_SoftwarePackage) string { //Inventory_WindowsUpdatePackage struct contains repeated fields //we should rely on fields that are stable and sufficient enough to uniquely identify the package. if wua := pkg.GetWuaPackage(); wua != nil { return fmt.Sprintf("%s-%s-%d", wua.GetTitle(), wua.GetUpdateId(), wua.GetRevisionNumber()) } // For all packages other then wua we can just rely on proto String() method. return pkg.String() } osconfig-20250416.02/agentendpoint/inventory_test.go000066400000000000000000000572551477773331400223260ustar00rootroot00000000000000// Copyright 2017 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package agentendpoint import ( "bytes" "compress/gzip" "context" "encoding/base64" "encoding/json" "fmt" "io" "math/rand" "net/http" "net/http/httptest" "reflect" "testing" "time" "github.com/GoogleCloudPlatform/osconfig/inventory" "github.com/GoogleCloudPlatform/osconfig/packages" "github.com/google/go-cmp/cmp" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/testing/protocmp" "google.golang.org/protobuf/types/known/timestamppb" "cloud.google.com/go/osconfig/agentendpoint/apiv1/agentendpointpb" ) type agentEndpointServiceInventoryTestServer struct { lastReportInventoryRequest *agentendpointpb.ReportInventoryRequest reportFullInventory bool } func (*agentEndpointServiceInventoryTestServer) ReceiveTaskNotification(req *agentendpointpb.ReceiveTaskNotificationRequest, srv agentendpointpb.AgentEndpointService_ReceiveTaskNotificationServer) error { return status.Errorf(codes.Unimplemented, "method ReceiveTaskNotification not implemented") } func (*agentEndpointServiceInventoryTestServer) StartNextTask(ctx context.Context, req *agentendpointpb.StartNextTaskRequest) (*agentendpointpb.StartNextTaskResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method StartNextTask not implemented") } func (*agentEndpointServiceInventoryTestServer) ReportTaskProgress(ctx context.Context, req *agentendpointpb.ReportTaskProgressRequest) (*agentendpointpb.ReportTaskProgressResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ReportTaskProgress not implemented") } func (*agentEndpointServiceInventoryTestServer) ReportTaskComplete(ctx context.Context, req *agentendpointpb.ReportTaskCompleteRequest) (*agentendpointpb.ReportTaskCompleteResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ReportTaskComplete not implemented") } func (*agentEndpointServiceInventoryTestServer) RegisterAgent(ctx context.Context, req *agentendpointpb.RegisterAgentRequest) (*agentendpointpb.RegisterAgentResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method RegisterAgent not implemented") } func (s *agentEndpointServiceInventoryTestServer) ReportInventory(ctx context.Context, req *agentendpointpb.ReportInventoryRequest) (*agentendpointpb.ReportInventoryResponse, error) { s.lastReportInventoryRequest = req resp := &agentendpointpb.ReportInventoryResponse{ReportFullInventory: s.reportFullInventory} if s.reportFullInventory { s.reportFullInventory = false } return resp, nil } func generateInventoryState() *inventory.InstanceInventory { return &inventory.InstanceInventory{ Hostname: "Hostname", LongName: "LongName", ShortName: "ShortName", Version: "Version", Architecture: "Architecture", KernelVersion: "KernelVersion", KernelRelease: "KernelRelease", OSConfigAgentVersion: "OSConfigAgentVersion", InstalledPackages: &packages.Packages{ Yum: []*packages.PkgInfo{{ Name: "YumInstalledPkg", Arch: "Arch", Version: "Version", Source: packages.Source{Name: "SourceName", Version: "SourceVersion"}}}, Rpm: []*packages.PkgInfo{{ Name: "RpmInstalledPkg", Arch: "Arch", Version: "Version", Source: packages.Source{Name: "SourceName", Version: "SourceVersion"}}}, Apt: []*packages.PkgInfo{{ Name: "AptInstalledPkg", Arch: "Arch", Version: "Version", Source: packages.Source{Name: "SourceName", Version: "SourceVersion"}}}, Deb: []*packages.PkgInfo{{ Name: "DebInstalledPkg", Arch: "Arch", Version: "Version", Source: packages.Source{Name: "SourceName", Version: "SourceVersion"}}}, Zypper: []*packages.PkgInfo{{Name: "ZypperInstalledPkg", Arch: "Arch", Version: "Version"}}, ZypperPatches: []*packages.ZypperPatch{{Name: "ZypperInstalledPatch", Category: "Category", Severity: "Severity", Summary: "Summary"}}, Gem: []*packages.PkgInfo{{Name: "GemInstalledPkg", Arch: "Arch", Version: "Version"}}, Pip: []*packages.PkgInfo{{Name: "PipInstalledPkg", Arch: "Arch", Version: "Version"}}, GooGet: []*packages.PkgInfo{{Name: "GooGetInstalledPkg", Arch: "Arch", Version: "Version"}}, WUA: []*packages.WUAPackage{{ Title: "WUAInstalled", Description: "Description", Categories: []string{"Category1", "Category2", "Category3", "Category4"}, CategoryIDs: []string{"CategoryID1", "CategoryID2", "CategoryID3", "CategoryID4"}, KBArticleIDs: []string{"KB1", "KB2", "KB3", "KB4"}, MoreInfoURLs: []string{"MoreInfoURL1", "MoreInfoURL2", "MoreInfoURL3", "MoreInfoURL4"}, SupportURL: "SupportURL", UpdateID: "UpdateID", RevisionNumber: 1, LastDeploymentChangeTime: time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC)}}, QFE: []*packages.QFEPackage{{Caption: "QFEInstalled", Description: "Description", HotFixID: "HotFixID", InstalledOn: "9/1/2020"}}, COS: []*packages.PkgInfo{{Name: "CosInstalledPkg", Arch: "Arch", Version: "Version"}}, }, PackageUpdates: &packages.Packages{ Yum: []*packages.PkgInfo{{Name: "YumPkgUpdate", Arch: "Arch", Version: "Version"}}, Apt: []*packages.PkgInfo{{Name: "AptPkgUpdate", Arch: "Arch", Version: "Version"}}, Zypper: []*packages.PkgInfo{{Name: "ZypperPkgUpdate", Arch: "Arch", Version: "Version"}}, ZypperPatches: []*packages.ZypperPatch{{Name: "ZypperPatchUpdate", Category: "Category", Severity: "Severity", Summary: "Summary"}}, Gem: []*packages.PkgInfo{{Name: "GemPkgUpdate", Arch: "Arch", Version: "Version"}}, Pip: []*packages.PkgInfo{{Name: "PipPkgUpdate", Arch: "Arch", Version: "Version"}}, GooGet: []*packages.PkgInfo{{Name: "GooGetPkgUpdate", Arch: "Arch", Version: "Version"}}, WUA: []*packages.WUAPackage{{ Title: "WUAUpdate", Description: "Description", Categories: []string{"Category1", "Category2", "Category3", "Category4"}, CategoryIDs: []string{"CategoryID1", "CategoryID2", "CategoryID3", "CategoryID4"}, KBArticleIDs: []string{"KB1", "KB2", "KB3", "KB4"}, MoreInfoURLs: []string{"MoreInfoURL1", "MoreInfoURL2", "MoreInfoURL3", "MoreInfoURL4"}, SupportURL: "SupportURL", UpdateID: "UpdateID", RevisionNumber: 1, LastDeploymentChangeTime: time.Time{}}}, }, } } func generateInventory() *agentendpointpb.Inventory { return &agentendpointpb.Inventory{ OsInfo: &agentendpointpb.Inventory_OsInfo{ Hostname: "Hostname", LongName: "LongName", ShortName: "ShortName", Version: "Version", Architecture: "Architecture", KernelVersion: "KernelVersion", KernelRelease: "KernelRelease", OsconfigAgentVersion: "OSConfigAgentVersion", }, InstalledPackages: []*agentendpointpb.Inventory_SoftwarePackage{ { Details: &agentendpointpb.Inventory_SoftwarePackage_AptPackage{ AptPackage: &agentendpointpb.Inventory_VersionedPackage{ PackageName: "AptInstalledPkg", Architecture: "Arch", Version: "Version", Source: &agentendpointpb.Inventory_VersionedPackage_Source{ Name: "SourceName", Version: "SourceVersion", }, }}}, { Details: &agentendpointpb.Inventory_SoftwarePackage_AptPackage{ AptPackage: &agentendpointpb.Inventory_VersionedPackage{ PackageName: "DebInstalledPkg", Architecture: "Arch", Version: "Version", Source: &agentendpointpb.Inventory_VersionedPackage_Source{ Name: "SourceName", Version: "SourceVersion", }, }}}, { Details: &agentendpointpb.Inventory_SoftwarePackage_GoogetPackage{ GoogetPackage: &agentendpointpb.Inventory_VersionedPackage{ PackageName: "GooGetInstalledPkg", Architecture: "Arch", Version: "Version"}}}, { Details: &agentendpointpb.Inventory_SoftwarePackage_YumPackage{ YumPackage: &agentendpointpb.Inventory_VersionedPackage{ PackageName: "YumInstalledPkg", Architecture: "Arch", Version: "Version", Source: &agentendpointpb.Inventory_VersionedPackage_Source{ Name: "SourceName", Version: "SourceVersion", }, }}}, { Details: &agentendpointpb.Inventory_SoftwarePackage_ZypperPackage{ ZypperPackage: &agentendpointpb.Inventory_VersionedPackage{ PackageName: "ZypperInstalledPkg", Architecture: "Arch", Version: "Version"}}}, { Details: &agentendpointpb.Inventory_SoftwarePackage_YumPackage{ YumPackage: &agentendpointpb.Inventory_VersionedPackage{ PackageName: "RpmInstalledPkg", Architecture: "Arch", Version: "Version", Source: &agentendpointpb.Inventory_VersionedPackage_Source{ Name: "SourceName", Version: "SourceVersion", }, }}}, { Details: &agentendpointpb.Inventory_SoftwarePackage_ZypperPatch{ ZypperPatch: &agentendpointpb.Inventory_ZypperPatch{ PatchName: "ZypperInstalledPatch", Category: "Category", Severity: "Severity", Summary: "Summary"}}}, { Details: &agentendpointpb.Inventory_SoftwarePackage_WuaPackage{ WuaPackage: &agentendpointpb.Inventory_WindowsUpdatePackage{ Title: "WUAInstalled", Description: "Description", Categories: []*agentendpointpb.Inventory_WindowsUpdatePackage_WindowsUpdateCategory{ {Id: "CategoryID1", Name: "Category1"}, {Id: "CategoryID2", Name: "Category2"}, {Id: "CategoryID3", Name: "Category3"}, {Id: "CategoryID4", Name: "Category4"}, }, KbArticleIds: []string{"KB1", "KB2", "KB3", "KB4"}, SupportUrl: "SupportURL", MoreInfoUrls: []string{"MoreInfoURL1", "MoreInfoURL2", "MoreInfoURL3", "MoreInfoURL4"}, UpdateId: "UpdateID", RevisionNumber: 1, LastDeploymentChangeTime: timestamppb.New(time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC)), }}}, { Details: &agentendpointpb.Inventory_SoftwarePackage_QfePackage{ QfePackage: &agentendpointpb.Inventory_WindowsQuickFixEngineeringPackage{ Caption: "QFEInstalled", Description: "Description", HotFixId: "HotFixID", InstallTime: timestamppb.New(time.Date(2020, time.September, 1, 0, 0, 0, 0, time.UTC))}}}, { Details: &agentendpointpb.Inventory_SoftwarePackage_CosPackage{ CosPackage: &agentendpointpb.Inventory_VersionedPackage{ PackageName: "CosInstalledPkg", Architecture: "Arch", Version: "Version"}}}, }, AvailablePackages: []*agentendpointpb.Inventory_SoftwarePackage{ { Details: &agentendpointpb.Inventory_SoftwarePackage_AptPackage{ AptPackage: &agentendpointpb.Inventory_VersionedPackage{ PackageName: "AptPkgUpdate", Architecture: "Arch", Version: "Version"}}}, { Details: &agentendpointpb.Inventory_SoftwarePackage_GoogetPackage{ GoogetPackage: &agentendpointpb.Inventory_VersionedPackage{ PackageName: "GooGetPkgUpdate", Architecture: "Arch", Version: "Version"}}}, { Details: &agentendpointpb.Inventory_SoftwarePackage_YumPackage{ YumPackage: &agentendpointpb.Inventory_VersionedPackage{ PackageName: "YumPkgUpdate", Architecture: "Arch", Version: "Version"}}}, { Details: &agentendpointpb.Inventory_SoftwarePackage_ZypperPackage{ ZypperPackage: &agentendpointpb.Inventory_VersionedPackage{ PackageName: "ZypperPkgUpdate", Architecture: "Arch", Version: "Version"}}}, { Details: &agentendpointpb.Inventory_SoftwarePackage_ZypperPatch{ ZypperPatch: &agentendpointpb.Inventory_ZypperPatch{ PatchName: "ZypperPatchUpdate", Category: "Category", Severity: "Severity", Summary: "Summary"}}}, { Details: &agentendpointpb.Inventory_SoftwarePackage_WuaPackage{ WuaPackage: &agentendpointpb.Inventory_WindowsUpdatePackage{ Title: "WUAUpdate", Description: "Description", Categories: []*agentendpointpb.Inventory_WindowsUpdatePackage_WindowsUpdateCategory{ {Id: "CategoryID1", Name: "Category1"}, {Id: "CategoryID2", Name: "Category2"}, {Id: "CategoryID3", Name: "Category3"}, {Id: "CategoryID4", Name: "Category4"}, }, KbArticleIds: []string{"KB1", "KB2", "KB3", "KB4"}, SupportUrl: "SupportURL", MoreInfoUrls: []string{"MoreInfoURL1", "MoreInfoURL2", "MoreInfoURL3", "MoreInfoURL4"}, UpdateId: "UpdateID", RevisionNumber: 1, LastDeploymentChangeTime: timestamppb.New(time.Time{})}}}, }, } } func decodePackages(str string) *packages.Packages { decoded, _ := base64.StdEncoding.DecodeString(str) zr, _ := gzip.NewReader(bytes.NewReader(decoded)) var buf bytes.Buffer io.Copy(&buf, zr) zr.Close() var pkgs packages.Packages json.Unmarshal(buf.Bytes(), &pkgs) return &pkgs } func TestWrite(t *testing.T) { inv := &inventory.InstanceInventory{ Hostname: "Hostname", LongName: "LongName", ShortName: "ShortName", Architecture: "Architecture", KernelVersion: "KernelVersion", KernelRelease: "KernelRelease", Version: "Version", InstalledPackages: &packages.Packages{ Yum: []*packages.PkgInfo{{Name: "Name", Arch: "Arch", Version: "Version"}}, WUA: []*packages.WUAPackage{{Title: "Title"}}, QFE: []*packages.QFEPackage{{HotFixID: "HotFixID"}}, }, PackageUpdates: &packages.Packages{ Apt: []*packages.PkgInfo{{Name: "Name", Arch: "Arch", Version: "Version"}}, }, OSConfigAgentVersion: "OSConfigAgentVersion", LastUpdated: "LastUpdated", } want := map[string]bool{ "Hostname": false, "LongName": false, "ShortName": false, "Architecture": false, "KernelVersion": false, "Version": false, "InstalledPackages": false, "PackageUpdates": false, "OSConfigAgentVersion": false, } svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { url := r.URL.String() buf := new(bytes.Buffer) if _, err := buf.ReadFrom(r.Body); err != nil { t.Fatal(err) } switch url { case "/Hostname": if buf.String() != inv.Hostname { t.Errorf("did not get expected Hostname, got: %q, want: %q", buf.String(), inv.Hostname) } want["Hostname"] = true case "/LongName": if buf.String() != inv.LongName { t.Errorf("did not get expected LongName, got: %q, want: %q", buf.String(), inv.LongName) } want["LongName"] = true case "/ShortName": if buf.String() != inv.ShortName { t.Errorf("did not get expected ShortName, got: %q, want: %q", buf.String(), inv.ShortName) } want["ShortName"] = true case "/Architecture": if buf.String() != inv.Architecture { t.Errorf("did not get expected Architecture, got: %q, want: %q", buf.String(), inv.Architecture) } want["Architecture"] = true case "/KernelVersion": if buf.String() != inv.KernelVersion { t.Errorf("did not get expected KernelVersion, got: %q, want: %q", buf.String(), inv.KernelVersion) } want["KernelVersion"] = true case "/KernelRelease": if buf.String() != inv.KernelRelease { t.Errorf("did not get expected KernelRelease, got: %q, want: %q", buf.String(), inv.KernelRelease) } want["KernelRelease"] = true case "/Version": if buf.String() != inv.Version { t.Errorf("did not get expected Version, got: %q, want: %q", buf.String(), inv.Version) } want["Version"] = true case "/InstalledPackages": got := decodePackages(buf.String()) if !reflect.DeepEqual(got, inv.InstalledPackages) { t.Errorf("did not get expected InstalledPackages, got: %+v, want: %+v", got, inv.InstalledPackages) } want["InstalledPackages"] = true case "/PackageUpdates": got := decodePackages(buf.String()) if !reflect.DeepEqual(got, inv.PackageUpdates) { t.Errorf("did not get expected PackageUpdates, got: %+v, want: %+v", got, inv.PackageUpdates) } want["PackageUpdates"] = true case "/OSConfigAgentVersion": if buf.String() != inv.OSConfigAgentVersion { t.Errorf("did not get expected OSConfigAgentVersion, got: %q, want: %q", buf.String(), inv.OSConfigAgentVersion) } want["OSConfigAgentVersion"] = true case "/LastUpdated": if buf.String() != inv.LastUpdated { t.Errorf("did not get expected LastUpdated, got: %q, want: %q", buf.String(), inv.LastUpdated) } want["LastUpdated"] = true default: w.WriteHeader(500) fmt.Fprintln(w, "URL and Method not recognized:", r.Method, url) } })) defer svr.Close() ctx := context.Background() write(ctx, inv, svr.URL) for k, v := range want { if v { continue } t.Errorf("writeInventory call did not write %q", k) } } func TestReport(t *testing.T) { ctx := context.Background() srv := &agentEndpointServiceInventoryTestServer{} tc, err := newTestClient(ctx, srv) if err != nil { t.Fatal(err) } defer tc.close() tests := []struct { name string reportFullInventory bool inventoryState *inventory.InstanceInventory wantInventory *agentendpointpb.Inventory }{ { name: "ReportChecksumOnly", reportFullInventory: false, inventoryState: generateInventoryState(), wantInventory: nil, }, { name: "ReportFullInventory", reportFullInventory: true, inventoryState: generateInventoryState(), wantInventory: generateInventory(), }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { srv.reportFullInventory = tt.reportFullInventory tc.client.report(ctx, tt.inventoryState) actualInventory := srv.lastReportInventoryRequest.Inventory if diff := cmp.Diff(tt.wantInventory, actualInventory, protocmp.Transform()); diff != "" { t.Fatalf("ReportInventoryRequest.Inventory mismatch (-want +got):\n%s", diff) } }) } } func Test_computeFingerprint_gotExpectedFingerprintFormat(t *testing.T) { ctx := context.Background() fingerprint, err := computeFingerprint(ctx, generateInventory()) if err != nil { t.Fatalf("unable to generate fingerprint, err - %s", err) } if !validFingerprint(fingerprint) { t.Fatalf("got fingerprint %q in unexpected format", fingerprint) } } func Test_computeFingerprint_fingerprintChangedAfterReshuffle(t *testing.T) { ctx := context.Background() inventory := generateInventory() initialFingerprint, err := computeFingerprint(ctx, inventory) if err != nil { t.Fatalf("unable to generate initial fingerprint, err - %s", err) } inventoryPackagesMixer(time.Now().UnixNano())(inventory) finalFingerprint, err := computeFingerprint(ctx, inventory) if err != nil { t.Fatalf("unable to generate final fingerprint, err - %s", err) } if initialFingerprint == finalFingerprint { t.Errorf("unstable fingerprint is equal for different inventories") } } func Test_computeStableFingerprint_fingerprintNotChangedAfterReshuffle(t *testing.T) { ctx := context.Background() inventory := generateInventory() initialFingerprint, err := computeStableFingerprint(ctx, inventory) if err != nil { t.Fatalf("unable to generate initial fingerprint, err - %s", err) } inventoryPackagesMixer(time.Now().UnixNano())(inventory) finalFingerprint, err := computeStableFingerprint(ctx, inventory) if err != nil { t.Fatalf("unable to generate final fingerprint, err - %s", err) } if initialFingerprint != finalFingerprint { t.Errorf("stable fingerprint is not equal for inventory with different order") } } func Test_computeStableFingerprint_fingerprintChangedAfterChanging(t *testing.T) { ctx := context.Background() inventory := generateInventory() initialFingerprint, err := computeStableFingerprint(ctx, inventory) if err != nil { t.Fatalf("unable to generate initial fingerprint, err - %s", err) } inventory.AvailablePackages = nil finalFingerprint, err := computeStableFingerprint(ctx, inventory) if err != nil { t.Fatalf("unable to generate final fingerprint, err - %s", err) } if initialFingerprint == finalFingerprint { t.Errorf("stable fingerprint should not be equal if inventory is actually changed") } } func validFingerprint(fingerprint string) bool { if fingerprint == "" { return false } if len(fingerprint) != 64 { return false } return true } func Test_computeStableFingerprint_testFingerprintStability(t *testing.T) { ctx := context.Background() inventory := generateInventory() mixer := inventoryPackagesMixer(time.Now().UnixNano()) n := 100 for i := 0; i < n; i++ { t.Run(fmt.Sprintf("Run %d", i), func(t *testing.T) { // Compute initial fingerprints. unstableFingerprintBefore, err := computeFingerprint(ctx, inventory) if err != nil { t.Errorf("unexpected error while calculating fingerprint, err %v", err) } stableFingerprintBefore, err := computeStableFingerprint(ctx, inventory) if err != nil { t.Errorf("unexpected error while calculating fingerprint, err %v", err) } // Reorder pacakges in the inventory, that should change result of computeFingerprint // and do not change the result of computeStableFingerptint. mixer(inventory) // Generate new fingerprints after reshufling of the packages. unstableFingerprintAfter, err := computeFingerprint(ctx, inventory) if err != nil { t.Errorf("unexpected error while calculating fingerprint, err %v", err) } stableFingerprintAfter, err := computeStableFingerprint(ctx, inventory) if err != nil { t.Errorf("unexpected error while calculating fingerprint, err %v", err) } //Confirm that unstable fingerprint changed and stable fingerprint not. if unstableFingerprintBefore == unstableFingerprintAfter { t.Errorf("unstable fingerprint is equal for different inventories") } if stableFingerprintBefore != stableFingerprintAfter { t.Errorf("stable fingerprint is not equal for identical inventories") } }) } } func inventoryPackagesMixer(source int64) func(inventory *agentendpointpb.Inventory) { fmt.Printf("Inventory packages mixer initialized with source %d\n", source) rng := rand.New(rand.NewSource(source)) return func(inventory *agentendpointpb.Inventory) { rng.Shuffle(len(inventory.InstalledPackages), func(i, j int) { inventory.InstalledPackages[i], inventory.InstalledPackages[j] = inventory.InstalledPackages[j], inventory.InstalledPackages[i] }) rng.Shuffle(len(inventory.AvailablePackages), func(i, j int) { inventory.AvailablePackages[i], inventory.AvailablePackages[j] = inventory.AvailablePackages[j], inventory.AvailablePackages[i] }) } } func Benchmark_computeFingerprint(b *testing.B) { ctx, inventory := context.Background(), generateInventory() for i := 0; i < b.N; i++ { _, err := computeFingerprint(ctx, inventory) if err != nil { b.Fatalf("unable to generate fingerprint, err - %s", err) } } } func Benchmark_computeStableFingerprint(b *testing.B) { ctx, inventory := context.Background(), generateInventory() for i := 0; i < b.N; i++ { _, err := computeStableFingerprint(ctx, inventory) if err != nil { b.Fatalf("unable to generate fingerprint, err - %s", err) } } } osconfig-20250416.02/agentendpoint/patch_linux.go000066400000000000000000000106641477773331400215410ustar00rootroot00000000000000// Copyright 2018 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package agentendpoint import ( "context" "errors" "regexp" "strings" "time" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/ospatch" "github.com/GoogleCloudPlatform/osconfig/packages" "github.com/GoogleCloudPlatform/osconfig/retryutil" "cloud.google.com/go/osconfig/agentendpoint/apiv1/agentendpointpb" ) func (r *patchTask) runUpdates(ctx context.Context) error { var errs []string const retryPeriod = 3 * time.Minute // Check for both apt-get and dpkg-query to give us a clean signal. if packages.AptExists && packages.DpkgQueryExists { excludes, err := convertInputToExcludes(r.Task.GetPatchConfig().GetApt().GetExcludes()) if err != nil { return err } opts := []ospatch.AptGetUpgradeOption{ ospatch.AptGetDryRun(r.Task.GetDryRun()), ospatch.AptGetExcludes(excludes), ospatch.AptGetExclusivePackages(r.Task.GetPatchConfig().GetApt().GetExclusivePackages()), } switch r.Task.GetPatchConfig().GetApt().GetType() { case agentendpointpb.AptSettings_DIST: opts = append(opts, ospatch.AptGetUpgradeType(packages.AptGetDistUpgrade)) } clog.Debugf(ctx, "Installing APT package updates.") if err := retryutil.RetryFunc(ctx, retryPeriod, "installing APT package updates", func() error { return ospatch.RunAptGetUpgrade(ctx, opts...) }); err != nil { errs = append(errs, err.Error()) } } if packages.YumExists && packages.RPMQueryExists { excludes, err := convertInputToExcludes(r.Task.GetPatchConfig().GetYum().GetExcludes()) if err != nil { return err } opts := []ospatch.YumUpdateOption{ ospatch.YumUpdateSecurity(r.Task.GetPatchConfig().GetYum().GetSecurity()), ospatch.YumUpdateMinimal(r.Task.GetPatchConfig().GetYum().GetMinimal()), ospatch.YumUpdateExcludes(excludes), ospatch.YumExclusivePackages(r.Task.GetPatchConfig().GetYum().GetExclusivePackages()), ospatch.YumDryRun(r.Task.GetDryRun()), } clog.Debugf(ctx, "Installing YUM package updates.") if err := retryutil.RetryFunc(ctx, retryPeriod, "installing YUM package updates", func() error { return ospatch.RunYumUpdate(ctx, opts...) }); err != nil { errs = append(errs, err.Error()) } } if packages.ZypperExists && packages.RPMQueryExists { excludes, err := convertInputToExcludes(r.Task.GetPatchConfig().GetZypper().GetExcludes()) if err != nil { return err } opts := []ospatch.ZypperPatchOption{ ospatch.ZypperPatchCategories(r.Task.GetPatchConfig().GetZypper().GetCategories()), ospatch.ZypperPatchSeverities(r.Task.GetPatchConfig().GetZypper().GetSeverities()), ospatch.ZypperUpdateWithUpdate(r.Task.GetPatchConfig().GetZypper().GetWithUpdate()), ospatch.ZypperUpdateWithOptional(r.Task.GetPatchConfig().GetZypper().GetWithOptional()), ospatch.ZypperUpdateWithExcludes(excludes), ospatch.ZypperUpdateWithExclusivePatches(r.Task.GetPatchConfig().GetZypper().GetExclusivePatches()), ospatch.ZypperUpdateDryrun(r.Task.GetDryRun()), } clog.Debugf(ctx, "Installing Zypper updates.") if err := retryutil.RetryFunc(ctx, retryPeriod, "installing Zypper updates", func() error { return ospatch.RunZypperPatch(ctx, opts...) }); err != nil { errs = append(errs, err.Error()) } } if errs == nil { return nil } return errors.New(strings.Join(errs, ",\n")) } func convertInputToExcludes(input []string) ([]*ospatch.Exclude, error) { var output []*ospatch.Exclude for _, s := range input { if len(s) >= 2 && (s)[0] == '/' && s[len(s)-1] == '/' { exclude, err := regexExcludeFromString(s[1 : len(s)-1]) if err != nil { return nil, err } output = append(output, exclude) } else { output = append(output, ospatch.CreateStringExclude(&s)) } } return output, nil } func regexExcludeFromString(s string) (*ospatch.Exclude, error) { compile, err := regexp.Compile(s) if err != nil { return nil, err } return ospatch.CreateRegexExclude(compile), nil } osconfig-20250416.02/agentendpoint/patch_linux_test.go000066400000000000000000000045621477773331400226000ustar00rootroot00000000000000// Copyright 2022 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package agentendpoint import ( "reflect" "regexp" "strings" "testing" "github.com/GoogleCloudPlatform/osconfig/ospatch" ) func TestExcludeConversion(t *testing.T) { regex, _ := regexp.Compile("PackageName") emptyRegex, _ := regexp.Compile("") tests := []struct { name string input []string want []*ospatch.Exclude }{ {name: "StrictStringConversion", input: []string{"PackageName"}, want: CreateStringExcludes("PackageName")}, {name: "MultipleStringConversion", input: []string{"PackageName1", "PackageName2"}, want: CreateStringExcludes("PackageName1", "PackageName2")}, {name: "RegexConversion", input: []string{"/PackageName/"}, want: []*ospatch.Exclude{ospatch.CreateRegexExclude(regex)}}, {name: "CornerCaseRegex", input: []string{"//"}, want: []*ospatch.Exclude{ospatch.CreateRegexExclude(emptyRegex)}}, {name: "CornerCaseStrictString", input: []string{"/"}, want: CreateStringExcludes("/")}, {name: "CornerCaseEmptyString", input: []string{""}, want: CreateStringExcludes("")}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { excludes, err := convertInputToExcludes(tt.input) if err != nil { t.Errorf("err = %v, want %v", err, nil) } if !reflect.DeepEqual(excludes, tt.want) { t.Errorf("convertInputToExcludes() = %s, want = %s", toString(excludes), toString(tt.want)) } }) } } func toString(excludes []*ospatch.Exclude) string { results := make([]string, len(excludes)) for i, exc := range excludes { results[i] = exc.String() } return strings.Join(results, ",") } func CreateStringExcludes(pkgs ...string) []*ospatch.Exclude { excludes := make([]*ospatch.Exclude, len(pkgs)) for i := 0; i < len(pkgs); i++ { pkg := pkgs[i] excludes[i] = ospatch.CreateStringExclude(&pkg) } return excludes } osconfig-20250416.02/agentendpoint/patch_task.go000066400000000000000000000240451477773331400213420ustar00rootroot00000000000000// Copyright 2018 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package agentendpoint import ( "context" "fmt" "time" "github.com/GoogleCloudPlatform/osconfig/agentconfig" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/ospatch" "google.golang.org/protobuf/encoding/protojson" "cloud.google.com/go/osconfig/agentendpoint/apiv1/agentendpointpb" ) func systemRebootRequired(ctx context.Context) (bool, error) { return ospatch.SystemRebootRequired(ctx) } type patchStep string const ( prePatch = "PrePatch" patching = "Patching" postPatch = "PostPatch" totalRebootCountLimit = 5 ) type patchTask struct { client *Client lastProgressState map[agentendpointpb.ApplyPatchesTaskProgress_State]time.Time state *taskState TaskID string Task *applyPatchesTask StartedAt time.Time `json:",omitempty"` PatchStep patchStep `json:",omitempty"` PrePatchRebootCount int PostPatchRebootCount int // TODO: add Attempts and track number of retries with backoff, jitter, etc. } func (r *patchTask) saveState() error { r.state.PatchTask = r return r.state.save(taskStateFile) } func (r *patchTask) complete(ctx context.Context) { if err := (&taskState{}).save(taskStateFile); err != nil { clog.Errorf(ctx, "Error saving state: %v", err) } } type applyPatchesTask struct { *agentendpointpb.ApplyPatchesTask } // MarshalJSON marshals a patchConfig using protojson. func (a *applyPatchesTask) MarshalJSON() ([]byte, error) { m := &protojson.MarshalOptions{AllowPartial: true, EmitUnpopulated: false} return m.Marshal(a) } // UnmarshalJSON unmarshals a patchConfig using protojson. func (a *applyPatchesTask) UnmarshalJSON(b []byte) error { a.ApplyPatchesTask = &agentendpointpb.ApplyPatchesTask{} un := &protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true} return un.Unmarshal(b, a.ApplyPatchesTask) } func (r *patchTask) setStep(step patchStep) error { r.PatchStep = step if err := r.saveState(); err != nil { return fmt.Errorf("error saving state: %v", err) } return nil } func (r *patchTask) handleErrorState(ctx context.Context, msg string, err error) error { if err == errServerCancel { return r.reportCanceled(ctx) } return r.reportFailed(ctx, msg) } func (r *patchTask) reportFailed(ctx context.Context, msg string) error { clog.Errorf(ctx, "%v", msg) return r.reportCompletedState(ctx, msg, &agentendpointpb.ReportTaskCompleteRequest_ApplyPatchesTaskOutput{ ApplyPatchesTaskOutput: &agentendpointpb.ApplyPatchesTaskOutput{State: agentendpointpb.ApplyPatchesTaskOutput_FAILED}, }) } func (r *patchTask) reportCanceled(ctx context.Context) error { clog.Infof(ctx, "Canceling patch execution") return r.reportCompletedState(ctx, errServerCancel.Error(), &agentendpointpb.ReportTaskCompleteRequest_ApplyPatchesTaskOutput{ // Is this right? Maybe there should be a canceled state instead. ApplyPatchesTaskOutput: &agentendpointpb.ApplyPatchesTaskOutput{State: agentendpointpb.ApplyPatchesTaskOutput_FAILED}, }) } func (r *patchTask) reportCompletedState(ctx context.Context, errMsg string, output *agentendpointpb.ReportTaskCompleteRequest_ApplyPatchesTaskOutput) error { req := &agentendpointpb.ReportTaskCompleteRequest{ TaskId: r.TaskID, TaskType: agentendpointpb.TaskType_APPLY_PATCHES, ErrorMessage: errMsg, Output: output, } if err := r.client.reportTaskComplete(ctx, req); err != nil { return fmt.Errorf("error reporting completed state: %v", err) } return nil } func (r *patchTask) reportContinuingState(ctx context.Context, patchState agentendpointpb.ApplyPatchesTaskProgress_State) error { st, ok := r.lastProgressState[patchState] if ok && st.After(time.Now().Add(sameStateTimeWindow)) { // Don't resend the same state more than once every 5s. return nil } req := &agentendpointpb.ReportTaskProgressRequest{ TaskId: r.TaskID, TaskType: agentendpointpb.TaskType_APPLY_PATCHES, Progress: &agentendpointpb.ReportTaskProgressRequest_ApplyPatchesTaskProgress{ ApplyPatchesTaskProgress: &agentendpointpb.ApplyPatchesTaskProgress{State: patchState}, }, } res, err := r.client.reportTaskProgress(ctx, req) if err != nil { return fmt.Errorf("error reporting state %s: %v", patchState, err) } if res.GetTaskDirective() == agentendpointpb.TaskDirective_STOP { return errServerCancel } if r.lastProgressState == nil { r.lastProgressState = make(map[agentendpointpb.ApplyPatchesTaskProgress_State]time.Time) } r.lastProgressState[patchState] = time.Now() return r.saveState() } func (r *patchTask) prePatchReboot(ctx context.Context) error { return r.rebootIfNeeded(ctx, true) } func (r *patchTask) postPatchReboot(ctx context.Context) error { return r.rebootIfNeeded(ctx, false) } func (r *patchTask) rebootIfNeeded(ctx context.Context, prePatch bool) error { var reboot bool var err error if r.Task.GetPatchConfig().GetRebootConfig() == agentendpointpb.PatchConfig_ALWAYS && !prePatch && r.PostPatchRebootCount == 0 { reboot = true clog.Infof(ctx, "PatchConfig RebootConfig set to %s.", agentendpointpb.PatchConfig_ALWAYS) } else { reboot, err = systemRebootRequired(ctx) if err != nil { return fmt.Errorf("error checking if a system reboot is required: %v", err) } if reboot { clog.Infof(ctx, "System indicates a reboot is required.") totalRebootCount := r.PrePatchRebootCount + r.PostPatchRebootCount if totalRebootCount >= totalRebootCountLimit { clog.Infof(ctx, "Detected abnormal number of reboots for a single patch task (%d). Not rebooting to prevent a possible boot loop", totalRebootCount) return nil } } else { clog.Infof(ctx, "System indicates a reboot is not required.") } } if !reboot { return nil } if r.Task.GetPatchConfig().GetRebootConfig() == agentendpointpb.PatchConfig_NEVER { clog.Infof(ctx, "Skipping reboot because of PatchConfig RebootConfig set to %s.", agentendpointpb.PatchConfig_NEVER) return nil } if err := r.reportContinuingState(ctx, agentendpointpb.ApplyPatchesTaskProgress_REBOOTING); err != nil { return err } if r.Task.GetDryRun() { clog.Infof(ctx, "Dry run - not rebooting for ApplyPatchesTask") return nil } if prePatch { r.PrePatchRebootCount++ } else { r.PostPatchRebootCount++ } if err := r.saveState(); err != nil { return fmt.Errorf("error saving state: %v", err) } if err := rebootSystem(); err != nil { return fmt.Errorf("failed to reboot system: %v", err) } // Reboot can take a bit, pause here so other activities don't start. for { clog.Debugf(ctx, "Waiting for system reboot.") time.Sleep(1 * time.Minute) } } func (r *patchTask) run(ctx context.Context) (err error) { ctx = clog.WithLabels(ctx, r.state.Labels) clog.Infof(ctx, "Beginning ApplyPatchesTask") defer func() { // This should not happen but the WUA libraries are complicated and // recovering with an error is better than crashing. if rec := recover(); rec != nil { err = fmt.Errorf("Recovered from panic: %v", rec) r.reportFailed(ctx, err.Error()) return } r.complete(ctx) if agentconfig.OSInventoryEnabled() { go r.client.ReportInventory(ctx) } }() for { clog.Debugf(ctx, "Running PatchStep %q.", r.PatchStep) switch r.PatchStep { default: return r.reportFailed(ctx, fmt.Sprintf("unknown step: %q", r.PatchStep)) case prePatch: r.StartedAt = time.Now() if err := r.setStep(patching); err != nil { return r.reportFailed(ctx, fmt.Sprintf("Error saving agent step: %v", err)) } if err := r.reportContinuingState(ctx, agentendpointpb.ApplyPatchesTaskProgress_STARTED); err != nil { return r.handleErrorState(ctx, err.Error(), err) } if err := r.prePatchReboot(ctx); err != nil { return r.handleErrorState(ctx, fmt.Sprintf("Error running prePatchReboot: %v", err), err) } case patching: if err := r.reportContinuingState(ctx, agentendpointpb.ApplyPatchesTaskProgress_APPLYING_PATCHES); err != nil { return r.handleErrorState(ctx, err.Error(), err) } if err := r.runUpdates(ctx); err != nil { return r.handleErrorState(ctx, fmt.Sprintf("Failed to apply patches: %v", err), err) } if err := r.postPatchReboot(ctx); err != nil { return r.handleErrorState(ctx, fmt.Sprintf("Error running postPatchReboot: %v", err), err) } // We have not rebooted so patching is complete. if err := r.setStep(postPatch); err != nil { return r.reportFailed(ctx, fmt.Sprintf("Error saving agent step: %v", err)) } case postPatch: isRebootRequired, err := systemRebootRequired(ctx) if err != nil { return r.reportFailed(ctx, fmt.Sprintf("Error checking if system reboot is required: %v", err)) } finalState := agentendpointpb.ApplyPatchesTaskOutput_SUCCEEDED if isRebootRequired { finalState = agentendpointpb.ApplyPatchesTaskOutput_SUCCEEDED_REBOOT_REQUIRED } if err := r.reportCompletedState(ctx, "", &agentendpointpb.ReportTaskCompleteRequest_ApplyPatchesTaskOutput{ ApplyPatchesTaskOutput: &agentendpointpb.ApplyPatchesTaskOutput{State: finalState}, }); err != nil { return fmt.Errorf("failed to report state %s: %v", finalState, err) } clog.Infof(ctx, "Successfully completed ApplyPatchesTask") return nil } } } // RunApplyPatches runs an ApplyPatchesTask. func (c *Client) RunApplyPatches(ctx context.Context, task *agentendpointpb.Task) error { r := &patchTask{ state: &taskState{Labels: task.GetServiceLabels()}, TaskID: task.GetTaskId(), client: c, Task: &applyPatchesTask{task.GetApplyPatchesTask()}, } r.setStep(prePatch) return r.run(ctx) } osconfig-20250416.02/agentendpoint/patch_windows.go000066400000000000000000000116531477773331400220730ustar00rootroot00000000000000// Copyright 2018 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build windows // +build windows package agentendpoint import ( "context" "fmt" "time" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/ospatch" "github.com/GoogleCloudPlatform/osconfig/packages" "github.com/GoogleCloudPlatform/osconfig/retryutil" "cloud.google.com/go/osconfig/agentendpoint/apiv1/agentendpointpb" ) func (r *patchTask) classFilter() ([]string, error) { var classifications = map[agentendpointpb.WindowsUpdateSettings_Classification]string{ agentendpointpb.WindowsUpdateSettings_CRITICAL: "e6cf1350-c01b-414d-a61f-263d14d133b4", agentendpointpb.WindowsUpdateSettings_SECURITY: "0fa1201d-4330-4fa8-8ae9-b877473b6441", agentendpointpb.WindowsUpdateSettings_DEFINITION: "e0789628-ce08-4437-be74-2495b842f43b", agentendpointpb.WindowsUpdateSettings_DRIVER: "ebfc1fc5-71a4-4f7b-9aca-3b9a503104a0", agentendpointpb.WindowsUpdateSettings_FEATURE_PACK: "b54e7d24-7add-428f-8b75-90a396fa584f", agentendpointpb.WindowsUpdateSettings_SERVICE_PACK: "68c5b0a3-d1a6-4553-ae49-01d3a7827828", agentendpointpb.WindowsUpdateSettings_TOOL: "b4832bd8-e735-4761-8daf-37f882276dab", agentendpointpb.WindowsUpdateSettings_UPDATE_ROLLUP: "28bc880e-0592-4cbf-8f95-c79b17911d5f", agentendpointpb.WindowsUpdateSettings_UPDATE: "cd5ffd1e-e932-4e3a-bf74-18bf0b1bbd83", } var cf []string for _, c := range r.Task.GetPatchConfig().GetWindowsUpdate().GetClassifications() { sc, ok := classifications[c] if !ok { return nil, fmt.Errorf("Unknown classification: %s", c) } cf = append(cf, sc) } return cf, nil } func (r *patchTask) installWUAUpdates(ctx context.Context, cf []string) (int32, error) { clog.Infof(ctx, "Searching for available Windows updates.") session, err := packages.NewUpdateSession() if err != nil { return 0, err } defer session.Close() updts, err := ospatch.GetWUAUpdates(ctx, session, cf, r.Task.GetPatchConfig().GetWindowsUpdate().GetExcludes(), r.Task.GetPatchConfig().GetWindowsUpdate().GetExclusivePatches()) if err != nil { return 0, err } defer updts.Release() count, err := updts.Count() if err != nil { return 0, err } if count == 0 { clog.Infof(ctx, "No Windows updates available to install") return 0, nil } clog.Infof(ctx, "%d Windows updates to install", count) if r.Task.GetDryRun() { clog.Infof(ctx, "Running in dryrun mode, not updating.") return 0, nil } for i := int32(0); i < count; i++ { if err := r.reportContinuingState(ctx, agentendpointpb.ApplyPatchesTaskProgress_APPLYING_PATCHES); err != nil { return i, err } updt, err := updts.Item(int(i)) if err != nil { return i, err } defer updt.Release() if err := session.InstallWUAUpdate(ctx, updt); err != nil { return i, fmt.Errorf(`installUpdate(updt): %v`, err) } } return count, nil } func (r *patchTask) wuaUpdates(ctx context.Context) error { cf, err := r.classFilter() if err != nil { return err } // We keep searching for and installing updates until the count == 0, // we get a stop signal, or retries exceed 10. retries := 10 for i := 1; i <= retries; i++ { if err := r.reportContinuingState(ctx, agentendpointpb.ApplyPatchesTaskProgress_APPLYING_PATCHES); err != nil { return err } count, err := r.installWUAUpdates(ctx, cf) if err != nil { clog.Errorf(ctx, "Error installing Windows updates (attempt %d): %v", i, err) time.Sleep(60 * time.Second) continue } if count == 0 { return nil } } return fmt.Errorf("failed to install all updates after trying %d times", retries) } func (r *patchTask) runUpdates(ctx context.Context) error { // Install GooGet updates first as this will allow us to update the agent prior to any potential WUA bugs/errors. if packages.GooGetExists { if err := r.reportContinuingState(ctx, agentendpointpb.ApplyPatchesTaskProgress_APPLYING_PATCHES); err != nil { return err } clog.Debugf(ctx, "Installing GooGet package updates.") opts := []ospatch.GooGetUpdateOption{ ospatch.GooGetDryRun(r.Task.GetDryRun()), } if err := retryutil.RetryFunc(ctx, 3*time.Minute, "installing GooGet package updates", func() error { return ospatch.RunGooGetUpdate(ctx, opts...) }); err != nil { return err } } // Don't use retry function as wuaUpdates handles it's own retries. if err := r.wuaUpdates(ctx); err != nil { return err } return nil } osconfig-20250416.02/agentendpoint/reboot_linux.go000066400000000000000000000024111477773331400217230ustar00rootroot00000000000000// Copyright 2018 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package agentendpoint import ( "os/exec" "syscall" "github.com/GoogleCloudPlatform/osconfig/util" ) const ( systemctl = "/bin/systemctl" reboot = "/bin/reboot" shutdown = "/bin/shutdown" ) func rebootSystem() error { // Start with systemctl and work down a list of reboot methods. if e := util.Exists(systemctl); e { return exec.Command(systemctl, "reboot").Start() } if e := util.Exists(reboot); e { return exec.Command(reboot).Run() } if e := util.Exists(shutdown); e { return exec.Command(shutdown, "-r", "-t", "0").Run() } // Fall back to reboot(2) system call syscall.Sync() return syscall.Reboot(syscall.LINUX_REBOOT_CMD_RESTART) } osconfig-20250416.02/agentendpoint/reboot_windows.go000066400000000000000000000016601477773331400222630ustar00rootroot00000000000000// Copyright 2018 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build windows // +build windows package agentendpoint import ( "os" "os/exec" "path/filepath" ) func rebootSystem() error { root := os.Getenv("SystemRoot") if root == "" { root = `C:\Windows` } return exec.Command(filepath.Join(root, `System32\shutdown.exe`), "/r", "/t", "00", "/f", "/d", "p:2:3").Run() } osconfig-20250416.02/agentendpoint/task_state.go000066400000000000000000000040001477773331400213500ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package agentendpoint import ( "encoding/json" "io/ioutil" "os" "path/filepath" ) type taskState struct { PatchTask *patchTask `json:",omitempty"` // Reboots during ExecTask is not supported. ExecTask *execTask `json:",omitempty"` Labels map[string]string `json:",omitempty"` } func (s *taskState) save(path string) error { if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { return err } if s == nil { return writeFile(path, []byte("{}")) } d, err := json.Marshal(s) if err != nil { return err } return writeFile(path, d) } func loadState(path string) (*taskState, error) { // We load the current state file first, if it does not exist we try to load the old state file. d, err := os.ReadFile(path) if os.IsNotExist(err) { d, err = os.ReadFile(oldTaskStateFile) if os.IsNotExist(err) { return nil, nil } } if err != nil { return nil, err } // Cleanup old state file if needed. os.Remove(oldTaskStateFile) var st taskState return &st, json.Unmarshal(d, &st) } func writeFile(path string, data []byte) error { // Write state to a temporary file first. tmp, err := ioutil.TempFile(filepath.Dir(path), "") if err != nil { return err } newStateFile := tmp.Name() if _, err = tmp.Write(data); err != nil { return err } if err := tmp.Close(); err != nil { return err } // Move the new temp file to the live path. return os.Rename(newStateFile, path) } osconfig-20250416.02/agentendpoint/task_state_test.go000066400000000000000000000141041477773331400224150ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package agentendpoint import ( "io/ioutil" "os" "path/filepath" "testing" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "google.golang.org/protobuf/testing/protocmp" "cloud.google.com/go/osconfig/agentendpoint/apiv1/agentendpointpb" ) var ( testPatchTaskStateString = "{\"PatchTask\":{\"TaskID\":\"foo\",\"Task\":{\"patchConfig\":{\"apt\":{\"type\":\"DIST\",\"excludes\":[\"foo\",\"bar\"],\"exclusivePackages\":[\"foo\",\"bar\"]},\"windowsUpdate\":{\"classifications\":[\"CRITICAL\",\"SECURITY\"],\"excludes\":[\"foo\",\"bar\"],\"exclusivePatches\":[\"foo\",\"bar\"]}}},\"StartedAt\":\"0001-01-01T00:00:00Z\",\"PrePatchRebootCount\":2,\"PostPatchRebootCount\":1},\"Labels\":{\"foo\":\"bar\"}}" testPatchTaskState = &taskState{ Labels: map[string]string{"foo": "bar"}, PatchTask: &patchTask{ TaskID: "foo", Task: &applyPatchesTask{ // This is not exhaustive but it's a good test for having multiple settings. &agentendpointpb.ApplyPatchesTask{ PatchConfig: &agentendpointpb.PatchConfig{ Apt: &agentendpointpb.AptSettings{Type: agentendpointpb.AptSettings_DIST, Excludes: []string{"foo", "bar"}, ExclusivePackages: []string{"foo", "bar"}}, WindowsUpdate: &agentendpointpb.WindowsUpdateSettings{Classifications: []agentendpointpb.WindowsUpdateSettings_Classification{agentendpointpb.WindowsUpdateSettings_CRITICAL, agentendpointpb.WindowsUpdateSettings_SECURITY}, Excludes: []string{"foo", "bar"}, ExclusivePatches: []string{"foo", "bar"}}, }, }, }, PrePatchRebootCount: 2, PostPatchRebootCount: 1, }, } ) func TestLoadState(t *testing.T) { td, err := ioutil.TempDir(os.TempDir(), "") if err != nil { t.Fatalf("error creating temp dir: %v", err) } defer os.RemoveAll(td) testState := filepath.Join(td, "testState") // test no state file if _, err := loadState(testState); err != nil { t.Errorf("no state file: unexpected error: %v", err) } // We don't test execTask as reboots during that task type is not supported. var tests = []struct { name string state []byte wantErr bool want *taskState }{ { "BlankState", []byte("{}"), false, &taskState{}, }, { "BadState", []byte("foo"), true, &taskState{}, }, { "PatchTask", []byte(testPatchTaskStateString), false, testPatchTaskState, }, { "IgnoresOldRebootFieldName", []byte("{\"PatchTask\":{\"Task\":{},\"RebootCount\":1}}"), false, &taskState{ PatchTask: &patchTask{ Task: &applyPatchesTask{ &agentendpointpb.ApplyPatchesTask{}, }, PrePatchRebootCount: 0, PostPatchRebootCount: 0, }, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if err := ioutil.WriteFile(testState, tt.state, 0600); err != nil { t.Fatalf("error writing state: %v", err) } st, err := loadState(testState) if err != nil && !tt.wantErr { t.Fatalf("unexpected error: %v", err) } if err == nil && tt.wantErr { t.Fatalf("expected error") } if diff := cmp.Diff(tt.want, st, cmpopts.IgnoreUnexported(patchTask{}), protocmp.Transform()); diff != "" { t.Errorf("State does not match expectation: (-got +want)\n%s", diff) } }) } } func TestLoadOldState(t *testing.T) { td, err := ioutil.TempDir(os.TempDir(), "") if err != nil { t.Fatalf("error creating temp dir: %v", err) } defer os.RemoveAll(td) testState := filepath.Join(td, "testState") oldTaskStateFile = testState if err := ioutil.WriteFile(testState, []byte(testPatchTaskStateString), 0600); err != nil { t.Fatalf("error writing state: %v", err) } st, err := loadState("/path/dne") if err != nil { t.Fatalf("unexpected error: %v", err) } if diff := cmp.Diff(testPatchTaskState, st, cmpopts.IgnoreUnexported(patchTask{}), protocmp.Transform()); diff != "" { t.Errorf("State does not match expectation: (-got +want)\n%s", diff) } } func TestStateSave(t *testing.T) { td, err := ioutil.TempDir(os.TempDir(), "") if err != nil { t.Fatalf("error creating temp dir: %v", err) } defer os.RemoveAll(td) testState := filepath.Join(td, "testState") var tests = []struct { desc string state *taskState want string }{ { "NilState", nil, "{}", }, { "BlankState", &taskState{}, "{}", }, { "PatchTask", testPatchTaskState, testPatchTaskStateString, }, { "ExecTask", &taskState{ExecTask: &execTask{TaskID: "foo"}}, "{\"ExecTask\":{\"StartedAt\":\"0001-01-01T00:00:00Z\",\"Task\":null,\"TaskID\":\"foo\"}}", }, } for _, tt := range tests { err := tt.state.save(testState) if err != nil { t.Errorf("%s: unexpected save error: %v", tt.desc, err) continue } got, err := ioutil.ReadFile(testState) if err != nil { t.Errorf("%s: error reading state: %v", tt.desc, err) continue } if string(got) != tt.want { t.Errorf("%s:\ngot:\n%q\nwant:\n%q", tt.desc, got, tt.want) } } } func TestSaveLoadState(t *testing.T) { td, err := ioutil.TempDir(os.TempDir(), "") if err != nil { t.Fatalf("error creating temp dir: %v", err) } defer os.RemoveAll(td) testState := filepath.Join(td, "testState") if err := testPatchTaskState.save(testState); err != nil { t.Errorf("Unexpected save error: %v", err) } st, err := loadState(testState) if err != nil { t.Fatalf("Unexpected load error: %v", err) } if diff := cmp.Diff(testPatchTaskState, st, cmpopts.IgnoreUnexported(patchTask{}), protocmp.Transform()); diff != "" { t.Errorf("State does not match expectation: (-got +want)\n%s", diff) } } osconfig-20250416.02/attributes/000077500000000000000000000000001477773331400162145ustar00rootroot00000000000000osconfig-20250416.02/attributes/attributes.go000066400000000000000000000036261477773331400207400ustar00rootroot00000000000000// Copyright 2018 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package attributes posts data to Guest Attributes. package attributes import ( "bytes" "compress/gzip" "encoding/base64" "encoding/json" "fmt" "io" "io/ioutil" "net/http" ) // PostAttribute posts data to Guest Attributes func PostAttribute(url string, value io.Reader) error { req, err := http.NewRequest("PUT", url, value) if err != nil { return err } req.Header.Add("Metadata-Flavor", "Google") resp, err := http.DefaultClient.Do(req) if err != nil { return err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { b, err := ioutil.ReadAll(resp.Body) responseErr := fmt.Sprintf(`received status code %q for request "%s %s"`, resp.Status, req.Method, req.URL.String()) if err == nil { responseErr = fmt.Sprintf("%s\n Error response: %s", responseErr, string(b)) } return fmt.Errorf("%s", responseErr) } return nil } // PostAttributeCompressed compresses and posts data to Guest Attributes func PostAttributeCompressed(url string, body any) error { buf := &bytes.Buffer{} b := base64.NewEncoder(base64.StdEncoding, buf) zw := gzip.NewWriter(b) w := json.NewEncoder(zw) if err := w.Encode(body); err != nil { return err } if err := zw.Close(); err != nil { return err } if err := b.Close(); err != nil { return err } return PostAttribute(url, buf) } osconfig-20250416.02/attributes/attributes_test.go000066400000000000000000000077531477773331400220040ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package attributes import ( "bytes" "compress/gzip" "encoding/base64" "encoding/json" "fmt" "io" "io/ioutil" "net/http" "net/http/httptest" "strings" "testing" "github.com/GoogleCloudPlatform/osconfig/packages" ) func TestPostAttributeHappyCase(t *testing.T) { testData := "test bytes" ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { buf := new(bytes.Buffer) buf.ReadFrom(r.Body) newStr := buf.String() if strings.Compare(testData, newStr) != 0 { // this is just a way to notify client that the data // recieved was different than what was sent w.WriteHeader(http.StatusExpectationFailed) } else { w.WriteHeader(http.StatusOK) } })) defer ts.Close() if err := PostAttribute(ts.URL, strings.NewReader(testData)); err != nil { // PostAttribute throw error if status is not 200 t.Errorf("test failed, should not be an error; got(%s)", err.Error()) } } func TestPostAttributeInvalidUrl(t *testing.T) { err := PostAttribute("http://foo.com/ctl\x80", nil) if err == nil { t.Errorf("test failed, Should be an error") } } func TestPostAttributeStatusNotOk(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusBadRequest) })) defer ts.Close() err := PostAttribute(ts.URL, nil) if err == nil || !strings.Contains(err.Error(), "400 Bad Request") { t.Errorf("test failed, Should be (400 bad request; got(%+v))", err) } } func TestPostAttributeCompressedhappyCase(t *testing.T) { td := packages.Packages{ Apt: []*packages.PkgInfo{ { Version: "1.2.3", Name: "test-package", Arch: "amd64", }, }, } ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { body, err := ioutil.ReadAll(r.Body) if err != nil { w.WriteHeader(http.StatusExpectationFailed) w.Write([]byte("error reading body")) return } pkg, err := getDecompressPackageInfo(string(body)) if td.Apt[0].Name != pkg.Apt[0].Name { w.WriteHeader(http.StatusExpectationFailed) w.Write([]byte(fmt.Sprintf("assert failed! expected(%s)! got(%s)!", td.Apt[0].Name, pkg.Apt[0].Name))) } if td.Apt[0].Version != pkg.Apt[0].Version { w.WriteHeader(http.StatusExpectationFailed) w.Write([]byte(fmt.Sprintf("assert failed! expected(%s)! got(%s)!", td.Apt[0].Version, pkg.Apt[0].Version))) } if td.Apt[0].Arch != pkg.Apt[0].Arch { w.WriteHeader(http.StatusExpectationFailed) w.Write([]byte(fmt.Sprintf("assert failed! expected(%s)! got(%s)!", td.Apt[0].Arch, pkg.Apt[0].Arch))) } })) err := PostAttributeCompressed(ts.URL, td) if err != nil { t.Errorf("test failed, should not be an error; got(%v)", err) } } func getDecompressPackageInfo(encoded string) (*packages.Packages, error) { decoded, err := base64.StdEncoding.DecodeString(encoded) if err != nil { return nil, fmt.Errorf("Error decoding base64: %+v", err) } gzipReader, err := gzip.NewReader(bytes.NewReader(decoded)) if err != nil { return nil, fmt.Errorf("Error creating gzip reader: %+v", err) } defer gzipReader.Close() var buf bytes.Buffer if _, err := io.Copy(&buf, gzipReader); err != nil { return nil, fmt.Errorf("Error reading gzip data: %+v", err) } var pkgs packages.Packages if err := json.Unmarshal(buf.Bytes(), &pkgs); err != nil { return nil, fmt.Errorf("Error unmarshalling json data: %+v", err) } return &pkgs, nil } osconfig-20250416.02/clog/000077500000000000000000000000001477773331400147525ustar00rootroot00000000000000osconfig-20250416.02/clog/clog.go000066400000000000000000000117511477773331400162320ustar00rootroot00000000000000// Copyright 2020 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package clog is a Context logger. package clog import ( "context" "encoding/json" "fmt" "sync" "github.com/GoogleCloudPlatform/guest-logging-go/logger" "github.com/GoogleCloudPlatform/osconfig/pretty" "google.golang.org/protobuf/proto" ) // DebugEnabled will log debug messages. var DebugEnabled bool // https://golang.org/pkg/context/#WithValue type clogKey struct{} var ctxValueKey = clogKey{} type log struct { ctx context.Context labels map[string]string sync.Mutex } func (l *log) log(structuredPayload any, msg string, sev logger.Severity) { // Set CallDepth 3, one for logger.Log, one for this function, and one for // the calling clog function. logger.Log(logger.LogEntry{Message: msg, StructuredPayload: structuredPayload, Severity: sev, CallDepth: 3, Labels: l.labels}) } // protoToJSON converts a proto message to a generic JSON object for the purpose // of passing to Cloud Logging. // // Conversion errors are encoded in the JSON object rather than returned, // because callers of logging functions should not be forced to handle errors. func protoToJSON(p proto.Message) any { bytes, err := pretty.MarshalOptions().Marshal(p) if err != nil { return fmt.Sprintf("Error converting proto: %s", err) } return json.RawMessage(bytes) } // DebugRPC logs a completed RPC call. func DebugRPC(ctx context.Context, method string, req proto.Message, resp proto.Message) { // Do this here so we don't spend resources building the log message if we don't need to. if !DebugEnabled || (req == nil && resp == nil) { return } // The Cloud Logging library doesn't handle proto messages nor structures containing generic JSON. // To work around this we construct map[string]any and fill it with JSON // resulting from explicit conversion of the proto messages. payload := map[string]any{} payload["MethodName"] = method var msg string if resp != nil && req != nil { payload["Response"] = protoToJSON(resp) payload["Request"] = protoToJSON(req) msg = fmt.Sprintf("Called: %s with request:\n%s\nresponse:\n%s\n", method, pretty.Format(req), pretty.Format(resp)) } else if resp != nil { payload["Response"] = protoToJSON(resp) msg = fmt.Sprintf("Called: %s with response:\n%s\n", method, pretty.Format(resp)) } else { payload["Request"] = protoToJSON(req) msg = fmt.Sprintf("Calling: %s with request:\n%s\n", method, pretty.Format(req)) } fromContext(ctx).log(payload, msg, logger.Debug) } // DebugStructured is like Debugf but sends structuredPayload instead of the text message // to Cloud Logging. func DebugStructured(ctx context.Context, structuredPayload any, format string, args ...any) { fromContext(ctx).log(structuredPayload, fmt.Sprintf(format, args...), logger.Debug) } // Debugf simulates logger.Debugf and adds context labels. func Debugf(ctx context.Context, format string, args ...any) { fromContext(ctx).log(nil, fmt.Sprintf(format, args...), logger.Debug) } // Infof simulates logger.Infof and adds context labels. func Infof(ctx context.Context, format string, args ...any) { fromContext(ctx).log(nil, fmt.Sprintf(format, args...), logger.Info) } // Warningf simulates logger.Warningf and context labels. func Warningf(ctx context.Context, format string, args ...any) { fromContext(ctx).log(nil, fmt.Sprintf(format, args...), logger.Warning) } // Errorf simulates logger.Errorf and adds context labels. func Errorf(ctx context.Context, format string, args ...any) { fromContext(ctx).log(nil, fmt.Sprintf(format, args...), logger.Error) } func (l *log) clone() *log { l.Lock() defer l.Unlock() labels := map[string]string{} for k, v := range l.labels { labels[k] = v } return &log{ labels: labels, } } func forContext(ctx context.Context) (*log, context.Context) { cv := ctx.Value(ctxValueKey) l, ok := cv.(*log) if !ok { l = &log{labels: map[string]string{}} } else { l = l.clone() } ctx = context.WithValue(ctx, ctxValueKey, l) l.ctx = ctx return l, ctx } func fromContext(ctx context.Context) *log { if ctx == nil { return &log{} } v := ctx.Value(ctxValueKey) l, ok := v.(*log) if !ok { l = &log{} } return l } // WithLabels makes a log and context and adds the labels (overwriting any with the same key). func WithLabels(ctx context.Context, labels map[string]string) context.Context { if len(labels) == 0 { return ctx } l, ctx := forContext(ctx) l.Lock() defer l.Unlock() for k, v := range labels { l.labels[k] = v } return ctx } osconfig-20250416.02/clog/clog_test.go000066400000000000000000000025541477773331400172720ustar00rootroot00000000000000// Copyright 2020 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package clog import ( "context" "testing" "github.com/google/go-cmp/cmp" ) func TestWithLabels(t *testing.T) { ctx := context.Background() tests := []struct { name string labels map[string]string want map[string]string }{ {"NoLables", map[string]string{}, nil}, {"OneLabel", map[string]string{"1": "1"}, map[string]string{"1": "1"}}, {"AddFourLables", map[string]string{"2": "2", "3": "3", "4": "4", "5": "5"}, map[string]string{"1": "1", "2": "2", "3": "3", "4": "4", "5": "5"}}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ctx = WithLabels(ctx, tt.labels) got := fromContext(ctx).labels if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Label mismatch (-want +got):\n%s", diff) } }) } } osconfig-20250416.02/config/000077500000000000000000000000001477773331400152735ustar00rootroot00000000000000osconfig-20250416.02/config/config.go000066400000000000000000000077341477773331400171020ustar00rootroot00000000000000// Copyright 2020 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package config import ( "context" "errors" "fmt" "runtime" "cloud.google.com/go/osconfig/agentendpoint/apiv1/agentendpointpb" ) var goos = runtime.GOOS // OSPolicyResource is a single OSPolicy resource. type OSPolicyResource struct { resource *agentendpointpb.OSPolicy_Resource managedResources *ManagedResources inDesiredState bool } // InDesiredState reports whether this resource is in the desired state. // CheckState or EnforceState should be run prior to calling InDesiredState. func (r *OSPolicyResource) InDesiredState() bool { return r.inDesiredState } // ManagedResources returns the resources that this OSPolicyResource manages. func (r *OSPolicyResource) ManagedResources() *ManagedResources { return r.managedResources } type resource interface { validate(context.Context) (*ManagedResources, error) checkState(context.Context) (bool, error) enforceState(context.Context) (bool, error) populateOutput(*agentendpointpb.OSPolicyResourceCompliance) cleanup(context.Context) error } // ManagedResources are the resources that an OSPolicyResource manages. type ManagedResources struct { Packages []ManagedPackage Repositories []ManagedRepository Files []ManagedFile } // Validate validates this resource. // Validate must be called before other methods. func (r *OSPolicyResource) Validate(ctx context.Context) error { switch x := r.GetResourceType().(type) { case *agentendpointpb.OSPolicy_Resource_Pkg: r.resource = resource(&packageResouce{OSPolicy_Resource_PackageResource: x.Pkg}) case *agentendpointpb.OSPolicy_Resource_Repository: r.resource = resource(&repositoryResource{OSPolicy_Resource_RepositoryResource: x.Repository}) case *agentendpointpb.OSPolicy_Resource_File_: r.resource = resource(&fileResource{OSPolicy_Resource_FileResource: x.File}) case *agentendpointpb.OSPolicy_Resource_Exec: r.resource = resource(&execResource{OSPolicy_Resource_ExecResource: x.Exec}) case nil: return errors.New("ResourceType field not set") default: return fmt.Errorf("ResourceType has unexpected type: %T", x) } var err error r.managedResources, err = r.validate(ctx) return err } // CheckState checks this resources state. // Validate must be called prior to running CheckState. func (r *OSPolicyResource) CheckState(ctx context.Context) error { if r.resource == nil { return errors.New("CheckState run before Validate") } inDesiredState, err := r.checkState(ctx) r.inDesiredState = inDesiredState return err } // EnforceState enforces this resources state. // Validate must be called prior to running EnforceState. func (r *OSPolicyResource) EnforceState(ctx context.Context) error { if r.resource == nil { return errors.New("EnforceState run before Validate") } inDesiredState, err := r.enforceState(ctx) r.inDesiredState = inDesiredState return err } // PopulateOutput populates the output field of the provided // OSPolicyResourceCompliance for this resource. func (r *OSPolicyResource) PopulateOutput(rCompliance *agentendpointpb.OSPolicyResourceCompliance) error { if r.resource == nil { return errors.New("PopulateOutput run before Validate") } r.populateOutput(rCompliance) return nil } // Cleanup cleans up any temporary files that this resource may have created. func (r *OSPolicyResource) Cleanup(ctx context.Context) error { if r.resource == nil { return errors.New("Cleanup run before Validate") } return r.cleanup(ctx) } osconfig-20250416.02/config/config_test.go000066400000000000000000000016201477773331400201250ustar00rootroot00000000000000// Copyright 2020 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package config import ( "github.com/GoogleCloudPlatform/osconfig/packages" ) func init() { packages.YumExists = true packages.AptExists = true packages.GooGetExists = true packages.DpkgExists = true packages.RPMExists = true packages.ZypperExists = true packages.MSIExists = true } osconfig-20250416.02/config/exec_resource.go000066400000000000000000000177521477773331400204710ustar00rootroot00000000000000// Copyright 2020 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package config import ( "context" "fmt" "io" "io/ioutil" "os" "os/exec" "path" "path/filepath" "strings" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/util" "cloud.google.com/go/osconfig/agentendpoint/apiv1/agentendpointpb" ) const maxExecOutputSize = 500 * 1024 var runner = util.CommandRunner(&util.DefaultRunner{}) type execResource struct { *agentendpointpb.OSPolicy_Resource_ExecResource validatePath, enforcePath, tempDir string enforceOutput []byte } // TODO: use a persistent cache for downloaded files so we dont need to redownload them each time func (e *execResource) download(ctx context.Context, execR *agentendpointpb.OSPolicy_Resource_ExecResource_Exec) (string, error) { tmpDir, err := ioutil.TempDir(e.tempDir, "") if err != nil { return "", fmt.Errorf("failed to create temp dir: %s", err) } // File extensions are important on Windows. var name string perms := os.FileMode(0644) switch execR.GetSource().(type) { case *agentendpointpb.OSPolicy_Resource_ExecResource_Exec_Script: switch execR.GetInterpreter() { case agentendpointpb.OSPolicy_Resource_ExecResource_Exec_NONE: if goos == "windows" { name = "script.cmd" } else { name = "script" } perms = os.FileMode(0755) case agentendpointpb.OSPolicy_Resource_ExecResource_Exec_SHELL: if goos == "windows" { name = "script.cmd" } else { name = "script.sh" } case agentendpointpb.OSPolicy_Resource_ExecResource_Exec_POWERSHELL: name = "script.ps1" default: return "", fmt.Errorf("unsupported interpreter %q", execR.GetInterpreter()) } name = filepath.Join(tmpDir, name) if _, err := util.AtomicWriteFileStream(strings.NewReader(execR.GetScript()), "", name, perms); err != nil { return "", err } case *agentendpointpb.OSPolicy_Resource_ExecResource_Exec_File: if execR.GetFile().GetLocalPath() != "" { return execR.GetFile().GetLocalPath(), nil } switch { case execR.GetFile().GetGcs().GetObject() != "": name = path.Base(execR.GetFile().GetGcs().GetObject()) case execR.GetFile().GetRemote().GetUri() != "": name = path.Base(execR.GetFile().GetRemote().GetUri()) default: return "", fmt.Errorf("unsupported File %v", execR.GetFile()) } if execR.GetInterpreter() == agentendpointpb.OSPolicy_Resource_ExecResource_Exec_NONE { perms = os.FileMode(0755) } name = filepath.Join(tmpDir, name) if _, err := downloadFile(ctx, name, perms, execR.GetFile()); err != nil { return "", err } default: return "", fmt.Errorf("unrecognized Source type for ExecResource: %q", execR.GetSource()) } return name, nil } func (e *execResource) validate(ctx context.Context) (*ManagedResources, error) { tmpDir, err := ioutil.TempDir("", "osconfig_exec_resource_") if err != nil { return nil, fmt.Errorf("failed to create temp dir: %s", err) } e.tempDir = tmpDir e.validatePath, err = e.download(ctx, e.GetValidate()) if err != nil { return nil, err } // Assume lack of Enforce means policy is in VALIDATE mode. if e.GetEnforce() != nil { e.enforcePath, err = e.download(ctx, e.GetEnforce()) if err != nil { return nil, err } } return nil, nil } func (e *execResource) run(ctx context.Context, name string, execR *agentendpointpb.OSPolicy_Resource_ExecResource_Exec) ([]byte, []byte, int, error) { if execR == nil { return nil, nil, 0, fmt.Errorf("ExecResource Exec cannot be nil") } var cmd string var args []string switch execR.GetInterpreter() { case agentendpointpb.OSPolicy_Resource_ExecResource_Exec_NONE: cmd = name case agentendpointpb.OSPolicy_Resource_ExecResource_Exec_SHELL: if goos == "windows" { cmd = name } else { args = append(args, name) cmd = "/bin/sh" } case agentendpointpb.OSPolicy_Resource_ExecResource_Exec_POWERSHELL: if goos != "windows" { return nil, nil, 0, fmt.Errorf("interpreter %q can only be used on Windows systems", execR.GetInterpreter()) } args = append(args, "-File", name) cmd = "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\PowerShell.exe" default: return nil, nil, 0, fmt.Errorf("unsupported interpreter %q", execR.GetInterpreter()) } args = append(args, execR.GetArgs()...) stdout, stderr, err := runner.Run(ctx, exec.CommandContext(ctx, cmd, args...)) code := 0 if err != nil { code = -1 if v, ok := err.(*exec.ExitError); ok { code = v.ExitCode() } } return stdout, stderr, code, err } func (e *execResource) checkState(ctx context.Context) (inDesiredState bool, err error) { // For validate we expect an exit code of 100 for "correct state" and 101 for "incorrect state". // 100 was chosen over 0 (and 101 vs 1) because we want an explicit indicator of // "correct" vs "incorrect" state and errors. Also Powershell will always exit 0 unless "exit" // is explicitly called. // A code of -1 indicates some other error, so we just return err. stdout, stderr, code, err := e.run(ctx, e.validatePath, e.GetValidate()) switch code { case -1: return false, err case 100: return true, nil case 101: return false, nil default: return false, fmt.Errorf("unexpected return code from validate: %d, stdout: %s, stderr: %s", code, stdout, stderr) } } func (e *execResource) enforceState(ctx context.Context) (inDesiredState bool, err error) { clog.Infof(ctx, `Running "Enforce" for ExecResource.`) // For enforce we expect an exit code of 100 for "success" and anything positive code is a failure". // 100 was chosen over 0 because we want an explicit indicator of "sucess" vs errors. // Also Powershell will always exit 0 unless "exit" is explicitly called. // A code of -1 indicates some other error, so we just return err. stdout, stderr, code, err := e.run(ctx, e.enforcePath, e.GetEnforce()) switch code { case -1: return false, err case 100: out, err := execOutput(ctx, e.GetEnforce().GetOutputFilePath()) e.enforceOutput = out return true, err default: return false, fmt.Errorf("unexpected return code from enforce: %d, stdout: %s, stderr: %s", code, stdout, stderr) } } func execOutput(ctx context.Context, outputFilePath string) ([]byte, error) { if outputFilePath == "" { return nil, nil } clog.Debugf(ctx, "Reading %q for ExecResource output", outputFilePath) f, err := os.Open(outputFilePath) if err != nil { return nil, fmt.Errorf("error opening OutputFilePath: %v", err) } defer f.Close() // Make a byte slice with a capacity of 1 over maxSize (for checking maxExecOutputSize). output := make([]byte, 0, maxExecOutputSize+1) // Read up to capactity. n, err := f.Read(output[:cap(output)]) output = output[:len(output)+n] if err != nil && err != io.EOF { return output, fmt.Errorf("error reading from OutputFilePath: %v", err) } // Return the output up to this point and an error if total size is greater than maxExecOutputSize. if n > maxExecOutputSize { return output[:maxExecOutputSize], fmt.Errorf("contents of OutputFilePath greater than %dK", maxExecOutputSize/1024) } return output, nil } func (e *execResource) populateOutput(rCompliance *agentendpointpb.OSPolicyResourceCompliance) { if e.enforceOutput != nil { rCompliance.Output = &agentendpointpb.OSPolicyResourceCompliance_ExecResourceOutput_{ ExecResourceOutput: &agentendpointpb.OSPolicyResourceCompliance_ExecResourceOutput{ EnforcementOutput: e.enforceOutput, }, } } } func (e *execResource) cleanup(ctx context.Context) error { if e.tempDir != "" { return os.RemoveAll(e.tempDir) } return nil } osconfig-20250416.02/config/exec_resource_test.go000066400000000000000000000155451477773331400215260ustar00rootroot00000000000000// Copyright 2021 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package config import ( "context" "io/ioutil" "math/rand" "os" "path" "path/filepath" "reflect" "testing" "cloud.google.com/go/osconfig/agentendpoint/apiv1/agentendpointpb" ) func TestExecResourceDownload(t *testing.T) { ctx := context.Background() var tests = []struct { name string erpb *agentendpointpb.OSPolicy_Resource_ExecResource wantValidatePath string wantValidateContents string wantEnforcePath string wantEnforceContents string goos string }{ { "Script NONE Linux", &agentendpointpb.OSPolicy_Resource_ExecResource{ Validate: &agentendpointpb.OSPolicy_Resource_ExecResource_Exec{ Source: &agentendpointpb.OSPolicy_Resource_ExecResource_Exec_Script{Script: "validate"}, Interpreter: agentendpointpb.OSPolicy_Resource_ExecResource_Exec_NONE, }, Enforce: &agentendpointpb.OSPolicy_Resource_ExecResource_Exec{ Source: &agentendpointpb.OSPolicy_Resource_ExecResource_Exec_Script{Script: "enforce"}, Interpreter: agentendpointpb.OSPolicy_Resource_ExecResource_Exec_NONE, }, }, "script", "validate", "script", "enforce", "linux", }, { "Script NONE Windows", &agentendpointpb.OSPolicy_Resource_ExecResource{ Validate: &agentendpointpb.OSPolicy_Resource_ExecResource_Exec{ Source: &agentendpointpb.OSPolicy_Resource_ExecResource_Exec_Script{Script: "validate"}, Interpreter: agentendpointpb.OSPolicy_Resource_ExecResource_Exec_NONE, }, Enforce: &agentendpointpb.OSPolicy_Resource_ExecResource_Exec{ Source: &agentendpointpb.OSPolicy_Resource_ExecResource_Exec_Script{Script: "enforce"}, Interpreter: agentendpointpb.OSPolicy_Resource_ExecResource_Exec_NONE, }, }, "script.cmd", "validate", "script.cmd", "enforce", "windows", }, { "Script SHELL Linux", &agentendpointpb.OSPolicy_Resource_ExecResource{ Validate: &agentendpointpb.OSPolicy_Resource_ExecResource_Exec{ Source: &agentendpointpb.OSPolicy_Resource_ExecResource_Exec_Script{Script: "validate"}, Interpreter: agentendpointpb.OSPolicy_Resource_ExecResource_Exec_SHELL, }, Enforce: &agentendpointpb.OSPolicy_Resource_ExecResource_Exec{ Source: &agentendpointpb.OSPolicy_Resource_ExecResource_Exec_Script{Script: "enforce"}, Interpreter: agentendpointpb.OSPolicy_Resource_ExecResource_Exec_SHELL, }, }, "script.sh", "validate", "script.sh", "enforce", "linux", }, { "Script SHELL Windows", &agentendpointpb.OSPolicy_Resource_ExecResource{ Validate: &agentendpointpb.OSPolicy_Resource_ExecResource_Exec{ Source: &agentendpointpb.OSPolicy_Resource_ExecResource_Exec_Script{Script: "validate"}, Interpreter: agentendpointpb.OSPolicy_Resource_ExecResource_Exec_SHELL, }, Enforce: &agentendpointpb.OSPolicy_Resource_ExecResource_Exec{ Source: &agentendpointpb.OSPolicy_Resource_ExecResource_Exec_Script{Script: "enforce"}, Interpreter: agentendpointpb.OSPolicy_Resource_ExecResource_Exec_SHELL, }, }, "script.cmd", "validate", "script.cmd", "enforce", "windows", }, { "Script POWERSHELL Windows", &agentendpointpb.OSPolicy_Resource_ExecResource{ Validate: &agentendpointpb.OSPolicy_Resource_ExecResource_Exec{ Source: &agentendpointpb.OSPolicy_Resource_ExecResource_Exec_Script{Script: "validate"}, Interpreter: agentendpointpb.OSPolicy_Resource_ExecResource_Exec_POWERSHELL, }, Enforce: &agentendpointpb.OSPolicy_Resource_ExecResource_Exec{ Source: &agentendpointpb.OSPolicy_Resource_ExecResource_Exec_Script{Script: "enforce"}, Interpreter: agentendpointpb.OSPolicy_Resource_ExecResource_Exec_POWERSHELL, }, }, "script.ps1", "validate", "script.ps1", "enforce", "windows", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { goos = tt.goos pr := &OSPolicyResource{ OSPolicy_Resource: &agentendpointpb.OSPolicy_Resource{ ResourceType: &agentendpointpb.OSPolicy_Resource_Exec{ Exec: tt.erpb, }, }, } defer pr.Cleanup(ctx) if err := pr.Validate(ctx); err != nil { t.Fatalf("Unexpected error: %v", err) } resource := pr.resource.(*execResource) if tt.wantValidatePath != path.Base(resource.validatePath) { t.Errorf("unexpected validate path: %q", resource.validatePath) } data, err := ioutil.ReadFile(resource.validatePath) if err != nil { t.Fatal(err) } if tt.wantValidateContents != string(data) { t.Errorf("unexpected validate contents: %q", data) } if tt.wantEnforcePath != path.Base(resource.enforcePath) { t.Errorf("unexpected enforce path: %q", resource.enforcePath) } data, err = ioutil.ReadFile(resource.enforcePath) if err != nil { t.Fatal(err) } if tt.wantEnforceContents != string(data) { t.Errorf("unexpected enforce contents: %q", data) } }) } } func TestExecOutput(t *testing.T) { ctx := context.Background() tmpDir, err := ioutil.TempDir("", "") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmpDir) fileA := filepath.Join(tmpDir, "fileA") contentsA := []byte("here is some text\nand some more\n") if err := ioutil.WriteFile(fileA, contentsA, 0600); err != nil { t.Fatal(err) } fileB := filepath.Join(tmpDir, "fileB") contentsB := make([]byte, maxExecOutputSize*2) if _, err := rand.Read(contentsB); err != nil { t.Fatal(err) } if err := ioutil.WriteFile(fileB, contentsB, 0600); err != nil { t.Fatal(err) } var tests = []struct { name string filePath string want []byte wantErr bool }{ { "empty path", "", nil, false, }, { "path DNE", "DNE", nil, true, }, { "normal case", fileA, contentsA, false, }, { "file to large case", fileB, contentsB[:maxExecOutputSize], true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := execOutput(ctx, tt.filePath) if err != nil && !tt.wantErr { t.Errorf("Unexpected error from execOutput: %v", err) } if err == nil && tt.wantErr { t.Error("Did not get expected error from execOutput") } if !reflect.DeepEqual(got, tt.want) { t.Errorf("got != want, string(got) = %q string(want) = %q", got, tt.want) } }) } } osconfig-20250416.02/config/file.go000066400000000000000000000040441477773331400165430ustar00rootroot00000000000000// Copyright 2020 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package config import ( "context" "crypto/sha256" "encoding/hex" "fmt" "io" "net/http" "os" "cloud.google.com/go/storage" "github.com/GoogleCloudPlatform/osconfig/external" "github.com/GoogleCloudPlatform/osconfig/util" "cloud.google.com/go/osconfig/agentendpoint/apiv1/agentendpointpb" ) func checksum(r io.Reader) string { hash := sha256.New() io.Copy(hash, r) return hex.EncodeToString(hash.Sum(nil)) } func downloadFile(ctx context.Context, path string, perms os.FileMode, file *agentendpointpb.OSPolicy_Resource_File) (string, error) { var reader io.ReadCloser var err error var wantChecksum string switch file.GetType().(type) { case *agentendpointpb.OSPolicy_Resource_File_Gcs_: client, err := storage.NewClient(ctx) if err != nil { return "", fmt.Errorf("error creating gcs client: %v", err) } defer client.Close() reader, err = external.FetchGCSObject(ctx, client, file.GetGcs().GetBucket(), file.GetGcs().GetObject(), file.GetGcs().GetGeneration()) if err != nil { return "", err } case *agentendpointpb.OSPolicy_Resource_File_Remote_: reader, err = external.FetchRemoteObjectHTTP(ctx, &http.Client{}, file.GetRemote().GetUri()) if err != nil { return "", err } wantChecksum = file.GetRemote().GetSha256Checksum() default: return "", fmt.Errorf("unknown remote File type: %+v", file.GetType()) } defer reader.Close() return util.AtomicWriteFileStream(reader, wantChecksum, path, perms) } osconfig-20250416.02/config/file_resource.go000066400000000000000000000152741477773331400204610ustar00rootroot00000000000000// Copyright 2020 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package config import ( "context" "fmt" "io" "io/ioutil" "os" "path/filepath" "strconv" "strings" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/util" "cloud.google.com/go/osconfig/agentendpoint/apiv1/agentendpointpb" ) const defaultFilePerms = 0644 type fileResource struct { *agentendpointpb.OSPolicy_Resource_FileResource managedFile ManagedFile } // ManagedFile is the file that this FileResouce manages. type ManagedFile struct { Path string tempDir string source string checksum string State agentendpointpb.OSPolicy_Resource_FileResource_DesiredState Permisions os.FileMode } func parsePermissions(s string) (os.FileMode, error) { if s == "" { return defaultFilePerms, nil } i, err := strconv.ParseUint(s, 8, 32) if err != nil { return 0, err } return os.FileMode(i), nil } // TODO: use a persistent cache for downloaded files so we dont need to redownload them each time. func (f *fileResource) download(ctx context.Context) error { // No need to download if source is a local file. if f.GetFile().GetLocalPath() != "" { return nil } tmpDir, err := ioutil.TempDir("", "osconfig_file_resource_") if err != nil { return fmt.Errorf("failed to create working dir: %s", err) } f.managedFile.tempDir = tmpDir tmpFile := filepath.Join(tmpDir, filepath.Base(f.GetPath())) f.managedFile.source = tmpFile perms := os.FileMode(0644) switch f.GetSource().(type) { case *agentendpointpb.OSPolicy_Resource_FileResource_Content: f.managedFile.checksum, err = util.AtomicWriteFileStream(strings.NewReader(f.GetContent()), "", tmpFile, perms) if err != nil { return err } case *agentendpointpb.OSPolicy_Resource_FileResource_File: f.managedFile.checksum, err = downloadFile(ctx, tmpFile, perms, f.GetFile()) if err != nil { return err } default: return fmt.Errorf("unrecognized Source type for FileResource: %q", f.GetSource()) } return nil } func (f *fileResource) validate(ctx context.Context) (*ManagedResources, error) { switch f.GetState() { case agentendpointpb.OSPolicy_Resource_FileResource_ABSENT, agentendpointpb.OSPolicy_Resource_FileResource_PRESENT, agentendpointpb.OSPolicy_Resource_FileResource_CONTENTS_MATCH: f.managedFile.State = f.GetState() default: return nil, fmt.Errorf("unrecognized DesiredState for FileResource: %q", f.GetState()) } f.managedFile.Path = f.GetPath() // If desired state is absent, we can return now. if f.GetState() == agentendpointpb.OSPolicy_Resource_FileResource_ABSENT { return &ManagedResources{Files: []ManagedFile{f.managedFile}}, nil } perms, err := parsePermissions(f.GetPermissions()) if err != nil { return nil, fmt.Errorf("can't parse permissions %q: %v", f.GetPermissions(), err) } f.managedFile.Permisions = perms if f.GetFile().GetLocalPath() != "" { f.managedFile.source = f.GetFile().GetLocalPath() file, err := os.Open(f.GetFile().GetLocalPath()) if err != nil { return nil, err } f.managedFile.checksum = checksum(file) file.Close() } switch f.managedFile.State { case agentendpointpb.OSPolicy_Resource_FileResource_ABSENT: case agentendpointpb.OSPolicy_Resource_FileResource_PRESENT: // If the file is already present no need to downloaded it. if !util.Exists(f.managedFile.Path) { if err := f.download(ctx); err != nil { return nil, err } } case agentendpointpb.OSPolicy_Resource_FileResource_CONTENTS_MATCH: if err := f.download(ctx); err != nil { return nil, err } default: return nil, fmt.Errorf("unrecognized DesiredState for FileResource: %q", f.managedFile.State) } return &ManagedResources{Files: []ManagedFile{f.managedFile}}, nil } func (f *fileResource) checkState(ctx context.Context) (inDesiredState bool, err error) { switch f.managedFile.State { case agentendpointpb.OSPolicy_Resource_FileResource_ABSENT: return !util.Exists(f.managedFile.Path), nil case agentendpointpb.OSPolicy_Resource_FileResource_PRESENT: return util.Exists(f.managedFile.Path), nil case agentendpointpb.OSPolicy_Resource_FileResource_CONTENTS_MATCH: return contentsMatch(ctx, f.managedFile.Path, f.managedFile.checksum) default: return false, fmt.Errorf("unrecognized DesiredState for FileResource: %q", f.managedFile.State) } } func copyFile(dst, src string, perms os.FileMode) (retErr error) { reader, err := os.Open(src) if err != nil { return fmt.Errorf("error opening source file: %v", err) } defer reader.Close() writer, err := os.OpenFile(dst, os.O_TRUNC|os.O_WRONLY|os.O_CREATE, perms) if err != nil { return fmt.Errorf("error opening destination file: %v", err) } defer func() { if err := writer.Close(); err != nil { if retErr == nil { retErr = fmt.Errorf("error closing destination file: %v", err) } } }() if _, err := io.Copy(writer, reader); err != nil { return err } return nil } func (f *fileResource) enforceState(ctx context.Context) (inDesiredState bool, err error) { clog.Infof(ctx, "Enforcing state %q for file %q.", f.managedFile.State, f.managedFile.Path) switch f.managedFile.State { case agentendpointpb.OSPolicy_Resource_FileResource_ABSENT: if err := os.Remove(f.managedFile.Path); err != nil { return false, fmt.Errorf("error removing %q: %v", f.managedFile.Path, err) } case agentendpointpb.OSPolicy_Resource_FileResource_PRESENT, agentendpointpb.OSPolicy_Resource_FileResource_CONTENTS_MATCH: // Download now if for some reason we got this point and have not. if f.managedFile.source == "" { if err := f.download(ctx); err != nil { return false, err } } if err := copyFile(f.managedFile.Path, f.managedFile.source, f.managedFile.Permisions); err != nil { return false, fmt.Errorf("error copying %q to %q: %v", f.managedFile.source, f.managedFile.Path, err) } default: return false, fmt.Errorf("unrecognized DesiredState for FileResource: %q", f.managedFile.State) } return true, nil } func (f *fileResource) populateOutput(rCompliance *agentendpointpb.OSPolicyResourceCompliance) {} func (f *fileResource) cleanup(ctx context.Context) error { if f.managedFile.tempDir != "" { return os.RemoveAll(f.managedFile.tempDir) } return nil } osconfig-20250416.02/config/file_resource_test.go000066400000000000000000000247641477773331400215240ustar00rootroot00000000000000// Copyright 2020 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package config import ( "context" "io/ioutil" "os" "path/filepath" "testing" "github.com/GoogleCloudPlatform/osconfig/util" "github.com/google/go-cmp/cmp" "cloud.google.com/go/osconfig/agentendpoint/apiv1/agentendpointpb" ) func TestFileResourceValidate(t *testing.T) { ctx := context.Background() tmpDir, err := ioutil.TempDir("", "") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmpDir) tmpFile := filepath.Join(tmpDir, "foo") if err := ioutil.WriteFile(tmpFile, nil, 0644); err != nil { t.Fatal(err) } var tests = []struct { name string frpb *agentendpointpb.OSPolicy_Resource_FileResource wantMR ManagedFile }{ { "Absent", &agentendpointpb.OSPolicy_Resource_FileResource{ Path: tmpFile, State: agentendpointpb.OSPolicy_Resource_FileResource_ABSENT, }, ManagedFile{ Path: tmpFile, State: agentendpointpb.OSPolicy_Resource_FileResource_ABSENT, }, }, { "Present", &agentendpointpb.OSPolicy_Resource_FileResource{ Path: tmpFile, State: agentendpointpb.OSPolicy_Resource_FileResource_PRESENT, }, ManagedFile{ Path: tmpFile, State: agentendpointpb.OSPolicy_Resource_FileResource_PRESENT, Permisions: defaultFilePerms, }, }, { "ContentsMatch", &agentendpointpb.OSPolicy_Resource_FileResource{ Path: tmpFile, Source: &agentendpointpb.OSPolicy_Resource_FileResource_File{ File: &agentendpointpb.OSPolicy_Resource_File{ Type: &agentendpointpb.OSPolicy_Resource_File_LocalPath{ LocalPath: tmpFile, }, }, }, State: agentendpointpb.OSPolicy_Resource_FileResource_CONTENTS_MATCH, }, ManagedFile{ Path: tmpFile, source: tmpFile, checksum: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", State: agentendpointpb.OSPolicy_Resource_FileResource_CONTENTS_MATCH, Permisions: defaultFilePerms, }, }, { "Permissions", &agentendpointpb.OSPolicy_Resource_FileResource{ Path: tmpFile, State: agentendpointpb.OSPolicy_Resource_FileResource_PRESENT, Permissions: "0777", }, ManagedFile{ Path: tmpFile, State: agentendpointpb.OSPolicy_Resource_FileResource_PRESENT, Permisions: 0777, }, }, { "LocalPath", &agentendpointpb.OSPolicy_Resource_FileResource{ Path: tmpFile, Source: &agentendpointpb.OSPolicy_Resource_FileResource_File{ File: &agentendpointpb.OSPolicy_Resource_File{ Type: &agentendpointpb.OSPolicy_Resource_File_LocalPath{ LocalPath: tmpFile, }, }, }, State: agentendpointpb.OSPolicy_Resource_FileResource_PRESENT, }, ManagedFile{ Path: tmpFile, State: agentendpointpb.OSPolicy_Resource_FileResource_PRESENT, Permisions: defaultFilePerms, checksum: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", source: tmpFile, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { pr := &OSPolicyResource{ OSPolicy_Resource: &agentendpointpb.OSPolicy_Resource{ ResourceType: &agentendpointpb.OSPolicy_Resource_File_{ File: tt.frpb, }, }, } if err := pr.Validate(ctx); err != nil { t.Fatalf("Unexpected error: %v", err) } if diff := cmp.Diff(pr.ManagedResources(), &ManagedResources{Files: []ManagedFile{tt.wantMR}}, cmp.AllowUnexported(ManagedFile{})); diff != "" { t.Errorf("OSPolicyResource does not match expectation: (-got +want)\n%s", diff) } if diff := cmp.Diff(pr.resource.(*fileResource).managedFile, tt.wantMR, cmp.AllowUnexported(ManagedFile{})); diff != "" { t.Errorf("fileResource does not match expectation: (-got +want)\n%s", diff) } }) } } func TestFileResourceCheckState(t *testing.T) { ctx := context.Background() tmpDir, err := ioutil.TempDir("", "") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmpDir) tmpFile := filepath.Join(tmpDir, "foo") if err := ioutil.WriteFile(tmpFile, []byte("foo"), 0644); err != nil { t.Fatal(err) } tmpFile2 := filepath.Join(tmpDir, "bar") if err := ioutil.WriteFile(tmpFile2, []byte("bar"), 0644); err != nil { t.Fatal(err) } var tests = []struct { name string frpb *agentendpointpb.OSPolicy_Resource_FileResource wantInDesiredState bool }{ { "AbsentAndAbsent", &agentendpointpb.OSPolicy_Resource_FileResource{ Path: filepath.Join(tmpDir, "dne"), State: agentendpointpb.OSPolicy_Resource_FileResource_ABSENT, }, true, }, { "AbsentAndPresent", &agentendpointpb.OSPolicy_Resource_FileResource{ Path: tmpFile, State: agentendpointpb.OSPolicy_Resource_FileResource_ABSENT, }, false, }, { "PresentAndAbsent", &agentendpointpb.OSPolicy_Resource_FileResource{ Path: filepath.Join(tmpDir, "dne"), Source: &agentendpointpb.OSPolicy_Resource_FileResource_File{ File: &agentendpointpb.OSPolicy_Resource_File{ Type: &agentendpointpb.OSPolicy_Resource_File_LocalPath{ LocalPath: tmpFile, }, }, }, State: agentendpointpb.OSPolicy_Resource_FileResource_PRESENT, }, false, }, { "PresentAndPresent", &agentendpointpb.OSPolicy_Resource_FileResource{ Path: tmpFile, State: agentendpointpb.OSPolicy_Resource_FileResource_PRESENT, }, true, }, { "ContentsMatchLocalPath", &agentendpointpb.OSPolicy_Resource_FileResource{ Path: tmpFile, Source: &agentendpointpb.OSPolicy_Resource_FileResource_File{ File: &agentendpointpb.OSPolicy_Resource_File{ Type: &agentendpointpb.OSPolicy_Resource_File_LocalPath{ LocalPath: tmpFile, }, }, }, State: agentendpointpb.OSPolicy_Resource_FileResource_CONTENTS_MATCH, }, true, }, { "ContentsDontMatchLocalPath", &agentendpointpb.OSPolicy_Resource_FileResource{ Path: tmpFile2, Source: &agentendpointpb.OSPolicy_Resource_FileResource_File{ File: &agentendpointpb.OSPolicy_Resource_File{ Type: &agentendpointpb.OSPolicy_Resource_File_LocalPath{ LocalPath: tmpFile, }, }, }, State: agentendpointpb.OSPolicy_Resource_FileResource_CONTENTS_MATCH, }, false, }, { "ContentsDontMatchDNE", &agentendpointpb.OSPolicy_Resource_FileResource{ Path: filepath.Join(tmpDir, "dne"), Source: &agentendpointpb.OSPolicy_Resource_FileResource_File{ File: &agentendpointpb.OSPolicy_Resource_File{ Type: &agentendpointpb.OSPolicy_Resource_File_LocalPath{ LocalPath: tmpFile, }, }, }, State: agentendpointpb.OSPolicy_Resource_FileResource_CONTENTS_MATCH, }, false, }, { "ContentMatchFromContent", &agentendpointpb.OSPolicy_Resource_FileResource{ Path: tmpFile, Source: &agentendpointpb.OSPolicy_Resource_FileResource_Content{ Content: "foo", }, State: agentendpointpb.OSPolicy_Resource_FileResource_CONTENTS_MATCH, }, true, }, { "ContentsDontMatchFromContent", &agentendpointpb.OSPolicy_Resource_FileResource{ Path: tmpFile, Source: &agentendpointpb.OSPolicy_Resource_FileResource_Content{ Content: "bar", }, State: agentendpointpb.OSPolicy_Resource_FileResource_CONTENTS_MATCH, }, false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { pr := &OSPolicyResource{ OSPolicy_Resource: &agentendpointpb.OSPolicy_Resource{ ResourceType: &agentendpointpb.OSPolicy_Resource_File_{ File: tt.frpb, }, }, } if err := pr.Validate(ctx); err != nil { t.Fatalf("Unexpected Validate error: %v", err) } if err := pr.CheckState(ctx); err != nil { t.Fatalf("Unexpected CheckState error: %v", err) } if tt.wantInDesiredState != pr.InDesiredState() { t.Fatalf("Unexpected InDesiredState, want: %t, got: %t", tt.wantInDesiredState, pr.InDesiredState()) } }) } } func TestFileResourceEnforceStateAbsent(t *testing.T) { ctx := context.Background() tmpDir, err := ioutil.TempDir("", "") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmpDir) tmpFile := filepath.Join(tmpDir, "foo") if err := ioutil.WriteFile(tmpFile, []byte("foo"), 0644); err != nil { t.Fatal(err) } frpb := &agentendpointpb.OSPolicy_Resource_FileResource{ Path: tmpFile, State: agentendpointpb.OSPolicy_Resource_FileResource_ABSENT, } pr := &OSPolicyResource{ OSPolicy_Resource: &agentendpointpb.OSPolicy_Resource{ ResourceType: &agentendpointpb.OSPolicy_Resource_File_{File: frpb}, }, } if err := pr.Validate(ctx); err != nil { t.Fatalf("Unexpected Validate error: %v", err) } if err := pr.EnforceState(ctx); err != nil { t.Fatalf("Unexpected EnforceState error: %v", err) } if util.Exists(tmpFile) { t.Error("tmpFile still exists after EnforceState") } } func TestFileResourceEnforceStatePresent(t *testing.T) { ctx := context.Background() tmpDir, err := ioutil.TempDir("", "") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmpDir) srcFile := filepath.Join(tmpDir, "foo") if err := ioutil.WriteFile(srcFile, []byte("foo"), 0644); err != nil { t.Fatal(err) } wantFile := filepath.Join(tmpDir, "bar") frpb := &agentendpointpb.OSPolicy_Resource_FileResource{ Path: wantFile, Source: &agentendpointpb.OSPolicy_Resource_FileResource_File{ File: &agentendpointpb.OSPolicy_Resource_File{ Type: &agentendpointpb.OSPolicy_Resource_File_LocalPath{ LocalPath: srcFile, }, }, }, State: agentendpointpb.OSPolicy_Resource_FileResource_PRESENT, } pr := &OSPolicyResource{ OSPolicy_Resource: &agentendpointpb.OSPolicy_Resource{ ResourceType: &agentendpointpb.OSPolicy_Resource_File_{File: frpb}, }, } if err := pr.Validate(ctx); err != nil { t.Fatalf("Unexpected Validate error: %v", err) } if err := pr.EnforceState(ctx); err != nil { t.Fatalf("Unexpected EnforceState error: %v", err) } match, err := contentsMatch(ctx, wantFile, pr.resource.(*fileResource).managedFile.checksum) if err != nil { t.Fatal(err) } if !match { t.Fatal("Repo file contents do not match after enforcement") } } osconfig-20250416.02/config/package_resource.go000066400000000000000000000523111477773331400211260ustar00rootroot00000000000000// Copyright 2020 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package config import ( "context" "encoding/base64" "encoding/json" "fmt" "io/ioutil" "os" "path/filepath" "strings" "time" "github.com/GoogleCloudPlatform/osconfig/agentconfig" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/packages" "github.com/GoogleCloudPlatform/osconfig/util" "cloud.google.com/go/osconfig/agentendpoint/apiv1/agentendpointpb" "google.golang.org/protobuf/proto" ) var ( packageInfoCacheFile = filepath.Join(agentconfig.CacheDir(), "config_package_info.cache") // Clear out the entry if the last lookup is > 7 days ago. packageInfoCacheTimeout = -168 * time.Hour packageInfoCacheStore packageInfoCache ) type packageResouce struct { *agentendpointpb.OSPolicy_Resource_PackageResource managedPackage ManagedPackage } // AptPackage describes an apt package resource. type AptPackage struct { PackageResource *agentendpointpb.OSPolicy_Resource_PackageResource_APT DesiredState agentendpointpb.OSPolicy_Resource_PackageResource_DesiredState } // DebPackage describes a deb package resource. type DebPackage struct { PackageResource *agentendpointpb.OSPolicy_Resource_PackageResource_Deb name, localPath string } // GooGetPackage describes a googet package resource. type GooGetPackage struct { PackageResource *agentendpointpb.OSPolicy_Resource_PackageResource_GooGet DesiredState agentendpointpb.OSPolicy_Resource_PackageResource_DesiredState } // MSIPackage describes an msi package resource. type MSIPackage struct { PackageResource *agentendpointpb.OSPolicy_Resource_PackageResource_MSI productName, productCode, localPath string } // YumPackage describes a yum package resource. type YumPackage struct { PackageResource *agentendpointpb.OSPolicy_Resource_PackageResource_YUM DesiredState agentendpointpb.OSPolicy_Resource_PackageResource_DesiredState } // ZypperPackage describes a zypper package resource. type ZypperPackage struct { PackageResource *agentendpointpb.OSPolicy_Resource_PackageResource_Zypper DesiredState agentendpointpb.OSPolicy_Resource_PackageResource_DesiredState } // RPMPackage describes an rpm package resource. type RPMPackage struct { PackageResource *agentendpointpb.OSPolicy_Resource_PackageResource_RPM name, localPath string } // ManagedPackage is the package that this PackageResource manages. type ManagedPackage struct { Apt *AptPackage Deb *DebPackage GooGet *GooGetPackage MSI *MSIPackage Yum *YumPackage Zypper *ZypperPackage RPM *RPMPackage tempDir string } func (p *packageResouce) validateFile(file *agentendpointpb.OSPolicy_Resource_File) error { if file.GetLocalPath() != "" { if !util.Exists(file.GetLocalPath()) { return fmt.Errorf("%q does not exist", file.GetLocalPath()) } } return nil } type packageInfoCache map[string]packageInfo type packageInfo struct { PkgInfo *packages.PkgInfo LastLookup time.Time } func getPackageInfoCacheKey(pkgFile *agentendpointpb.OSPolicy_Resource_File) (string, error) { // We use the base64 encoded binary proto as the key. raw, err := proto.Marshal(pkgFile) if err != nil { return "", err } return base64.RawStdEncoding.EncodeToString(raw), nil } func loadPackageInfoCache(ctx context.Context) { if packageInfoCacheStore != nil { return } data, err := ioutil.ReadFile(packageInfoCacheFile) if err != nil { // Just ignore the error and return early // The error mode here is to just always redownload the file. clog.Debugf(ctx, "Error reading the package info cache: %v", err) packageInfoCacheStore = packageInfoCache{} return } var cache packageInfoCache if err := json.Unmarshal(data, &cache); err != nil { clog.Debugf(ctx, "Error unmarshaling the package info cache: %v", err) packageInfoCacheStore = packageInfoCache{} return } packageInfoCacheStore = cache } func getPackageInfoFromCache(ctx context.Context, pkgFile *agentendpointpb.OSPolicy_Resource_File) *packages.PkgInfo { loadPackageInfoCache(ctx) key, err := getPackageInfoCacheKey(pkgFile) if err != nil { // Just ignore the error and return early // The error mode here is just always redownload the file. clog.Debugf(ctx, "Error creating the package info cache key: %v", err) return nil } packageInfo, ok := packageInfoCacheStore[key] if !ok { return nil } return packageInfo.PkgInfo } func updatePackageInfoCache(ctx context.Context, info *packages.PkgInfo, pkgFile *agentendpointpb.OSPolicy_Resource_File) { loadPackageInfoCache(ctx) for k, v := range packageInfoCacheStore { if time.Now().Add(packageInfoCacheTimeout).After(v.LastLookup) { delete(packageInfoCacheStore, k) } } key, err := getPackageInfoCacheKey(pkgFile) if err != nil { // Just ignore the error and return early // The error mode here is to just always redownload the file. clog.Warningf(ctx, "Error creating the package info cache: %v", err) return } packageInfoCacheStore[key] = packageInfo{PkgInfo: info, LastLookup: time.Now()} } func savePackageInfoCache(ctx context.Context) error { if packageInfoCacheStore == nil { return nil } data, err := json.Marshal(packageInfoCacheStore) if err != nil { return err } packageInfoCacheStore = nil return ioutil.WriteFile(packageInfoCacheFile, data, 0644) } func (p *packageResouce) validate(ctx context.Context) (*ManagedResources, error) { switch p.GetSystemPackage().(type) { case *agentendpointpb.OSPolicy_Resource_PackageResource_Apt: pr := p.GetApt() if !packages.AptExists { return nil, fmt.Errorf("cannot manage Apt package %q because apt-get does not exist on the system", pr.GetName()) } p.managedPackage.Apt = &AptPackage{DesiredState: p.GetDesiredState(), PackageResource: pr} case *agentendpointpb.OSPolicy_Resource_PackageResource_Deb_: pr := p.GetDeb() if !packages.DpkgExists { return nil, fmt.Errorf("cannot manage Deb package because dpkg does not exist on the system") } if p.GetDesiredState() != agentendpointpb.OSPolicy_Resource_PackageResource_INSTALLED { return nil, fmt.Errorf("desired state of %q not applicable for deb package", p.GetDesiredState()) } if err := p.validateFile(pr.GetSource()); err != nil { return nil, err } var localPath string var err error source := p.GetDeb().GetSource() info := getPackageInfoFromCache(ctx, source) if info == nil { localPath, err = p.download(ctx, "pkg.deb", source) if err != nil { return nil, err } info, err = packages.DebPkgInfo(ctx, localPath) if err != nil { return nil, err } } // Always update the cache to update the timestamps. updatePackageInfoCache(ctx, info, source) p.managedPackage.Deb = &DebPackage{PackageResource: pr, localPath: localPath, name: info.Name} case *agentendpointpb.OSPolicy_Resource_PackageResource_Googet: pr := p.GetGooget() if !packages.GooGetExists { return nil, fmt.Errorf("cannot manage GooGet package %q because googet does not exist on the system", pr.GetName()) } p.managedPackage.GooGet = &GooGetPackage{DesiredState: p.GetDesiredState(), PackageResource: pr} case *agentendpointpb.OSPolicy_Resource_PackageResource_Msi: pr := p.GetMsi() if !packages.MSIExists { return nil, fmt.Errorf("cannot manage MSI package because msiexec does not exist on the system") } if p.GetDesiredState() != agentendpointpb.OSPolicy_Resource_PackageResource_INSTALLED { return nil, fmt.Errorf("desired state of %q not applicable for MSI package", p.GetDesiredState()) } if err := p.validateFile(pr.GetSource()); err != nil { return nil, err } var localPath string var err error source := p.GetMsi().GetSource() info := getPackageInfoFromCache(ctx, source) if info == nil { localPath, err = p.download(ctx, "pkg.msi", source) if err != nil { return nil, err } productName, productCode, err := packages.MSIInfo(localPath) if err != nil { return nil, err } // We store productCode as version in the packageinfo struct. info = &packages.PkgInfo{Name: productName, Version: productCode} } // Always update the cache to update the timestamps. updatePackageInfoCache(ctx, info, source) p.managedPackage.MSI = &MSIPackage{PackageResource: pr, localPath: localPath, productName: info.Name, productCode: info.Version} case *agentendpointpb.OSPolicy_Resource_PackageResource_Yum: pr := p.GetYum() if !packages.YumExists { return nil, fmt.Errorf("cannot manage Yum package %q because yum does not exist on the system", pr.GetName()) } p.managedPackage.Yum = &YumPackage{DesiredState: p.GetDesiredState(), PackageResource: pr} case *agentendpointpb.OSPolicy_Resource_PackageResource_Zypper_: pr := p.GetZypper() if !packages.ZypperExists { return nil, fmt.Errorf("cannot manage Zypper package %q because zypper does not exist on the system", pr.GetName()) } p.managedPackage.Zypper = &ZypperPackage{DesiredState: p.GetDesiredState(), PackageResource: pr} case *agentendpointpb.OSPolicy_Resource_PackageResource_Rpm: pr := p.GetRpm() if !packages.RPMExists { return nil, fmt.Errorf("cannot manage RPM package because rpm does not exist on the system") } if p.GetDesiredState() != agentendpointpb.OSPolicy_Resource_PackageResource_INSTALLED { return nil, fmt.Errorf("desired state of %q not applicable for rpm package", p.GetDesiredState()) } if err := p.validateFile(pr.GetSource()); err != nil { return nil, err } var localPath string var err error source := p.GetRpm().GetSource() info := getPackageInfoFromCache(ctx, source) if info == nil { localPath, err = p.download(ctx, "pkg.rpm", source) if err != nil { return nil, err } info, err = packages.RPMPkgInfo(ctx, localPath) if err != nil { return nil, err } } // Always update the cache to update the timestamps. updatePackageInfoCache(ctx, info, source) p.managedPackage.RPM = &RPMPackage{PackageResource: pr, localPath: localPath, name: info.Name} default: return nil, fmt.Errorf("SystemPackage field not set or references unknown package manager: %v", p.GetSystemPackage()) } return &ManagedResources{Packages: []ManagedPackage{p.managedPackage}}, nil } type packageCache struct { cache map[string]struct{} refreshed time.Time } var ( aptInstalled = &packageCache{} debInstalled = &packageCache{} gooInstalled = &packageCache{} yumInstalled = &packageCache{} zypperInstalled = &packageCache{} rpmInstalled = &packageCache{} ) func populateInstalledCache(ctx context.Context, mp ManagedPackage) error { var cache *packageCache var refreshFunc func(context.Context) ([]*packages.PkgInfo, error) var err error switch { case mp.Apt != nil: cache = aptInstalled refreshFunc = packages.InstalledDebPackages case mp.Deb != nil: cache = debInstalled refreshFunc = packages.InstalledDebPackages case mp.GooGet != nil: cache = gooInstalled refreshFunc = packages.InstalledGooGetPackages case mp.MSI != nil: // We just query per each MSI. return nil // TODO: implement yum functions case mp.Yum != nil: cache = yumInstalled refreshFunc = packages.InstalledRPMPackages // TODO: implement zypper functions case mp.Zypper != nil: cache = zypperInstalled refreshFunc = packages.InstalledRPMPackages case mp.RPM != nil: cache = rpmInstalled refreshFunc = packages.InstalledRPMPackages default: return fmt.Errorf("unknown or unpopulated ManagedPackage package type: %+v", mp) } // Cache already populated within the last 3 min. if cache.cache != nil && cache.refreshed.After(time.Now().Add(-3*time.Minute)) { return nil } pis, err := refreshFunc(ctx) if err != nil { return err } cache.cache = map[string]struct{}{} for _, pkg := range pis { cache.cache[pkg.Name] = struct{}{} } cache.refreshed = time.Now() return nil } // TODO: use a persistent cache for downloaded files so we dont need to redownload them each time func (p *packageResouce) download(ctx context.Context, name string, file *agentendpointpb.OSPolicy_Resource_File) (string, error) { var path string perms := os.FileMode(0644) switch { case file.GetLocalPath() != "": path = file.GetLocalPath() default: tmpDir, err := ioutil.TempDir("", "osconfig_package_resource_") if err != nil { return "", fmt.Errorf("failed to create temp dir: %s", err) } p.managedPackage.tempDir = tmpDir path = filepath.Join(p.managedPackage.tempDir, name) if _, err := downloadFile(ctx, path, perms, file); err != nil { return "", err } } return path, nil } func (p *packageResouce) checkState(ctx context.Context) (inDesiredState bool, err error) { if err := populateInstalledCache(ctx, p.managedPackage); err != nil { return false, err } var desiredState agentendpointpb.OSPolicy_Resource_PackageResource_DesiredState var pkgIns bool switch { case p.managedPackage.Apt != nil: desiredState = p.managedPackage.Apt.DesiredState _, pkgIns = aptInstalled.cache[p.managedPackage.Apt.PackageResource.GetName()] case p.managedPackage.Deb != nil: desiredState = agentendpointpb.OSPolicy_Resource_PackageResource_INSTALLED _, pkgIns = debInstalled.cache[p.managedPackage.Deb.name] case p.managedPackage.GooGet != nil: desiredState = p.managedPackage.GooGet.DesiredState _, pkgIns = gooInstalled.cache[p.managedPackage.GooGet.PackageResource.GetName()] case p.managedPackage.MSI != nil: desiredState = agentendpointpb.OSPolicy_Resource_PackageResource_INSTALLED pkgIns, err = packages.MSIInstalled(p.managedPackage.MSI.productCode) if err != nil { return false, err } case p.managedPackage.Yum != nil: desiredState = p.managedPackage.Yum.DesiredState _, pkgIns = yumInstalled.cache[p.managedPackage.Yum.PackageResource.GetName()] case p.managedPackage.Zypper != nil: desiredState = p.managedPackage.Zypper.DesiredState _, pkgIns = zypperInstalled.cache[p.managedPackage.Zypper.PackageResource.GetName()] case p.managedPackage.RPM != nil: desiredState = agentendpointpb.OSPolicy_Resource_PackageResource_INSTALLED _, pkgIns = rpmInstalled.cache[p.managedPackage.RPM.name] } switch desiredState { case agentendpointpb.OSPolicy_Resource_PackageResource_INSTALLED: if pkgIns { return true, nil } case agentendpointpb.OSPolicy_Resource_PackageResource_REMOVED: if !pkgIns { return true, nil } default: return false, fmt.Errorf("DesiredState field not set or references state: %q", desiredState) } return false, nil } func (p *packageResouce) enforceState(ctx context.Context) (inDesiredState bool, err error) { var ( installing = "installing" removing = "removing" enforcePackage struct { actionFunc func() error installedCache *packageCache name string action string packageType string } ) switch { case p.managedPackage.Apt != nil: enforcePackage.name = p.managedPackage.Apt.PackageResource.GetName() enforcePackage.packageType = "apt" enforcePackage.installedCache = aptInstalled switch p.managedPackage.Apt.DesiredState { case agentendpointpb.OSPolicy_Resource_PackageResource_INSTALLED: enforcePackage.action, enforcePackage.actionFunc = installing, func() error { if _, err := packages.AptUpdate(ctx); err != nil { return err } return packages.InstallAptPackages(ctx, []string{enforcePackage.name}) } case agentendpointpb.OSPolicy_Resource_PackageResource_REMOVED: enforcePackage.action, enforcePackage.actionFunc = removing, func() error { return packages.RemoveAptPackages(ctx, []string{enforcePackage.name}) } } case p.managedPackage.Deb != nil: enforcePackage.name = p.managedPackage.Deb.name enforcePackage.packageType = "deb" enforcePackage.installedCache = debInstalled enforcePackage.action = installing // Check if we have not pulled the package yet. if p.managedPackage.Deb.localPath == "" { localPath, err := p.download(ctx, "pkg.deb", p.GetDeb().GetSource()) if err != nil { return false, err } p.managedPackage.Deb.localPath = localPath } if p.GetDeb().GetPullDeps() { enforcePackage.actionFunc = func() error { return packages.InstallAptPackages(ctx, []string{p.managedPackage.Deb.localPath}) } } else { enforcePackage.actionFunc = func() error { return packages.DpkgInstall(ctx, p.managedPackage.Deb.localPath) } } case p.managedPackage.GooGet != nil: enforcePackage.name = p.managedPackage.GooGet.PackageResource.GetName() enforcePackage.packageType = "googet" enforcePackage.installedCache = gooInstalled switch p.managedPackage.GooGet.DesiredState { case agentendpointpb.OSPolicy_Resource_PackageResource_INSTALLED: enforcePackage.action, enforcePackage.actionFunc = installing, func() error { return packages.InstallGooGetPackages(ctx, []string{enforcePackage.name}) } case agentendpointpb.OSPolicy_Resource_PackageResource_REMOVED: enforcePackage.action, enforcePackage.actionFunc = removing, func() error { return packages.RemoveGooGetPackages(ctx, []string{enforcePackage.name}) } } case p.managedPackage.MSI != nil: enforcePackage.name = p.managedPackage.MSI.productName enforcePackage.packageType = "msi" enforcePackage.action = installing enforcePackage.installedCache = &packageCache{} // No package cache for msi. // Check if we have not pulled the package yet. if p.managedPackage.MSI.localPath == "" { localPath, err := p.download(ctx, "pkg.msi", p.GetMsi().GetSource()) if err != nil { return false, err } p.managedPackage.MSI.localPath = localPath } enforcePackage.actionFunc = func() error { return packages.InstallMSIPackage(ctx, p.managedPackage.MSI.localPath, p.managedPackage.MSI.PackageResource.GetProperties()) } case p.managedPackage.Yum != nil: enforcePackage.name = p.managedPackage.Yum.PackageResource.GetName() enforcePackage.packageType = "yum" enforcePackage.installedCache = yumInstalled switch p.managedPackage.Yum.DesiredState { case agentendpointpb.OSPolicy_Resource_PackageResource_INSTALLED: enforcePackage.action, enforcePackage.actionFunc = installing, func() error { return packages.InstallYumPackages(ctx, []string{enforcePackage.name}) } case agentendpointpb.OSPolicy_Resource_PackageResource_REMOVED: enforcePackage.action, enforcePackage.actionFunc = removing, func() error { return packages.RemoveYumPackages(ctx, []string{enforcePackage.name}) } } case p.managedPackage.Zypper != nil: enforcePackage.name = p.managedPackage.Zypper.PackageResource.GetName() enforcePackage.packageType = "zypper" enforcePackage.installedCache = zypperInstalled switch p.managedPackage.Zypper.DesiredState { case agentendpointpb.OSPolicy_Resource_PackageResource_INSTALLED: enforcePackage.action, enforcePackage.actionFunc = installing, func() error { return packages.InstallZypperPackages(ctx, []string{enforcePackage.name}) } case agentendpointpb.OSPolicy_Resource_PackageResource_REMOVED: enforcePackage.action, enforcePackage.actionFunc = removing, func() error { return packages.RemoveZypperPackages(ctx, []string{enforcePackage.name}) } } case p.managedPackage.RPM != nil: enforcePackage.name = p.managedPackage.RPM.name enforcePackage.packageType = "rpm" enforcePackage.installedCache = rpmInstalled enforcePackage.action = installing // Check if we have not pulled the package yet. if p.managedPackage.RPM.localPath == "" { localPath, err := p.download(ctx, "pkg.rpm", p.GetRpm().GetSource()) if err != nil { return false, err } p.managedPackage.RPM.localPath = localPath } if p.GetRpm().GetPullDeps() { switch { case packages.YumExists: enforcePackage.actionFunc = func() error { return packages.InstallYumPackages(ctx, []string{p.managedPackage.RPM.localPath}) } case packages.ZypperExists: enforcePackage.actionFunc = func() error { return packages.InstallZypperPackages(ctx, []string{p.managedPackage.RPM.localPath}) } default: return false, fmt.Errorf("cannot install rpm %q with 'PullDeps' option as neither yum or zypper exist on system", enforcePackage.name) } } else { enforcePackage.actionFunc = func() error { return packages.RPMInstall(ctx, p.managedPackage.RPM.localPath) } } } clog.Infof(ctx, "%s %s package %q", strings.Title(enforcePackage.action), enforcePackage.packageType, enforcePackage.name) // Reset the cache as we are taking action on. enforcePackage.installedCache.cache = nil if err := enforcePackage.actionFunc(); err != nil { return false, fmt.Errorf("error %s %s package %q", enforcePackage.action, enforcePackage.packageType, enforcePackage.name) } return true, nil } func (p *packageResouce) populateOutput(rCompliance *agentendpointpb.OSPolicyResourceCompliance) {} func (p *packageResouce) cleanup(ctx context.Context) error { // Save cache and clear the variable. if err := savePackageInfoCache(ctx); err != nil { clog.Warningf(ctx, "Error saving the package info cache: %v", err) } if p.managedPackage.tempDir != "" { return os.RemoveAll(p.managedPackage.tempDir) } return nil } osconfig-20250416.02/config/package_resource_test.go000066400000000000000000000454211477773331400221710ustar00rootroot00000000000000// Copyright 2020 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package config import ( "context" "encoding/json" "io/ioutil" "os" "os/exec" "path/filepath" "reflect" "testing" "time" "github.com/GoogleCloudPlatform/osconfig/packages" utilmocks "github.com/GoogleCloudPlatform/osconfig/util/mocks" "github.com/golang/mock/gomock" "github.com/google/go-cmp/cmp" "google.golang.org/protobuf/testing/protocmp" "cloud.google.com/go/osconfig/agentendpoint/apiv1/agentendpointpb" ) var ( aptInstalledPR = &agentendpointpb.OSPolicy_Resource_PackageResource{ DesiredState: agentendpointpb.OSPolicy_Resource_PackageResource_INSTALLED, SystemPackage: &agentendpointpb.OSPolicy_Resource_PackageResource_Apt{ Apt: &agentendpointpb.OSPolicy_Resource_PackageResource_APT{Name: "foo"}}} aptRemovedPR = &agentendpointpb.OSPolicy_Resource_PackageResource{ DesiredState: agentendpointpb.OSPolicy_Resource_PackageResource_REMOVED, SystemPackage: &agentendpointpb.OSPolicy_Resource_PackageResource_Apt{ Apt: &agentendpointpb.OSPolicy_Resource_PackageResource_APT{Name: "foo"}}} googetInstalledPR = &agentendpointpb.OSPolicy_Resource_PackageResource{ DesiredState: agentendpointpb.OSPolicy_Resource_PackageResource_INSTALLED, SystemPackage: &agentendpointpb.OSPolicy_Resource_PackageResource_Googet{ Googet: &agentendpointpb.OSPolicy_Resource_PackageResource_GooGet{Name: "foo"}}} googetRemovedPR = &agentendpointpb.OSPolicy_Resource_PackageResource{ DesiredState: agentendpointpb.OSPolicy_Resource_PackageResource_REMOVED, SystemPackage: &agentendpointpb.OSPolicy_Resource_PackageResource_Googet{ Googet: &agentendpointpb.OSPolicy_Resource_PackageResource_GooGet{Name: "foo"}}} yumInstalledPR = &agentendpointpb.OSPolicy_Resource_PackageResource{ DesiredState: agentendpointpb.OSPolicy_Resource_PackageResource_INSTALLED, SystemPackage: &agentendpointpb.OSPolicy_Resource_PackageResource_Yum{ Yum: &agentendpointpb.OSPolicy_Resource_PackageResource_YUM{Name: "foo"}}} yumRemovedPR = &agentendpointpb.OSPolicy_Resource_PackageResource{ DesiredState: agentendpointpb.OSPolicy_Resource_PackageResource_REMOVED, SystemPackage: &agentendpointpb.OSPolicy_Resource_PackageResource_Yum{ Yum: &agentendpointpb.OSPolicy_Resource_PackageResource_YUM{Name: "foo"}}} zypperInstalledPR = &agentendpointpb.OSPolicy_Resource_PackageResource{ DesiredState: agentendpointpb.OSPolicy_Resource_PackageResource_INSTALLED, SystemPackage: &agentendpointpb.OSPolicy_Resource_PackageResource_Zypper_{ Zypper: &agentendpointpb.OSPolicy_Resource_PackageResource_Zypper{Name: "foo"}}} zypperRemovedPR = &agentendpointpb.OSPolicy_Resource_PackageResource{ DesiredState: agentendpointpb.OSPolicy_Resource_PackageResource_REMOVED, SystemPackage: &agentendpointpb.OSPolicy_Resource_PackageResource_Zypper_{ Zypper: &agentendpointpb.OSPolicy_Resource_PackageResource_Zypper{Name: "foo"}}} ) type fakeCommandRunner struct{} func (m *fakeCommandRunner) Run(_ context.Context, _ *exec.Cmd) ([]byte, []byte, error) { return nil, nil, nil } func TestPackageResourceValidate(t *testing.T) { ctx := context.Background() tmpDir, err := ioutil.TempDir("", "") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmpDir) tmpFile := filepath.Join(tmpDir, "foo") if err := ioutil.WriteFile(tmpFile, nil, 0644); err != nil { t.Fatal(err) } mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) packages.SetCommandRunner(mockCommandRunner) var tests = []struct { name string wantErr bool prpb *agentendpointpb.OSPolicy_Resource_PackageResource wantMP ManagedPackage expectedCmd *exec.Cmd expectedCmdReturn []byte }{ { "Blank", true, &agentendpointpb.OSPolicy_Resource_PackageResource{}, ManagedPackage{}, nil, nil, }, { "AptInstalled", false, aptInstalledPR, ManagedPackage{Apt: &AptPackage{ DesiredState: agentendpointpb.OSPolicy_Resource_PackageResource_INSTALLED, PackageResource: &agentendpointpb.OSPolicy_Resource_PackageResource_APT{Name: "foo"}}}, nil, nil, }, { "AptRemoved", false, aptRemovedPR, ManagedPackage{Apt: &AptPackage{ DesiredState: agentendpointpb.OSPolicy_Resource_PackageResource_REMOVED, PackageResource: &agentendpointpb.OSPolicy_Resource_PackageResource_APT{Name: "foo"}}}, nil, nil, }, { "DebInstalled", false, &agentendpointpb.OSPolicy_Resource_PackageResource{ DesiredState: agentendpointpb.OSPolicy_Resource_PackageResource_INSTALLED, SystemPackage: &agentendpointpb.OSPolicy_Resource_PackageResource_Deb_{ Deb: &agentendpointpb.OSPolicy_Resource_PackageResource_Deb{ Source: &agentendpointpb.OSPolicy_Resource_File{ Type: &agentendpointpb.OSPolicy_Resource_File_LocalPath{LocalPath: tmpFile}}}}}, ManagedPackage{Deb: &DebPackage{ localPath: tmpFile, name: "foo", PackageResource: &agentendpointpb.OSPolicy_Resource_PackageResource_Deb{ Source: &agentendpointpb.OSPolicy_Resource_File{ Type: &agentendpointpb.OSPolicy_Resource_File_LocalPath{LocalPath: tmpFile}}}}}, exec.Command("/usr/bin/dpkg-deb", "-I", tmpFile), []byte("Package: foo\nVersion: 1:1dummy-g1\nArchitecture: amd64"), }, { "GoGetInstalled", false, googetInstalledPR, ManagedPackage{GooGet: &GooGetPackage{ DesiredState: agentendpointpb.OSPolicy_Resource_PackageResource_INSTALLED, PackageResource: &agentendpointpb.OSPolicy_Resource_PackageResource_GooGet{Name: "foo"}}}, nil, nil, }, { "GooGetRemoved", false, googetRemovedPR, ManagedPackage{GooGet: &GooGetPackage{ DesiredState: agentendpointpb.OSPolicy_Resource_PackageResource_REMOVED, PackageResource: &agentendpointpb.OSPolicy_Resource_PackageResource_GooGet{Name: "foo"}}}, nil, nil, }, { "MSIInstalled", false, &agentendpointpb.OSPolicy_Resource_PackageResource{ DesiredState: agentendpointpb.OSPolicy_Resource_PackageResource_INSTALLED, SystemPackage: &agentendpointpb.OSPolicy_Resource_PackageResource_Msi{ Msi: &agentendpointpb.OSPolicy_Resource_PackageResource_MSI{ Source: &agentendpointpb.OSPolicy_Resource_File{ Type: &agentendpointpb.OSPolicy_Resource_File_LocalPath{LocalPath: tmpFile}}}}}, ManagedPackage{MSI: &MSIPackage{ localPath: tmpFile, PackageResource: &agentendpointpb.OSPolicy_Resource_PackageResource_MSI{ Source: &agentendpointpb.OSPolicy_Resource_File{ Type: &agentendpointpb.OSPolicy_Resource_File_LocalPath{LocalPath: tmpFile}}}}}, nil, nil, }, { "YumInstalled", false, yumInstalledPR, ManagedPackage{Yum: &YumPackage{ DesiredState: agentendpointpb.OSPolicy_Resource_PackageResource_INSTALLED, PackageResource: &agentendpointpb.OSPolicy_Resource_PackageResource_YUM{Name: "foo"}}}, nil, nil, }, { "YumRemoved", false, yumRemovedPR, ManagedPackage{Yum: &YumPackage{ DesiredState: agentendpointpb.OSPolicy_Resource_PackageResource_REMOVED, PackageResource: &agentendpointpb.OSPolicy_Resource_PackageResource_YUM{Name: "foo"}}}, nil, nil, }, { "ZypperInstalled", false, zypperInstalledPR, ManagedPackage{Zypper: &ZypperPackage{ DesiredState: agentendpointpb.OSPolicy_Resource_PackageResource_INSTALLED, PackageResource: &agentendpointpb.OSPolicy_Resource_PackageResource_Zypper{Name: "foo"}}}, nil, nil, }, { "ZypperRemoved", false, zypperRemovedPR, ManagedPackage{Zypper: &ZypperPackage{ DesiredState: agentendpointpb.OSPolicy_Resource_PackageResource_REMOVED, PackageResource: &agentendpointpb.OSPolicy_Resource_PackageResource_Zypper{Name: "foo"}}}, nil, nil, }, { "RPMInstalled", false, &agentendpointpb.OSPolicy_Resource_PackageResource{ DesiredState: agentendpointpb.OSPolicy_Resource_PackageResource_INSTALLED, SystemPackage: &agentendpointpb.OSPolicy_Resource_PackageResource_Rpm{ Rpm: &agentendpointpb.OSPolicy_Resource_PackageResource_RPM{ Source: &agentendpointpb.OSPolicy_Resource_File{ Type: &agentendpointpb.OSPolicy_Resource_File_LocalPath{LocalPath: tmpFile}}}}}, ManagedPackage{RPM: &RPMPackage{ localPath: tmpFile, name: "gcc", PackageResource: &agentendpointpb.OSPolicy_Resource_PackageResource_RPM{ Source: &agentendpointpb.OSPolicy_Resource_File{ Type: &agentendpointpb.OSPolicy_Resource_File_LocalPath{LocalPath: tmpFile}}}}}, exec.Command("/usr/bin/rpmquery", "--queryformat", "\\{\"architecture\":\"%{ARCH}\",\"package\":\"%{NAME}\",\"source_name\":\"%{SOURCERPM}\",\"version\":\"%|EPOCH?{%{EPOCH}:}:{}|%{VERSION}-%{RELEASE}\"\\}\n", "-p", tmpFile), []byte("{\"architecture\":\"x86_64\",\"package\":\"gcc\",\"source_name\":\"gcc-11.4.1-3.el9.src.rpm\",\"version\":\"11.4.1-3.el9\"}"), }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { pr := &OSPolicyResource{ OSPolicy_Resource: &agentendpointpb.OSPolicy_Resource{ ResourceType: &agentendpointpb.OSPolicy_Resource_Pkg{Pkg: tt.prpb}, }, } defer pr.Cleanup(ctx) if tt.expectedCmd != nil { mockCommandRunner.EXPECT().Run(ctx, utilmocks.EqCmd(tt.expectedCmd)).Return(tt.expectedCmdReturn, nil, nil) } err := pr.Validate(ctx) if err != nil && !tt.wantErr { t.Fatalf("Unexpected error: %v", err) } if err == nil && tt.wantErr { t.Fatal("Expected error and did not get one.") } wantMR := &ManagedResources{Packages: []ManagedPackage{tt.wantMP}} if err != nil { wantMR = nil } opts := []cmp.Option{protocmp.Transform(), cmp.AllowUnexported(ManagedPackage{}), cmp.AllowUnexported(DebPackage{}), cmp.AllowUnexported(RPMPackage{}), cmp.AllowUnexported(MSIPackage{})} if diff := cmp.Diff(pr.ManagedResources(), wantMR, opts...); diff != "" { t.Errorf("OSPolicyResource does not match expectation: (-got +want)\n%s", diff) } if diff := cmp.Diff(pr.resource.(*packageResouce).managedPackage, tt.wantMP, opts...); diff != "" { t.Errorf("packageResouce does not match expectation: (-got +want)\n%s", diff) } }) } } func TestPopulateInstalledCache(t *testing.T) { ctx := context.Background() mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) packages.SetCommandRunner(mockCommandRunner) mockCommandRunner.EXPECT().Run(ctx, utilmocks.EqCmd(exec.Command("googet.exe", "installed"))).Return([]byte("Installed Packages:\nfoo.x86_64 1.2.3@4\nbar.noarch 1.2.3@4"), nil, nil).Times(1) if err := populateInstalledCache(ctx, ManagedPackage{GooGet: &GooGetPackage{}}); err != nil { t.Fatalf("Unexpected error from populateInstalledCache: %v", err) } want := map[string]struct{}{"foo": {}, "bar": {}} if diff := cmp.Diff(gooInstalled.cache, want); diff != "" { t.Errorf("OSPolicyResource does not match expectation: (-got +want)\n%s", diff) } } func TestPackageResourceCheckState(t *testing.T) { ctx := context.Background() var tests = []struct { name string installedCache map[string]struct{} cachePointer *packageCache prpb *agentendpointpb.OSPolicy_Resource_PackageResource wantInDesiredState bool }{ // We only need to test the full set once as all the logic is shared. { "AptInstalledNeedsInstalled", map[string]struct{}{"foo": {}}, aptInstalled, aptInstalledPR, true, }, { "AptInstalledNeedsRemoved", map[string]struct{}{"foo": {}}, aptInstalled, aptRemovedPR, false, }, { "AptRemovedNeedsInstalled", map[string]struct{}{}, aptInstalled, aptInstalledPR, false, }, { "AptRemovedNeedsRemoved", map[string]struct{}{}, aptInstalled, aptRemovedPR, true, }, // For the rest of the package types we only need to test one scenario. { "GooGetInstalledNeedsInstalled", map[string]struct{}{"foo": {}}, gooInstalled, googetInstalledPR, true, }, { "YUMInstalledNeedsInstalled", map[string]struct{}{"foo": {}}, yumInstalled, yumInstalledPR, true, }, { "ZypperInstalledNeedsInstalled", map[string]struct{}{"foo": {}}, zypperInstalled, zypperInstalledPR, true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { pr := &OSPolicyResource{ OSPolicy_Resource: &agentendpointpb.OSPolicy_Resource{ ResourceType: &agentendpointpb.OSPolicy_Resource_Pkg{Pkg: tt.prpb}, }, } defer pr.Cleanup(ctx) // Run validate first to make sure everything gets setup correctly. // This adds complexity to this 'unit' test and turns it into more // of a integration test but reduces overall test functions and gives // us good coverage. if err := pr.Validate(ctx); err != nil { t.Fatalf("Unexpected Validate error: %v", err) } tt.cachePointer.cache = tt.installedCache tt.cachePointer.refreshed = time.Now() if err := pr.CheckState(ctx); err != nil { t.Fatalf("Unexpected error: %v", err) } if tt.wantInDesiredState != pr.InDesiredState() { t.Fatalf("Unexpected InDesiredState, want: %t, got: %t", tt.wantInDesiredState, pr.InDesiredState()) } }) } } func TestPackageResourceEnforceState(t *testing.T) { ctx := context.Background() mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) packages.SetCommandRunner(mockCommandRunner) var tests = []struct { name string prpb *agentendpointpb.OSPolicy_Resource_PackageResource cachePointer *packageCache expectedCmds []*exec.Cmd }{ { "AptInstalled", aptInstalledPR, aptInstalled, func() []*exec.Cmd { cmd1 := exec.Command("/usr/bin/apt-get", "update") cmd1.Env = append(os.Environ(), "DEBIAN_FRONTEND=noninteractive", ) cmd2 := exec.Command("/usr/bin/apt-get", "install", "-y", "foo") cmd2.Env = append(os.Environ(), "DEBIAN_FRONTEND=noninteractive", ) return []*exec.Cmd{cmd1, cmd2} }(), }, { "AptRemoved", aptRemovedPR, aptInstalled, func() []*exec.Cmd { cmd1 := exec.Command("/usr/bin/apt-get", "remove", "-y", "foo") cmd1.Env = append(os.Environ(), "DEBIAN_FRONTEND=noninteractive", ) return []*exec.Cmd{cmd1} }(), }, { "GooGetInstalled", googetInstalledPR, gooInstalled, []*exec.Cmd{exec.Command("googet.exe", "-noconfirm", "install", "foo")}, }, { "GooGetRemoved", googetRemovedPR, gooInstalled, []*exec.Cmd{exec.Command("googet.exe", "-noconfirm", "remove", "foo")}, }, { "YumInstalled", yumInstalledPR, yumInstalled, []*exec.Cmd{exec.Command("/usr/bin/yum", "install", "--assumeyes", "foo")}, }, { "YumRemoved", yumRemovedPR, yumInstalled, []*exec.Cmd{exec.Command("/usr/bin/yum", "remove", "--assumeyes", "foo")}, }, { "ZypperInstalled", zypperInstalledPR, zypperInstalled, []*exec.Cmd{exec.Command("/usr/bin/zypper", "--gpg-auto-import-keys", "--non-interactive", "install", "--auto-agree-with-licenses", "foo")}, }, { "ZypperRemoved", zypperRemovedPR, zypperInstalled, []*exec.Cmd{exec.Command("/usr/bin/zypper", "--non-interactive", "remove", "foo")}, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { pr := &OSPolicyResource{ OSPolicy_Resource: &agentendpointpb.OSPolicy_Resource{ ResourceType: &agentendpointpb.OSPolicy_Resource_Pkg{Pkg: tt.prpb}, }, } defer pr.Cleanup(ctx) // Run Validate first to make sure everything gets setup correctly. // This adds complexity to this 'unit' test and turns it into more // of a integration test but reduces overall test functions and gives // us good coverage. if err := pr.Validate(ctx); err != nil { t.Fatalf("Unexpected Validate error: %v", err) } tt.cachePointer.cache = map[string]struct{}{"foo": {}} for _, expectedCmd := range tt.expectedCmds { mockCommandRunner.EXPECT().Run(ctx, utilmocks.EqCmd(expectedCmd)) } if err := pr.EnforceState(ctx); err != nil { t.Fatalf("Unexpected error: %v", err) } if tt.cachePointer.cache != nil { t.Errorf("Enforce function did not set package cache to nil") } }) } } func TestPackageInfoCache(t *testing.T) { ctx := context.Background() pkgInfo := &packages.PkgInfo{Name: "name", Arch: "arch", Version: "version"} pkgFile := &agentendpointpb.OSPolicy_Resource_File{AllowInsecure: true, Type: &agentendpointpb.OSPolicy_Resource_File_Gcs_{Gcs: &agentendpointpb.OSPolicy_Resource_File_Gcs{Bucket: "bucket", Object: "object", Generation: 123456789}}} wantKey := "IAESFQoGYnVja2V0EgZvYmplY3QYlZrvOg" tmpDir, err := ioutil.TempDir("", "") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmpDir) packageInfoCacheFile = filepath.Join(tmpDir, "file.cache") packageInfoCacheStore = nil updatePackageInfoCache(ctx, pkgInfo, pkgFile) if err := savePackageInfoCache(ctx); err != nil { t.Fatal(err) } got := getPackageInfoFromCache(ctx, pkgFile) if !reflect.DeepEqual(got, pkgInfo) { t.Errorf("Did not get expected cache data, got: %+v, want: %+v", got, pkgInfo) } if _, ok := packageInfoCacheStore[wantKey]; !ok { t.Errorf("Cache did not contain expected key, cache: %+v, want: %q", packageInfoCacheStore, wantKey) } // Now test save and reload. savePackageInfoCache(ctx) if packageInfoCacheStore != nil { t.Fatal("expected packageInfoCacheStore to be nil") } loadPackageInfoCache(ctx) if _, ok := packageInfoCacheStore[wantKey]; !ok { t.Errorf("Cache did not contain expected key, cache: %+v, want: %q", packageInfoCacheStore, wantKey) } } func TestUpdatePackageInfoCacheTimeout(t *testing.T) { ctx := context.Background() tmpDir, err := ioutil.TempDir("", "") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmpDir) packageInfoCacheFile = filepath.Join(tmpDir, "file.cache") packageInfoCacheStore = nil cache := packageInfoCache{} key := "IAESFQoGYnVja2V0EgZvYmplY3QYlZrvOg" info := &packages.PkgInfo{Name: "name", Arch: "arch", Version: "version"} cache[key] = packageInfo{PkgInfo: info, LastLookup: time.Now().Add(packageInfoCacheTimeout).Add(-1 * time.Hour)} data, err := json.Marshal(cache) if err != nil { t.Fatal(err) } if err := ioutil.WriteFile(packageInfoCacheFile, data, 0644); err != nil { t.Fatal(err) } updatePackageInfoCache(ctx, nil, nil) if _, ok := packageInfoCacheStore[key]; ok { t.Errorf("Cache should not contain expired data, cache: %+v", packageInfoCacheStore) } } osconfig-20250416.02/config/repository_resource.go000066400000000000000000000261521477773331400217560ustar00rootroot00000000000000// Copyright 2020 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package config import ( "bytes" "context" "errors" "fmt" "io" "io/ioutil" "net/http" "os" "path/filepath" "github.com/GoogleCloudPlatform/osconfig/agentconfig" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/packages" "github.com/GoogleCloudPlatform/osconfig/util" "golang.org/x/crypto/openpgp" "golang.org/x/crypto/openpgp/armor" "cloud.google.com/go/osconfig/agentendpoint/apiv1/agentendpointpb" ) const aptGPGDir = "/etc/apt/trusted.gpg.d" type repositoryResource struct { *agentendpointpb.OSPolicy_Resource_RepositoryResource managedRepository ManagedRepository } // AptRepository describes an apt repository resource. type AptRepository struct { RepositoryResource *agentendpointpb.OSPolicy_Resource_RepositoryResource_AptRepository GpgFilePath string GpgChecksum string GpgFileContents []byte } // GooGetRepository describes an googet repository resource. type GooGetRepository struct { RepositoryResource *agentendpointpb.OSPolicy_Resource_RepositoryResource_GooRepository } // YumRepository describes an yum repository resource. type YumRepository struct { RepositoryResource *agentendpointpb.OSPolicy_Resource_RepositoryResource_YumRepository } // ZypperRepository describes an zypper repository resource. type ZypperRepository struct { RepositoryResource *agentendpointpb.OSPolicy_Resource_RepositoryResource_ZypperRepository } // ManagedRepository is the repository that this RepositoryResource manages. type ManagedRepository struct { Apt *AptRepository GooGet *GooGetRepository Yum *YumRepository Zypper *ZypperRepository RepoFilePath string RepoChecksum string RepoFileContents []byte } func aptRepoContents(repo *agentendpointpb.OSPolicy_Resource_RepositoryResource_AptRepository) []byte { var debArchiveTypeMap = map[agentendpointpb.OSPolicy_Resource_RepositoryResource_AptRepository_ArchiveType]string{ agentendpointpb.OSPolicy_Resource_RepositoryResource_AptRepository_DEB: "deb", agentendpointpb.OSPolicy_Resource_RepositoryResource_AptRepository_DEB_SRC: "deb-src", } /* # Repo file managed by Google OSConfig agent deb http://repo1-url/ repo main */ var buf bytes.Buffer buf.WriteString("# Repo file managed by Google OSConfig agent\n") archiveType, ok := debArchiveTypeMap[repo.GetArchiveType()] if !ok { archiveType = "deb" } line := fmt.Sprintf("%s %s %s", archiveType, repo.GetUri(), repo.GetDistribution()) for _, c := range repo.GetComponents() { line = fmt.Sprintf("%s %s", line, c) } buf.WriteString(line + "\n") return buf.Bytes() } func googetRepoContents(repo *agentendpointpb.OSPolicy_Resource_RepositoryResource_GooRepository) []byte { /* # Repo file managed by Google OSConfig agent - name: repo1-name url: https://repo1-url */ var buf bytes.Buffer buf.WriteString("# Repo file managed by Google OSConfig agent\n") buf.WriteString(fmt.Sprintf("- name: %s\n", repo.Name)) buf.WriteString(fmt.Sprintf(" url: %s\n", repo.Url)) return buf.Bytes() } func yumRepoContents(repo *agentendpointpb.OSPolicy_Resource_RepositoryResource_YumRepository) []byte { /* # Repo file managed by Google OSConfig agent [Id] name=DisplayName baseurl=https://repo-url enabled=1 gpgcheck=1 gpgkey=http://repo-url/gpg1 http://repo-url/gpg2 */ var buf bytes.Buffer buf.WriteString("# Repo file managed by Google OSConfig agent\n") buf.WriteString(fmt.Sprintf("[%s]\n", repo.Id)) if repo.DisplayName == "" { buf.WriteString(fmt.Sprintf("name=%s\n", repo.Id)) } else { buf.WriteString(fmt.Sprintf("name=%s\n", repo.DisplayName)) } buf.WriteString(fmt.Sprintf("baseurl=%s\n", repo.BaseUrl)) buf.WriteString("enabled=1\ngpgcheck=1\n") if len(repo.GpgKeys) > 0 { buf.WriteString(fmt.Sprintf("gpgkey=%s\n", repo.GpgKeys[0])) for _, k := range repo.GpgKeys[1:] { buf.WriteString(fmt.Sprintf(" %s\n", k)) } } return buf.Bytes() } func zypperRepoContents(repo *agentendpointpb.OSPolicy_Resource_RepositoryResource_ZypperRepository) []byte { /* # Repo file managed by Google OSConfig agent [Id] name=DisplayName baseurl=https://repo-url enabled=1 gpgkey=https://repo-url/gpg1 https://repo-url/gpg2 */ var buf bytes.Buffer buf.WriteString("# Repo file managed by Google OSConfig agent\n") buf.WriteString(fmt.Sprintf("[%s]\n", repo.Id)) if repo.DisplayName == "" { buf.WriteString(fmt.Sprintf("name=%s\n", repo.Id)) } else { buf.WriteString(fmt.Sprintf("name=%s\n", repo.DisplayName)) } buf.WriteString(fmt.Sprintf("baseurl=%s\n", repo.BaseUrl)) buf.WriteString("enabled=1\n") if len(repo.GpgKeys) > 0 { buf.WriteString(fmt.Sprintf("gpgkey=%s\n", repo.GpgKeys[0])) for _, k := range repo.GpgKeys[1:] { buf.WriteString(fmt.Sprintf(" %s\n", k)) } } return buf.Bytes() } func serializeGPGKeyEntity(entityList openpgp.EntityList) ([]byte, error) { var buf bytes.Buffer for _, entity := range entityList { if err := entity.Serialize(&buf); err != nil { return nil, fmt.Errorf("error serializing gpg key: %v", err) } } return buf.Bytes(), nil } func isArmoredGPGKey(keyData []byte) bool { var buf bytes.Buffer tee := io.TeeReader(bytes.NewReader(keyData), &buf) // Try decoding as armored decodedBlock, err := armor.Decode(tee) if err == nil && decodedBlock != nil { return true } return false } func fetchGPGKey(key string) (openpgp.EntityList, error) { resp, err := http.Get(key) if err != nil { return nil, err } defer resp.Body.Close() if resp.ContentLength > 1024*1024 { return nil, fmt.Errorf("key size of %d too large", resp.ContentLength) } responseBody, err := io.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("can not read response body for key %s, err: %v", key, err) } if isArmoredGPGKey(responseBody) { return openpgp.ReadArmoredKeyRing(bytes.NewBuffer(responseBody)) } return openpgp.ReadKeyRing(bytes.NewReader(responseBody)) } func (r *repositoryResource) validate(ctx context.Context) (*ManagedResources, error) { var repoFormat string switch r.GetRepository().(type) { case *agentendpointpb.OSPolicy_Resource_RepositoryResource_Apt: if !packages.AptExists { return nil, errors.New("cannot manage Apt repository because apt-get does not exist on the system") } gpgkey := r.GetApt().GetGpgKey() r.managedRepository.Apt = &AptRepository{RepositoryResource: r.GetApt()} r.managedRepository.RepoFileContents = aptRepoContents(r.GetApt()) repoFormat = agentconfig.AptRepoFormat() if gpgkey != "" { entityList, err := fetchGPGKey(gpgkey) if err != nil { return nil, fmt.Errorf("error fetching apt gpg key %q: %v", gpgkey, err) } keyContents, err := serializeGPGKeyEntity(entityList) if err != nil { return nil, fmt.Errorf("error fetching apt gpg key %q: %v", gpgkey, err) } r.managedRepository.Apt.GpgFileContents = keyContents r.managedRepository.Apt.GpgChecksum = checksum(bytes.NewReader(keyContents)) r.managedRepository.Apt.GpgFilePath = filepath.Join(aptGPGDir, "osconfig_added_"+r.managedRepository.Apt.GpgChecksum+".gpg") } case *agentendpointpb.OSPolicy_Resource_RepositoryResource_Goo: if !packages.GooGetExists { return nil, errors.New("cannot manage googet repository because googet does not exist on the system") } r.managedRepository.GooGet = &GooGetRepository{RepositoryResource: r.GetGoo()} r.managedRepository.RepoFileContents = googetRepoContents(r.GetGoo()) repoFormat = agentconfig.GooGetRepoFormat() case *agentendpointpb.OSPolicy_Resource_RepositoryResource_Yum: if !packages.YumExists { return nil, errors.New("cannot manage yum repository because yum does not exist on the system") } r.managedRepository.Yum = &YumRepository{RepositoryResource: r.GetYum()} r.managedRepository.RepoFileContents = yumRepoContents(r.GetYum()) repoFormat = agentconfig.YumRepoFormat() case *agentendpointpb.OSPolicy_Resource_RepositoryResource_Zypper: if !packages.ZypperExists { return nil, errors.New("cannot manage zypper repository because zypper does not exist on the system") } r.managedRepository.Zypper = &ZypperRepository{RepositoryResource: r.GetZypper()} r.managedRepository.RepoFileContents = zypperRepoContents(r.GetZypper()) repoFormat = agentconfig.ZypperRepoFormat() default: return nil, fmt.Errorf("Repository field not set or references unknown repository type: %v", r.GetRepository()) } r.managedRepository.RepoChecksum = checksum(bytes.NewReader(r.managedRepository.RepoFileContents)) r.managedRepository.RepoFilePath = fmt.Sprintf(repoFormat, r.managedRepository.RepoChecksum[:10]) return &ManagedResources{Repositories: []ManagedRepository{r.managedRepository}}, nil } func contentsMatch(ctx context.Context, path, chksum string) (bool, error) { file, err := os.OpenFile(path, os.O_RDONLY, 0644) if err != nil { if os.IsNotExist(err) { clog.Debugf(ctx, "File not found: %s", path) return false, nil } clog.Debugf(ctx, "Error opening file %s.", path) return false, err } defer file.Close() actualChecksum := checksum(file) if actualChecksum != chksum { clog.Debugf(ctx, "Checksums don't match, got: %s, actual: %s", chksum, actualChecksum) return false, nil } return true, nil } func (r *repositoryResource) checkState(ctx context.Context) (inDesiredState bool, err error) { // Check APT gpg key if applicable. if r.managedRepository.Apt != nil && r.managedRepository.Apt.GpgFileContents != nil { match, err := contentsMatch(ctx, r.managedRepository.Apt.GpgFilePath, r.managedRepository.Apt.GpgChecksum) if err != nil { return false, err } if !match { return false, nil } } return contentsMatch(ctx, r.managedRepository.RepoFilePath, r.managedRepository.RepoChecksum) } func (r *repositoryResource) enforceState(ctx context.Context) (inDesiredState bool, err error) { clog.Infof(ctx, "Enforcing repo %s.", r.managedRepository.RepoFilePath) // Set APT gpg key if applicable. if r.managedRepository.Apt != nil && r.managedRepository.Apt.GpgFileContents != nil { if err := ioutil.WriteFile(r.managedRepository.Apt.GpgFilePath, r.managedRepository.Apt.GpgFileContents, 0644); err != nil { return false, err } } if err := os.MkdirAll(filepath.Dir(r.managedRepository.RepoFilePath), 0755); err != nil { return false, err } if err := util.AtomicWrite(r.managedRepository.RepoFilePath, r.managedRepository.RepoFileContents, 0644); err != nil { return false, err } return true, nil } func (r *repositoryResource) populateOutput(rCompliance *agentendpointpb.OSPolicyResourceCompliance) { } func (r *repositoryResource) cleanup(ctx context.Context) error { return nil } osconfig-20250416.02/config/repository_resource_test.go000066400000000000000000000221201477773331400230040ustar00rootroot00000000000000// Copyright 2020 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package config import ( "context" "io/ioutil" "os" "path/filepath" "strings" "testing" "github.com/google/go-cmp/cmp" "google.golang.org/protobuf/testing/protocmp" "cloud.google.com/go/osconfig/agentendpoint/apiv1/agentendpointpb" ) var ( aptRepositoryResource = &agentendpointpb.OSPolicy_Resource_RepositoryResource_AptRepository{ ArchiveType: agentendpointpb.OSPolicy_Resource_RepositoryResource_AptRepository_DEB, Uri: "uri", Distribution: "distribution", Components: []string{"c1", "c2"}, } gooRepositoryResource = &agentendpointpb.OSPolicy_Resource_RepositoryResource_GooRepository{ Name: "name", Url: "url", } yumRepositoryResource = &agentendpointpb.OSPolicy_Resource_RepositoryResource_YumRepository{ Id: "id", DisplayName: "displayname", BaseUrl: "baseurl", GpgKeys: []string{"key1", "key2"}, } zypperRepositoryResource = &agentendpointpb.OSPolicy_Resource_RepositoryResource_ZypperRepository{ Id: "id", DisplayName: "displayname", BaseUrl: "baseurl", GpgKeys: []string{"key1", "key2"}, } ) func TestRepositoryResourceValidate(t *testing.T) { ctx := context.Background() var tests = []struct { name string rrpb *agentendpointpb.OSPolicy_Resource_RepositoryResource wantMR ManagedRepository }{ { "Apt", &agentendpointpb.OSPolicy_Resource_RepositoryResource{ Repository: &agentendpointpb.OSPolicy_Resource_RepositoryResource_Apt{ Apt: aptRepositoryResource, }, }, ManagedRepository{ Apt: &AptRepository{ RepositoryResource: aptRepositoryResource, }, RepoChecksum: "8faacd43b230b08e7a1da7b670bf6f90fcc59ade1a5e7179a0ccffc9aa3d7cdf", RepoFileContents: []byte("# Repo file managed by Google OSConfig agent\ndeb uri distribution c1 c2\n"), RepoFilePath: "/etc/apt/sources.list.d/osconfig_managed_8faacd43b2.list", }, }, { "GooGet", &agentendpointpb.OSPolicy_Resource_RepositoryResource{ Repository: &agentendpointpb.OSPolicy_Resource_RepositoryResource_Goo{ Goo: gooRepositoryResource, }, }, ManagedRepository{ GooGet: &GooGetRepository{ RepositoryResource: gooRepositoryResource, }, RepoChecksum: "76ae1ea015cd184a18434ae45e233c22f36e35faa80f495cf21f95495af3b599", RepoFileContents: []byte("# Repo file managed by Google OSConfig agent\n- name: name\n url: url\n"), RepoFilePath: "C:/ProgramData/GooGet/repos/osconfig_managed_76ae1ea015.repo", }, }, { "Yum", &agentendpointpb.OSPolicy_Resource_RepositoryResource{ Repository: &agentendpointpb.OSPolicy_Resource_RepositoryResource_Yum{ Yum: yumRepositoryResource, }, }, ManagedRepository{ Yum: &YumRepository{ RepositoryResource: yumRepositoryResource, }, RepoChecksum: "c588551e69834e5f2f4d825324b2add5df3064af7d5d68021e83a308c6f62048", RepoFileContents: []byte("# Repo file managed by Google OSConfig agent\n[id]\nname=displayname\nbaseurl=baseurl\nenabled=1\ngpgcheck=1\ngpgkey=key1\n key2\n"), RepoFilePath: "/etc/yum.repos.d/osconfig_managed_c588551e69.repo", }, }, { "Zypper", &agentendpointpb.OSPolicy_Resource_RepositoryResource{ Repository: &agentendpointpb.OSPolicy_Resource_RepositoryResource_Zypper{ Zypper: zypperRepositoryResource, }, }, ManagedRepository{ Zypper: &ZypperRepository{ RepositoryResource: zypperRepositoryResource, }, RepoChecksum: "415a52ad70e5118cd797882d5f421b0a8d84bfe1e35cd53e8dcac486bc93186d", RepoFileContents: []byte("# Repo file managed by Google OSConfig agent\n[id]\nname=displayname\nbaseurl=baseurl\nenabled=1\ngpgkey=key1\n key2\n"), RepoFilePath: "/etc/zypp/repos.d/osconfig_managed_415a52ad70.repo", }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { pr := &OSPolicyResource{ OSPolicy_Resource: &agentendpointpb.OSPolicy_Resource{ ResourceType: &agentendpointpb.OSPolicy_Resource_Repository{Repository: tt.rrpb}, }, } if err := pr.Validate(ctx); err != nil { t.Fatalf("Unexpected error: %v", err) } if diff := cmp.Diff(pr.ManagedResources(), &ManagedResources{Repositories: []ManagedRepository{tt.wantMR}}, protocmp.Transform()); diff != "" { t.Errorf("OSPolicyResource does not match expectation: (-got +want)\n%s", diff) } if diff := cmp.Diff(pr.resource.(*repositoryResource).managedRepository, tt.wantMR, protocmp.Transform()); diff != "" { t.Errorf("packageResouce does not match expectation: (-got +want)\n%s", diff) } }) } } func TestRepositoryResourceCheckState(t *testing.T) { ctx := context.Background() var tests = []struct { name string rrpb *agentendpointpb.OSPolicy_Resource_RepositoryResource contents []byte wantInDesiredState bool }{ { "Matches", &agentendpointpb.OSPolicy_Resource_RepositoryResource{ Repository: &agentendpointpb.OSPolicy_Resource_RepositoryResource_Apt{ Apt: aptRepositoryResource, }, }, []byte("# Repo file managed by Google OSConfig agent\ndeb uri distribution c1 c2\n"), true, }, { "DoesNotMatch", &agentendpointpb.OSPolicy_Resource_RepositoryResource{ Repository: &agentendpointpb.OSPolicy_Resource_RepositoryResource_Apt{ Apt: aptRepositoryResource, }, }, []byte("# Repo file managed by Google OSConfig agent\nsome other repo\n"), false, }, { "NoRepoFile", &agentendpointpb.OSPolicy_Resource_RepositoryResource{ Repository: &agentendpointpb.OSPolicy_Resource_RepositoryResource_Apt{ Apt: aptRepositoryResource, }, }, nil, false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { pr := &OSPolicyResource{ OSPolicy_Resource: &agentendpointpb.OSPolicy_Resource{ ResourceType: &agentendpointpb.OSPolicy_Resource_Repository{Repository: tt.rrpb}, }, } if err := pr.Validate(ctx); err != nil { t.Fatalf("Unexpected Validate error: %v", err) } dir, err := ioutil.TempDir("", "") if err != nil { t.Fatal(err) } defer os.Remove(dir) path := filepath.Join(dir, "repo") if tt.contents != nil { if err := ioutil.WriteFile(path, tt.contents, 0755); err != nil { t.Fatal(err) } } pr.resource.(*repositoryResource).managedRepository.RepoFilePath = path if err := pr.CheckState(ctx); err != nil { t.Fatalf("Unexpected CheckState error: %v", err) } if tt.wantInDesiredState != pr.InDesiredState() { t.Fatalf("Unexpected InDesiredState, want: %t, got: %t", tt.wantInDesiredState, pr.InDesiredState()) } }) } } func TestRepositoryResourceEnforceState(t *testing.T) { ctx := context.Background() dir, err := ioutil.TempDir("", "") if err != nil { t.Fatal(err) } defer os.Remove(dir) path := filepath.Join(dir, "repo") if err := ioutil.WriteFile(path, []byte("foo"), 0755); err != nil { t.Fatal(err) } rrpb := &agentendpointpb.OSPolicy_Resource_RepositoryResource{ Repository: &agentendpointpb.OSPolicy_Resource_RepositoryResource_Apt{ Apt: aptRepositoryResource, }, } for _, tt := range []struct { name string path string }{ { "FileExists", path, }, { "FileDNE", filepath.Join(dir, "some/other/dir/repo"), }, } { t.Run(tt.name, func(t *testing.T) { pr := &OSPolicyResource{ OSPolicy_Resource: &agentendpointpb.OSPolicy_Resource{ ResourceType: &agentendpointpb.OSPolicy_Resource_Repository{Repository: rrpb}, }, } if err := pr.Validate(ctx); err != nil { t.Fatalf("Unexpected Validate error: %v", err) } pr.resource.(*repositoryResource).managedRepository.RepoFilePath = tt.path if err := pr.EnforceState(ctx); err != nil { t.Fatalf("Unexpected EnforceState error: %v", err) } match, err := contentsMatch(ctx, pr.resource.(*repositoryResource).managedRepository.RepoFilePath, pr.resource.(*repositoryResource).managedRepository.RepoChecksum) if err != nil { t.Fatal(err) } if !match { t.Fatal("Repo file contents do not match after enforcement") } }) } } func TestFetchGPGKey(t *testing.T) { key := "https://packages.cloud.google.com/apt/doc/apt-key.gpg" entityList, err := fetchGPGKey(key) if err != nil { t.Fatal(err) } // check if Artifact Regitry key exist or not artifactRegistryKeyFound := false for _, e := range entityList { for key := range e.Identities { if strings.Contains(key, "Artifact Registry") { artifactRegistryKeyFound = true } } } if !artifactRegistryKeyFound { t.Errorf("Expected to find Artifact Registry key in Google Cloud Public GPG key, but its missed.") } } osconfig-20250416.02/e2e_tests/000077500000000000000000000000001477773331400157235ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/Dockerfile000066400000000000000000000017521477773331400177220ustar00rootroot00000000000000# Copyright 2018 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # We use this image just for ca-certificates.crt FROM golang:alpine COPY . /source WORKDIR /source RUN go mod download && CGO_ENABLED=0 go build -o /e2e_tests main.go RUN chmod +x /e2e_tests FROM gcr.io/compute-image-tools-test/wrapper:latest COPY --from=0 /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt COPY --from=0 /e2e_tests e2e_tests ENTRYPOINT ["./wrapper", "./e2e_tests"] osconfig-20250416.02/e2e_tests/cloudbuild.yaml000066400000000000000000000004441477773331400207370ustar00rootroot00000000000000steps: - name: 'gcr.io/cloud-builders/docker' args: ['build', '--tag=gcr.io/$PROJECT_ID/osconfig-tests:latest', '--tag=gcr.io/$PROJECT_ID/osconfig-tests:$COMMIT_SHA', './e2e_tests'] images: - 'gcr.io/$PROJECT_ID/osconfig-tests:latest' - 'gcr.io/$PROJECT_ID/osconfig-tests:$COMMIT_SHA' osconfig-20250416.02/e2e_tests/compute/000077500000000000000000000000001477773331400173775ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/compute/instance.go000066400000000000000000000144511477773331400215370ustar00rootroot00000000000000// Copyright 2018 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package compute contains wrappers around the GCE compute API. package compute import ( "context" "fmt" "net/http" "os" "path" "regexp" "strings" "time" daisyCompute "github.com/GoogleCloudPlatform/compute-image-tools/daisy/compute" computeApiBeta "google.golang.org/api/compute/v0.beta" computeApi "google.golang.org/api/compute/v1" "google.golang.org/api/googleapi" ) // Instance is a compute instance. type Instance struct { *computeApi.Instance client daisyCompute.Client Project, Zone string } // Cleanup deletes the Instance. func (i *Instance) Cleanup() { if err := i.client.DeleteInstance(i.Project, i.Zone, i.Name); err != nil { fmt.Printf("Error deleting instance: %v\n", err) } } // WaitForGuestAttributes waits for guest attribute (queryPath, variableKey) to appear. func (i *Instance) WaitForGuestAttributes(queryPath string, interval, timeout time.Duration) ([]*computeApiBeta.GuestAttributesEntry, error) { tick := time.Tick(interval) timedout := time.After(timeout) for { select { case <-timedout: return nil, fmt.Errorf("timed out waiting for guest attribute %q", queryPath) case <-tick: attr, err := i.GetGuestAttributes(queryPath) if err != nil { apiErr, ok := err.(*googleapi.Error) if ok && apiErr.Code == http.StatusNotFound { continue } return nil, err } return attr, nil } } } // GetGuestAttributes gets guest attributes for an instance. func (i *Instance) GetGuestAttributes(queryPath string) ([]*computeApiBeta.GuestAttributesEntry, error) { resp, err := i.client.GetGuestAttributes(i.Project, i.Zone, i.Name, queryPath, "") if err != nil { return nil, err } if resp.QueryValue == nil { return nil, nil } return resp.QueryValue.Items, nil } // AddMetadata adds metadata to the instance. func (i *Instance) AddMetadata(mdi ...*computeApi.MetadataItems) error { resp, err := i.client.GetInstance(i.Project, i.Zone, i.Name) if err != nil { return err } for _, old := range resp.Metadata.Items { found := false for _, new := range mdi { if old.Key == new.Key { found = true break } } if found { continue } mdi = append(mdi, old) } resp.Metadata.Items = mdi return i.client.SetInstanceMetadata(i.Project, i.Zone, i.Name, resp.Metadata) } // WaitForSerialOutput waits for all positive regex matches and reports error for any negative regex match on a serial port. func (i *Instance) WaitForSerialOutput(positiveRegexes []*regexp.Regexp, negativeRegexes []*regexp.Regexp, port int64, interval, timeout time.Duration) error { var start int64 var errs int matches := make([]bool, len(positiveRegexes)) tick := time.Tick(interval) timedout := time.After(timeout) for { select { case <-timedout: var patterns []string for _, regex := range positiveRegexes { patterns = append(patterns, regex.String()) } return fmt.Errorf("timed out waiting for regexes [%s]", strings.Join(patterns, ",")) case <-tick: resp, err := i.client.GetSerialPortOutput(i.Project, i.Zone, i.Name, port, start) if err != nil { status, sErr := i.client.InstanceStatus(i.Project, i.Zone, i.Name) if sErr != nil { err = fmt.Errorf("%v, error getting InstanceStatus: %v", err, sErr) } else { err = fmt.Errorf("%v, InstanceStatus: %q", err, status) } // Wait until machine restarts to evaluate SerialOutput. if isTerminal(status) { continue } // Retry up to 3 times in a row on any error if we successfully got InstanceStatus. if errs < 3 { errs++ continue } return err } start = resp.Next for _, ln := range strings.Split(resp.Contents, "\n") { for _, regex := range negativeRegexes { if regex.MatchString(ln) { return fmt.Errorf("matched negative regexes [%s]", regex) } } for i, regex := range positiveRegexes { if regex.MatchString(ln) { matches[i] = true } } matched := 0 for _, match := range matches { if match { matched++ } } if matched == len(positiveRegexes) { return nil } } errs = 0 } } } // RecordSerialOutput stores the serial output of an instance to GCS bucket func (i *Instance) RecordSerialOutput(ctx context.Context, logsPath string, port int64) { os.MkdirAll(logsPath, 0770) f, err := os.Create(path.Join(logsPath, fmt.Sprintf("%s-serial-port%d.log", i.Name, port))) if err != nil { fmt.Printf("Instance %q: error creating serial log file: %s", i.Name, err) } resp, err := i.client.GetSerialPortOutput(path.Base(i.Project), path.Base(i.Zone), i.Name, port, 0) if err != nil { // Instance is stopped or stopping. status, _ := i.client.InstanceStatus(path.Base(i.Project), path.Base(i.Zone), i.Name) if !isTerminal(status) { fmt.Printf("Instance %q: error getting serial port: %s", i.Name, err) } return } if _, err := f.Write([]byte(resp.Contents)); err != nil { fmt.Printf("Instance %q: error writing serial log file: %s", i.Name, err) } if err := f.Close(); err != nil { fmt.Printf("Instance %q: error closing serial log file: %s", i.Name, err) } } func isTerminal(status string) bool { return status == "TERMINATED" || status == "STOPPED" || status == "STOPPING" } // CreateInstance creates a compute instance. func CreateInstance(client daisyCompute.Client, project, zone string, i *computeApi.Instance) (*Instance, error) { if err := client.CreateInstance(project, zone, i); err != nil { return nil, err } return &Instance{Instance: i, client: client, Project: project, Zone: zone}, nil } // BuildInstanceMetadataItem create an metadata item func BuildInstanceMetadataItem(key, value string) *computeApi.MetadataItems { return &computeApi.MetadataItems{ Key: key, Value: func() *string { v := value; return &v }(), } } osconfig-20250416.02/e2e_tests/config/000077500000000000000000000000001477773331400171705ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/config/config.go000066400000000000000000000100211477773331400207560ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package config import ( "encoding/json" "flag" "fmt" "math" "os" "regexp" "strings" "time" ) var ( agentEndpoint = flag.String("agent_endpoint", "", "API endpoint to use for the agent to use for the tests") endpoint = flag.String("endpoint", "osconfig.googleapis.com:443", "API endpoint to use for the tests") oauthDefault = flag.String("local_oauth", "", "path to service creds file") agentRepo = flag.String("agent_repo", "", "repo to pull agent from (unstable, staging, or stable, leave blank for no agent install)") bucketDefault = "osconfig-agent-end2end-tests" logPushIntervalDefault = 3 * time.Second logsPath = fmt.Sprintf("logs-%s", time.Now().Format("2006-01-02-15:04:05")) testSuiteRegex *regexp.Regexp testSuiteFilter = flag.String("test_suite_filter", "", "test suite filter") testCaseRegex *regexp.Regexp testCaseFilter = flag.String("test_case_filter", "", "test case filter") zones map[string]int testZone = flag.String("test_zone", "", "test zone") testZones = flag.String("test_zones", "{}", "test zones") projects []string testProjectIDs = flag.String("test_project_ids", "", "test project ids") // OutDir is the out directory to use. OutDir = flag.String("out_dir", "/tmp", "artifact directory") ) func init() { flag.Parse() if *testSuiteFilter != "" { var err error testSuiteRegex, err = regexp.Compile(*testSuiteFilter) if err != nil { fmt.Println("-test_suite_filter flag not valid:", err) os.Exit(1) } } if *testCaseFilter != "" { var err error testCaseRegex, err = regexp.Compile(*testCaseFilter) if err != nil { fmt.Println("-test_case_filter flag not valid:", err) os.Exit(1) } } if len(strings.TrimSpace(*testProjectIDs)) == 0 { fmt.Println("-test_project_ids must be specified") os.Exit(1) } projects = strings.Split(*testProjectIDs, ",") zones = make(map[string]int) if len(strings.TrimSpace(*testZone)) != 0 { zones[*testZone] = math.MaxInt32 } else { err := json.Unmarshal([]byte(*testZones), &zones) if err != nil { fmt.Printf("Error parsing zones `%s`\n", *testZones) os.Exit(1) } } if len(zones) == 0 { fmt.Println("Error, no zones specified") os.Exit(1) } } // Projects are the projects to use. func Projects() []string { return projects } // Zones are the zones and associated quota to use. func Zones() map[string]int { return zones } // TestSuiteFilter is the test suite filter regex. func TestSuiteFilter() *regexp.Regexp { return testSuiteRegex } // TestCaseFilter is the test case filter regex. func TestCaseFilter() *regexp.Regexp { return testCaseRegex } // AgentRepo returns the agentRepo func AgentRepo() string { return *agentRepo } // AgentSvcEndpoint returns the agentEndpoint func AgentSvcEndpoint() string { return *agentEndpoint } // SvcEndpoint returns the endpoint func SvcEndpoint() string { return *endpoint } // OauthPath returns the oauthPath file path func OauthPath() string { return *oauthDefault } // LogBucket returns the oauthPath file path func LogBucket() string { return bucketDefault } // LogsPath returns the oauthPath file path func LogsPath() string { return logsPath } // LogPushInterval returns the interval at which the serial console logs are written to GCS func LogPushInterval() time.Duration { return logPushIntervalDefault } osconfig-20250416.02/e2e_tests/gcp_clients/000077500000000000000000000000001477773331400202155ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/gcp_clients/gcp_clients.go000066400000000000000000000055221477773331400230420ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package gcpclients import ( "context" "fmt" osconfigV1beta "cloud.google.com/go/osconfig/apiv1beta" "github.com/GoogleCloudPlatform/compute-image-tools/daisy/compute" "github.com/GoogleCloudPlatform/osconfig/e2e_tests/config" osconfigV1 "github.com/GoogleCloudPlatform/osconfig/e2e_tests/internal/cloud.google.com/go/osconfig/apiv1" "google.golang.org/api/option" ) var ( computeClient compute.Client osconfigClientV1beta *osconfigV1beta.Client osconfigZonalClientV1 *osconfigV1.OsConfigZonalClient ) // PopulateClients populates the GCP clients. func PopulateClients(ctx context.Context) error { if err := createComputeClient(ctx); err != nil { return err } if err := createOsConfigClientV1(ctx); err != nil { return err } return createOsConfigClientV1beta(ctx) } func createComputeClient(ctx context.Context) error { var err error computeClient, err = compute.NewClient(ctx, option.WithCredentialsFile(config.OauthPath())) return err } func createOsConfigClientV1beta(ctx context.Context) error { var err error osconfigClientV1beta, err = osconfigV1beta.NewClient(ctx, option.WithCredentialsFile(config.OauthPath()), option.WithEndpoint(config.SvcEndpoint())) return err } func createOsConfigClientV1(ctx context.Context) error { var err error osconfigZonalClientV1, err = osconfigV1.NewOsConfigZonalClient(ctx, option.WithCredentialsFile(config.OauthPath()), option.WithEndpoint(config.SvcEndpoint())) return err } // GetComputeClient returns a singleton GCP client for osconfig tests func GetComputeClient() (compute.Client, error) { if computeClient == nil { return nil, fmt.Errorf("compute client was not initialized") } return computeClient, nil } // GetOsConfigClientV1beta returns a singleton GCP client for osconfig tests func GetOsConfigClientV1beta() (*osconfigV1beta.Client, error) { if osconfigClientV1beta == nil { return nil, fmt.Errorf("v1beta osconfig client was not initialized") } return osconfigClientV1beta, nil } // GetOsConfigClientV1 returns a singleton GCP client for osconfig tests func GetOsConfigClientV1() (*osconfigV1.OsConfigZonalClient, error) { if osconfigZonalClientV1 == nil { return nil, fmt.Errorf("v1 osconfig client was not initialized") } return osconfigZonalClientV1, nil } osconfig-20250416.02/e2e_tests/go.mod000066400000000000000000000017121477773331400170320ustar00rootroot00000000000000module github.com/GoogleCloudPlatform/osconfig/e2e_tests go 1.13 require ( cloud.google.com/go/longrunning v0.4.1 cloud.google.com/go/osconfig v1.11.0 github.com/GoogleCloudPlatform/compute-image-tools/daisy v0.0.0-20210719160539-19df456994a5 github.com/GoogleCloudPlatform/compute-image-tools/go/e2e_test_utils v0.0.0-20210719160539-19df456994a5 github.com/GoogleCloudPlatform/guest-logging-go v0.0.0-20210621170517-facc9c0d81b9 github.com/GoogleCloudPlatform/osconfig v0.0.0-20211102225806-9b40a0ba0ce2 github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 github.com/google/go-cmp v0.5.9 github.com/googleapis/gax-go/v2 v2.7.1 github.com/kylelemons/godebug v1.1.0 go.chromium.org/luci v0.0.0-20210524194916-901fa619ed56 // indirect google.golang.org/api v0.114.0 google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 google.golang.org/grpc v1.56.3 google.golang.org/protobuf v1.33.0 ) osconfig-20250416.02/e2e_tests/go.sum000066400000000000000000005166101477773331400170670ustar00rootroot00000000000000cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.47.0/go.mod h1:5p3Ky/7f3N10VBkhuR5LFtddroTiMyjZV/Kj5qOQFxU= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go v0.55.0/go.mod h1:ZHmoY+/lIMNkN2+fBmuTiqZ4inFhvQad8ft7MT8IV5Y= cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.60.0/go.mod h1:yw2G51M9IfRboUH61Us8GqCeF1PzPblB823Mn2q2eAU= cloud.google.com/go v0.61.0/go.mod h1:XukKJg4Y7QsUu0Hxg3qQKUWR4VuWivmyMK2+rUyxAqw= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= cloud.google.com/go v0.95.0/go.mod h1:MzZUAH870Y7E+c14j23Ir66FC1+PK8WLG7OG4SjP+0k= cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E= cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o= cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE= cloud.google.com/go/accesscontextmanager v1.6.0/go.mod h1:8XCvZWfYw3K/ji0iVnp+6pu7huxoQTLmxAbVjbloTtM= cloud.google.com/go/accesscontextmanager v1.7.0/go.mod h1:CEGLewx8dwa33aDAZQujl7Dx+uYhS0eay198wB/VumQ= cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= cloud.google.com/go/aiplatform v1.35.0/go.mod h1:7MFT/vCaOyZT/4IIFfxH4ErVg/4ku6lKv3w0+tFTgXQ= cloud.google.com/go/aiplatform v1.36.1/go.mod h1:WTm12vJRPARNvJ+v6P52RDHCNe4AhvjcIZ/9/RRHy/k= cloud.google.com/go/aiplatform v1.37.0/go.mod h1:IU2Cv29Lv9oCn/9LkFiiuKfwrRTq+QQMbW+hPCxJGZw= cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= cloud.google.com/go/analytics v0.17.0/go.mod h1:WXFa3WSym4IZ+JiKmavYdJwGG/CvpqiqczmL59bTD9M= cloud.google.com/go/analytics v0.18.0/go.mod h1:ZkeHGQlcIPkw0R/GW+boWHhCOR43xz9RN/jn7WcqfIE= cloud.google.com/go/analytics v0.19.0/go.mod h1:k8liqf5/HCnOUkbawNtrWWc+UAzyDlW89doe8TtoDsE= cloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk= cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= cloud.google.com/go/apigateway v1.5.0/go.mod h1:GpnZR3Q4rR7LVu5951qfXPJCHquZt02jf7xQx7kpqN8= cloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc= cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04= cloud.google.com/go/apigeeconnect v1.5.0/go.mod h1:KFaCqvBRU6idyhSNyn3vlHXc8VMDJdRmwDF6JyFRqZ8= cloud.google.com/go/apigeeregistry v0.4.0/go.mod h1:EUG4PGcsZvxOXAdyEghIdXwAEi/4MEaoqLMLDMIwKXY= cloud.google.com/go/apigeeregistry v0.5.0/go.mod h1:YR5+s0BVNZfVOUkMa5pAR2xGd0A473vA5M7j247o1wM= cloud.google.com/go/apigeeregistry v0.6.0/go.mod h1:BFNzW7yQVLZ3yj0TKcwzb8n25CFBri51GVGOEUcgQsc= cloud.google.com/go/apikeys v0.4.0/go.mod h1:XATS/yqZbaBK0HOssf+ALHp8jAlNHUgyfprvNcBIszU= cloud.google.com/go/apikeys v0.5.0/go.mod h1:5aQfwY4D+ewMMWScd3hm2en3hCj+BROlyrt3ytS7KLI= cloud.google.com/go/apikeys v0.6.0/go.mod h1:kbpXu5upyiAlGkKrJgQl8A0rKNNJ7dQ377pdroRSSi8= cloud.google.com/go/appengine v1.4.0/go.mod h1:CS2NhuBuDXM9f+qscZ6V86m1MIIqPj3WC/UoEuR1Sno= cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak= cloud.google.com/go/appengine v1.6.0/go.mod h1:hg6i0J/BD2cKmDJbaFSYHFyZkgBEfQrDg/X0V5fJn84= cloud.google.com/go/appengine v1.7.0/go.mod h1:eZqpbHFCqRGa2aCdope7eC0SWLV1j0neb/QnMJVWx6A= cloud.google.com/go/appengine v1.7.1/go.mod h1:IHLToyb/3fKutRysUlFO0BPt5j7RiQ45nrzEJmKTo6E= cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= cloud.google.com/go/area120 v0.7.0/go.mod h1:a3+8EUD1SX5RUcCs3MY5YasiO1z6yLiNLRiFrykbynY= cloud.google.com/go/area120 v0.7.1/go.mod h1:j84i4E1RboTWjKtZVWXPqvK5VHQFJRF2c1Nm69pWm9k= cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= cloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0= cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc= cloud.google.com/go/artifactregistry v1.11.1/go.mod h1:lLYghw+Itq9SONbCa1YWBoWs1nOucMH0pwXN1rOBZFI= cloud.google.com/go/artifactregistry v1.11.2/go.mod h1:nLZns771ZGAwVLzTX/7Al6R9ehma4WUEhZGWV6CeQNQ= cloud.google.com/go/artifactregistry v1.12.0/go.mod h1:o6P3MIvtzTOnmvGagO9v/rOjjA0HmhJ+/6KAXrmYDCI= cloud.google.com/go/artifactregistry v1.13.0/go.mod h1:uy/LNfoOIivepGhooAUpL1i30Hgee3Cu0l4VTWHUC08= cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= cloud.google.com/go/asset v1.9.0/go.mod h1:83MOE6jEJBMqFKadM9NLRcs80Gdw76qGuHn8m3h8oHQ= cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY= cloud.google.com/go/asset v1.11.1/go.mod h1:fSwLhbRvC9p9CXQHJ3BgFeQNM4c9x10lqlrdEUYXlJo= cloud.google.com/go/asset v1.12.0/go.mod h1:h9/sFOa4eDIyKmH6QMpm4eUK3pDojWnUhTgJlk762Hg= cloud.google.com/go/asset v1.13.0/go.mod h1:WQAMyYek/b7NBpYq/K4KJWcRqzoalEsxz/t/dTk4THw= cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo= cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= cloud.google.com/go/assuredworkloads v1.10.0/go.mod h1:kwdUQuXcedVdsIaKgKTp9t0UJkE5+PAVNhdQm4ZVq2E= cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8= cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM= cloud.google.com/go/automl v1.12.0/go.mod h1:tWDcHDp86aMIuHmyvjuKeeHEGq76lD7ZqfGLN6B0NuU= cloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc= cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= cloud.google.com/go/baremetalsolution v0.5.0/go.mod h1:dXGxEkmR9BMwxhzBhV0AioD0ULBmuLZI8CdwalUxuss= cloud.google.com/go/batch v0.3.0/go.mod h1:TR18ZoAekj1GuirsUsR1ZTKN3FC/4UDnScjT8NXImFE= cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE= cloud.google.com/go/batch v0.7.0/go.mod h1:vLZN95s6teRUqRQ4s3RLDsH8PvboqBK+rn1oevL159g= cloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckmnSFS+xwTfm4= cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8= cloud.google.com/go/beyondcorp v0.4.0/go.mod h1:3ApA0mbhHx6YImmuubf5pyW8srKnCEPON32/5hj+RmM= cloud.google.com/go/beyondcorp v0.5.0/go.mod h1:uFqj9X+dSfrheVp7ssLTaRHd2EHqSL4QZmH4e8WXGGU= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.1.0/go.mod h1:g4RsfUkOvV3Vi5yRujQETpqwCN0F+faPZ2/ykNYfBJc= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= cloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw= cloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc= cloud.google.com/go/bigquery v1.47.0/go.mod h1:sA9XOgy0A8vQK9+MWhEQTY6Tix87M/ZurWFIxmF9I/E= cloud.google.com/go/bigquery v1.48.0/go.mod h1:QAwSz+ipNgfL5jxiaK7weyOhzdoAy1zFm0Nf1fysJac= cloud.google.com/go/bigquery v1.49.0/go.mod h1:Sv8hMmTFFYBlt/ftw2uN6dFdQPzBlREY9yBh7Oy7/4Q= cloud.google.com/go/bigquery v1.50.0/go.mod h1:YrleYEh2pSEbgTBZYMJ5SuSr0ML3ypjRB1zgf7pvQLU= cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= cloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI= cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y= cloud.google.com/go/billing v1.12.0/go.mod h1:yKrZio/eu+okO/2McZEbch17O5CB5NpZhhXG6Z766ss= cloud.google.com/go/billing v1.13.0/go.mod h1:7kB2W9Xf98hP9Sr12KfECgfGclsH3CQR0R08tnRlRbc= cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= cloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0= cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk= cloud.google.com/go/binaryauthorization v1.5.0/go.mod h1:OSe4OU1nN/VswXKRBmciKpo9LulY41gch5c68htf3/Q= cloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg= cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590= cloud.google.com/go/certificatemanager v1.6.0/go.mod h1:3Hh64rCKjRAX8dXgRAyOcY5vQ/fE1sh8o+Mdd6KPgY8= cloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk= cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk= cloud.google.com/go/channel v1.11.0/go.mod h1:IdtI0uWGqhEeatSB62VOoJ8FSUhJ9/+iGkJVqp74CGE= cloud.google.com/go/channel v1.12.0/go.mod h1:VkxCGKASi4Cq7TbXxlaBezonAYpp1GCnKMY6tnMQnLU= cloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U= cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA= cloud.google.com/go/cloudbuild v1.6.0/go.mod h1:UIbc/w9QCbH12xX+ezUsgblrWv+Cv4Tw83GiSMHOn9M= cloud.google.com/go/cloudbuild v1.7.0/go.mod h1:zb5tWh2XI6lR9zQmsm1VRA+7OCuve5d8S+zJUul8KTg= cloud.google.com/go/cloudbuild v1.9.0/go.mod h1:qK1d7s4QlO0VwfYn5YuClDGg2hfmLZEb4wQGAbIgL1s= cloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM= cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk= cloud.google.com/go/clouddms v1.5.0/go.mod h1:QSxQnhikCLUw13iAbffF2CZxAER3xDGNHjsTAkQJcQA= cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= cloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4= cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI= cloud.google.com/go/cloudtasks v1.9.0/go.mod h1:w+EyLsVkLWHcOaqNEyvcKAsWp9p29dL6uL9Nst1cI7Y= cloud.google.com/go/cloudtasks v1.10.0/go.mod h1:NDSoTLkZ3+vExFEWu2UJV1arUyzVDAiZtdWcsUyNwBs= cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= cloud.google.com/go/compute v1.12.0/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE= cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= cloud.google.com/go/compute v1.19.1 h1:am86mquDUgjGNWxiGn+5PGLbmgiWXlE/yNWpIpNvuXY= cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE= cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY= cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w= cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg= cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo= cloud.google.com/go/container v1.13.1/go.mod h1:6wgbMPeQRw9rSnKBCAJXnds3Pzj03C4JHamr8asWKy4= cloud.google.com/go/container v1.14.0/go.mod h1:3AoJMPhHfLDxLvrlVWaK57IXzaPnLaZq63WX59aQBfM= cloud.google.com/go/container v1.15.0/go.mod h1:ft+9S0WGjAyjDggg5S06DXj+fHJICWg8L7isCQe9pQA= cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= cloud.google.com/go/containeranalysis v0.7.0/go.mod h1:9aUL+/vZ55P2CXfuZjS4UjQ9AgXoSw8Ts6lemfmxBxI= cloud.google.com/go/containeranalysis v0.9.0/go.mod h1:orbOANbwk5Ejoom+s+DUCTTJ7IBdBQJDcSylAx/on9s= cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= cloud.google.com/go/datacatalog v1.7.0/go.mod h1:9mEl4AuDYWw81UGc41HonIHH7/sn52H0/tc8f8ZbZIE= cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM= cloud.google.com/go/datacatalog v1.8.1/go.mod h1:RJ58z4rMp3gvETA465Vg+ag8BGgBdnRPEMMSTr5Uv+M= cloud.google.com/go/datacatalog v1.12.0/go.mod h1:CWae8rFkfp6LzLumKOnmVh4+Zle4A3NXLzVJ1d1mRm0= cloud.google.com/go/datacatalog v1.13.0/go.mod h1:E4Rj9a5ZtAxcQJlEBTLgMTphfP11/lNaAshpoBgemX8= cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= cloud.google.com/go/dataflow v0.8.0/go.mod h1:Rcf5YgTKPtQyYz8bLYhFoIV/vP39eL7fWNcSOyFfLJE= cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0= cloud.google.com/go/dataform v0.6.0/go.mod h1:QPflImQy33e29VuapFdf19oPbE4aYTJxr31OAPV+ulA= cloud.google.com/go/dataform v0.7.0/go.mod h1:7NulqnVozfHvWUBpMDfKMUESr+85aJsC/2O0o3jWPDE= cloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38= cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w= cloud.google.com/go/datafusion v1.6.0/go.mod h1:WBsMF8F1RhSXvVM8rCV3AeyWVxcC2xY6vith3iw3S+8= cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= cloud.google.com/go/datalabeling v0.7.0/go.mod h1:WPQb1y08RJbmpM3ww0CSUAGweL0SxByuW2E+FU+wXcM= cloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA= cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A= cloud.google.com/go/dataplex v1.5.2/go.mod h1:cVMgQHsmfRoI5KFYq4JtIBEUbYwc3c7tXmIDhRmNNVQ= cloud.google.com/go/dataplex v1.6.0/go.mod h1:bMsomC/aEJOSpHXdFKFGQ1b0TDPIeL28nJObeO1ppRs= cloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s= cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI= cloud.google.com/go/dataproc v1.12.0/go.mod h1:zrF3aX0uV3ikkMz6z4uBbIKyhRITnxvr4i3IjKsKrw4= cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= cloud.google.com/go/dataqna v0.7.0/go.mod h1:Lx9OcIIeqCrw1a6KdO3/5KMP1wAmTc0slZWwP12Qq3c= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM= cloud.google.com/go/datastore v1.11.0/go.mod h1:TvGxBIHCS50u8jzG+AW/ppf87v1of8nwzFNgEZU1D3c= cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= cloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g= cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4= cloud.google.com/go/datastream v1.6.0/go.mod h1:6LQSuswqLa7S4rPAOZFVjHIG3wJIjZcZrw8JDEDJuIs= cloud.google.com/go/datastream v1.7.0/go.mod h1:uxVRMm2elUSPuh65IbZpzJNMbuzkcvu5CjMqVIUHrww= cloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c= cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s= cloud.google.com/go/deploy v1.6.0/go.mod h1:f9PTHehG/DjCom3QH0cntOVRm93uGBDt2vKzAPwpXQI= cloud.google.com/go/deploy v1.8.0/go.mod h1:z3myEJnA/2wnB4sgjqdMfgxCA0EqC3RBTNcVPs93mtQ= cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= cloud.google.com/go/dialogflow v1.18.0/go.mod h1:trO7Zu5YdyEuR+BhSNOqJezyFQ3aUzz0njv7sMx/iek= cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0= cloud.google.com/go/dialogflow v1.29.0/go.mod h1:b+2bzMe+k1s9V+F2jbJwpHPzrnIyHihAdRFMtn2WXuM= cloud.google.com/go/dialogflow v1.31.0/go.mod h1:cuoUccuL1Z+HADhyIA7dci3N5zUssgpBJmCzI6fNRB4= cloud.google.com/go/dialogflow v1.32.0/go.mod h1:jG9TRJl8CKrDhMEcvfcfFkkpp8ZhgPz3sBGmAUYJ2qE= cloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM= cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q= cloud.google.com/go/dlp v1.9.0/go.mod h1:qdgmqgTyReTz5/YNSSuueR8pl7hO0o9bQ39ZhtgkWp4= cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= cloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k= cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4= cloud.google.com/go/documentai v1.16.0/go.mod h1:o0o0DLTEZ+YnJZ+J4wNfTxmDVyrkzFvttBXXtYRMHkM= cloud.google.com/go/documentai v1.18.0/go.mod h1:F6CK6iUH8J81FehpskRmhLq/3VlwQvb7TvwOceQ2tbs= cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= cloud.google.com/go/domains v0.8.0/go.mod h1:M9i3MMDzGFXsydri9/vW+EWz9sWb4I6WyHqdlAk0idE= cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= cloud.google.com/go/edgecontainer v0.3.0/go.mod h1:FLDpP4nykgwwIfcLt6zInhprzw0lEi2P1fjO6Ie0qbc= cloud.google.com/go/edgecontainer v1.0.0/go.mod h1:cttArqZpBB2q58W/upSG++ooo6EsblxDIolxa3jSjbY= cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= cloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI= cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8= cloud.google.com/go/essentialcontacts v1.5.0/go.mod h1:ay29Z4zODTuwliK7SnX8E86aUF2CTzdNtvv42niCX0M= cloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc= cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw= cloud.google.com/go/eventarc v1.10.0/go.mod h1:u3R35tmZ9HvswGRBnF48IlYgYeBcPUCjkr4BTdem2Kw= cloud.google.com/go/eventarc v1.11.0/go.mod h1:PyUjsUKPWoRBCHeOxZd/lbOOjahV41icXyUY5kSTvVY= cloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w= cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= cloud.google.com/go/filestore v1.5.0/go.mod h1:FqBXDWBp4YLHqRnVGveOkHDf8svj9r5+mUDLupOWEDs= cloud.google.com/go/filestore v1.6.0/go.mod h1:di5unNuss/qfZTw2U9nhFqo8/ZDSc466dre85Kydllg= cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= cloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY= cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08= cloud.google.com/go/functions v1.10.0/go.mod h1:0D3hEOe3DbEvCXtYOZHQZmD+SzYsi1YbI7dGvHfldXw= cloud.google.com/go/functions v1.12.0/go.mod h1:AXWGrF3e2C/5ehvwYo/GH6O5s09tOPksiKhz+hH8WkA= cloud.google.com/go/functions v1.13.0/go.mod h1:EU4O007sQm6Ef/PwRsI8N2umygGqPBS/IZQKBQBcJ3c= cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= cloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w= cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM= cloud.google.com/go/gaming v1.9.0/go.mod h1:Fc7kEmCObylSWLO334NcO+O9QMDyz+TKC4v1D7X+Bc0= cloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60= cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo= cloud.google.com/go/gkebackup v0.4.0/go.mod h1:byAyBGUwYGEEww7xsbnUTBHIYcOPy/PgUWUtOeRm9Vg= cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= cloud.google.com/go/gkeconnect v0.7.0/go.mod h1:SNfmVqPkaEi3bF/B3CNZOAYPYdg7sU+obZ+QTky2Myw= cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= cloud.google.com/go/gkehub v0.11.0/go.mod h1:JOWHlmN+GHyIbuWQPl47/C2RFhnFKH38jH9Ascu3n0E= cloud.google.com/go/gkehub v0.12.0/go.mod h1:djiIwwzTTBrF5NaXCGv3mf7klpEMcST17VBTVVDcuaw= cloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA= cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI= cloud.google.com/go/gkemulticloud v0.5.0/go.mod h1:W0JDkiyi3Tqh0TJr//y19wyb1yf8llHVto2Htf2Ja3Y= cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= cloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM= cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o= cloud.google.com/go/gsuiteaddons v1.5.0/go.mod h1:TFCClYLd64Eaa12sFVmUyG62tk4mdIsI7pAnSXRkcFo= cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc= cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= cloud.google.com/go/iam v0.11.0/go.mod h1:9PiLDanza5D+oWFZiH1uG+RnRCfEGKoyl6yo4cgWZGY= cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY= cloud.google.com/go/iam v0.13.0 h1:+CmB+K0J/33d0zSQ9SlFWUeCCEn5XJA0ZMZ3pHE9u8k= cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0= cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= cloud.google.com/go/iap v1.6.0/go.mod h1:NSuvI9C/j7UdjGjIde7t7HBz+QTwBcapPE07+sSRcLk= cloud.google.com/go/iap v1.7.0/go.mod h1:beqQx56T9O1G1yNPph+spKpNibDlYIiIixiqsQXxLIo= cloud.google.com/go/iap v1.7.1/go.mod h1:WapEwPc7ZxGt2jFGB/C/bm+hP0Y6NXzOYGjpPnmMS74= cloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM= cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY= cloud.google.com/go/ids v1.3.0/go.mod h1:JBdTYwANikFKaDP6LtW5JAi4gubs57SVNQjemdt6xV4= cloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs= cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g= cloud.google.com/go/iot v1.5.0/go.mod h1:mpz5259PDl3XJthEmh9+ap0affn/MqNSP4My77Qql9o= cloud.google.com/go/iot v1.6.0/go.mod h1:IqdAsmE2cTYYNO1Fvjfzo9po179rAtJeVGUvkLN3rLE= cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg= cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= cloud.google.com/go/kms v1.8.0/go.mod h1:4xFEhYFqvW+4VMELtZyxomGSYtSQKzM178ylFW4jMAg= cloud.google.com/go/kms v1.9.0/go.mod h1:qb1tPTgfF9RQP8e1wq4cLFErVuTJv7UsSC915J8dh3w= cloud.google.com/go/kms v1.10.0/go.mod h1:ng3KTUtQQU9bPX3+QGLsflZIHlkbn8amFAMY63m8d24= cloud.google.com/go/kms v1.10.1/go.mod h1:rIWk/TryCkR59GMC3YtHtXeLzd634lBbKenvyySAyYI= cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE= cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8= cloud.google.com/go/language v1.9.0/go.mod h1:Ns15WooPM5Ad/5no/0n81yUetis74g3zrbeJBE+ptUY= cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= cloud.google.com/go/lifesciences v0.8.0/go.mod h1:lFxiEOMqII6XggGbOnKiyZ7IBwoIqA84ClvoezaA/bo= cloud.google.com/go/logging v1.0.0/go.mod h1:V1cc3ogwobYzQq5f2R7DS/GvRIrI4FKj01Gs5glwAls= cloud.google.com/go/logging v1.4.2/go.mod h1:jco9QZSx8HiVVqLJReq7z7bVdj0P1Jb9PDFs63T+axo= cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= cloud.google.com/go/logging v1.7.0 h1:CJYxlNNNNAMkHp9em/YEXcfJg+rPDg7YfwoRpMU+t5I= cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M= cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE= cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM= cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo= cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE= cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM= cloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA= cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI= cloud.google.com/go/maps v0.6.0/go.mod h1:o6DAMMfb+aINHz/p/jbcY+mYeXBoZoxTfdSQ8VAJaCw= cloud.google.com/go/maps v0.7.0/go.mod h1:3GnvVl3cqeSvgMcpRlQidXsPYuDGQ8naBis7MVzpXsY= cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= cloud.google.com/go/mediatranslation v0.7.0/go.mod h1:LCnB/gZr90ONOIQLgSXagp8XUW1ODs2UmUMvcgMfI2I= cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= cloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA= cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY= cloud.google.com/go/memcache v1.9.0/go.mod h1:8oEyzXCu+zo9RzlEaEjHl4KkgjlNDaXbCQeQWlzNFJM= cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= cloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8= cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI= cloud.google.com/go/metastore v1.10.0/go.mod h1:fPEnH3g4JJAk+gMRnrAnoqyv2lpUCqJPWOodSaf45Eo= cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk= cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4= cloud.google.com/go/monitoring v1.12.0/go.mod h1:yx8Jj2fZNEkL/GYZyTLS4ZtZEZN8WtDEiEqG4kLK50w= cloud.google.com/go/monitoring v1.13.0/go.mod h1:k2yMBAB1H9JT/QETjNkgdCGD9bPF712XiLTVr+cBrpw= cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM= cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8= cloud.google.com/go/networkconnectivity v1.10.0/go.mod h1:UP4O4sWXJG13AqrTdQCD9TnLGEbtNRqjuaaA7bNjF5E= cloud.google.com/go/networkconnectivity v1.11.0/go.mod h1:iWmDD4QF16VCDLXUqvyspJjIEtBR/4zq5hwnY2X3scM= cloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8= cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4= cloud.google.com/go/networkmanagement v1.6.0/go.mod h1:5pKPqyXjB/sgtvB5xqOemumoQNB7y95Q7S+4rjSOPYY= cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= cloud.google.com/go/networksecurity v0.7.0/go.mod h1:mAnzoxx/8TBSyXEeESMy9OOYwo1v+gZ5eMRnsT5bC8k= cloud.google.com/go/networksecurity v0.8.0/go.mod h1:B78DkqsxFG5zRSVuwYFRZ9Xz8IcQ5iECsNrPn74hKHU= cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= cloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA= cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0= cloud.google.com/go/notebooks v1.7.0/go.mod h1:PVlaDGfJgj1fl1S3dUwhFMXFgfYGhYQt2164xOMONmE= cloud.google.com/go/notebooks v1.8.0/go.mod h1:Lq6dYKOYOWUCTvw5t2q1gp1lAp0zxAxRycayS0iJcqQ= cloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4= cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs= cloud.google.com/go/optimization v1.3.1/go.mod h1:IvUSefKiwd1a5p0RgHDbWCIbDFgKuEdB+fPPuP0IDLI= cloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA= cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk= cloud.google.com/go/orchestration v1.6.0/go.mod h1:M62Bevp7pkxStDfFfTuCOaXgaaqRAga1yKyoMtEoWPQ= cloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE= cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc= cloud.google.com/go/orgpolicy v1.10.0/go.mod h1:w1fo8b7rRqlXlIJbVhOMPrwVljyuW5mqssvBtU18ONc= cloud.google.com/go/osconfig v0.2.0/go.mod h1:IFwlgdzxGai6vEje/+9gnyy4xaIiVWxe1nEMax2UJyc= cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= cloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo= cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw= cloud.google.com/go/osconfig v1.11.0 h1:PkSQx4OHit5xz2bNyr11KGcaFccL5oqglFPdTboyqwQ= cloud.google.com/go/osconfig v1.11.0/go.mod h1:aDICxrur2ogRd9zY5ytBLV89KEgT2MKB2L/n6x1ooPw= cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= cloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70= cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo= cloud.google.com/go/oslogin v1.9.0/go.mod h1:HNavntnH8nzrn8JCTT5fj18FuJLFJc4NaZJtBnQtKFs= cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= cloud.google.com/go/phishingprotection v0.7.0/go.mod h1:8qJI4QKHoda/sb/7/YmMQ2omRLSLYSu9bU0EKCNI+Lk= cloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg= cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE= cloud.google.com/go/policytroubleshooter v1.5.0/go.mod h1:Rz1WfV+1oIpPdN2VvvuboLVRsB1Hclg3CKQ53j9l8vw= cloud.google.com/go/policytroubleshooter v1.6.0/go.mod h1:zYqaPTsmfvpjm5ULxAyD/lINQxJ0DDsnWOP/GZ7xzBc= cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= cloud.google.com/go/privatecatalog v0.7.0/go.mod h1:2s5ssIFO69F5csTXcwBP7NPFTZvps26xGzvQ2PQaBYg= cloud.google.com/go/privatecatalog v0.8.0/go.mod h1:nQ6pfaegeDAq/Q5lrfCQzQLhubPiZhSaNhIgfJlnIXs= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI= cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0= cloud.google.com/go/pubsub v1.28.0/go.mod h1:vuXFpwaVoIPQMGXqRyUQigu/AX1S3IWugR9xznmcXX8= cloud.google.com/go/pubsub v1.30.0/go.mod h1:qWi1OPS0B+b5L+Sg6Gmc9zD1Y+HaM0MdUr7LsupY1P4= cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= cloud.google.com/go/pubsublite v1.6.0/go.mod h1:1eFCS0U11xlOuMFV/0iBqw3zP12kddMeCbj/F3FSj9k= cloud.google.com/go/pubsublite v1.7.0/go.mod h1:8hVMwRXfDfvGm3fahVbtDbiLePT3gpoiJYJY+vxWxVM= cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= cloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI5sbwx9LBg3te2N6hGvHn2mE= cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U= cloud.google.com/go/recaptchaenterprise/v2 v2.6.0/go.mod h1:RPauz9jeLtB3JVzg6nCbe12qNoaa8pXc4d/YukAmcnA= cloud.google.com/go/recaptchaenterprise/v2 v2.7.0/go.mod h1:19wVj/fs5RtYtynAPJdDTb69oW0vNHYDBTbB4NvMD9c= cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= cloud.google.com/go/recommendationengine v0.7.0/go.mod h1:1reUcE3GIu6MeBz/h5xZJqNLuuVjNg1lmWMPyjatzac= cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= cloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs= cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70= cloud.google.com/go/recommender v1.9.0/go.mod h1:PnSsnZY7q+VL1uax2JWkt/UegHssxjUVVCrX52CuEmQ= cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= cloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA= cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM= cloud.google.com/go/redis v1.11.0/go.mod h1:/X6eicana+BWcUda5PpwZC48o37SiFVTFSs0fWAJ7uQ= cloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA= cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0= cloud.google.com/go/resourcemanager v1.5.0/go.mod h1:eQoXNAiAvCf5PXxWxXjhKQoTMaUSNrEfg+6qdf/wots= cloud.google.com/go/resourcemanager v1.6.0/go.mod h1:YcpXGRs8fDzcUl1Xw8uOVmI8JEadvhRIkoXXUNVYcVo= cloud.google.com/go/resourcemanager v1.7.0/go.mod h1:HlD3m6+bwhzj9XCouqmeiGuni95NTrExfhoSrkC/3EI= cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU= cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg= cloud.google.com/go/resourcesettings v1.5.0/go.mod h1:+xJF7QSG6undsQDfsCJyqWXyBwUoJLhetkRMDRnIoXA= cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= cloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc= cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y= cloud.google.com/go/retail v1.12.0/go.mod h1:UMkelN/0Z8XvKymXFbD4EhFJlYKRx1FGhQkVPU5kF14= cloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do= cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo= cloud.google.com/go/run v0.8.0/go.mod h1:VniEnuBwqjigv0A7ONfQUaEItaiCRVujlMqerPPiktM= cloud.google.com/go/run v0.9.0/go.mod h1:Wwu+/vvg8Y+JUApMwEDfVfhetv30hCG4ZwDR/IXl2Qg= cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= cloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRrYB5ZtT+KOk= cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44= cloud.google.com/go/scheduler v1.8.0/go.mod h1:TCET+Y5Gp1YgHT8py4nlg2Sew8nUHMqcpousDgXJVQc= cloud.google.com/go/scheduler v1.9.0/go.mod h1:yexg5t+KSmqu+njTIh3b7oYPheFtBWGcbVUYF1GGMIc= cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= cloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4= cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4= cloud.google.com/go/secretmanager v1.10.0/go.mod h1:MfnrdvKMPNra9aZtQFvBcvRU54hbPD8/HayQdlUgJpU= cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= cloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq/t9dzI+2Q= cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA= cloud.google.com/go/security v1.12.0/go.mod h1:rV6EhrpbNHrrxqlvW0BWAIawFWq3X90SduMJdFwtLB8= cloud.google.com/go/security v1.13.0/go.mod h1:Q1Nvxl1PAgmeW0y3HTt54JYIvUdtcpYKVfIB8AOMZ+0= cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= cloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk= cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk= cloud.google.com/go/securitycenter v1.18.1/go.mod h1:0/25gAzCM/9OL9vVx4ChPeM/+DlfGQJDwBy/UC8AKK0= cloud.google.com/go/securitycenter v1.19.0/go.mod h1:LVLmSg8ZkkyaNy4u7HCIshAngSQ8EcIRREP3xBnyfag= cloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU= cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s= cloud.google.com/go/servicecontrol v1.10.0/go.mod h1:pQvyvSRh7YzUF2efw7H87V92mxU8FnFDawMClGCNuAA= cloud.google.com/go/servicecontrol v1.11.0/go.mod h1:kFmTzYzTUIuZs0ycVqRHNaNhgR+UMUpw9n02l/pY+mc= cloud.google.com/go/servicecontrol v1.11.1/go.mod h1:aSnNNlwEFBY+PWGQ2DoM0JJ/QUXqV5/ZD9DOLB7SnUk= cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= cloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPjsRs1RlmJ4pqiNjVL4= cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U= cloud.google.com/go/servicedirectory v1.8.0/go.mod h1:srXodfhY1GFIPvltunswqXpVxFPpZjf8nkKQT7XcXaY= cloud.google.com/go/servicedirectory v1.9.0/go.mod h1:29je5JjiygNYlmsGz8k6o+OZ8vd4f//bQLtvzkPPT/s= cloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco= cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo= cloud.google.com/go/servicemanagement v1.6.0/go.mod h1:aWns7EeeCOtGEX4OvZUWCCJONRZeFKiptqKf1D0l/Jc= cloud.google.com/go/servicemanagement v1.8.0/go.mod h1:MSS2TDlIEQD/fzsSGfCdJItQveu9NXnUniTrq/L8LK4= cloud.google.com/go/serviceusage v1.3.0/go.mod h1:Hya1cozXM4SeSKTAgGXgj97GlqUvF5JaoXacR1JTP/E= cloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU= cloud.google.com/go/serviceusage v1.5.0/go.mod h1:w8U1JvqUqwJNPEOTQjrMHkw3IaIFLoLsPLvsE3xueec= cloud.google.com/go/serviceusage v1.6.0/go.mod h1:R5wwQcbOWsyuOfbP9tGdAnCAc6B9DRwPG1xtWMDeuPA= cloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4= cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw= cloud.google.com/go/shell v1.6.0/go.mod h1:oHO8QACS90luWgxP3N9iZVuEiSF84zNyLytb+qE2f9A= cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos= cloud.google.com/go/spanner v1.44.0/go.mod h1:G8XIgYdOK+Fbcpbs7p2fiprDw4CaZX63whnSMLVBxjk= cloud.google.com/go/spanner v1.45.0/go.mod h1:FIws5LowYz8YAE1J8fOS7DJup8ff7xJeetWEo5REA2M= cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0= cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco= cloud.google.com/go/speech v1.14.1/go.mod h1:gEosVRPJ9waG7zqqnsHpYTOoAS4KouMRLDFMekpJ0J0= cloud.google.com/go/speech v1.15.0/go.mod h1:y6oH7GhqCaZANH7+Oe0BhgIogsNInLlz542tg3VqeYI= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.1.1/go.mod h1:nbQkUX8zrWh07WKekXr/Phd0q/ERj4IOJnkE+v56Qys= cloud.google.com/go/storage v1.4.0/go.mod h1:ZusYJWlOshgSBGbt6K3GnB3MT3H1xs2id9+TCl4fDBA= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= cloud.google.com/go/storage v1.16.1/go.mod h1:LaNorbty3ehnU3rEjXSNV/NRgQA0O8Y+uh6bPe5UOk4= cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y= cloud.google.com/go/storage v1.29.0 h1:6weCgzRvMg7lzuUurI4697AqIRPU1SvzHhynwpW31jI= cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4= cloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w= cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= cloud.google.com/go/storagetransfer v1.7.0/go.mod h1:8Giuj1QNb1kfLAiWM1bN6dHzfdlDAVC9rv9abHot2W4= cloud.google.com/go/storagetransfer v1.8.0/go.mod h1:JpegsHHU1eXg7lMHkvf+KE5XDJ7EQu0GwNJbbVGanEw= cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= cloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM= cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA= cloud.google.com/go/talent v1.5.0/go.mod h1:G+ODMj9bsasAEJkQSzO2uHQWXHHXUomArjWQQYkqK6c= cloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8= cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4= cloud.google.com/go/texttospeech v1.6.0/go.mod h1:YmwmFT8pj1aBblQOI3TfKmwibnsfvhIBzPXcW4EBovc= cloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ= cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg= cloud.google.com/go/tpu v1.5.0/go.mod h1:8zVo1rYDFuW2l4yZVY0R0fb/v44xLh3llq7RuV61fPM= cloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28= cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y= cloud.google.com/go/trace v1.8.0/go.mod h1:zH7vcsbAhklH8hWFig58HvxcxyQbaIqMarMg9hn5ECA= cloud.google.com/go/trace v1.9.0/go.mod h1:lOQqpE5IaWY0Ixg7/r2SjixMuc6lfTFeO4QGM4dQWOk= cloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs= cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg= cloud.google.com/go/translate v1.5.0/go.mod h1:29YDSYveqqpA1CQFD7NQuP49xymq17RXNaUDdc0mNu0= cloud.google.com/go/translate v1.6.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= cloud.google.com/go/translate v1.7.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= cloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk= cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw= cloud.google.com/go/video v1.12.0/go.mod h1:MLQew95eTuaNDEGriQdcYn0dTwf9oWiA4uYebxM5kdg= cloud.google.com/go/video v1.13.0/go.mod h1:ulzkYlYgCp15N2AokzKjy7MQ9ejuynOJdf1tR5lGthk= cloud.google.com/go/video v1.14.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= cloud.google.com/go/video v1.15.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= cloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M= cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU= cloud.google.com/go/videointelligence v1.10.0/go.mod h1:LHZngX1liVtUhZvi2uNS0VQuOzNi2TkY1OakiuoUOjU= cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= cloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb+MhPqRbPsY= cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E= cloud.google.com/go/vision/v2 v2.6.0/go.mod h1:158Hes0MvOS9Z/bDMSFpjwsUrZ5fPrdwuyyvKSGAGMY= cloud.google.com/go/vision/v2 v2.7.0/go.mod h1:H89VysHy21avemp6xcf9b9JvZHVehWbET0uT/bcuY/0= cloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE= cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g= cloud.google.com/go/vmmigration v1.5.0/go.mod h1:E4YQ8q7/4W9gobHjQg4JJSgXXSgY21nA5r8swQV+Xxc= cloud.google.com/go/vmmigration v1.6.0/go.mod h1:bopQ/g4z+8qXzichC7GW1w2MjbErL54rk3/C843CjfY= cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208= cloud.google.com/go/vmwareengine v0.2.2/go.mod h1:sKdctNJxb3KLZkE/6Oui94iw/xs9PRNC2wnNLXsHvH8= cloud.google.com/go/vmwareengine v0.3.0/go.mod h1:wvoyMvNWdIzxMYSpH/R7y2h5h3WFkx6d+1TIsP39WGY= cloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w= cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8= cloud.google.com/go/vpcaccess v1.6.0/go.mod h1:wX2ILaNhe7TlVa4vC5xce1bCnqE3AeH27RV31lnmZes= cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= cloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc= cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A= cloud.google.com/go/webrisk v1.8.0/go.mod h1:oJPDuamzHXgUc+b8SiHRcVInZQuybnvEW72PqTc7sSg= cloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo= cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ= cloud.google.com/go/websecurityscanner v1.5.0/go.mod h1:Y6xdCPy81yi0SQnDY1xdNTNpfY1oAgXUlcfN3B3eSng= cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= cos.googlesource.com/cos/tools.git v0.0.0-20210329212435-a349a79f950d h1:qj1jlxRkQblujpwNPW4BOEWmGkrWP+Y5ADIoSKBxO5s= cos.googlesource.com/cos/tools.git v0.0.0-20210329212435-a349a79f950d/go.mod h1:1TJafpZtNmYwNzCwoWQRHfBDl59dxO6l/YW88HezBuk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/GoogleCloudPlatform/compute-image-tools/cli_tools v0.0.0-20200114193945-760dc9647411/go.mod h1:928Ttg3SXjfF1mOI37hjnFUahdU4R234SpDcgcBO0I8= github.com/GoogleCloudPlatform/compute-image-tools/cli_tools v0.0.0-20200406182414-bf9021434372/go.mod h1:zkxkF+fdCQyagLcSSWbQeDcvShTFro3HbulNmXzbBJg= github.com/GoogleCloudPlatform/compute-image-tools/cli_tools v0.0.0-20200805192452-5b81051e3e71/go.mod h1:ZUhSc6SjsB6cNgBVCZrYlB8ptdxEgnkDLD0Z/yyizQQ= github.com/GoogleCloudPlatform/compute-image-tools/daisy v0.0.0-20200111002017-35d3756114c9/go.mod h1:F+pk+WYiOJPq6m9oQkFZ3Vyw2l4nYJUgDyl4UW58+Q4= github.com/GoogleCloudPlatform/compute-image-tools/daisy v0.0.0-20200114193104-06c8be9a6a7d/go.mod h1:F+pk+WYiOJPq6m9oQkFZ3Vyw2l4nYJUgDyl4UW58+Q4= github.com/GoogleCloudPlatform/compute-image-tools/daisy v0.0.0-20200114232830-6d2d59acb179/go.mod h1:LyRbPkZMX3sR7WdIxBa1OYQlAO4opSezuhOXjc5xd2I= github.com/GoogleCloudPlatform/compute-image-tools/daisy v0.0.0-20200214212030-cdab85f8f241/go.mod h1:6xFWwnAALibczYyaAbXDaQSRIyqZ+A/uzJeGcr3kvcQ= github.com/GoogleCloudPlatform/compute-image-tools/daisy v0.0.0-20200406182414-bf9021434372/go.mod h1:OMlTSl6FloIMDs+kZxW4B5fVlj4RudzYDvKEQ+sH15U= github.com/GoogleCloudPlatform/compute-image-tools/daisy v0.0.0-20200721213208-00ba2b996712/go.mod h1:OMlTSl6FloIMDs+kZxW4B5fVlj4RudzYDvKEQ+sH15U= github.com/GoogleCloudPlatform/compute-image-tools/daisy v0.0.0-20200805192452-5b81051e3e71/go.mod h1:OMlTSl6FloIMDs+kZxW4B5fVlj4RudzYDvKEQ+sH15U= github.com/GoogleCloudPlatform/compute-image-tools/daisy v0.0.0-20210719160539-19df456994a5 h1:sw06v5L+hROoxD3u9YR6q2pWhiyocOaXxqToU6BOmsI= github.com/GoogleCloudPlatform/compute-image-tools/daisy v0.0.0-20210719160539-19df456994a5/go.mod h1:Z9jsyfegJlbSvjxGJnLf0vFf5yn20YyYkFaANYscwCU= github.com/GoogleCloudPlatform/compute-image-tools/go/e2e_test_utils v0.0.0-20200114232830-6d2d59acb179/go.mod h1:2hxlZPfWalIdOXnzbPATwW+Rs7FMMNWD5QnHDE49QZA= github.com/GoogleCloudPlatform/compute-image-tools/go/e2e_test_utils v0.0.0-20200128181915-c0775e429077/go.mod h1:2hxlZPfWalIdOXnzbPATwW+Rs7FMMNWD5QnHDE49QZA= github.com/GoogleCloudPlatform/compute-image-tools/go/e2e_test_utils v0.0.0-20210719160539-19df456994a5 h1:1WICMVQvWHbVFwt2kDUqe5YBn1cZFzfvuDzB2UOcEqM= github.com/GoogleCloudPlatform/compute-image-tools/go/e2e_test_utils v0.0.0-20210719160539-19df456994a5/go.mod h1:93wnO6RFVF68ebG+Lfz/o4ial0dnufRnFznlvp8KUdM= github.com/GoogleCloudPlatform/compute-image-tools/mocks v0.0.0-20200206014411-426b6301f679/go.mod h1:zDumkSJOQQ31fB0OWcg5h5zlVhU92LvYNXkpGQh2jz8= github.com/GoogleCloudPlatform/compute-image-tools/mocks v0.0.0-20200414213327-359251a2c860/go.mod h1:2Tz4TQzUbAzDwoQE70BFKJfWKLoZnhHuDZ28rJ//2g4= github.com/GoogleCloudPlatform/guest-logging-go v0.0.0-20191226203445-d798144cee48/go.mod h1:YWYrZjvs/qwZhDmsDnTaMXcno5Y0MYPN7rhMarLiUmI= github.com/GoogleCloudPlatform/guest-logging-go v0.0.0-20200113214433-6cbb518174d4/go.mod h1:YWYrZjvs/qwZhDmsDnTaMXcno5Y0MYPN7rhMarLiUmI= github.com/GoogleCloudPlatform/guest-logging-go v0.0.0-20210621170517-facc9c0d81b9 h1:Qq6KJSPMb1wCih/rqzQs3Ni2ShuCYc4q51wTx8lpy6Q= github.com/GoogleCloudPlatform/guest-logging-go v0.0.0-20210621170517-facc9c0d81b9/go.mod h1:3F/urXs15KEI7RBGoOsK9/jCCJPBKHxyZH/Nzc7uldo= github.com/GoogleCloudPlatform/osconfig v0.0.0-20200113163233-44035fcbfdd9/go.mod h1:nljBbLz4lHbiK1P6TwNhW0tanjfrRMYgtvLnLTIxygk= github.com/GoogleCloudPlatform/osconfig v0.0.0-20200115000133-a7c6fc334759/go.mod h1:nljBbLz4lHbiK1P6TwNhW0tanjfrRMYgtvLnLTIxygk= github.com/GoogleCloudPlatform/osconfig v0.0.0-20200211005319-080372593330/go.mod h1:nT1RIv+FL9qTdvhWYUd85m6Vpcy2fi7ZpLwS6Yuflb0= github.com/GoogleCloudPlatform/osconfig v0.0.0-20200721210327-c9ab1b6aeb02/go.mod h1:nfw/IdEPsQueLEhAFL9anXqtORP0hQoCF0P1sd+X398= github.com/GoogleCloudPlatform/osconfig v0.0.0-20211102225806-9b40a0ba0ce2 h1:s/mnP+OhdliWvymu6LJbP6H1RLvpWsZIYO++uWSffK4= github.com/GoogleCloudPlatform/osconfig v0.0.0-20211102225806-9b40a0ba0ce2/go.mod h1:fXl2vgC8Xk5MZAhwb+u2nmOZFohrF/YdjSegJPNpZS8= github.com/GoogleCloudPlatform/osconfig/e2e_tests v0.0.0-20200128231920-2ddeb2407498/go.mod h1:YHx1ltdJOZNKtDNUBBIwzyiq4Kh4EwQWm1NOcMEU/OA= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/andygrunwald/go-gerrit v0.0.0-20201231163137-46815e48bfe0/go.mod h1:soxaYLbAFToS0OelBriItCts/mtUZOuLBkCk1Xv4ZSo= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0= github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI= github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= github.com/aws/aws-sdk-go v1.33.9/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/cenkalti/backoff/v4 v4.0.2/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-xdr v0.0.0-20161123171359-e6a2ba005892/go.mod h1:CTDl0pzVzE5DEzZhPfvhY/9sPFMQIxaJ9VAMs9AagrE= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U= github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk= github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191002201903-404acd9df4cc/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/logger v1.0.1/go.mod h1:w7O8nrRr0xufejBlQMI83MXqRusvREoJdaAxV+CoAB4= github.com/google/logger v1.1.0/go.mod h1:w7O8nrRr0xufejBlQMI83MXqRusvREoJdaAxV+CoAB4= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200507031123-427632fa3b1c/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v0.0.0-20170306145142-6a5e28554805/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= github.com/googleapis/gax-go/v2 v2.7.1 h1:gF4c0zjUP2H/s/hEGyLA3I0fA2ZWjzYiONAD6cvPr8A= github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.10.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/pgzip v1.2.1/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/klauspost/pgzip v1.2.4/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= github.com/minio/highwayhash v1.0.0/go.mod h1:xQboMTeM9nY9v/LlAOxFctujiv5+Aq2hR5dxBpaMbdc= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.1.1 h1:T/YLemO5Yp7KPzS+lVtu+WsHn8yoSwTfItdAd1r3cck= github.com/smartystreets/assertions v1.1.1/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= github.com/vmware/govmomi v0.22.0/go.mod h1:Y+Wq4lst78L85Ge/F8+ORXIWiKYqaro1vhAulACy9Lc= github.com/vmware/govmomi v0.22.1/go.mod h1:Y+Wq4lst78L85Ge/F8+ORXIWiKYqaro1vhAulACy9Lc= github.com/vmware/govmomi v0.22.2/go.mod h1:Y+Wq4lst78L85Ge/F8+ORXIWiKYqaro1vhAulACy9Lc= github.com/vmware/govmomi v0.23.1/go.mod h1:Y+Wq4lst78L85Ge/F8+ORXIWiKYqaro1vhAulACy9Lc= github.com/vmware/vmw-guestinfo v0.0.0-20170707015358-25eff159a728/go.mod h1:x9oS4Wk2s2u4tS29nEaDLdzvuHdB19CvSGJjPgkZJNk= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= go.chromium.org/luci v0.0.0-20200722211809-bab0c30be68b/go.mod h1:MIQewVTLvOvc0UioV0JNqTNO/RspKFS0XEeoKrOxsdM= go.chromium.org/luci v0.0.0-20201204084249-3e81ee3e83fe/go.mod h1:MIQewVTLvOvc0UioV0JNqTNO/RspKFS0XEeoKrOxsdM= go.chromium.org/luci v0.0.0-20210524194916-901fa619ed56 h1:22ggwyJVInzkJwr4ZZ/8tlq0FMtkiSkW7otWOU+WA68= go.chromium.org/luci v0.0.0-20210524194916-901fa619ed56/go.mod h1:MIQewVTLvOvc0UioV0JNqTNO/RspKFS0XEeoKrOxsdM= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200707235045-ab33eee955e0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa h1:idItI2DDfCokpg0N51B2VtiLdJ4vAuXC9fnCb2gACo4= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20190912063710-ac5d2bfcbfe0/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE= golang.org/x/exp v0.0.0-20191014171548-69215a2ee97e/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200213203834-85f925bdd4d0/go.mod h1:IX6Eufr4L0ErOUlzqX/aFlHqsiKZRbV42Kb69e9VsTE= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200228211341-fcea875c7e85/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107160858-eca82077e2d1/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g= golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200406155108-e3b113bbe6a4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200720211630-cb9d2d5c5666/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200805065543-0cf7623e9dbd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210923061019-b8560ed6a9b7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190917162342-3b4f30a44f3b/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191010171213-8abd42400456/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191017205301-920acffc3e65/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200107184032-11e9d9cc0042/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200116165751-0508ad4c83ab/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200206152323-64a0f23fc32d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200214201135-548b770e2dfa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200317043434-63da46f3035e/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200318150045-ba25ddc85566/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200406172401-903869a8272d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200709181711-e327e1019dfe/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200721223218-6123e77877b2/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200805200255-b4d825fe358b/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY= gonum.org/v1/plot v0.10.1/go.mod h1:VZW5OlhkL1mysU9vaqNHnsy86inf6Ot+jB3r+BczCEo= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.11.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.16.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.21.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/api v0.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08= google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= google.golang.org/api v0.106.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= google.golang.org/api v0.111.0/go.mod h1:qtFHvU9mhgTJegR31csQ+rwxyUTHOKFqCKWp1J0fdw0= google.golang.org/api v0.114.0 h1:1xQPji6cO2E2vLiI+C/XiFAnsn1WV3mjaEwGLhi3grE= google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190708153700-3bdd9d9f5532/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191009194640-548a555dbc03/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200113173426-e1de0a7b01eb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200205142000-a86caf926a67/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200317114155-1f3552e48f24/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200318110522-7735f76e9fa5/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200406120821-33397c535dc2/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200626011028-ee7919e894b5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200709005830-7a2ca40e9dc3/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200711021454-869866162049/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200721032028-5044d0edf986/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804151602-45615f50871c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210517163617-5e0236093d7a/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210825212027-de86158e7fda/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210909144509-af19c3c38cb7/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210921142501-181ce0d877f6/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20210923133937-385e58f4e555/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= google.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221024153911-1573dae28c9c/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= google.golang.org/genproto v0.0.0-20221109142239-94d6d90a7d66/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= google.golang.org/genproto v0.0.0-20221117204609-8f9c96812029/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= google.golang.org/genproto v0.0.0-20221201204527-e3fa12d562f3/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE= google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/genproto v0.0.0-20230112194545-e10362b5ecf9/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/genproto v0.0.0-20230113154510-dbe35b8444a5/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/genproto v0.0.0-20230123190316-2c411cf9d197/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/genproto v0.0.0-20230127162408-596548ed4efa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA= google.golang.org/genproto v0.0.0-20230222225845-10f96fb3dbec/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= google.golang.org/genproto v0.0.0-20230223222841-637eb2293923/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= google.golang.org/genproto v0.0.0-20230303212802-e74f57abe488/go.mod h1:TvhZT5f700eVlTNwND1xoEZQeWTB2RY/65kplwl/bFA= google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= google.golang.org/genproto v0.0.0-20230320184635-7606e756e683/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= google.golang.org/grpc v1.52.3/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= modernc.org/cc/v3 v3.36.2/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= modernc.org/cc/v3 v3.36.3/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc= modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw= modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= modernc.org/ccgo/v3 v3.16.8/go.mod h1:zNjwkizS+fIFDrDjIAgBSCLkWbJuHF+ar3QRn+Z9aws= modernc.org/ccgo/v3 v3.16.9/go.mod h1:zNMzC9A9xeNUepy6KuZBbugn3c0Mc9TeiJO4lgvkJDo= modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A= modernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU= modernc.org/libc v1.16.17/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU= modernc.org/libc v1.16.19/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= modernc.org/libc v1.17.0/go.mod h1:XsgLldpP4aWlPlsjqKRdHPqCxCjISdHfM/yeWC5GyW0= modernc.org/libc v1.17.1/go.mod h1:FZ23b+8LjxZs7XtFMbSzL/EhPxNbfZbErxEHc7cbD9s= modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= modernc.org/memory v1.2.0/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= modernc.org/memory v1.2.1/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4= modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw= modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= osconfig-20250416.02/e2e_tests/internal/000077500000000000000000000000001477773331400175375ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/internal/cloud.google.com/000077500000000000000000000000001477773331400226755ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/internal/cloud.google.com/go/000077500000000000000000000000001477773331400233025ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/internal/cloud.google.com/go/osconfig/000077500000000000000000000000001477773331400251115ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/internal/cloud.google.com/go/osconfig/apiv1/000077500000000000000000000000001477773331400261315ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/internal/cloud.google.com/go/osconfig/apiv1/doc.go000066400000000000000000000104141477773331400272250ustar00rootroot00000000000000// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. // Package osconfig is an auto-generated package for the // OS Config API. // // OS management tools that can be used for patch management, patch // compliance, and configuration management on VM instances. // // # Example usage // // To get started with this package, create a client. // // ctx := context.Background() // c, err := osconfig.NewClient(ctx) // if err != nil { // // TODO: Handle error. // } // defer c.Close() // // The client will use your default application credentials. Clients should be reused instead of created as needed. // The methods of Client are safe for concurrent use by multiple goroutines. // The returned client must be Closed when it is done being used. // // # Using the Client // // The following is an example of making an API call with the newly created client. // // ctx := context.Background() // c, err := osconfig.NewClient(ctx) // if err != nil { // // TODO: Handle error. // } // defer c.Close() // // req := &osconfigpb.ExecutePatchJobRequest{ // // TODO: Fill request struct fields. // // See https://pkg.go.dev/google.golang.org/genproto/googleapis/cloud/osconfig/v1#ExecutePatchJobRequest. // } // resp, err := c.ExecutePatchJob(ctx, req) // if err != nil { // // TODO: Handle error. // } // // TODO: Use resp. // _ = resp // // # Use of Context // // The ctx passed to NewClient is used for authentication requests and // for creating the underlying connection, but is not used for subsequent calls. // Individual methods on the client use the ctx given to them. // // To close the open connection, use the Close() method. // // For information about setting deadlines, reusing contexts, and more // please visit https://pkg.go.dev/cloud.google.com/go. package osconfig // import "cloud.google.com/go/osconfig/apiv1" import ( "context" "os" "runtime" "strconv" "strings" "unicode" "google.golang.org/api/option" "google.golang.org/grpc/metadata" ) // For more information on implementing a client constructor hook, see // https://github.com/googleapis/google-cloud-go/wiki/Customizing-constructors. type clientHookParams struct{} type clientHook func(context.Context, clientHookParams) ([]option.ClientOption, error) const versionClient = "UNKNOWN" func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context { out, _ := metadata.FromOutgoingContext(ctx) out = out.Copy() for _, md := range mds { for k, v := range md { out[k] = append(out[k], v...) } } return metadata.NewOutgoingContext(ctx, out) } func checkDisableDeadlines() (bool, error) { raw, ok := os.LookupEnv("GOOGLE_API_GO_EXPERIMENTAL_DISABLE_DEFAULT_DEADLINE") if !ok { return false, nil } b, err := strconv.ParseBool(raw) return b, err } // DefaultAuthScopes reports the default set of authentication scopes to use with this package. func DefaultAuthScopes() []string { return []string{ "https://www.googleapis.com/auth/cloud-platform", } } // versionGo returns the Go runtime version. The returned string // has no whitespace, suitable for reporting in header. func versionGo() string { const develPrefix = "devel +" s := runtime.Version() if strings.HasPrefix(s, develPrefix) { s = s[len(develPrefix):] if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { s = s[:p] } return s } notSemverRune := func(r rune) bool { return !strings.ContainsRune("0123456789.", r) } if strings.HasPrefix(s, "go1") { s = s[2:] var prerelease string if p := strings.IndexFunc(s, notSemverRune); p >= 0 { s, prerelease = s[:p], s[p:] } if strings.HasSuffix(s, ".") { s += "0" } else if strings.Count(s, ".") < 2 { s += ".0" } if prerelease != "" { s += "-" + prerelease } return s } return "UNKNOWN" } osconfig-20250416.02/e2e_tests/internal/cloud.google.com/go/osconfig/apiv1/gapic_metadata.json000066400000000000000000000066021477773331400317530ustar00rootroot00000000000000{ "schema": "1.0", "comment": "This file maps proto services/RPCs to the corresponding library clients/methods.", "language": "go", "protoPackage": "google.cloud.osconfig.v1", "libraryPackage": "cloud.google.com/go/osconfig/apiv1", "services": { "OsConfigService": { "clients": { "grpc": { "libraryClient": "Client", "rpcs": { "CancelPatchJob": { "methods": [ "CancelPatchJob" ] }, "CreatePatchDeployment": { "methods": [ "CreatePatchDeployment" ] }, "DeletePatchDeployment": { "methods": [ "DeletePatchDeployment" ] }, "ExecutePatchJob": { "methods": [ "ExecutePatchJob" ] }, "GetPatchDeployment": { "methods": [ "GetPatchDeployment" ] }, "GetPatchJob": { "methods": [ "GetPatchJob" ] }, "ListPatchDeployments": { "methods": [ "ListPatchDeployments" ] }, "ListPatchJobInstanceDetails": { "methods": [ "ListPatchJobInstanceDetails" ] }, "ListPatchJobs": { "methods": [ "ListPatchJobs" ] } } } } }, "OsConfigZonalService": { "clients": { "grpc": { "libraryClient": "OsConfigZonalClient", "rpcs": { "CreateOSPolicyAssignment": { "methods": [ "CreateOSPolicyAssignment" ] }, "DeleteOSPolicyAssignment": { "methods": [ "DeleteOSPolicyAssignment" ] }, "GetInventory": { "methods": [ "GetInventory" ] }, "GetOSPolicyAssignment": { "methods": [ "GetOSPolicyAssignment" ] }, "GetOSPolicyAssignmentReport": { "methods": [ "GetOSPolicyAssignmentReport" ] }, "GetVulnerabilityReport": { "methods": [ "GetVulnerabilityReport" ] }, "ListInventories": { "methods": [ "ListInventories" ] }, "ListOSPolicyAssignmentReports": { "methods": [ "ListOSPolicyAssignmentReports" ] }, "ListOSPolicyAssignmentRevisions": { "methods": [ "ListOSPolicyAssignmentRevisions" ] }, "ListOSPolicyAssignments": { "methods": [ "ListOSPolicyAssignments" ] }, "ListVulnerabilityReports": { "methods": [ "ListVulnerabilityReports" ] }, "UpdateOSPolicyAssignment": { "methods": [ "UpdateOSPolicyAssignment" ] } } } } } } } osconfig-20250416.02/e2e_tests/internal/cloud.google.com/go/osconfig/apiv1/os_config_client.go000066400000000000000000000666551477773331400320060ustar00rootroot00000000000000// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. package osconfig import ( "context" "fmt" "math" "net/url" "time" osconfigpb "github.com/GoogleCloudPlatform/osconfig/e2e_tests/internal/google.golang.org/genproto/googleapis/cloud/osconfig/v1" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/option/internaloption" gtransport "google.golang.org/api/transport/grpc" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/protobuf/proto" ) var newClientHook clientHook // CallOptions contains the retry settings for each method of Client. type CallOptions struct { ExecutePatchJob []gax.CallOption GetPatchJob []gax.CallOption CancelPatchJob []gax.CallOption ListPatchJobs []gax.CallOption ListPatchJobInstanceDetails []gax.CallOption CreatePatchDeployment []gax.CallOption GetPatchDeployment []gax.CallOption ListPatchDeployments []gax.CallOption DeletePatchDeployment []gax.CallOption } func defaultGRPCClientOptions() []option.ClientOption { return []option.ClientOption{ internaloption.WithDefaultEndpoint("osconfig.googleapis.com:443"), internaloption.WithDefaultMTLSEndpoint("osconfig.mtls.googleapis.com:443"), internaloption.WithDefaultAudience("https://osconfig.googleapis.com/"), internaloption.WithDefaultScopes(DefaultAuthScopes()...), internaloption.EnableJwtWithScope(), option.WithGRPCDialOption(grpc.WithDisableServiceConfig()), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultCallOptions() *CallOptions { return &CallOptions{ ExecutePatchJob: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 1000 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, GetPatchJob: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 1000 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, CancelPatchJob: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 1000 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, ListPatchJobs: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 1000 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, ListPatchJobInstanceDetails: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 1000 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, CreatePatchDeployment: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 1000 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, GetPatchDeployment: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 1000 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, ListPatchDeployments: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 1000 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, DeletePatchDeployment: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 1000 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, } } // internalClient is an interface that defines the methods availaible from OS Config API. type internalClient interface { Close() error setGoogleClientInfo(...string) Connection() *grpc.ClientConn ExecutePatchJob(context.Context, *osconfigpb.ExecutePatchJobRequest, ...gax.CallOption) (*osconfigpb.PatchJob, error) GetPatchJob(context.Context, *osconfigpb.GetPatchJobRequest, ...gax.CallOption) (*osconfigpb.PatchJob, error) CancelPatchJob(context.Context, *osconfigpb.CancelPatchJobRequest, ...gax.CallOption) (*osconfigpb.PatchJob, error) ListPatchJobs(context.Context, *osconfigpb.ListPatchJobsRequest, ...gax.CallOption) *PatchJobIterator ListPatchJobInstanceDetails(context.Context, *osconfigpb.ListPatchJobInstanceDetailsRequest, ...gax.CallOption) *PatchJobInstanceDetailsIterator CreatePatchDeployment(context.Context, *osconfigpb.CreatePatchDeploymentRequest, ...gax.CallOption) (*osconfigpb.PatchDeployment, error) GetPatchDeployment(context.Context, *osconfigpb.GetPatchDeploymentRequest, ...gax.CallOption) (*osconfigpb.PatchDeployment, error) ListPatchDeployments(context.Context, *osconfigpb.ListPatchDeploymentsRequest, ...gax.CallOption) *PatchDeploymentIterator DeletePatchDeployment(context.Context, *osconfigpb.DeletePatchDeploymentRequest, ...gax.CallOption) error } // Client is a client for interacting with OS Config API. // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. // // # OS Config API // // The OS Config service is a server-side component that you can use to // manage package installations and patch jobs for virtual machine instances. type Client struct { // The internal transport-dependent client. internalClient internalClient // The call options for this service. CallOptions *CallOptions } // Wrapper methods routed to the internal client. // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *Client) Close() error { return c.internalClient.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *Client) setGoogleClientInfo(keyval ...string) { c.internalClient.setGoogleClientInfo(keyval...) } // Connection returns a connection to the API service. // // Deprecated. func (c *Client) Connection() *grpc.ClientConn { return c.internalClient.Connection() } // ExecutePatchJob patch VM instances by creating and running a patch job. func (c *Client) ExecutePatchJob(ctx context.Context, req *osconfigpb.ExecutePatchJobRequest, opts ...gax.CallOption) (*osconfigpb.PatchJob, error) { return c.internalClient.ExecutePatchJob(ctx, req, opts...) } // GetPatchJob get the patch job. This can be used to track the progress of an // ongoing patch job or review the details of completed jobs. func (c *Client) GetPatchJob(ctx context.Context, req *osconfigpb.GetPatchJobRequest, opts ...gax.CallOption) (*osconfigpb.PatchJob, error) { return c.internalClient.GetPatchJob(ctx, req, opts...) } // CancelPatchJob cancel a patch job. The patch job must be active. Canceled patch jobs // cannot be restarted. func (c *Client) CancelPatchJob(ctx context.Context, req *osconfigpb.CancelPatchJobRequest, opts ...gax.CallOption) (*osconfigpb.PatchJob, error) { return c.internalClient.CancelPatchJob(ctx, req, opts...) } // ListPatchJobs get a list of patch jobs. func (c *Client) ListPatchJobs(ctx context.Context, req *osconfigpb.ListPatchJobsRequest, opts ...gax.CallOption) *PatchJobIterator { return c.internalClient.ListPatchJobs(ctx, req, opts...) } // ListPatchJobInstanceDetails get a list of instance details for a given patch job. func (c *Client) ListPatchJobInstanceDetails(ctx context.Context, req *osconfigpb.ListPatchJobInstanceDetailsRequest, opts ...gax.CallOption) *PatchJobInstanceDetailsIterator { return c.internalClient.ListPatchJobInstanceDetails(ctx, req, opts...) } // CreatePatchDeployment create an OS Config patch deployment. func (c *Client) CreatePatchDeployment(ctx context.Context, req *osconfigpb.CreatePatchDeploymentRequest, opts ...gax.CallOption) (*osconfigpb.PatchDeployment, error) { return c.internalClient.CreatePatchDeployment(ctx, req, opts...) } // GetPatchDeployment get an OS Config patch deployment. func (c *Client) GetPatchDeployment(ctx context.Context, req *osconfigpb.GetPatchDeploymentRequest, opts ...gax.CallOption) (*osconfigpb.PatchDeployment, error) { return c.internalClient.GetPatchDeployment(ctx, req, opts...) } // ListPatchDeployments get a page of OS Config patch deployments. func (c *Client) ListPatchDeployments(ctx context.Context, req *osconfigpb.ListPatchDeploymentsRequest, opts ...gax.CallOption) *PatchDeploymentIterator { return c.internalClient.ListPatchDeployments(ctx, req, opts...) } // DeletePatchDeployment delete an OS Config patch deployment. func (c *Client) DeletePatchDeployment(ctx context.Context, req *osconfigpb.DeletePatchDeploymentRequest, opts ...gax.CallOption) error { return c.internalClient.DeletePatchDeployment(ctx, req, opts...) } // gRPCClient is a client for interacting with OS Config API over gRPC transport. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type gRPCClient struct { // Connection pool of gRPC connections to the service. connPool gtransport.ConnPool // flag to opt out of default deadlines via GOOGLE_API_GO_EXPERIMENTAL_DISABLE_DEFAULT_DEADLINE disableDeadlines bool // Points back to the CallOptions field of the containing Client CallOptions **CallOptions // The gRPC API client. client osconfigpb.OsConfigServiceClient // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewClient creates a new os config service client based on gRPC. // The returned client must be Closed when it is done being used to clean up its underlying connections. // // # OS Config API // // The OS Config service is a server-side component that you can use to // manage package installations and patch jobs for virtual machine instances. func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) { clientOpts := defaultGRPCClientOptions() if newClientHook != nil { hookOpts, err := newClientHook(ctx, clientHookParams{}) if err != nil { return nil, err } clientOpts = append(clientOpts, hookOpts...) } disableDeadlines, err := checkDisableDeadlines() if err != nil { return nil, err } connPool, err := gtransport.DialPool(ctx, append(clientOpts, opts...)...) if err != nil { return nil, err } client := Client{CallOptions: defaultCallOptions()} c := &gRPCClient{ connPool: connPool, disableDeadlines: disableDeadlines, client: osconfigpb.NewOsConfigServiceClient(connPool), CallOptions: &client.CallOptions, } c.setGoogleClientInfo() client.internalClient = c return &client, nil } // Connection returns a connection to the API service. // // Deprecated. func (c *gRPCClient) Connection() *grpc.ClientConn { return c.connPool.Conn() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *gRPCClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *gRPCClient) Close() error { return c.connPool.Close() } func (c *gRPCClient) ExecutePatchJob(ctx context.Context, req *osconfigpb.ExecutePatchJobRequest, opts ...gax.CallOption) (*osconfigpb.PatchJob, error) { if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond) defer cancel() ctx = cctx } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).ExecutePatchJob[0:len((*c.CallOptions).ExecutePatchJob):len((*c.CallOptions).ExecutePatchJob)], opts...) var resp *osconfigpb.PatchJob err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ExecutePatchJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } func (c *gRPCClient) GetPatchJob(ctx context.Context, req *osconfigpb.GetPatchJobRequest, opts ...gax.CallOption) (*osconfigpb.PatchJob, error) { if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond) defer cancel() ctx = cctx } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).GetPatchJob[0:len((*c.CallOptions).GetPatchJob):len((*c.CallOptions).GetPatchJob)], opts...) var resp *osconfigpb.PatchJob err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetPatchJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } func (c *gRPCClient) CancelPatchJob(ctx context.Context, req *osconfigpb.CancelPatchJobRequest, opts ...gax.CallOption) (*osconfigpb.PatchJob, error) { if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond) defer cancel() ctx = cctx } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).CancelPatchJob[0:len((*c.CallOptions).CancelPatchJob):len((*c.CallOptions).CancelPatchJob)], opts...) var resp *osconfigpb.PatchJob err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CancelPatchJob(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } func (c *gRPCClient) ListPatchJobs(ctx context.Context, req *osconfigpb.ListPatchJobsRequest, opts ...gax.CallOption) *PatchJobIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).ListPatchJobs[0:len((*c.CallOptions).ListPatchJobs):len((*c.CallOptions).ListPatchJobs)], opts...) it := &PatchJobIterator{} req = proto.Clone(req).(*osconfigpb.ListPatchJobsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*osconfigpb.PatchJob, string, error) { resp := &osconfigpb.ListPatchJobsResponse{} if pageToken != "" { req.PageToken = pageToken } if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else if pageSize != 0 { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListPatchJobs(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } it.Response = resp return resp.GetPatchJobs(), resp.GetNextPageToken(), nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.GetPageSize()) it.pageInfo.Token = req.GetPageToken() return it } func (c *gRPCClient) ListPatchJobInstanceDetails(ctx context.Context, req *osconfigpb.ListPatchJobInstanceDetailsRequest, opts ...gax.CallOption) *PatchJobInstanceDetailsIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).ListPatchJobInstanceDetails[0:len((*c.CallOptions).ListPatchJobInstanceDetails):len((*c.CallOptions).ListPatchJobInstanceDetails)], opts...) it := &PatchJobInstanceDetailsIterator{} req = proto.Clone(req).(*osconfigpb.ListPatchJobInstanceDetailsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*osconfigpb.PatchJobInstanceDetails, string, error) { resp := &osconfigpb.ListPatchJobInstanceDetailsResponse{} if pageToken != "" { req.PageToken = pageToken } if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else if pageSize != 0 { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListPatchJobInstanceDetails(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } it.Response = resp return resp.GetPatchJobInstanceDetails(), resp.GetNextPageToken(), nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.GetPageSize()) it.pageInfo.Token = req.GetPageToken() return it } func (c *gRPCClient) CreatePatchDeployment(ctx context.Context, req *osconfigpb.CreatePatchDeploymentRequest, opts ...gax.CallOption) (*osconfigpb.PatchDeployment, error) { if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond) defer cancel() ctx = cctx } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).CreatePatchDeployment[0:len((*c.CallOptions).CreatePatchDeployment):len((*c.CallOptions).CreatePatchDeployment)], opts...) var resp *osconfigpb.PatchDeployment err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.CreatePatchDeployment(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } func (c *gRPCClient) GetPatchDeployment(ctx context.Context, req *osconfigpb.GetPatchDeploymentRequest, opts ...gax.CallOption) (*osconfigpb.PatchDeployment, error) { if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond) defer cancel() ctx = cctx } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).GetPatchDeployment[0:len((*c.CallOptions).GetPatchDeployment):len((*c.CallOptions).GetPatchDeployment)], opts...) var resp *osconfigpb.PatchDeployment err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.GetPatchDeployment(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } func (c *gRPCClient) ListPatchDeployments(ctx context.Context, req *osconfigpb.ListPatchDeploymentsRequest, opts ...gax.CallOption) *PatchDeploymentIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).ListPatchDeployments[0:len((*c.CallOptions).ListPatchDeployments):len((*c.CallOptions).ListPatchDeployments)], opts...) it := &PatchDeploymentIterator{} req = proto.Clone(req).(*osconfigpb.ListPatchDeploymentsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*osconfigpb.PatchDeployment, string, error) { resp := &osconfigpb.ListPatchDeploymentsResponse{} if pageToken != "" { req.PageToken = pageToken } if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else if pageSize != 0 { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.client.ListPatchDeployments(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } it.Response = resp return resp.GetPatchDeployments(), resp.GetNextPageToken(), nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.GetPageSize()) it.pageInfo.Token = req.GetPageToken() return it } func (c *gRPCClient) DeletePatchDeployment(ctx context.Context, req *osconfigpb.DeletePatchDeploymentRequest, opts ...gax.CallOption) error { if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond) defer cancel() ctx = cctx } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).DeletePatchDeployment[0:len((*c.CallOptions).DeletePatchDeployment):len((*c.CallOptions).DeletePatchDeployment)], opts...) err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error _, err = c.client.DeletePatchDeployment(ctx, req, settings.GRPC...) return err }, opts...) return err } // PatchDeploymentIterator manages a stream of *osconfigpb.PatchDeployment. type PatchDeploymentIterator struct { items []*osconfigpb.PatchDeployment pageInfo *iterator.PageInfo nextFunc func() error // Response is the raw response for the current page. // It must be cast to the RPC response type. // Calling Next() or InternalFetch() updates this value. Response interface{} // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*osconfigpb.PatchDeployment, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *PatchDeploymentIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *PatchDeploymentIterator) Next() (*osconfigpb.PatchDeployment, error) { var item *osconfigpb.PatchDeployment if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *PatchDeploymentIterator) bufLen() int { return len(it.items) } func (it *PatchDeploymentIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // PatchJobInstanceDetailsIterator manages a stream of *osconfigpb.PatchJobInstanceDetails. type PatchJobInstanceDetailsIterator struct { items []*osconfigpb.PatchJobInstanceDetails pageInfo *iterator.PageInfo nextFunc func() error // Response is the raw response for the current page. // It must be cast to the RPC response type. // Calling Next() or InternalFetch() updates this value. Response interface{} // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*osconfigpb.PatchJobInstanceDetails, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *PatchJobInstanceDetailsIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *PatchJobInstanceDetailsIterator) Next() (*osconfigpb.PatchJobInstanceDetails, error) { var item *osconfigpb.PatchJobInstanceDetails if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *PatchJobInstanceDetailsIterator) bufLen() int { return len(it.items) } func (it *PatchJobInstanceDetailsIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // PatchJobIterator manages a stream of *osconfigpb.PatchJob. type PatchJobIterator struct { items []*osconfigpb.PatchJob pageInfo *iterator.PageInfo nextFunc func() error // Response is the raw response for the current page. // It must be cast to the RPC response type. // Calling Next() or InternalFetch() updates this value. Response interface{} // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*osconfigpb.PatchJob, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *PatchJobIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *PatchJobIterator) Next() (*osconfigpb.PatchJob, error) { var item *osconfigpb.PatchJob if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *PatchJobIterator) bufLen() int { return len(it.items) } func (it *PatchJobIterator) takeBuf() interface{} { b := it.items it.items = nil return b } osconfig-20250416.02/e2e_tests/internal/cloud.google.com/go/osconfig/apiv1/os_config_zonal_client.go000066400000000000000000001461011477773331400331720ustar00rootroot00000000000000// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go_gapic. DO NOT EDIT. package osconfig import ( "context" "fmt" "math" "net/url" "time" "cloud.google.com/go/longrunning" lroauto "cloud.google.com/go/longrunning/autogen" osconfigpb "github.com/GoogleCloudPlatform/osconfig/e2e_tests/internal/google.golang.org/genproto/googleapis/cloud/osconfig/v1" //"github.com/davecgh/go-spew/spew" "cloud.google.com/go/longrunning/autogen/longrunningpb" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/option/internaloption" gtransport "google.golang.org/api/transport/grpc" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/protobuf/proto" ) var newOsConfigZonalClientHook clientHook // OsConfigZonalCallOptions contains the retry settings for each method of OsConfigZonalClient. type OsConfigZonalCallOptions struct { CreateOSPolicyAssignment []gax.CallOption UpdateOSPolicyAssignment []gax.CallOption GetOSPolicyAssignment []gax.CallOption ListOSPolicyAssignments []gax.CallOption ListOSPolicyAssignmentRevisions []gax.CallOption DeleteOSPolicyAssignment []gax.CallOption GetOSPolicyAssignmentReport []gax.CallOption ListOSPolicyAssignmentReports []gax.CallOption GetInventory []gax.CallOption ListInventories []gax.CallOption GetVulnerabilityReport []gax.CallOption ListVulnerabilityReports []gax.CallOption } func defaultOsConfigZonalGRPCClientOptions() []option.ClientOption { return []option.ClientOption{ internaloption.WithDefaultEndpoint("osconfig.googleapis.com:443"), internaloption.WithDefaultMTLSEndpoint("osconfig.mtls.googleapis.com:443"), internaloption.WithDefaultAudience("https://osconfig.googleapis.com/"), internaloption.WithDefaultScopes(DefaultAuthScopes()...), internaloption.EnableJwtWithScope(), option.WithGRPCDialOption(grpc.WithDisableServiceConfig()), option.WithGRPCDialOption(grpc.WithDefaultCallOptions( grpc.MaxCallRecvMsgSize(math.MaxInt32))), } } func defaultOsConfigZonalCallOptions() *OsConfigZonalCallOptions { return &OsConfigZonalCallOptions{ CreateOSPolicyAssignment: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 1000 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, UpdateOSPolicyAssignment: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 1000 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, GetOSPolicyAssignment: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 1000 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, ListOSPolicyAssignments: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 1000 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, ListOSPolicyAssignmentRevisions: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 1000 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, DeleteOSPolicyAssignment: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 1000 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, GetOSPolicyAssignmentReport: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 1000 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, ListOSPolicyAssignmentReports: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 1000 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, GetInventory: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 1000 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, ListInventories: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 1000 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, GetVulnerabilityReport: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 1000 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, ListVulnerabilityReports: []gax.CallOption{ gax.WithRetry(func() gax.Retryer { return gax.OnCodes([]codes.Code{ codes.Unavailable, }, gax.Backoff{ Initial: 1000 * time.Millisecond, Max: 60000 * time.Millisecond, Multiplier: 1.30, }) }), }, } } // internalOsConfigZonalClient is an interface that defines the methods availaible from OS Config API. type internalOsConfigZonalClient interface { Close() error setGoogleClientInfo(...string) Connection() *grpc.ClientConn CreateOSPolicyAssignment(context.Context, *osconfigpb.CreateOSPolicyAssignmentRequest, ...gax.CallOption) (*CreateOSPolicyAssignmentOperation, error) CreateOSPolicyAssignmentOperation(name string) *CreateOSPolicyAssignmentOperation UpdateOSPolicyAssignment(context.Context, *osconfigpb.UpdateOSPolicyAssignmentRequest, ...gax.CallOption) (*UpdateOSPolicyAssignmentOperation, error) UpdateOSPolicyAssignmentOperation(name string) *UpdateOSPolicyAssignmentOperation GetOSPolicyAssignment(context.Context, *osconfigpb.GetOSPolicyAssignmentRequest, ...gax.CallOption) (*osconfigpb.OSPolicyAssignment, error) ListOSPolicyAssignments(context.Context, *osconfigpb.ListOSPolicyAssignmentsRequest, ...gax.CallOption) *OSPolicyAssignmentIterator ListOSPolicyAssignmentRevisions(context.Context, *osconfigpb.ListOSPolicyAssignmentRevisionsRequest, ...gax.CallOption) *OSPolicyAssignmentIterator DeleteOSPolicyAssignment(context.Context, *osconfigpb.DeleteOSPolicyAssignmentRequest, ...gax.CallOption) (*DeleteOSPolicyAssignmentOperation, error) DeleteOSPolicyAssignmentOperation(name string) *DeleteOSPolicyAssignmentOperation GetOSPolicyAssignmentReport(context.Context, *osconfigpb.GetOSPolicyAssignmentReportRequest, ...gax.CallOption) (*osconfigpb.OSPolicyAssignmentReport, error) ListOSPolicyAssignmentReports(context.Context, *osconfigpb.ListOSPolicyAssignmentReportsRequest, ...gax.CallOption) *OSPolicyAssignmentReportIterator GetInventory(context.Context, *osconfigpb.GetInventoryRequest, ...gax.CallOption) (*osconfigpb.Inventory, error) ListInventories(context.Context, *osconfigpb.ListInventoriesRequest, ...gax.CallOption) *InventoryIterator GetVulnerabilityReport(context.Context, *osconfigpb.GetVulnerabilityReportRequest, ...gax.CallOption) (*osconfigpb.VulnerabilityReport, error) ListVulnerabilityReports(context.Context, *osconfigpb.ListVulnerabilityReportsRequest, ...gax.CallOption) *VulnerabilityReportIterator } // OsConfigZonalClient is a client for interacting with OS Config API. // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. // // # Zonal OS Config API // // The OS Config service is the server-side component that allows users to // manage package installations and patch jobs for Compute Engine VM instances. type OsConfigZonalClient struct { // The internal transport-dependent client. internalClient internalOsConfigZonalClient // The call options for this service. CallOptions *OsConfigZonalCallOptions // LROClient is used internally to handle long-running operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient *lroauto.OperationsClient } // Wrapper methods routed to the internal client. // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *OsConfigZonalClient) Close() error { return c.internalClient.Close() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *OsConfigZonalClient) setGoogleClientInfo(keyval ...string) { c.internalClient.setGoogleClientInfo(keyval...) } // Connection returns a connection to the API service. // // Deprecated. func (c *OsConfigZonalClient) Connection() *grpc.ClientConn { return c.internalClient.Connection() } // CreateOSPolicyAssignment create an OS policy assignment. // // This method also creates the first revision of the OS policy assignment. // // This method returns a long running operation (LRO) that contains the // rollout details. The rollout can be cancelled by cancelling the LRO. // // For more information, see Method: // projects.locations.osPolicyAssignments.operations.cancel (at https://cloud.google.com/compute/docs/osconfig/rest/v1/projects.locations.osPolicyAssignments.operations/cancel). func (c *OsConfigZonalClient) CreateOSPolicyAssignment(ctx context.Context, req *osconfigpb.CreateOSPolicyAssignmentRequest, opts ...gax.CallOption) (*CreateOSPolicyAssignmentOperation, error) { return c.internalClient.CreateOSPolicyAssignment(ctx, req, opts...) } // CreateOSPolicyAssignmentOperation returns a new CreateOSPolicyAssignmentOperation from a given name. // The name must be that of a previously created CreateOSPolicyAssignmentOperation, possibly from a different process. func (c *OsConfigZonalClient) CreateOSPolicyAssignmentOperation(name string) *CreateOSPolicyAssignmentOperation { return c.internalClient.CreateOSPolicyAssignmentOperation(name) } // UpdateOSPolicyAssignment update an existing OS policy assignment. // // This method creates a new revision of the OS policy assignment. // // This method returns a long running operation (LRO) that contains the // rollout details. The rollout can be cancelled by cancelling the LRO. // // For more information, see Method: // projects.locations.osPolicyAssignments.operations.cancel (at https://cloud.google.com/compute/docs/osconfig/rest/v1/projects.locations.osPolicyAssignments.operations/cancel). func (c *OsConfigZonalClient) UpdateOSPolicyAssignment(ctx context.Context, req *osconfigpb.UpdateOSPolicyAssignmentRequest, opts ...gax.CallOption) (*UpdateOSPolicyAssignmentOperation, error) { return c.internalClient.UpdateOSPolicyAssignment(ctx, req, opts...) } // UpdateOSPolicyAssignmentOperation returns a new UpdateOSPolicyAssignmentOperation from a given name. // The name must be that of a previously created UpdateOSPolicyAssignmentOperation, possibly from a different process. func (c *OsConfigZonalClient) UpdateOSPolicyAssignmentOperation(name string) *UpdateOSPolicyAssignmentOperation { return c.internalClient.UpdateOSPolicyAssignmentOperation(name) } // GetOSPolicyAssignment retrieve an existing OS policy assignment. // // This method always returns the latest revision. In order to retrieve a // previous revision of the assignment, also provide the revision ID in the // name parameter. func (c *OsConfigZonalClient) GetOSPolicyAssignment(ctx context.Context, req *osconfigpb.GetOSPolicyAssignmentRequest, opts ...gax.CallOption) (*osconfigpb.OSPolicyAssignment, error) { return c.internalClient.GetOSPolicyAssignment(ctx, req, opts...) } // ListOSPolicyAssignments list the OS policy assignments under the parent resource. // // For each OS policy assignment, the latest revision is returned. func (c *OsConfigZonalClient) ListOSPolicyAssignments(ctx context.Context, req *osconfigpb.ListOSPolicyAssignmentsRequest, opts ...gax.CallOption) *OSPolicyAssignmentIterator { return c.internalClient.ListOSPolicyAssignments(ctx, req, opts...) } // ListOSPolicyAssignmentRevisions list the OS policy assignment revisions for a given OS policy assignment. func (c *OsConfigZonalClient) ListOSPolicyAssignmentRevisions(ctx context.Context, req *osconfigpb.ListOSPolicyAssignmentRevisionsRequest, opts ...gax.CallOption) *OSPolicyAssignmentIterator { return c.internalClient.ListOSPolicyAssignmentRevisions(ctx, req, opts...) } // DeleteOSPolicyAssignment delete the OS policy assignment. // // This method creates a new revision of the OS policy assignment. // // This method returns a long running operation (LRO) that contains the // rollout details. The rollout can be cancelled by cancelling the LRO. // // If the LRO completes and is not cancelled, all revisions associated with // the OS policy assignment are deleted. // // For more information, see Method: // projects.locations.osPolicyAssignments.operations.cancel (at https://cloud.google.com/compute/docs/osconfig/rest/v1/projects.locations.osPolicyAssignments.operations/cancel). func (c *OsConfigZonalClient) DeleteOSPolicyAssignment(ctx context.Context, req *osconfigpb.DeleteOSPolicyAssignmentRequest, opts ...gax.CallOption) (*DeleteOSPolicyAssignmentOperation, error) { return c.internalClient.DeleteOSPolicyAssignment(ctx, req, opts...) } // DeleteOSPolicyAssignmentOperation returns a new DeleteOSPolicyAssignmentOperation from a given name. // The name must be that of a previously created DeleteOSPolicyAssignmentOperation, possibly from a different process. func (c *OsConfigZonalClient) DeleteOSPolicyAssignmentOperation(name string) *DeleteOSPolicyAssignmentOperation { return c.internalClient.DeleteOSPolicyAssignmentOperation(name) } // GetOSPolicyAssignmentReport get the OS policy asssignment report for the specified Compute Engine VM // instance. func (c *OsConfigZonalClient) GetOSPolicyAssignmentReport(ctx context.Context, req *osconfigpb.GetOSPolicyAssignmentReportRequest, opts ...gax.CallOption) (*osconfigpb.OSPolicyAssignmentReport, error) { return c.internalClient.GetOSPolicyAssignmentReport(ctx, req, opts...) } // ListOSPolicyAssignmentReports list OS policy asssignment reports for all Compute Engine VM instances in // the specified zone. func (c *OsConfigZonalClient) ListOSPolicyAssignmentReports(ctx context.Context, req *osconfigpb.ListOSPolicyAssignmentReportsRequest, opts ...gax.CallOption) *OSPolicyAssignmentReportIterator { return c.internalClient.ListOSPolicyAssignmentReports(ctx, req, opts...) } // GetInventory get inventory data for the specified VM instance. If the VM has no // associated inventory, the message NOT_FOUND is returned. func (c *OsConfigZonalClient) GetInventory(ctx context.Context, req *osconfigpb.GetInventoryRequest, opts ...gax.CallOption) (*osconfigpb.Inventory, error) { return c.internalClient.GetInventory(ctx, req, opts...) } // ListInventories list inventory data for all VM instances in the specified zone. func (c *OsConfigZonalClient) ListInventories(ctx context.Context, req *osconfigpb.ListInventoriesRequest, opts ...gax.CallOption) *InventoryIterator { return c.internalClient.ListInventories(ctx, req, opts...) } // GetVulnerabilityReport gets the vulnerability report for the specified VM instance. Only VMs with // inventory data have vulnerability reports associated with them. func (c *OsConfigZonalClient) GetVulnerabilityReport(ctx context.Context, req *osconfigpb.GetVulnerabilityReportRequest, opts ...gax.CallOption) (*osconfigpb.VulnerabilityReport, error) { return c.internalClient.GetVulnerabilityReport(ctx, req, opts...) } // ListVulnerabilityReports list vulnerability reports for all VM instances in the specified zone. func (c *OsConfigZonalClient) ListVulnerabilityReports(ctx context.Context, req *osconfigpb.ListVulnerabilityReportsRequest, opts ...gax.CallOption) *VulnerabilityReportIterator { return c.internalClient.ListVulnerabilityReports(ctx, req, opts...) } // osConfigZonalGRPCClient is a client for interacting with OS Config API over gRPC transport. // // Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls. type osConfigZonalGRPCClient struct { // Connection pool of gRPC connections to the service. connPool gtransport.ConnPool // flag to opt out of default deadlines via GOOGLE_API_GO_EXPERIMENTAL_DISABLE_DEFAULT_DEADLINE disableDeadlines bool // Points back to the CallOptions field of the containing OsConfigZonalClient CallOptions **OsConfigZonalCallOptions // The gRPC API client. osConfigZonalClient osconfigpb.OsConfigZonalServiceClient // LROClient is used internally to handle long-running operations. // It is exposed so that its CallOptions can be modified if required. // Users should not Close this client. LROClient **lroauto.OperationsClient // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } // NewOsConfigZonalClient creates a new os config zonal service client based on gRPC. // The returned client must be Closed when it is done being used to clean up its underlying connections. // // # Zonal OS Config API // // The OS Config service is the server-side component that allows users to // manage package installations and patch jobs for Compute Engine VM instances. func NewOsConfigZonalClient(ctx context.Context, opts ...option.ClientOption) (*OsConfigZonalClient, error) { clientOpts := defaultOsConfigZonalGRPCClientOptions() if newOsConfigZonalClientHook != nil { hookOpts, err := newOsConfigZonalClientHook(ctx, clientHookParams{}) if err != nil { return nil, err } clientOpts = append(clientOpts, hookOpts...) } disableDeadlines, err := checkDisableDeadlines() if err != nil { return nil, err } connPool, err := gtransport.DialPool(ctx, append(clientOpts, opts...)...) if err != nil { return nil, err } client := OsConfigZonalClient{CallOptions: defaultOsConfigZonalCallOptions()} c := &osConfigZonalGRPCClient{ connPool: connPool, disableDeadlines: disableDeadlines, osConfigZonalClient: osconfigpb.NewOsConfigZonalServiceClient(connPool), CallOptions: &client.CallOptions, } c.setGoogleClientInfo() client.internalClient = c client.LROClient, err = lroauto.NewOperationsClient(ctx, gtransport.WithConnPool(connPool)) if err != nil { // This error "should not happen", since we are just reusing old connection pool // and never actually need to dial. // If this does happen, we could leak connp. However, we cannot close conn: // If the user invoked the constructor with option.WithGRPCConn, // we would close a connection that's still in use. // TODO: investigate error conditions. return nil, err } c.LROClient = &client.LROClient return &client, nil } // Connection returns a connection to the API service. // // Deprecated. func (c *osConfigZonalGRPCClient) Connection() *grpc.ClientConn { return c.connPool.Conn() } // setGoogleClientInfo sets the name and version of the application in // the `x-goog-api-client` header passed on each request. Intended for // use by Google-written clients. func (c *osConfigZonalGRPCClient) setGoogleClientInfo(keyval ...string) { kv := append([]string{"gl-go", versionGo()}, keyval...) kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version) c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...)) } // Close closes the connection to the API service. The user should invoke this when // the client is no longer required. func (c *osConfigZonalGRPCClient) Close() error { return c.connPool.Close() } func (c *osConfigZonalGRPCClient) CreateOSPolicyAssignment(ctx context.Context, req *osconfigpb.CreateOSPolicyAssignmentRequest, opts ...gax.CallOption) (*CreateOSPolicyAssignmentOperation, error) { if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond) defer cancel() ctx = cctx } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).CreateOSPolicyAssignment[0:len((*c.CallOptions).CreateOSPolicyAssignment):len((*c.CallOptions).CreateOSPolicyAssignment)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.osConfigZonalClient.CreateOSPolicyAssignment(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &CreateOSPolicyAssignmentOperation{ lro: longrunning.InternalNewOperation(*c.LROClient, resp), }, nil } func (c *osConfigZonalGRPCClient) UpdateOSPolicyAssignment(ctx context.Context, req *osconfigpb.UpdateOSPolicyAssignmentRequest, opts ...gax.CallOption) (*UpdateOSPolicyAssignmentOperation, error) { if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond) defer cancel() ctx = cctx } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "os_policy_assignment.name", url.QueryEscape(req.GetOsPolicyAssignment().GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).UpdateOSPolicyAssignment[0:len((*c.CallOptions).UpdateOSPolicyAssignment):len((*c.CallOptions).UpdateOSPolicyAssignment)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.osConfigZonalClient.UpdateOSPolicyAssignment(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &UpdateOSPolicyAssignmentOperation{ lro: longrunning.InternalNewOperation(*c.LROClient, resp), }, nil } func (c *osConfigZonalGRPCClient) GetOSPolicyAssignment(ctx context.Context, req *osconfigpb.GetOSPolicyAssignmentRequest, opts ...gax.CallOption) (*osconfigpb.OSPolicyAssignment, error) { if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond) defer cancel() ctx = cctx } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).GetOSPolicyAssignment[0:len((*c.CallOptions).GetOSPolicyAssignment):len((*c.CallOptions).GetOSPolicyAssignment)], opts...) var resp *osconfigpb.OSPolicyAssignment err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.osConfigZonalClient.GetOSPolicyAssignment(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } func (c *osConfigZonalGRPCClient) ListOSPolicyAssignments(ctx context.Context, req *osconfigpb.ListOSPolicyAssignmentsRequest, opts ...gax.CallOption) *OSPolicyAssignmentIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).ListOSPolicyAssignments[0:len((*c.CallOptions).ListOSPolicyAssignments):len((*c.CallOptions).ListOSPolicyAssignments)], opts...) it := &OSPolicyAssignmentIterator{} req = proto.Clone(req).(*osconfigpb.ListOSPolicyAssignmentsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*osconfigpb.OSPolicyAssignment, string, error) { resp := &osconfigpb.ListOSPolicyAssignmentsResponse{} if pageToken != "" { req.PageToken = pageToken } if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else if pageSize != 0 { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.osConfigZonalClient.ListOSPolicyAssignments(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } it.Response = resp return resp.GetOsPolicyAssignments(), resp.GetNextPageToken(), nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.GetPageSize()) it.pageInfo.Token = req.GetPageToken() return it } func (c *osConfigZonalGRPCClient) ListOSPolicyAssignmentRevisions(ctx context.Context, req *osconfigpb.ListOSPolicyAssignmentRevisionsRequest, opts ...gax.CallOption) *OSPolicyAssignmentIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).ListOSPolicyAssignmentRevisions[0:len((*c.CallOptions).ListOSPolicyAssignmentRevisions):len((*c.CallOptions).ListOSPolicyAssignmentRevisions)], opts...) it := &OSPolicyAssignmentIterator{} req = proto.Clone(req).(*osconfigpb.ListOSPolicyAssignmentRevisionsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*osconfigpb.OSPolicyAssignment, string, error) { resp := &osconfigpb.ListOSPolicyAssignmentRevisionsResponse{} if pageToken != "" { req.PageToken = pageToken } if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else if pageSize != 0 { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.osConfigZonalClient.ListOSPolicyAssignmentRevisions(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } it.Response = resp return resp.GetOsPolicyAssignments(), resp.GetNextPageToken(), nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.GetPageSize()) it.pageInfo.Token = req.GetPageToken() return it } func (c *osConfigZonalGRPCClient) DeleteOSPolicyAssignment(ctx context.Context, req *osconfigpb.DeleteOSPolicyAssignmentRequest, opts ...gax.CallOption) (*DeleteOSPolicyAssignmentOperation, error) { if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond) defer cancel() ctx = cctx } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).DeleteOSPolicyAssignment[0:len((*c.CallOptions).DeleteOSPolicyAssignment):len((*c.CallOptions).DeleteOSPolicyAssignment)], opts...) var resp *longrunningpb.Operation err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.osConfigZonalClient.DeleteOSPolicyAssignment(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return &DeleteOSPolicyAssignmentOperation{ lro: longrunning.InternalNewOperation(*c.LROClient, resp), }, nil } func (c *osConfigZonalGRPCClient) GetOSPolicyAssignmentReport(ctx context.Context, req *osconfigpb.GetOSPolicyAssignmentReportRequest, opts ...gax.CallOption) (*osconfigpb.OSPolicyAssignmentReport, error) { if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond) defer cancel() ctx = cctx } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).GetOSPolicyAssignmentReport[0:len((*c.CallOptions).GetOSPolicyAssignmentReport):len((*c.CallOptions).GetOSPolicyAssignmentReport)], opts...) var resp *osconfigpb.OSPolicyAssignmentReport err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.osConfigZonalClient.GetOSPolicyAssignmentReport(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } func (c *osConfigZonalGRPCClient) ListOSPolicyAssignmentReports(ctx context.Context, req *osconfigpb.ListOSPolicyAssignmentReportsRequest, opts ...gax.CallOption) *OSPolicyAssignmentReportIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).ListOSPolicyAssignmentReports[0:len((*c.CallOptions).ListOSPolicyAssignmentReports):len((*c.CallOptions).ListOSPolicyAssignmentReports)], opts...) it := &OSPolicyAssignmentReportIterator{} req = proto.Clone(req).(*osconfigpb.ListOSPolicyAssignmentReportsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*osconfigpb.OSPolicyAssignmentReport, string, error) { resp := &osconfigpb.ListOSPolicyAssignmentReportsResponse{} if pageToken != "" { req.PageToken = pageToken } if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else if pageSize != 0 { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.osConfigZonalClient.ListOSPolicyAssignmentReports(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } it.Response = resp return resp.GetOsPolicyAssignmentReports(), resp.GetNextPageToken(), nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.GetPageSize()) it.pageInfo.Token = req.GetPageToken() return it } func (c *osConfigZonalGRPCClient) GetInventory(ctx context.Context, req *osconfigpb.GetInventoryRequest, opts ...gax.CallOption) (*osconfigpb.Inventory, error) { if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond) defer cancel() ctx = cctx } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).GetInventory[0:len((*c.CallOptions).GetInventory):len((*c.CallOptions).GetInventory)], opts...) var resp *osconfigpb.Inventory err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.osConfigZonalClient.GetInventory(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } func (c *osConfigZonalGRPCClient) ListInventories(ctx context.Context, req *osconfigpb.ListInventoriesRequest, opts ...gax.CallOption) *InventoryIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).ListInventories[0:len((*c.CallOptions).ListInventories):len((*c.CallOptions).ListInventories)], opts...) it := &InventoryIterator{} req = proto.Clone(req).(*osconfigpb.ListInventoriesRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*osconfigpb.Inventory, string, error) { resp := &osconfigpb.ListInventoriesResponse{} if pageToken != "" { req.PageToken = pageToken } if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else if pageSize != 0 { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.osConfigZonalClient.ListInventories(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } it.Response = resp return resp.GetInventories(), resp.GetNextPageToken(), nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.GetPageSize()) it.pageInfo.Token = req.GetPageToken() return it } func (c *osConfigZonalGRPCClient) GetVulnerabilityReport(ctx context.Context, req *osconfigpb.GetVulnerabilityReportRequest, opts ...gax.CallOption) (*osconfigpb.VulnerabilityReport, error) { if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines { cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond) defer cancel() ctx = cctx } md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).GetVulnerabilityReport[0:len((*c.CallOptions).GetVulnerabilityReport):len((*c.CallOptions).GetVulnerabilityReport)], opts...) var resp *osconfigpb.VulnerabilityReport err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.osConfigZonalClient.GetVulnerabilityReport(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, err } return resp, nil } func (c *osConfigZonalGRPCClient) ListVulnerabilityReports(ctx context.Context, req *osconfigpb.ListVulnerabilityReportsRequest, opts ...gax.CallOption) *VulnerabilityReportIterator { md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))) ctx = insertMetadata(ctx, c.xGoogMetadata, md) opts = append((*c.CallOptions).ListVulnerabilityReports[0:len((*c.CallOptions).ListVulnerabilityReports):len((*c.CallOptions).ListVulnerabilityReports)], opts...) it := &VulnerabilityReportIterator{} req = proto.Clone(req).(*osconfigpb.ListVulnerabilityReportsRequest) it.InternalFetch = func(pageSize int, pageToken string) ([]*osconfigpb.VulnerabilityReport, string, error) { resp := &osconfigpb.ListVulnerabilityReportsResponse{} if pageToken != "" { req.PageToken = pageToken } if pageSize > math.MaxInt32 { req.PageSize = math.MaxInt32 } else if pageSize != 0 { req.PageSize = int32(pageSize) } err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { var err error resp, err = c.osConfigZonalClient.ListVulnerabilityReports(ctx, req, settings.GRPC...) return err }, opts...) if err != nil { return nil, "", err } it.Response = resp return resp.GetVulnerabilityReports(), resp.GetNextPageToken(), nil } fetch := func(pageSize int, pageToken string) (string, error) { items, nextPageToken, err := it.InternalFetch(pageSize, pageToken) if err != nil { return "", err } it.items = append(it.items, items...) return nextPageToken, nil } it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf) it.pageInfo.MaxSize = int(req.GetPageSize()) it.pageInfo.Token = req.GetPageToken() return it } // CreateOSPolicyAssignmentOperation manages a long-running operation from CreateOSPolicyAssignment. type CreateOSPolicyAssignmentOperation struct { lro *longrunning.Operation } // CreateOSPolicyAssignmentOperation returns a new CreateOSPolicyAssignmentOperation from a given name. // The name must be that of a previously created CreateOSPolicyAssignmentOperation, possibly from a different process. func (c *osConfigZonalGRPCClient) CreateOSPolicyAssignmentOperation(name string) *CreateOSPolicyAssignmentOperation { return &CreateOSPolicyAssignmentOperation{ lro: longrunning.InternalNewOperation(*c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *CreateOSPolicyAssignmentOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*osconfigpb.OSPolicyAssignment, error) { var resp osconfigpb.OSPolicyAssignment if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *CreateOSPolicyAssignmentOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*osconfigpb.OSPolicyAssignment, error) { var resp osconfigpb.OSPolicyAssignment if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *CreateOSPolicyAssignmentOperation) Metadata() (*osconfigpb.OSPolicyAssignmentOperationMetadata, error) { var meta osconfigpb.OSPolicyAssignmentOperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *CreateOSPolicyAssignmentOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *CreateOSPolicyAssignmentOperation) Name() string { return op.lro.Name() } // DeleteOSPolicyAssignmentOperation manages a long-running operation from DeleteOSPolicyAssignment. type DeleteOSPolicyAssignmentOperation struct { lro *longrunning.Operation } // DeleteOSPolicyAssignmentOperation returns a new DeleteOSPolicyAssignmentOperation from a given name. // The name must be that of a previously created DeleteOSPolicyAssignmentOperation, possibly from a different process. func (c *osConfigZonalGRPCClient) DeleteOSPolicyAssignmentOperation(name string) *DeleteOSPolicyAssignmentOperation { return &DeleteOSPolicyAssignmentOperation{ lro: longrunning.InternalNewOperation(*c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *DeleteOSPolicyAssignmentOperation) Wait(ctx context.Context, opts ...gax.CallOption) error { return op.lro.WaitWithInterval(ctx, nil, time.Minute, opts...) } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *DeleteOSPolicyAssignmentOperation) Poll(ctx context.Context, opts ...gax.CallOption) error { return op.lro.Poll(ctx, nil, opts...) } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *DeleteOSPolicyAssignmentOperation) Metadata() (*osconfigpb.OSPolicyAssignmentOperationMetadata, error) { var meta osconfigpb.OSPolicyAssignmentOperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *DeleteOSPolicyAssignmentOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *DeleteOSPolicyAssignmentOperation) Name() string { return op.lro.Name() } // UpdateOSPolicyAssignmentOperation manages a long-running operation from UpdateOSPolicyAssignment. type UpdateOSPolicyAssignmentOperation struct { lro *longrunning.Operation } // UpdateOSPolicyAssignmentOperation returns a new UpdateOSPolicyAssignmentOperation from a given name. // The name must be that of a previously created UpdateOSPolicyAssignmentOperation, possibly from a different process. func (c *osConfigZonalGRPCClient) UpdateOSPolicyAssignmentOperation(name string) *UpdateOSPolicyAssignmentOperation { return &UpdateOSPolicyAssignmentOperation{ lro: longrunning.InternalNewOperation(*c.LROClient, &longrunningpb.Operation{Name: name}), } } // Wait blocks until the long-running operation is completed, returning the response and any errors encountered. // // See documentation of Poll for error-handling information. func (op *UpdateOSPolicyAssignmentOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*osconfigpb.OSPolicyAssignment, error) { var resp osconfigpb.OSPolicyAssignment if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil { return nil, err } return &resp, nil } // Poll fetches the latest state of the long-running operation. // // Poll also fetches the latest metadata, which can be retrieved by Metadata. // // If Poll fails, the error is returned and op is unmodified. If Poll succeeds and // the operation has completed with failure, the error is returned and op.Done will return true. // If Poll succeeds and the operation has completed successfully, // op.Done will return true, and the response of the operation is returned. // If Poll succeeds and the operation has not completed, the returned response and error are both nil. func (op *UpdateOSPolicyAssignmentOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*osconfigpb.OSPolicyAssignment, error) { var resp osconfigpb.OSPolicyAssignment if err := op.lro.Poll(ctx, &resp, opts...); err != nil { return nil, err } if !op.Done() { return nil, nil } return &resp, nil } // Metadata returns metadata associated with the long-running operation. // Metadata itself does not contact the server, but Poll does. // To get the latest metadata, call this method after a successful call to Poll. // If the metadata is not available, the returned metadata and error are both nil. func (op *UpdateOSPolicyAssignmentOperation) Metadata() (*osconfigpb.OSPolicyAssignmentOperationMetadata, error) { var meta osconfigpb.OSPolicyAssignmentOperationMetadata if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { return nil, nil } else if err != nil { return nil, err } return &meta, nil } // Done reports whether the long-running operation has completed. func (op *UpdateOSPolicyAssignmentOperation) Done() bool { return op.lro.Done() } // Name returns the name of the long-running operation. // The name is assigned by the server and is unique within the service from which the operation is created. func (op *UpdateOSPolicyAssignmentOperation) Name() string { return op.lro.Name() } // InventoryIterator manages a stream of *osconfigpb.Inventory. type InventoryIterator struct { items []*osconfigpb.Inventory pageInfo *iterator.PageInfo nextFunc func() error // Response is the raw response for the current page. // It must be cast to the RPC response type. // Calling Next() or InternalFetch() updates this value. Response interface{} // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*osconfigpb.Inventory, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *InventoryIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *InventoryIterator) Next() (*osconfigpb.Inventory, error) { var item *osconfigpb.Inventory if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *InventoryIterator) bufLen() int { return len(it.items) } func (it *InventoryIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // OSPolicyAssignmentIterator manages a stream of *osconfigpb.OSPolicyAssignment. type OSPolicyAssignmentIterator struct { items []*osconfigpb.OSPolicyAssignment pageInfo *iterator.PageInfo nextFunc func() error // Response is the raw response for the current page. // It must be cast to the RPC response type. // Calling Next() or InternalFetch() updates this value. Response interface{} // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*osconfigpb.OSPolicyAssignment, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *OSPolicyAssignmentIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *OSPolicyAssignmentIterator) Next() (*osconfigpb.OSPolicyAssignment, error) { var item *osconfigpb.OSPolicyAssignment if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *OSPolicyAssignmentIterator) bufLen() int { return len(it.items) } func (it *OSPolicyAssignmentIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // OSPolicyAssignmentReportIterator manages a stream of *osconfigpb.OSPolicyAssignmentReport. type OSPolicyAssignmentReportIterator struct { items []*osconfigpb.OSPolicyAssignmentReport pageInfo *iterator.PageInfo nextFunc func() error // Response is the raw response for the current page. // It must be cast to the RPC response type. // Calling Next() or InternalFetch() updates this value. Response interface{} // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*osconfigpb.OSPolicyAssignmentReport, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *OSPolicyAssignmentReportIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *OSPolicyAssignmentReportIterator) Next() (*osconfigpb.OSPolicyAssignmentReport, error) { var item *osconfigpb.OSPolicyAssignmentReport if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *OSPolicyAssignmentReportIterator) bufLen() int { return len(it.items) } func (it *OSPolicyAssignmentReportIterator) takeBuf() interface{} { b := it.items it.items = nil return b } // VulnerabilityReportIterator manages a stream of *osconfigpb.VulnerabilityReport. type VulnerabilityReportIterator struct { items []*osconfigpb.VulnerabilityReport pageInfo *iterator.PageInfo nextFunc func() error // Response is the raw response for the current page. // It must be cast to the RPC response type. // Calling Next() or InternalFetch() updates this value. Response interface{} // InternalFetch is for use by the Google Cloud Libraries only. // It is not part of the stable interface of this package. // // InternalFetch returns results from a single call to the underlying RPC. // The number of results is no greater than pageSize. // If there are no more results, nextPageToken is empty and err is nil. InternalFetch func(pageSize int, pageToken string) (results []*osconfigpb.VulnerabilityReport, nextPageToken string, err error) } // PageInfo supports pagination. See the google.golang.org/api/iterator package for details. func (it *VulnerabilityReportIterator) PageInfo() *iterator.PageInfo { return it.pageInfo } // Next returns the next result. Its second return value is iterator.Done if there are no more // results. Once Next returns Done, all subsequent calls will return Done. func (it *VulnerabilityReportIterator) Next() (*osconfigpb.VulnerabilityReport, error) { var item *osconfigpb.VulnerabilityReport if err := it.nextFunc(); err != nil { return item, err } item = it.items[0] it.items = it.items[1:] return item, nil } func (it *VulnerabilityReportIterator) bufLen() int { return len(it.items) } func (it *VulnerabilityReportIterator) takeBuf() interface{} { b := it.items it.items = nil return b } osconfig-20250416.02/e2e_tests/internal/google.golang.org/000077500000000000000000000000001477773331400230475ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/internal/google.golang.org/genproto/000077500000000000000000000000001477773331400247045ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/internal/google.golang.org/genproto/googleapis/000077500000000000000000000000001477773331400270355ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/internal/google.golang.org/genproto/googleapis/cloud/000077500000000000000000000000001477773331400301435ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/internal/google.golang.org/genproto/googleapis/cloud/osconfig/000077500000000000000000000000001477773331400317525ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/internal/google.golang.org/genproto/googleapis/cloud/osconfig/v1/000077500000000000000000000000001477773331400323005ustar00rootroot00000000000000inventory.pb.go000066400000000000000000002505601477773331400352150ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/internal/google.golang.org/genproto/googleapis/cloud/osconfig/v1// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.25.0 // protoc v3.15.3 // source: google/cloud/osconfig/v1/inventory.proto package osconfig import ( proto "github.com/golang/protobuf/proto" _ "google.golang.org/genproto/googleapis/api/annotations" date "google.golang.org/genproto/googleapis/type/date" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" ) const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) // Verify that runtime/protoimpl is sufficiently up-to-date. _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) // This is a compile-time assertion that a sufficiently up-to-date version // of the legacy proto package is being used. const _ = proto.ProtoPackageIsVersion4 // The view for inventory objects. type InventoryView int32 const ( // The default value. // The API defaults to the BASIC view. InventoryView_INVENTORY_VIEW_UNSPECIFIED InventoryView = 0 // Returns the basic inventory information that includes `os_info`. InventoryView_BASIC InventoryView = 1 // Returns all fields. InventoryView_FULL InventoryView = 2 ) // Enum value maps for InventoryView. var ( InventoryView_name = map[int32]string{ 0: "INVENTORY_VIEW_UNSPECIFIED", 1: "BASIC", 2: "FULL", } InventoryView_value = map[string]int32{ "INVENTORY_VIEW_UNSPECIFIED": 0, "BASIC": 1, "FULL": 2, } ) func (x InventoryView) Enum() *InventoryView { p := new(InventoryView) *p = x return p } func (x InventoryView) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (InventoryView) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_inventory_proto_enumTypes[0].Descriptor() } func (InventoryView) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_inventory_proto_enumTypes[0] } func (x InventoryView) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use InventoryView.Descriptor instead. func (InventoryView) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_inventory_proto_rawDescGZIP(), []int{0} } // The origin of a specific inventory item. type Inventory_Item_OriginType int32 const ( // Invalid. An origin type must be specified. Inventory_Item_ORIGIN_TYPE_UNSPECIFIED Inventory_Item_OriginType = 0 // This inventory item was discovered as the result of the agent // reporting inventory via the reporting API. Inventory_Item_INVENTORY_REPORT Inventory_Item_OriginType = 1 ) // Enum value maps for Inventory_Item_OriginType. var ( Inventory_Item_OriginType_name = map[int32]string{ 0: "ORIGIN_TYPE_UNSPECIFIED", 1: "INVENTORY_REPORT", } Inventory_Item_OriginType_value = map[string]int32{ "ORIGIN_TYPE_UNSPECIFIED": 0, "INVENTORY_REPORT": 1, } ) func (x Inventory_Item_OriginType) Enum() *Inventory_Item_OriginType { p := new(Inventory_Item_OriginType) *p = x return p } func (x Inventory_Item_OriginType) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (Inventory_Item_OriginType) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_inventory_proto_enumTypes[1].Descriptor() } func (Inventory_Item_OriginType) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_inventory_proto_enumTypes[1] } func (x Inventory_Item_OriginType) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use Inventory_Item_OriginType.Descriptor instead. func (Inventory_Item_OriginType) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_inventory_proto_rawDescGZIP(), []int{0, 1, 0} } // The different types of inventory that are tracked on a VM. type Inventory_Item_Type int32 const ( // Invalid. An type must be specified. Inventory_Item_TYPE_UNSPECIFIED Inventory_Item_Type = 0 // This represents a package that is installed on the VM. Inventory_Item_INSTALLED_PACKAGE Inventory_Item_Type = 1 // This represents an update that is available for a package. Inventory_Item_AVAILABLE_PACKAGE Inventory_Item_Type = 2 ) // Enum value maps for Inventory_Item_Type. var ( Inventory_Item_Type_name = map[int32]string{ 0: "TYPE_UNSPECIFIED", 1: "INSTALLED_PACKAGE", 2: "AVAILABLE_PACKAGE", } Inventory_Item_Type_value = map[string]int32{ "TYPE_UNSPECIFIED": 0, "INSTALLED_PACKAGE": 1, "AVAILABLE_PACKAGE": 2, } ) func (x Inventory_Item_Type) Enum() *Inventory_Item_Type { p := new(Inventory_Item_Type) *p = x return p } func (x Inventory_Item_Type) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (Inventory_Item_Type) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_inventory_proto_enumTypes[2].Descriptor() } func (Inventory_Item_Type) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_inventory_proto_enumTypes[2] } func (x Inventory_Item_Type) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use Inventory_Item_Type.Descriptor instead. func (Inventory_Item_Type) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_inventory_proto_rawDescGZIP(), []int{0, 1, 1} } // This API resource represents the available inventory data for a // Compute Engine virtual machine (VM) instance at a given point in time. // // You can use this API resource to determine the inventory data of your VM. // // For more information, see [Information provided by OS inventory // management](https://cloud.google.com/compute/docs/instances/os-inventory-management#data-collected). type Inventory struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Output only. The `Inventory` API resource name. // // Format: // `projects/{project_number}/locations/{location}/instances/{instance_id}/inventory` Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` // Base level operating system information for the VM. OsInfo *Inventory_OsInfo `protobuf:"bytes,1,opt,name=os_info,json=osInfo,proto3" json:"os_info,omitempty"` // Inventory items related to the VM keyed by an opaque unique identifier for // each inventory item. The identifier is unique to each distinct and // addressable inventory item and will change, when there is a new package // version. Items map[string]*Inventory_Item `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // Output only. Timestamp of the last reported inventory for the VM. UpdateTime *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty"` } func (x *Inventory) Reset() { *x = Inventory{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *Inventory) String() string { return protoimpl.X.MessageStringOf(x) } func (*Inventory) ProtoMessage() {} func (x *Inventory) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use Inventory.ProtoReflect.Descriptor instead. func (*Inventory) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_inventory_proto_rawDescGZIP(), []int{0} } func (x *Inventory) GetName() string { if x != nil { return x.Name } return "" } func (x *Inventory) GetOsInfo() *Inventory_OsInfo { if x != nil { return x.OsInfo } return nil } func (x *Inventory) GetItems() map[string]*Inventory_Item { if x != nil { return x.Items } return nil } func (x *Inventory) GetUpdateTime() *timestamppb.Timestamp { if x != nil { return x.UpdateTime } return nil } // A request message for getting inventory data for the specified VM. type GetInventoryRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. API resource name for inventory resource. // // Format: // `projects/{project}/locations/{location}/instances/{instance}/inventory` // // For `{project}`, either `project-number` or `project-id` can be provided. // For `{instance}`, either Compute Engine `instance-id` or `instance-name` // can be provided. Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // Inventory view indicating what information should be included in the // inventory resource. If unspecified, the default view is BASIC. View InventoryView `protobuf:"varint,2,opt,name=view,proto3,enum=google.cloud.osconfig.v1.InventoryView" json:"view,omitempty"` } func (x *GetInventoryRequest) Reset() { *x = GetInventoryRequest{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *GetInventoryRequest) String() string { return protoimpl.X.MessageStringOf(x) } func (*GetInventoryRequest) ProtoMessage() {} func (x *GetInventoryRequest) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use GetInventoryRequest.ProtoReflect.Descriptor instead. func (*GetInventoryRequest) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_inventory_proto_rawDescGZIP(), []int{1} } func (x *GetInventoryRequest) GetName() string { if x != nil { return x.Name } return "" } func (x *GetInventoryRequest) GetView() InventoryView { if x != nil { return x.View } return InventoryView_INVENTORY_VIEW_UNSPECIFIED } // A request message for listing inventory data for all VMs in the specified // location. type ListInventoriesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. The parent resource name. // // Format: `projects/{project}/locations/{location}/instances/-` // // For `{project}`, either `project-number` or `project-id` can be provided. Parent string `protobuf:"bytes,1,opt,name=parent,proto3" json:"parent,omitempty"` // Inventory view indicating what information should be included in the // inventory resource. If unspecified, the default view is BASIC. View InventoryView `protobuf:"varint,2,opt,name=view,proto3,enum=google.cloud.osconfig.v1.InventoryView" json:"view,omitempty"` // The maximum number of results to return. PageSize int32 `protobuf:"varint,3,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` // A pagination token returned from a previous call to // `ListInventories` that indicates where this listing // should continue from. PageToken string `protobuf:"bytes,4,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"` // If provided, this field specifies the criteria that must be met by a // `Inventory` API resource to be included in the response. Filter string `protobuf:"bytes,5,opt,name=filter,proto3" json:"filter,omitempty"` } func (x *ListInventoriesRequest) Reset() { *x = ListInventoriesRequest{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *ListInventoriesRequest) String() string { return protoimpl.X.MessageStringOf(x) } func (*ListInventoriesRequest) ProtoMessage() {} func (x *ListInventoriesRequest) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use ListInventoriesRequest.ProtoReflect.Descriptor instead. func (*ListInventoriesRequest) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_inventory_proto_rawDescGZIP(), []int{2} } func (x *ListInventoriesRequest) GetParent() string { if x != nil { return x.Parent } return "" } func (x *ListInventoriesRequest) GetView() InventoryView { if x != nil { return x.View } return InventoryView_INVENTORY_VIEW_UNSPECIFIED } func (x *ListInventoriesRequest) GetPageSize() int32 { if x != nil { return x.PageSize } return 0 } func (x *ListInventoriesRequest) GetPageToken() string { if x != nil { return x.PageToken } return "" } func (x *ListInventoriesRequest) GetFilter() string { if x != nil { return x.Filter } return "" } // A response message for listing inventory data for all VMs in a specified // location. type ListInventoriesResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // List of inventory objects. Inventories []*Inventory `protobuf:"bytes,1,rep,name=inventories,proto3" json:"inventories,omitempty"` // The pagination token to retrieve the next page of inventory objects. NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` } func (x *ListInventoriesResponse) Reset() { *x = ListInventoriesResponse{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *ListInventoriesResponse) String() string { return protoimpl.X.MessageStringOf(x) } func (*ListInventoriesResponse) ProtoMessage() {} func (x *ListInventoriesResponse) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use ListInventoriesResponse.ProtoReflect.Descriptor instead. func (*ListInventoriesResponse) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_inventory_proto_rawDescGZIP(), []int{3} } func (x *ListInventoriesResponse) GetInventories() []*Inventory { if x != nil { return x.Inventories } return nil } func (x *ListInventoriesResponse) GetNextPageToken() string { if x != nil { return x.NextPageToken } return "" } // Operating system information for the VM. type Inventory_OsInfo struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // The VM hostname. Hostname string `protobuf:"bytes,9,opt,name=hostname,proto3" json:"hostname,omitempty"` // The operating system long name. // For example 'Debian GNU/Linux 9' or 'Microsoft Window Server 2019 // Datacenter'. LongName string `protobuf:"bytes,2,opt,name=long_name,json=longName,proto3" json:"long_name,omitempty"` // The operating system short name. // For example, 'windows' or 'debian'. ShortName string `protobuf:"bytes,3,opt,name=short_name,json=shortName,proto3" json:"short_name,omitempty"` // The version of the operating system. Version string `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"` // The system architecture of the operating system. Architecture string `protobuf:"bytes,5,opt,name=architecture,proto3" json:"architecture,omitempty"` // The kernel version of the operating system. KernelVersion string `protobuf:"bytes,6,opt,name=kernel_version,json=kernelVersion,proto3" json:"kernel_version,omitempty"` // The kernel release of the operating system. KernelRelease string `protobuf:"bytes,7,opt,name=kernel_release,json=kernelRelease,proto3" json:"kernel_release,omitempty"` // The current version of the OS Config agent running on the VM. OsconfigAgentVersion string `protobuf:"bytes,8,opt,name=osconfig_agent_version,json=osconfigAgentVersion,proto3" json:"osconfig_agent_version,omitempty"` } func (x *Inventory_OsInfo) Reset() { *x = Inventory_OsInfo{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *Inventory_OsInfo) String() string { return protoimpl.X.MessageStringOf(x) } func (*Inventory_OsInfo) ProtoMessage() {} func (x *Inventory_OsInfo) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use Inventory_OsInfo.ProtoReflect.Descriptor instead. func (*Inventory_OsInfo) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_inventory_proto_rawDescGZIP(), []int{0, 0} } func (x *Inventory_OsInfo) GetHostname() string { if x != nil { return x.Hostname } return "" } func (x *Inventory_OsInfo) GetLongName() string { if x != nil { return x.LongName } return "" } func (x *Inventory_OsInfo) GetShortName() string { if x != nil { return x.ShortName } return "" } func (x *Inventory_OsInfo) GetVersion() string { if x != nil { return x.Version } return "" } func (x *Inventory_OsInfo) GetArchitecture() string { if x != nil { return x.Architecture } return "" } func (x *Inventory_OsInfo) GetKernelVersion() string { if x != nil { return x.KernelVersion } return "" } func (x *Inventory_OsInfo) GetKernelRelease() string { if x != nil { return x.KernelRelease } return "" } func (x *Inventory_OsInfo) GetOsconfigAgentVersion() string { if x != nil { return x.OsconfigAgentVersion } return "" } // A single piece of inventory on a VM. type Inventory_Item struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Identifier for this item, unique across items for this VM. Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // The origin of this inventory item. OriginType Inventory_Item_OriginType `protobuf:"varint,2,opt,name=origin_type,json=originType,proto3,enum=google.cloud.osconfig.v1.Inventory_Item_OriginType" json:"origin_type,omitempty"` // When this inventory item was first detected. CreateTime *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"` // When this inventory item was last modified. UpdateTime *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty"` // The specific type of inventory, correlating to its specific details. Type Inventory_Item_Type `protobuf:"varint,5,opt,name=type,proto3,enum=google.cloud.osconfig.v1.Inventory_Item_Type" json:"type,omitempty"` // Specific details of this inventory item based on its type. // // Types that are assignable to Details: // *Inventory_Item_InstalledPackage // *Inventory_Item_AvailablePackage Details isInventory_Item_Details `protobuf_oneof:"details"` } func (x *Inventory_Item) Reset() { *x = Inventory_Item{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *Inventory_Item) String() string { return protoimpl.X.MessageStringOf(x) } func (*Inventory_Item) ProtoMessage() {} func (x *Inventory_Item) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use Inventory_Item.ProtoReflect.Descriptor instead. func (*Inventory_Item) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_inventory_proto_rawDescGZIP(), []int{0, 1} } func (x *Inventory_Item) GetId() string { if x != nil { return x.Id } return "" } func (x *Inventory_Item) GetOriginType() Inventory_Item_OriginType { if x != nil { return x.OriginType } return Inventory_Item_ORIGIN_TYPE_UNSPECIFIED } func (x *Inventory_Item) GetCreateTime() *timestamppb.Timestamp { if x != nil { return x.CreateTime } return nil } func (x *Inventory_Item) GetUpdateTime() *timestamppb.Timestamp { if x != nil { return x.UpdateTime } return nil } func (x *Inventory_Item) GetType() Inventory_Item_Type { if x != nil { return x.Type } return Inventory_Item_TYPE_UNSPECIFIED } func (m *Inventory_Item) GetDetails() isInventory_Item_Details { if m != nil { return m.Details } return nil } func (x *Inventory_Item) GetInstalledPackage() *Inventory_SoftwarePackage { if x, ok := x.GetDetails().(*Inventory_Item_InstalledPackage); ok { return x.InstalledPackage } return nil } func (x *Inventory_Item) GetAvailablePackage() *Inventory_SoftwarePackage { if x, ok := x.GetDetails().(*Inventory_Item_AvailablePackage); ok { return x.AvailablePackage } return nil } type isInventory_Item_Details interface { isInventory_Item_Details() } type Inventory_Item_InstalledPackage struct { // Software package present on the VM instance. InstalledPackage *Inventory_SoftwarePackage `protobuf:"bytes,6,opt,name=installed_package,json=installedPackage,proto3,oneof"` } type Inventory_Item_AvailablePackage struct { // Software package available to be installed on the VM instance. AvailablePackage *Inventory_SoftwarePackage `protobuf:"bytes,7,opt,name=available_package,json=availablePackage,proto3,oneof"` } func (*Inventory_Item_InstalledPackage) isInventory_Item_Details() {} func (*Inventory_Item_AvailablePackage) isInventory_Item_Details() {} // Software package information of the operating system. type Inventory_SoftwarePackage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Information about the different types of software packages. // // Types that are assignable to Details: // *Inventory_SoftwarePackage_YumPackage // *Inventory_SoftwarePackage_AptPackage // *Inventory_SoftwarePackage_ZypperPackage // *Inventory_SoftwarePackage_GoogetPackage // *Inventory_SoftwarePackage_ZypperPatch // *Inventory_SoftwarePackage_WuaPackage // *Inventory_SoftwarePackage_QfePackage // *Inventory_SoftwarePackage_CosPackage // *Inventory_SoftwarePackage_WindowsApplication Details isInventory_SoftwarePackage_Details `protobuf_oneof:"details"` } func (x *Inventory_SoftwarePackage) Reset() { *x = Inventory_SoftwarePackage{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *Inventory_SoftwarePackage) String() string { return protoimpl.X.MessageStringOf(x) } func (*Inventory_SoftwarePackage) ProtoMessage() {} func (x *Inventory_SoftwarePackage) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use Inventory_SoftwarePackage.ProtoReflect.Descriptor instead. func (*Inventory_SoftwarePackage) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_inventory_proto_rawDescGZIP(), []int{0, 2} } func (m *Inventory_SoftwarePackage) GetDetails() isInventory_SoftwarePackage_Details { if m != nil { return m.Details } return nil } func (x *Inventory_SoftwarePackage) GetYumPackage() *Inventory_VersionedPackage { if x, ok := x.GetDetails().(*Inventory_SoftwarePackage_YumPackage); ok { return x.YumPackage } return nil } func (x *Inventory_SoftwarePackage) GetAptPackage() *Inventory_VersionedPackage { if x, ok := x.GetDetails().(*Inventory_SoftwarePackage_AptPackage); ok { return x.AptPackage } return nil } func (x *Inventory_SoftwarePackage) GetZypperPackage() *Inventory_VersionedPackage { if x, ok := x.GetDetails().(*Inventory_SoftwarePackage_ZypperPackage); ok { return x.ZypperPackage } return nil } func (x *Inventory_SoftwarePackage) GetGoogetPackage() *Inventory_VersionedPackage { if x, ok := x.GetDetails().(*Inventory_SoftwarePackage_GoogetPackage); ok { return x.GoogetPackage } return nil } func (x *Inventory_SoftwarePackage) GetZypperPatch() *Inventory_ZypperPatch { if x, ok := x.GetDetails().(*Inventory_SoftwarePackage_ZypperPatch); ok { return x.ZypperPatch } return nil } func (x *Inventory_SoftwarePackage) GetWuaPackage() *Inventory_WindowsUpdatePackage { if x, ok := x.GetDetails().(*Inventory_SoftwarePackage_WuaPackage); ok { return x.WuaPackage } return nil } func (x *Inventory_SoftwarePackage) GetQfePackage() *Inventory_WindowsQuickFixEngineeringPackage { if x, ok := x.GetDetails().(*Inventory_SoftwarePackage_QfePackage); ok { return x.QfePackage } return nil } func (x *Inventory_SoftwarePackage) GetCosPackage() *Inventory_VersionedPackage { if x, ok := x.GetDetails().(*Inventory_SoftwarePackage_CosPackage); ok { return x.CosPackage } return nil } func (x *Inventory_SoftwarePackage) GetWindowsApplication() *Inventory_WindowsApplication { if x, ok := x.GetDetails().(*Inventory_SoftwarePackage_WindowsApplication); ok { return x.WindowsApplication } return nil } type isInventory_SoftwarePackage_Details interface { isInventory_SoftwarePackage_Details() } type Inventory_SoftwarePackage_YumPackage struct { // Yum package info. // For details about the yum package manager, see // https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/deployment_guide/ch-yum. YumPackage *Inventory_VersionedPackage `protobuf:"bytes,1,opt,name=yum_package,json=yumPackage,proto3,oneof"` } type Inventory_SoftwarePackage_AptPackage struct { // Details of an APT package. // For details about the apt package manager, see // https://wiki.debian.org/Apt. AptPackage *Inventory_VersionedPackage `protobuf:"bytes,2,opt,name=apt_package,json=aptPackage,proto3,oneof"` } type Inventory_SoftwarePackage_ZypperPackage struct { // Details of a Zypper package. // For details about the Zypper package manager, see // https://en.opensuse.org/SDB:Zypper_manual. ZypperPackage *Inventory_VersionedPackage `protobuf:"bytes,3,opt,name=zypper_package,json=zypperPackage,proto3,oneof"` } type Inventory_SoftwarePackage_GoogetPackage struct { // Details of a Googet package. // For details about the googet package manager, see // https://github.com/google/googet. GoogetPackage *Inventory_VersionedPackage `protobuf:"bytes,4,opt,name=googet_package,json=googetPackage,proto3,oneof"` } type Inventory_SoftwarePackage_ZypperPatch struct { // Details of a Zypper patch. // For details about the Zypper package manager, see // https://en.opensuse.org/SDB:Zypper_manual. ZypperPatch *Inventory_ZypperPatch `protobuf:"bytes,5,opt,name=zypper_patch,json=zypperPatch,proto3,oneof"` } type Inventory_SoftwarePackage_WuaPackage struct { // Details of a Windows Update package. // See https://docs.microsoft.com/en-us/windows/win32/api/_wua/ for // information about Windows Update. WuaPackage *Inventory_WindowsUpdatePackage `protobuf:"bytes,6,opt,name=wua_package,json=wuaPackage,proto3,oneof"` } type Inventory_SoftwarePackage_QfePackage struct { // Details of a Windows Quick Fix engineering package. // See // https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-quickfixengineering // for info in Windows Quick Fix Engineering. QfePackage *Inventory_WindowsQuickFixEngineeringPackage `protobuf:"bytes,7,opt,name=qfe_package,json=qfePackage,proto3,oneof"` } type Inventory_SoftwarePackage_CosPackage struct { // Details of a COS package. CosPackage *Inventory_VersionedPackage `protobuf:"bytes,8,opt,name=cos_package,json=cosPackage,proto3,oneof"` } type Inventory_SoftwarePackage_WindowsApplication struct { // Details of Windows Application. WindowsApplication *Inventory_WindowsApplication `protobuf:"bytes,9,opt,name=windows_application,json=windowsApplication,proto3,oneof"` } func (*Inventory_SoftwarePackage_YumPackage) isInventory_SoftwarePackage_Details() {} func (*Inventory_SoftwarePackage_AptPackage) isInventory_SoftwarePackage_Details() {} func (*Inventory_SoftwarePackage_ZypperPackage) isInventory_SoftwarePackage_Details() {} func (*Inventory_SoftwarePackage_GoogetPackage) isInventory_SoftwarePackage_Details() {} func (*Inventory_SoftwarePackage_ZypperPatch) isInventory_SoftwarePackage_Details() {} func (*Inventory_SoftwarePackage_WuaPackage) isInventory_SoftwarePackage_Details() {} func (*Inventory_SoftwarePackage_QfePackage) isInventory_SoftwarePackage_Details() {} func (*Inventory_SoftwarePackage_CosPackage) isInventory_SoftwarePackage_Details() {} func (*Inventory_SoftwarePackage_WindowsApplication) isInventory_SoftwarePackage_Details() {} // Information related to the a standard versioned package. This includes // package info for APT, Yum, Zypper, and Googet package managers. type Inventory_VersionedPackage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // The name of the package. PackageName string `protobuf:"bytes,4,opt,name=package_name,json=packageName,proto3" json:"package_name,omitempty"` // The system architecture this package is intended for. Architecture string `protobuf:"bytes,2,opt,name=architecture,proto3" json:"architecture,omitempty"` // The version of the package. Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` } func (x *Inventory_VersionedPackage) Reset() { *x = Inventory_VersionedPackage{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *Inventory_VersionedPackage) String() string { return protoimpl.X.MessageStringOf(x) } func (*Inventory_VersionedPackage) ProtoMessage() {} func (x *Inventory_VersionedPackage) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use Inventory_VersionedPackage.ProtoReflect.Descriptor instead. func (*Inventory_VersionedPackage) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_inventory_proto_rawDescGZIP(), []int{0, 3} } func (x *Inventory_VersionedPackage) GetPackageName() string { if x != nil { return x.PackageName } return "" } func (x *Inventory_VersionedPackage) GetArchitecture() string { if x != nil { return x.Architecture } return "" } func (x *Inventory_VersionedPackage) GetVersion() string { if x != nil { return x.Version } return "" } // Details related to a Zypper Patch. type Inventory_ZypperPatch struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // The name of the patch. PatchName string `protobuf:"bytes,5,opt,name=patch_name,json=patchName,proto3" json:"patch_name,omitempty"` // The category of the patch. Category string `protobuf:"bytes,2,opt,name=category,proto3" json:"category,omitempty"` // The severity specified for this patch Severity string `protobuf:"bytes,3,opt,name=severity,proto3" json:"severity,omitempty"` // Any summary information provided about this patch. Summary string `protobuf:"bytes,4,opt,name=summary,proto3" json:"summary,omitempty"` } func (x *Inventory_ZypperPatch) Reset() { *x = Inventory_ZypperPatch{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *Inventory_ZypperPatch) String() string { return protoimpl.X.MessageStringOf(x) } func (*Inventory_ZypperPatch) ProtoMessage() {} func (x *Inventory_ZypperPatch) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use Inventory_ZypperPatch.ProtoReflect.Descriptor instead. func (*Inventory_ZypperPatch) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_inventory_proto_rawDescGZIP(), []int{0, 4} } func (x *Inventory_ZypperPatch) GetPatchName() string { if x != nil { return x.PatchName } return "" } func (x *Inventory_ZypperPatch) GetCategory() string { if x != nil { return x.Category } return "" } func (x *Inventory_ZypperPatch) GetSeverity() string { if x != nil { return x.Severity } return "" } func (x *Inventory_ZypperPatch) GetSummary() string { if x != nil { return x.Summary } return "" } // Details related to a Windows Update package. // Field data and names are taken from Windows Update API IUpdate Interface: // https://docs.microsoft.com/en-us/windows/win32/api/_wua/ // Descriptive fields like title, and description are localized based on // the locale of the VM being updated. type Inventory_WindowsUpdatePackage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // The localized title of the update package. Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` // The localized description of the update package. Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // The categories that are associated with this update package. Categories []*Inventory_WindowsUpdatePackage_WindowsUpdateCategory `protobuf:"bytes,3,rep,name=categories,proto3" json:"categories,omitempty"` // A collection of Microsoft Knowledge Base article IDs that are associated // with the update package. KbArticleIds []string `protobuf:"bytes,4,rep,name=kb_article_ids,json=kbArticleIds,proto3" json:"kb_article_ids,omitempty"` // A hyperlink to the language-specific support information for the update. SupportUrl string `protobuf:"bytes,11,opt,name=support_url,json=supportUrl,proto3" json:"support_url,omitempty"` // A collection of URLs that provide more information about the update // package. MoreInfoUrls []string `protobuf:"bytes,5,rep,name=more_info_urls,json=moreInfoUrls,proto3" json:"more_info_urls,omitempty"` // Gets the identifier of an update package. Stays the same across // revisions. UpdateId string `protobuf:"bytes,6,opt,name=update_id,json=updateId,proto3" json:"update_id,omitempty"` // The revision number of this update package. RevisionNumber int32 `protobuf:"varint,7,opt,name=revision_number,json=revisionNumber,proto3" json:"revision_number,omitempty"` // The last published date of the update, in (UTC) date and time. LastDeploymentChangeTime *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=last_deployment_change_time,json=lastDeploymentChangeTime,proto3" json:"last_deployment_change_time,omitempty"` } func (x *Inventory_WindowsUpdatePackage) Reset() { *x = Inventory_WindowsUpdatePackage{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *Inventory_WindowsUpdatePackage) String() string { return protoimpl.X.MessageStringOf(x) } func (*Inventory_WindowsUpdatePackage) ProtoMessage() {} func (x *Inventory_WindowsUpdatePackage) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use Inventory_WindowsUpdatePackage.ProtoReflect.Descriptor instead. func (*Inventory_WindowsUpdatePackage) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_inventory_proto_rawDescGZIP(), []int{0, 5} } func (x *Inventory_WindowsUpdatePackage) GetTitle() string { if x != nil { return x.Title } return "" } func (x *Inventory_WindowsUpdatePackage) GetDescription() string { if x != nil { return x.Description } return "" } func (x *Inventory_WindowsUpdatePackage) GetCategories() []*Inventory_WindowsUpdatePackage_WindowsUpdateCategory { if x != nil { return x.Categories } return nil } func (x *Inventory_WindowsUpdatePackage) GetKbArticleIds() []string { if x != nil { return x.KbArticleIds } return nil } func (x *Inventory_WindowsUpdatePackage) GetSupportUrl() string { if x != nil { return x.SupportUrl } return "" } func (x *Inventory_WindowsUpdatePackage) GetMoreInfoUrls() []string { if x != nil { return x.MoreInfoUrls } return nil } func (x *Inventory_WindowsUpdatePackage) GetUpdateId() string { if x != nil { return x.UpdateId } return "" } func (x *Inventory_WindowsUpdatePackage) GetRevisionNumber() int32 { if x != nil { return x.RevisionNumber } return 0 } func (x *Inventory_WindowsUpdatePackage) GetLastDeploymentChangeTime() *timestamppb.Timestamp { if x != nil { return x.LastDeploymentChangeTime } return nil } // Information related to a Quick Fix Engineering package. // Fields are taken from Windows QuickFixEngineering Interface and match // the source names: // https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-quickfixengineering type Inventory_WindowsQuickFixEngineeringPackage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // A short textual description of the QFE update. Caption string `protobuf:"bytes,1,opt,name=caption,proto3" json:"caption,omitempty"` // A textual description of the QFE update. Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // Unique identifier associated with a particular QFE update. HotFixId string `protobuf:"bytes,3,opt,name=hot_fix_id,json=hotFixId,proto3" json:"hot_fix_id,omitempty"` // Date that the QFE update was installed. Mapped from installed_on field. InstallTime *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=install_time,json=installTime,proto3" json:"install_time,omitempty"` } func (x *Inventory_WindowsQuickFixEngineeringPackage) Reset() { *x = Inventory_WindowsQuickFixEngineeringPackage{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *Inventory_WindowsQuickFixEngineeringPackage) String() string { return protoimpl.X.MessageStringOf(x) } func (*Inventory_WindowsQuickFixEngineeringPackage) ProtoMessage() {} func (x *Inventory_WindowsQuickFixEngineeringPackage) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use Inventory_WindowsQuickFixEngineeringPackage.ProtoReflect.Descriptor instead. func (*Inventory_WindowsQuickFixEngineeringPackage) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_inventory_proto_rawDescGZIP(), []int{0, 6} } func (x *Inventory_WindowsQuickFixEngineeringPackage) GetCaption() string { if x != nil { return x.Caption } return "" } func (x *Inventory_WindowsQuickFixEngineeringPackage) GetDescription() string { if x != nil { return x.Description } return "" } func (x *Inventory_WindowsQuickFixEngineeringPackage) GetHotFixId() string { if x != nil { return x.HotFixId } return "" } func (x *Inventory_WindowsQuickFixEngineeringPackage) GetInstallTime() *timestamppb.Timestamp { if x != nil { return x.InstallTime } return nil } // Contains information about a Windows application that is retrieved from the // Windows Registry. For more information about these fields, see // Windows Installer Properties for the Uninstall // Registry. type Inventory_WindowsApplication struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // The name of the application or product. DisplayName string `protobuf:"bytes,1,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` // The version of the product or application in string format. DisplayVersion string `protobuf:"bytes,2,opt,name=display_version,json=displayVersion,proto3" json:"display_version,omitempty"` // The name of the manufacturer for the product or application. Publisher string `protobuf:"bytes,3,opt,name=publisher,proto3" json:"publisher,omitempty"` // The last time this product received service. The value of this property // is replaced each time a patch is applied or removed from the product or // the command-line option is used to repair the product. InstallDate *date.Date `protobuf:"bytes,4,opt,name=install_date,json=installDate,proto3" json:"install_date,omitempty"` // The internet address for technical support. HelpLink string `protobuf:"bytes,5,opt,name=help_link,json=helpLink,proto3" json:"help_link,omitempty"` } func (x *Inventory_WindowsApplication) Reset() { *x = Inventory_WindowsApplication{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *Inventory_WindowsApplication) String() string { return protoimpl.X.MessageStringOf(x) } func (*Inventory_WindowsApplication) ProtoMessage() {} func (x *Inventory_WindowsApplication) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use Inventory_WindowsApplication.ProtoReflect.Descriptor instead. func (*Inventory_WindowsApplication) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_inventory_proto_rawDescGZIP(), []int{0, 7} } func (x *Inventory_WindowsApplication) GetDisplayName() string { if x != nil { return x.DisplayName } return "" } func (x *Inventory_WindowsApplication) GetDisplayVersion() string { if x != nil { return x.DisplayVersion } return "" } func (x *Inventory_WindowsApplication) GetPublisher() string { if x != nil { return x.Publisher } return "" } func (x *Inventory_WindowsApplication) GetInstallDate() *date.Date { if x != nil { return x.InstallDate } return nil } func (x *Inventory_WindowsApplication) GetHelpLink() string { if x != nil { return x.HelpLink } return "" } // Categories specified by the Windows Update. type Inventory_WindowsUpdatePackage_WindowsUpdateCategory struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // The identifier of the windows update category. Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // The name of the windows update category. Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` } func (x *Inventory_WindowsUpdatePackage_WindowsUpdateCategory) Reset() { *x = Inventory_WindowsUpdatePackage_WindowsUpdateCategory{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *Inventory_WindowsUpdatePackage_WindowsUpdateCategory) String() string { return protoimpl.X.MessageStringOf(x) } func (*Inventory_WindowsUpdatePackage_WindowsUpdateCategory) ProtoMessage() {} func (x *Inventory_WindowsUpdatePackage_WindowsUpdateCategory) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_inventory_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use Inventory_WindowsUpdatePackage_WindowsUpdateCategory.ProtoReflect.Descriptor instead. func (*Inventory_WindowsUpdatePackage_WindowsUpdateCategory) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_inventory_proto_rawDescGZIP(), []int{0, 5, 0} } func (x *Inventory_WindowsUpdatePackage_WindowsUpdateCategory) GetId() string { if x != nil { return x.Id } return "" } func (x *Inventory_WindowsUpdatePackage_WindowsUpdateCategory) GetName() string { if x != nil { return x.Name } return "" } var File_google_cloud_osconfig_v1_inventory_proto protoreflect.FileDescriptor var file_google_cloud_osconfig_v1_inventory_proto_rawDesc = []byte{ 0x0a, 0x28, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x18, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x16, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x2f, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xfa, 0x1a, 0x0a, 0x09, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x17, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x03, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x43, 0x0a, 0x07, 0x6f, 0x73, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x4f, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x6f, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x44, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x40, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x03, 0xe0, 0x41, 0x03, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x1a, 0xa2, 0x02, 0x0a, 0x06, 0x4f, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x6e, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x89, 0x05, 0x0a, 0x04, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x54, 0x0a, 0x0b, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x41, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x62, 0x0a, 0x11, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x62, 0x0a, 0x11, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x10, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x22, 0x3f, 0x0a, 0x0a, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x4f, 0x52, 0x49, 0x47, 0x49, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x49, 0x4e, 0x56, 0x45, 0x4e, 0x54, 0x4f, 0x52, 0x59, 0x5f, 0x52, 0x45, 0x50, 0x4f, 0x52, 0x54, 0x10, 0x01, 0x22, 0x4a, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x41, 0x47, 0x45, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x41, 0x56, 0x41, 0x49, 0x4c, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x41, 0x47, 0x45, 0x10, 0x02, 0x42, 0x09, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0xed, 0x06, 0x0a, 0x0f, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x57, 0x0a, 0x0b, 0x79, 0x75, 0x6d, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0a, 0x79, 0x75, 0x6d, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x57, 0x0a, 0x0b, 0x61, 0x70, 0x74, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x70, 0x74, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x5d, 0x0a, 0x0e, 0x7a, 0x79, 0x70, 0x70, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x7a, 0x79, 0x70, 0x70, 0x65, 0x72, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x5d, 0x0a, 0x0e, 0x67, 0x6f, 0x6f, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x67, 0x6f, 0x6f, 0x67, 0x65, 0x74, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x54, 0x0a, 0x0c, 0x7a, 0x79, 0x70, 0x70, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x5a, 0x79, 0x70, 0x70, 0x65, 0x72, 0x50, 0x61, 0x74, 0x63, 0x68, 0x48, 0x00, 0x52, 0x0b, 0x7a, 0x79, 0x70, 0x70, 0x65, 0x72, 0x50, 0x61, 0x74, 0x63, 0x68, 0x12, 0x5b, 0x0a, 0x0b, 0x77, 0x75, 0x61, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0a, 0x77, 0x75, 0x61, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x68, 0x0a, 0x0b, 0x71, 0x66, 0x65, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x51, 0x75, 0x69, 0x63, 0x6b, 0x46, 0x69, 0x78, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0a, 0x71, 0x66, 0x65, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x57, 0x0a, 0x0b, 0x63, 0x6f, 0x73, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0a, 0x63, 0x6f, 0x73, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x69, 0x0a, 0x13, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x12, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x09, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x73, 0x0a, 0x10, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x7e, 0x0a, 0x0b, 0x5a, 0x79, 0x70, 0x70, 0x65, 0x72, 0x50, 0x61, 0x74, 0x63, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x74, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x1a, 0x89, 0x04, 0x0a, 0x14, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x6e, 0x0a, 0x0a, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x4e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x52, 0x0a, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x6b, 0x62, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x6b, 0x62, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x49, 0x64, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x55, 0x72, 0x6c, 0x12, 0x24, 0x0a, 0x0e, 0x6d, 0x6f, 0x72, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x75, 0x72, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x6d, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x55, 0x72, 0x6c, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x59, 0x0a, 0x1b, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x18, 0x6c, 0x61, 0x73, 0x74, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x1a, 0x3b, 0x0a, 0x15, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x1a, 0xbc, 0x01, 0x0a, 0x21, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x51, 0x75, 0x69, 0x63, 0x6b, 0x46, 0x69, 0x78, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x61, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x61, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x0a, 0x68, 0x6f, 0x74, 0x5f, 0x66, 0x69, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x74, 0x46, 0x69, 0x78, 0x49, 0x64, 0x12, 0x3d, 0x0a, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x1a, 0xd1, 0x01, 0x0a, 0x12, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x12, 0x34, 0x0a, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x44, 0x61, 0x74, 0x65, 0x52, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x44, 0x61, 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x68, 0x65, 0x6c, 0x70, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x65, 0x6c, 0x70, 0x4c, 0x69, 0x6e, 0x6b, 0x1a, 0x62, 0x0a, 0x0a, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x6e, 0xea, 0x41, 0x6b, 0x0a, 0x21, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x46, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x7d, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7d, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x7d, 0x2f, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x91, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3d, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x29, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x23, 0x0a, 0x21, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x76, 0x69, 0x65, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x56, 0x69, 0x65, 0x77, 0x52, 0x04, 0x76, 0x69, 0x65, 0x77, 0x22, 0xea, 0x01, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x27, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x21, 0x0a, 0x1f, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x3b, 0x0a, 0x04, 0x76, 0x69, 0x65, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x56, 0x69, 0x65, 0x77, 0x52, 0x04, 0x76, 0x69, 0x65, 0x77, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x88, 0x01, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0b, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x0b, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x2a, 0x44, 0x0a, 0x0d, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x56, 0x69, 0x65, 0x77, 0x12, 0x1e, 0x0a, 0x1a, 0x49, 0x4e, 0x56, 0x45, 0x4e, 0x54, 0x4f, 0x52, 0x59, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x55, 0x4c, 0x4c, 0x10, 0x02, 0x42, 0xc3, 0x01, 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x50, 0x01, 0x5a, 0x40, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x3b, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0xaa, 0x02, 0x18, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x18, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5c, 0x56, 0x31, 0xea, 0x02, 0x1b, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( file_google_cloud_osconfig_v1_inventory_proto_rawDescOnce sync.Once file_google_cloud_osconfig_v1_inventory_proto_rawDescData = file_google_cloud_osconfig_v1_inventory_proto_rawDesc ) func file_google_cloud_osconfig_v1_inventory_proto_rawDescGZIP() []byte { file_google_cloud_osconfig_v1_inventory_proto_rawDescOnce.Do(func() { file_google_cloud_osconfig_v1_inventory_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_cloud_osconfig_v1_inventory_proto_rawDescData) }) return file_google_cloud_osconfig_v1_inventory_proto_rawDescData } var file_google_cloud_osconfig_v1_inventory_proto_enumTypes = make([]protoimpl.EnumInfo, 3) var file_google_cloud_osconfig_v1_inventory_proto_msgTypes = make([]protoimpl.MessageInfo, 14) var file_google_cloud_osconfig_v1_inventory_proto_goTypes = []interface{}{ (InventoryView)(0), // 0: google.cloud.osconfig.v1.InventoryView (Inventory_Item_OriginType)(0), // 1: google.cloud.osconfig.v1.Inventory.Item.OriginType (Inventory_Item_Type)(0), // 2: google.cloud.osconfig.v1.Inventory.Item.Type (*Inventory)(nil), // 3: google.cloud.osconfig.v1.Inventory (*GetInventoryRequest)(nil), // 4: google.cloud.osconfig.v1.GetInventoryRequest (*ListInventoriesRequest)(nil), // 5: google.cloud.osconfig.v1.ListInventoriesRequest (*ListInventoriesResponse)(nil), // 6: google.cloud.osconfig.v1.ListInventoriesResponse (*Inventory_OsInfo)(nil), // 7: google.cloud.osconfig.v1.Inventory.OsInfo (*Inventory_Item)(nil), // 8: google.cloud.osconfig.v1.Inventory.Item (*Inventory_SoftwarePackage)(nil), // 9: google.cloud.osconfig.v1.Inventory.SoftwarePackage (*Inventory_VersionedPackage)(nil), // 10: google.cloud.osconfig.v1.Inventory.VersionedPackage (*Inventory_ZypperPatch)(nil), // 11: google.cloud.osconfig.v1.Inventory.ZypperPatch (*Inventory_WindowsUpdatePackage)(nil), // 12: google.cloud.osconfig.v1.Inventory.WindowsUpdatePackage (*Inventory_WindowsQuickFixEngineeringPackage)(nil), // 13: google.cloud.osconfig.v1.Inventory.WindowsQuickFixEngineeringPackage (*Inventory_WindowsApplication)(nil), // 14: google.cloud.osconfig.v1.Inventory.WindowsApplication nil, // 15: google.cloud.osconfig.v1.Inventory.ItemsEntry (*Inventory_WindowsUpdatePackage_WindowsUpdateCategory)(nil), // 16: google.cloud.osconfig.v1.Inventory.WindowsUpdatePackage.WindowsUpdateCategory (*timestamppb.Timestamp)(nil), // 17: google.protobuf.Timestamp (*date.Date)(nil), // 18: google.type.Date } var file_google_cloud_osconfig_v1_inventory_proto_depIdxs = []int32{ 7, // 0: google.cloud.osconfig.v1.Inventory.os_info:type_name -> google.cloud.osconfig.v1.Inventory.OsInfo 15, // 1: google.cloud.osconfig.v1.Inventory.items:type_name -> google.cloud.osconfig.v1.Inventory.ItemsEntry 17, // 2: google.cloud.osconfig.v1.Inventory.update_time:type_name -> google.protobuf.Timestamp 0, // 3: google.cloud.osconfig.v1.GetInventoryRequest.view:type_name -> google.cloud.osconfig.v1.InventoryView 0, // 4: google.cloud.osconfig.v1.ListInventoriesRequest.view:type_name -> google.cloud.osconfig.v1.InventoryView 3, // 5: google.cloud.osconfig.v1.ListInventoriesResponse.inventories:type_name -> google.cloud.osconfig.v1.Inventory 1, // 6: google.cloud.osconfig.v1.Inventory.Item.origin_type:type_name -> google.cloud.osconfig.v1.Inventory.Item.OriginType 17, // 7: google.cloud.osconfig.v1.Inventory.Item.create_time:type_name -> google.protobuf.Timestamp 17, // 8: google.cloud.osconfig.v1.Inventory.Item.update_time:type_name -> google.protobuf.Timestamp 2, // 9: google.cloud.osconfig.v1.Inventory.Item.type:type_name -> google.cloud.osconfig.v1.Inventory.Item.Type 9, // 10: google.cloud.osconfig.v1.Inventory.Item.installed_package:type_name -> google.cloud.osconfig.v1.Inventory.SoftwarePackage 9, // 11: google.cloud.osconfig.v1.Inventory.Item.available_package:type_name -> google.cloud.osconfig.v1.Inventory.SoftwarePackage 10, // 12: google.cloud.osconfig.v1.Inventory.SoftwarePackage.yum_package:type_name -> google.cloud.osconfig.v1.Inventory.VersionedPackage 10, // 13: google.cloud.osconfig.v1.Inventory.SoftwarePackage.apt_package:type_name -> google.cloud.osconfig.v1.Inventory.VersionedPackage 10, // 14: google.cloud.osconfig.v1.Inventory.SoftwarePackage.zypper_package:type_name -> google.cloud.osconfig.v1.Inventory.VersionedPackage 10, // 15: google.cloud.osconfig.v1.Inventory.SoftwarePackage.googet_package:type_name -> google.cloud.osconfig.v1.Inventory.VersionedPackage 11, // 16: google.cloud.osconfig.v1.Inventory.SoftwarePackage.zypper_patch:type_name -> google.cloud.osconfig.v1.Inventory.ZypperPatch 12, // 17: google.cloud.osconfig.v1.Inventory.SoftwarePackage.wua_package:type_name -> google.cloud.osconfig.v1.Inventory.WindowsUpdatePackage 13, // 18: google.cloud.osconfig.v1.Inventory.SoftwarePackage.qfe_package:type_name -> google.cloud.osconfig.v1.Inventory.WindowsQuickFixEngineeringPackage 10, // 19: google.cloud.osconfig.v1.Inventory.SoftwarePackage.cos_package:type_name -> google.cloud.osconfig.v1.Inventory.VersionedPackage 14, // 20: google.cloud.osconfig.v1.Inventory.SoftwarePackage.windows_application:type_name -> google.cloud.osconfig.v1.Inventory.WindowsApplication 16, // 21: google.cloud.osconfig.v1.Inventory.WindowsUpdatePackage.categories:type_name -> google.cloud.osconfig.v1.Inventory.WindowsUpdatePackage.WindowsUpdateCategory 17, // 22: google.cloud.osconfig.v1.Inventory.WindowsUpdatePackage.last_deployment_change_time:type_name -> google.protobuf.Timestamp 17, // 23: google.cloud.osconfig.v1.Inventory.WindowsQuickFixEngineeringPackage.install_time:type_name -> google.protobuf.Timestamp 18, // 24: google.cloud.osconfig.v1.Inventory.WindowsApplication.install_date:type_name -> google.type.Date 8, // 25: google.cloud.osconfig.v1.Inventory.ItemsEntry.value:type_name -> google.cloud.osconfig.v1.Inventory.Item 26, // [26:26] is the sub-list for method output_type 26, // [26:26] is the sub-list for method input_type 26, // [26:26] is the sub-list for extension type_name 26, // [26:26] is the sub-list for extension extendee 0, // [0:26] is the sub-list for field type_name } func init() { file_google_cloud_osconfig_v1_inventory_proto_init() } func file_google_cloud_osconfig_v1_inventory_proto_init() { if File_google_cloud_osconfig_v1_inventory_proto != nil { return } if !protoimpl.UnsafeEnabled { file_google_cloud_osconfig_v1_inventory_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Inventory); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_inventory_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetInventoryRequest); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_inventory_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListInventoriesRequest); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_inventory_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListInventoriesResponse); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_inventory_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Inventory_OsInfo); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_inventory_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Inventory_Item); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_inventory_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Inventory_SoftwarePackage); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_inventory_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Inventory_VersionedPackage); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_inventory_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Inventory_ZypperPatch); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_inventory_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Inventory_WindowsUpdatePackage); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_inventory_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Inventory_WindowsQuickFixEngineeringPackage); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_inventory_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Inventory_WindowsApplication); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_inventory_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Inventory_WindowsUpdatePackage_WindowsUpdateCategory); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } } file_google_cloud_osconfig_v1_inventory_proto_msgTypes[5].OneofWrappers = []interface{}{ (*Inventory_Item_InstalledPackage)(nil), (*Inventory_Item_AvailablePackage)(nil), } file_google_cloud_osconfig_v1_inventory_proto_msgTypes[6].OneofWrappers = []interface{}{ (*Inventory_SoftwarePackage_YumPackage)(nil), (*Inventory_SoftwarePackage_AptPackage)(nil), (*Inventory_SoftwarePackage_ZypperPackage)(nil), (*Inventory_SoftwarePackage_GoogetPackage)(nil), (*Inventory_SoftwarePackage_ZypperPatch)(nil), (*Inventory_SoftwarePackage_WuaPackage)(nil), (*Inventory_SoftwarePackage_QfePackage)(nil), (*Inventory_SoftwarePackage_CosPackage)(nil), (*Inventory_SoftwarePackage_WindowsApplication)(nil), } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_google_cloud_osconfig_v1_inventory_proto_rawDesc, NumEnums: 3, NumMessages: 14, NumExtensions: 0, NumServices: 0, }, GoTypes: file_google_cloud_osconfig_v1_inventory_proto_goTypes, DependencyIndexes: file_google_cloud_osconfig_v1_inventory_proto_depIdxs, EnumInfos: file_google_cloud_osconfig_v1_inventory_proto_enumTypes, MessageInfos: file_google_cloud_osconfig_v1_inventory_proto_msgTypes, }.Build() File_google_cloud_osconfig_v1_inventory_proto = out.File file_google_cloud_osconfig_v1_inventory_proto_rawDesc = nil file_google_cloud_osconfig_v1_inventory_proto_goTypes = nil file_google_cloud_osconfig_v1_inventory_proto_depIdxs = nil } os_policy.pb.go000066400000000000000000003704131477773331400351600ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/internal/google.golang.org/genproto/googleapis/cloud/osconfig/v1// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.25.0 // protoc v3.15.3 // source: google/cloud/osconfig/v1/os_policy.proto package osconfig import ( proto "github.com/golang/protobuf/proto" _ "google.golang.org/genproto/googleapis/api/annotations" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" ) const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) // Verify that runtime/protoimpl is sufficiently up-to-date. _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) // This is a compile-time assertion that a sufficiently up-to-date version // of the legacy proto package is being used. const _ = proto.ProtoPackageIsVersion4 // Policy mode type OSPolicy_Mode int32 const ( // Invalid mode OSPolicy_MODE_UNSPECIFIED OSPolicy_Mode = 0 // This mode checks if the configuration resources in the policy are in // their desired state. No actions are performed if they are not in the // desired state. This mode is used for reporting purposes. OSPolicy_VALIDATION OSPolicy_Mode = 1 // This mode checks if the configuration resources in the policy are in // their desired state, and if not, enforces the desired state. OSPolicy_ENFORCEMENT OSPolicy_Mode = 2 ) // Enum value maps for OSPolicy_Mode. var ( OSPolicy_Mode_name = map[int32]string{ 0: "MODE_UNSPECIFIED", 1: "VALIDATION", 2: "ENFORCEMENT", } OSPolicy_Mode_value = map[string]int32{ "MODE_UNSPECIFIED": 0, "VALIDATION": 1, "ENFORCEMENT": 2, } ) func (x OSPolicy_Mode) Enum() *OSPolicy_Mode { p := new(OSPolicy_Mode) *p = x return p } func (x OSPolicy_Mode) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (OSPolicy_Mode) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_os_policy_proto_enumTypes[0].Descriptor() } func (OSPolicy_Mode) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_os_policy_proto_enumTypes[0] } func (x OSPolicy_Mode) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use OSPolicy_Mode.Descriptor instead. func (OSPolicy_Mode) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 0} } // The desired state that the OS Config agent maintains on the VM. type OSPolicy_Resource_PackageResource_DesiredState int32 const ( // Unspecified is invalid. OSPolicy_Resource_PackageResource_DESIRED_STATE_UNSPECIFIED OSPolicy_Resource_PackageResource_DesiredState = 0 // Ensure that the package is installed. OSPolicy_Resource_PackageResource_INSTALLED OSPolicy_Resource_PackageResource_DesiredState = 1 // The agent ensures that the package is not installed and // uninstalls it if detected. OSPolicy_Resource_PackageResource_REMOVED OSPolicy_Resource_PackageResource_DesiredState = 2 ) // Enum value maps for OSPolicy_Resource_PackageResource_DesiredState. var ( OSPolicy_Resource_PackageResource_DesiredState_name = map[int32]string{ 0: "DESIRED_STATE_UNSPECIFIED", 1: "INSTALLED", 2: "REMOVED", } OSPolicy_Resource_PackageResource_DesiredState_value = map[string]int32{ "DESIRED_STATE_UNSPECIFIED": 0, "INSTALLED": 1, "REMOVED": 2, } ) func (x OSPolicy_Resource_PackageResource_DesiredState) Enum() *OSPolicy_Resource_PackageResource_DesiredState { p := new(OSPolicy_Resource_PackageResource_DesiredState) *p = x return p } func (x OSPolicy_Resource_PackageResource_DesiredState) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (OSPolicy_Resource_PackageResource_DesiredState) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_os_policy_proto_enumTypes[1].Descriptor() } func (OSPolicy_Resource_PackageResource_DesiredState) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_os_policy_proto_enumTypes[1] } func (x OSPolicy_Resource_PackageResource_DesiredState) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use OSPolicy_Resource_PackageResource_DesiredState.Descriptor instead. func (OSPolicy_Resource_PackageResource_DesiredState) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 1, 1, 0} } // Type of archive. type OSPolicy_Resource_RepositoryResource_AptRepository_ArchiveType int32 const ( // Unspecified is invalid. OSPolicy_Resource_RepositoryResource_AptRepository_ARCHIVE_TYPE_UNSPECIFIED OSPolicy_Resource_RepositoryResource_AptRepository_ArchiveType = 0 // Deb indicates that the archive contains binary files. OSPolicy_Resource_RepositoryResource_AptRepository_DEB OSPolicy_Resource_RepositoryResource_AptRepository_ArchiveType = 1 // Deb-src indicates that the archive contains source files. OSPolicy_Resource_RepositoryResource_AptRepository_DEB_SRC OSPolicy_Resource_RepositoryResource_AptRepository_ArchiveType = 2 ) // Enum value maps for OSPolicy_Resource_RepositoryResource_AptRepository_ArchiveType. var ( OSPolicy_Resource_RepositoryResource_AptRepository_ArchiveType_name = map[int32]string{ 0: "ARCHIVE_TYPE_UNSPECIFIED", 1: "DEB", 2: "DEB_SRC", } OSPolicy_Resource_RepositoryResource_AptRepository_ArchiveType_value = map[string]int32{ "ARCHIVE_TYPE_UNSPECIFIED": 0, "DEB": 1, "DEB_SRC": 2, } ) func (x OSPolicy_Resource_RepositoryResource_AptRepository_ArchiveType) Enum() *OSPolicy_Resource_RepositoryResource_AptRepository_ArchiveType { p := new(OSPolicy_Resource_RepositoryResource_AptRepository_ArchiveType) *p = x return p } func (x OSPolicy_Resource_RepositoryResource_AptRepository_ArchiveType) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (OSPolicy_Resource_RepositoryResource_AptRepository_ArchiveType) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_os_policy_proto_enumTypes[2].Descriptor() } func (OSPolicy_Resource_RepositoryResource_AptRepository_ArchiveType) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_os_policy_proto_enumTypes[2] } func (x OSPolicy_Resource_RepositoryResource_AptRepository_ArchiveType) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use OSPolicy_Resource_RepositoryResource_AptRepository_ArchiveType.Descriptor instead. func (OSPolicy_Resource_RepositoryResource_AptRepository_ArchiveType) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 1, 2, 0, 0} } // The interpreter to use. type OSPolicy_Resource_ExecResource_Exec_Interpreter int32 const ( // Defaults to NONE. OSPolicy_Resource_ExecResource_Exec_INTERPRETER_UNSPECIFIED OSPolicy_Resource_ExecResource_Exec_Interpreter = 0 // If an interpreter is not specified, the // source is executed directly. This execution, without an // interpreter, only succeeds for executables and scripts that have shebang lines. OSPolicy_Resource_ExecResource_Exec_NONE OSPolicy_Resource_ExecResource_Exec_Interpreter = 1 // Indicates that the script runs with `/bin/sh` on Linux and // `cmd.exe` on Windows. OSPolicy_Resource_ExecResource_Exec_SHELL OSPolicy_Resource_ExecResource_Exec_Interpreter = 2 // Indicates that the script runs with PowerShell. OSPolicy_Resource_ExecResource_Exec_POWERSHELL OSPolicy_Resource_ExecResource_Exec_Interpreter = 3 ) // Enum value maps for OSPolicy_Resource_ExecResource_Exec_Interpreter. var ( OSPolicy_Resource_ExecResource_Exec_Interpreter_name = map[int32]string{ 0: "INTERPRETER_UNSPECIFIED", 1: "NONE", 2: "SHELL", 3: "POWERSHELL", } OSPolicy_Resource_ExecResource_Exec_Interpreter_value = map[string]int32{ "INTERPRETER_UNSPECIFIED": 0, "NONE": 1, "SHELL": 2, "POWERSHELL": 3, } ) func (x OSPolicy_Resource_ExecResource_Exec_Interpreter) Enum() *OSPolicy_Resource_ExecResource_Exec_Interpreter { p := new(OSPolicy_Resource_ExecResource_Exec_Interpreter) *p = x return p } func (x OSPolicy_Resource_ExecResource_Exec_Interpreter) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (OSPolicy_Resource_ExecResource_Exec_Interpreter) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_os_policy_proto_enumTypes[3].Descriptor() } func (OSPolicy_Resource_ExecResource_Exec_Interpreter) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_os_policy_proto_enumTypes[3] } func (x OSPolicy_Resource_ExecResource_Exec_Interpreter) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use OSPolicy_Resource_ExecResource_Exec_Interpreter.Descriptor instead. func (OSPolicy_Resource_ExecResource_Exec_Interpreter) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 1, 3, 0, 0} } // Desired state of the file. type OSPolicy_Resource_FileResource_DesiredState int32 const ( // Unspecified is invalid. OSPolicy_Resource_FileResource_DESIRED_STATE_UNSPECIFIED OSPolicy_Resource_FileResource_DesiredState = 0 // Ensure file at path is present. OSPolicy_Resource_FileResource_PRESENT OSPolicy_Resource_FileResource_DesiredState = 1 // Ensure file at path is absent. OSPolicy_Resource_FileResource_ABSENT OSPolicy_Resource_FileResource_DesiredState = 2 // Ensure the contents of the file at path matches. If the file does // not exist it will be created. OSPolicy_Resource_FileResource_CONTENTS_MATCH OSPolicy_Resource_FileResource_DesiredState = 3 ) // Enum value maps for OSPolicy_Resource_FileResource_DesiredState. var ( OSPolicy_Resource_FileResource_DesiredState_name = map[int32]string{ 0: "DESIRED_STATE_UNSPECIFIED", 1: "PRESENT", 2: "ABSENT", 3: "CONTENTS_MATCH", } OSPolicy_Resource_FileResource_DesiredState_value = map[string]int32{ "DESIRED_STATE_UNSPECIFIED": 0, "PRESENT": 1, "ABSENT": 2, "CONTENTS_MATCH": 3, } ) func (x OSPolicy_Resource_FileResource_DesiredState) Enum() *OSPolicy_Resource_FileResource_DesiredState { p := new(OSPolicy_Resource_FileResource_DesiredState) *p = x return p } func (x OSPolicy_Resource_FileResource_DesiredState) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (OSPolicy_Resource_FileResource_DesiredState) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_os_policy_proto_enumTypes[4].Descriptor() } func (OSPolicy_Resource_FileResource_DesiredState) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_os_policy_proto_enumTypes[4] } func (x OSPolicy_Resource_FileResource_DesiredState) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use OSPolicy_Resource_FileResource_DesiredState.Descriptor instead. func (OSPolicy_Resource_FileResource_DesiredState) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 1, 4, 0} } // An OS policy defines the desired state configuration for a VM. type OSPolicy struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. The id of the OS policy with the following restrictions: // // * Must contain only lowercase letters, numbers, and hyphens. // * Must start with a letter. // * Must be between 1-63 characters. // * Must end with a number or a letter. // * Must be unique within the assignment. Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // Policy description. // Length of the description is limited to 1024 characters. Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // Required. Policy mode Mode OSPolicy_Mode `protobuf:"varint,3,opt,name=mode,proto3,enum=google.cloud.osconfig.v1.OSPolicy_Mode" json:"mode,omitempty"` // Required. List of resource groups for the policy. // For a particular VM, resource groups are evaluated in the order specified // and the first resource group that is applicable is selected and the rest // are ignored. // // If none of the resource groups are applicable for a VM, the VM is // considered to be non-compliant w.r.t this policy. This behavior can be // toggled by the flag `allow_no_resource_group_match` ResourceGroups []*OSPolicy_ResourceGroup `protobuf:"bytes,4,rep,name=resource_groups,json=resourceGroups,proto3" json:"resource_groups,omitempty"` // This flag determines the OS policy compliance status when none of the // resource groups within the policy are applicable for a VM. Set this value // to `true` if the policy needs to be reported as compliant even if the // policy has nothing to validate or enforce. AllowNoResourceGroupMatch bool `protobuf:"varint,5,opt,name=allow_no_resource_group_match,json=allowNoResourceGroupMatch,proto3" json:"allow_no_resource_group_match,omitempty"` } func (x *OSPolicy) Reset() { *x = OSPolicy{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicy) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicy) ProtoMessage() {} func (x *OSPolicy) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicy.ProtoReflect.Descriptor instead. func (*OSPolicy) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0} } func (x *OSPolicy) GetId() string { if x != nil { return x.Id } return "" } func (x *OSPolicy) GetDescription() string { if x != nil { return x.Description } return "" } func (x *OSPolicy) GetMode() OSPolicy_Mode { if x != nil { return x.Mode } return OSPolicy_MODE_UNSPECIFIED } func (x *OSPolicy) GetResourceGroups() []*OSPolicy_ResourceGroup { if x != nil { return x.ResourceGroups } return nil } func (x *OSPolicy) GetAllowNoResourceGroupMatch() bool { if x != nil { return x.AllowNoResourceGroupMatch } return false } // Filtering criteria to select VMs based on inventory details. type OSPolicy_InventoryFilter struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. The OS short name OsShortName string `protobuf:"bytes,1,opt,name=os_short_name,json=osShortName,proto3" json:"os_short_name,omitempty"` // The OS version // // Prefix matches are supported if asterisk(*) is provided as the // last character. For example, to match all versions with a major // version of `7`, specify the following value for this field `7.*` // // An empty string matches all OS versions. OsVersion string `protobuf:"bytes,2,opt,name=os_version,json=osVersion,proto3" json:"os_version,omitempty"` } func (x *OSPolicy_InventoryFilter) Reset() { *x = OSPolicy_InventoryFilter{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicy_InventoryFilter) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicy_InventoryFilter) ProtoMessage() {} func (x *OSPolicy_InventoryFilter) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicy_InventoryFilter.ProtoReflect.Descriptor instead. func (*OSPolicy_InventoryFilter) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 0} } func (x *OSPolicy_InventoryFilter) GetOsShortName() string { if x != nil { return x.OsShortName } return "" } func (x *OSPolicy_InventoryFilter) GetOsVersion() string { if x != nil { return x.OsVersion } return "" } // An OS policy resource is used to define the desired state configuration // and provides a specific functionality like installing/removing packages, // executing a script etc. // // The system ensures that resources are always in their desired state by // taking necessary actions if they have drifted from their desired state. type OSPolicy_Resource struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. The id of the resource with the following restrictions: // // * Must contain only lowercase letters, numbers, and hyphens. // * Must start with a letter. // * Must be between 1-63 characters. // * Must end with a number or a letter. // * Must be unique within the OS policy. Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // Resource type. // // Types that are assignable to ResourceType: // *OSPolicy_Resource_Pkg // *OSPolicy_Resource_Repository // *OSPolicy_Resource_Exec // *OSPolicy_Resource_File_ ResourceType isOSPolicy_Resource_ResourceType `protobuf_oneof:"resource_type"` } func (x *OSPolicy_Resource) Reset() { *x = OSPolicy_Resource{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicy_Resource) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicy_Resource) ProtoMessage() {} func (x *OSPolicy_Resource) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicy_Resource.ProtoReflect.Descriptor instead. func (*OSPolicy_Resource) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 1} } func (x *OSPolicy_Resource) GetId() string { if x != nil { return x.Id } return "" } func (m *OSPolicy_Resource) GetResourceType() isOSPolicy_Resource_ResourceType { if m != nil { return m.ResourceType } return nil } func (x *OSPolicy_Resource) GetPkg() *OSPolicy_Resource_PackageResource { if x, ok := x.GetResourceType().(*OSPolicy_Resource_Pkg); ok { return x.Pkg } return nil } func (x *OSPolicy_Resource) GetRepository() *OSPolicy_Resource_RepositoryResource { if x, ok := x.GetResourceType().(*OSPolicy_Resource_Repository); ok { return x.Repository } return nil } func (x *OSPolicy_Resource) GetExec() *OSPolicy_Resource_ExecResource { if x, ok := x.GetResourceType().(*OSPolicy_Resource_Exec); ok { return x.Exec } return nil } func (x *OSPolicy_Resource) GetFile() *OSPolicy_Resource_FileResource { if x, ok := x.GetResourceType().(*OSPolicy_Resource_File_); ok { return x.File } return nil } type isOSPolicy_Resource_ResourceType interface { isOSPolicy_Resource_ResourceType() } type OSPolicy_Resource_Pkg struct { // Package resource Pkg *OSPolicy_Resource_PackageResource `protobuf:"bytes,2,opt,name=pkg,proto3,oneof"` } type OSPolicy_Resource_Repository struct { // Package repository resource Repository *OSPolicy_Resource_RepositoryResource `protobuf:"bytes,3,opt,name=repository,proto3,oneof"` } type OSPolicy_Resource_Exec struct { // Exec resource Exec *OSPolicy_Resource_ExecResource `protobuf:"bytes,4,opt,name=exec,proto3,oneof"` } type OSPolicy_Resource_File_ struct { // File resource File *OSPolicy_Resource_FileResource `protobuf:"bytes,5,opt,name=file,proto3,oneof"` } func (*OSPolicy_Resource_Pkg) isOSPolicy_Resource_ResourceType() {} func (*OSPolicy_Resource_Repository) isOSPolicy_Resource_ResourceType() {} func (*OSPolicy_Resource_Exec) isOSPolicy_Resource_ResourceType() {} func (*OSPolicy_Resource_File_) isOSPolicy_Resource_ResourceType() {} // Resource groups provide a mechanism to group OS policy resources. // // Resource groups enable OS policy authors to create a single OS policy // to be applied to VMs running different operating Systems. // // When the OS policy is applied to a target VM, the appropriate resource // group within the OS policy is selected based on the `OSFilter` specified // within the resource group. type OSPolicy_ResourceGroup struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // List of inventory filters for the resource group. // // The resources in this resource group are applied to the target VM if it // satisfies at least one of the following inventory filters. // // For example, to apply this resource group to VMs running either `RHEL` or // `CentOS` operating systems, specify 2 items for the list with following // values: // inventory_filters[0].os_short_name='rhel' and // inventory_filters[1].os_short_name='centos' // // If the list is empty, this resource group will be applied to the target // VM unconditionally. InventoryFilters []*OSPolicy_InventoryFilter `protobuf:"bytes,1,rep,name=inventory_filters,json=inventoryFilters,proto3" json:"inventory_filters,omitempty"` // Required. List of resources configured for this resource group. // The resources are executed in the exact order specified here. Resources []*OSPolicy_Resource `protobuf:"bytes,2,rep,name=resources,proto3" json:"resources,omitempty"` } func (x *OSPolicy_ResourceGroup) Reset() { *x = OSPolicy_ResourceGroup{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicy_ResourceGroup) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicy_ResourceGroup) ProtoMessage() {} func (x *OSPolicy_ResourceGroup) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicy_ResourceGroup.ProtoReflect.Descriptor instead. func (*OSPolicy_ResourceGroup) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 2} } func (x *OSPolicy_ResourceGroup) GetInventoryFilters() []*OSPolicy_InventoryFilter { if x != nil { return x.InventoryFilters } return nil } func (x *OSPolicy_ResourceGroup) GetResources() []*OSPolicy_Resource { if x != nil { return x.Resources } return nil } // A remote or local file. type OSPolicy_Resource_File struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // A specific type of file. // // Types that are assignable to Type: // *OSPolicy_Resource_File_Remote_ // *OSPolicy_Resource_File_Gcs_ // *OSPolicy_Resource_File_LocalPath Type isOSPolicy_Resource_File_Type `protobuf_oneof:"type"` // Defaults to false. When false, files are subject to validations // based on the file type: // // Remote: A checksum must be specified. // Cloud Storage: An object generation number must be specified. AllowInsecure bool `protobuf:"varint,4,opt,name=allow_insecure,json=allowInsecure,proto3" json:"allow_insecure,omitempty"` } func (x *OSPolicy_Resource_File) Reset() { *x = OSPolicy_Resource_File{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicy_Resource_File) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicy_Resource_File) ProtoMessage() {} func (x *OSPolicy_Resource_File) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicy_Resource_File.ProtoReflect.Descriptor instead. func (*OSPolicy_Resource_File) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 1, 0} } func (m *OSPolicy_Resource_File) GetType() isOSPolicy_Resource_File_Type { if m != nil { return m.Type } return nil } func (x *OSPolicy_Resource_File) GetRemote() *OSPolicy_Resource_File_Remote { if x, ok := x.GetType().(*OSPolicy_Resource_File_Remote_); ok { return x.Remote } return nil } func (x *OSPolicy_Resource_File) GetGcs() *OSPolicy_Resource_File_Gcs { if x, ok := x.GetType().(*OSPolicy_Resource_File_Gcs_); ok { return x.Gcs } return nil } func (x *OSPolicy_Resource_File) GetLocalPath() string { if x, ok := x.GetType().(*OSPolicy_Resource_File_LocalPath); ok { return x.LocalPath } return "" } func (x *OSPolicy_Resource_File) GetAllowInsecure() bool { if x != nil { return x.AllowInsecure } return false } type isOSPolicy_Resource_File_Type interface { isOSPolicy_Resource_File_Type() } type OSPolicy_Resource_File_Remote_ struct { // A generic remote file. Remote *OSPolicy_Resource_File_Remote `protobuf:"bytes,1,opt,name=remote,proto3,oneof"` } type OSPolicy_Resource_File_Gcs_ struct { // A Cloud Storage object. Gcs *OSPolicy_Resource_File_Gcs `protobuf:"bytes,2,opt,name=gcs,proto3,oneof"` } type OSPolicy_Resource_File_LocalPath struct { // A local path within the VM to use. LocalPath string `protobuf:"bytes,3,opt,name=local_path,json=localPath,proto3,oneof"` } func (*OSPolicy_Resource_File_Remote_) isOSPolicy_Resource_File_Type() {} func (*OSPolicy_Resource_File_Gcs_) isOSPolicy_Resource_File_Type() {} func (*OSPolicy_Resource_File_LocalPath) isOSPolicy_Resource_File_Type() {} // A resource that manages a system package. type OSPolicy_Resource_PackageResource struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. The desired state the agent should maintain for this package. DesiredState OSPolicy_Resource_PackageResource_DesiredState `protobuf:"varint,1,opt,name=desired_state,json=desiredState,proto3,enum=google.cloud.osconfig.v1.OSPolicy_Resource_PackageResource_DesiredState" json:"desired_state,omitempty"` // A system package. // // Types that are assignable to SystemPackage: // *OSPolicy_Resource_PackageResource_Apt // *OSPolicy_Resource_PackageResource_Deb_ // *OSPolicy_Resource_PackageResource_Yum // *OSPolicy_Resource_PackageResource_Zypper_ // *OSPolicy_Resource_PackageResource_Rpm // *OSPolicy_Resource_PackageResource_Googet // *OSPolicy_Resource_PackageResource_Msi SystemPackage isOSPolicy_Resource_PackageResource_SystemPackage `protobuf_oneof:"system_package"` } func (x *OSPolicy_Resource_PackageResource) Reset() { *x = OSPolicy_Resource_PackageResource{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicy_Resource_PackageResource) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicy_Resource_PackageResource) ProtoMessage() {} func (x *OSPolicy_Resource_PackageResource) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicy_Resource_PackageResource.ProtoReflect.Descriptor instead. func (*OSPolicy_Resource_PackageResource) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 1, 1} } func (x *OSPolicy_Resource_PackageResource) GetDesiredState() OSPolicy_Resource_PackageResource_DesiredState { if x != nil { return x.DesiredState } return OSPolicy_Resource_PackageResource_DESIRED_STATE_UNSPECIFIED } func (m *OSPolicy_Resource_PackageResource) GetSystemPackage() isOSPolicy_Resource_PackageResource_SystemPackage { if m != nil { return m.SystemPackage } return nil } func (x *OSPolicy_Resource_PackageResource) GetApt() *OSPolicy_Resource_PackageResource_APT { if x, ok := x.GetSystemPackage().(*OSPolicy_Resource_PackageResource_Apt); ok { return x.Apt } return nil } func (x *OSPolicy_Resource_PackageResource) GetDeb() *OSPolicy_Resource_PackageResource_Deb { if x, ok := x.GetSystemPackage().(*OSPolicy_Resource_PackageResource_Deb_); ok { return x.Deb } return nil } func (x *OSPolicy_Resource_PackageResource) GetYum() *OSPolicy_Resource_PackageResource_YUM { if x, ok := x.GetSystemPackage().(*OSPolicy_Resource_PackageResource_Yum); ok { return x.Yum } return nil } func (x *OSPolicy_Resource_PackageResource) GetZypper() *OSPolicy_Resource_PackageResource_Zypper { if x, ok := x.GetSystemPackage().(*OSPolicy_Resource_PackageResource_Zypper_); ok { return x.Zypper } return nil } func (x *OSPolicy_Resource_PackageResource) GetRpm() *OSPolicy_Resource_PackageResource_RPM { if x, ok := x.GetSystemPackage().(*OSPolicy_Resource_PackageResource_Rpm); ok { return x.Rpm } return nil } func (x *OSPolicy_Resource_PackageResource) GetGooget() *OSPolicy_Resource_PackageResource_GooGet { if x, ok := x.GetSystemPackage().(*OSPolicy_Resource_PackageResource_Googet); ok { return x.Googet } return nil } func (x *OSPolicy_Resource_PackageResource) GetMsi() *OSPolicy_Resource_PackageResource_MSI { if x, ok := x.GetSystemPackage().(*OSPolicy_Resource_PackageResource_Msi); ok { return x.Msi } return nil } type isOSPolicy_Resource_PackageResource_SystemPackage interface { isOSPolicy_Resource_PackageResource_SystemPackage() } type OSPolicy_Resource_PackageResource_Apt struct { // A package managed by Apt. Apt *OSPolicy_Resource_PackageResource_APT `protobuf:"bytes,2,opt,name=apt,proto3,oneof"` } type OSPolicy_Resource_PackageResource_Deb_ struct { // A deb package file. Deb *OSPolicy_Resource_PackageResource_Deb `protobuf:"bytes,3,opt,name=deb,proto3,oneof"` } type OSPolicy_Resource_PackageResource_Yum struct { // A package managed by YUM. Yum *OSPolicy_Resource_PackageResource_YUM `protobuf:"bytes,4,opt,name=yum,proto3,oneof"` } type OSPolicy_Resource_PackageResource_Zypper_ struct { // A package managed by Zypper. Zypper *OSPolicy_Resource_PackageResource_Zypper `protobuf:"bytes,5,opt,name=zypper,proto3,oneof"` } type OSPolicy_Resource_PackageResource_Rpm struct { // An rpm package file. Rpm *OSPolicy_Resource_PackageResource_RPM `protobuf:"bytes,6,opt,name=rpm,proto3,oneof"` } type OSPolicy_Resource_PackageResource_Googet struct { // A package managed by GooGet. Googet *OSPolicy_Resource_PackageResource_GooGet `protobuf:"bytes,7,opt,name=googet,proto3,oneof"` } type OSPolicy_Resource_PackageResource_Msi struct { // An MSI package. Msi *OSPolicy_Resource_PackageResource_MSI `protobuf:"bytes,8,opt,name=msi,proto3,oneof"` } func (*OSPolicy_Resource_PackageResource_Apt) isOSPolicy_Resource_PackageResource_SystemPackage() {} func (*OSPolicy_Resource_PackageResource_Deb_) isOSPolicy_Resource_PackageResource_SystemPackage() {} func (*OSPolicy_Resource_PackageResource_Yum) isOSPolicy_Resource_PackageResource_SystemPackage() {} func (*OSPolicy_Resource_PackageResource_Zypper_) isOSPolicy_Resource_PackageResource_SystemPackage() { } func (*OSPolicy_Resource_PackageResource_Rpm) isOSPolicy_Resource_PackageResource_SystemPackage() {} func (*OSPolicy_Resource_PackageResource_Googet) isOSPolicy_Resource_PackageResource_SystemPackage() { } func (*OSPolicy_Resource_PackageResource_Msi) isOSPolicy_Resource_PackageResource_SystemPackage() {} // A resource that manages a package repository. type OSPolicy_Resource_RepositoryResource struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // A specific type of repository. // // Types that are assignable to Repository: // *OSPolicy_Resource_RepositoryResource_Apt // *OSPolicy_Resource_RepositoryResource_Yum // *OSPolicy_Resource_RepositoryResource_Zypper // *OSPolicy_Resource_RepositoryResource_Goo Repository isOSPolicy_Resource_RepositoryResource_Repository `protobuf_oneof:"repository"` } func (x *OSPolicy_Resource_RepositoryResource) Reset() { *x = OSPolicy_Resource_RepositoryResource{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicy_Resource_RepositoryResource) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicy_Resource_RepositoryResource) ProtoMessage() {} func (x *OSPolicy_Resource_RepositoryResource) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicy_Resource_RepositoryResource.ProtoReflect.Descriptor instead. func (*OSPolicy_Resource_RepositoryResource) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 1, 2} } func (m *OSPolicy_Resource_RepositoryResource) GetRepository() isOSPolicy_Resource_RepositoryResource_Repository { if m != nil { return m.Repository } return nil } func (x *OSPolicy_Resource_RepositoryResource) GetApt() *OSPolicy_Resource_RepositoryResource_AptRepository { if x, ok := x.GetRepository().(*OSPolicy_Resource_RepositoryResource_Apt); ok { return x.Apt } return nil } func (x *OSPolicy_Resource_RepositoryResource) GetYum() *OSPolicy_Resource_RepositoryResource_YumRepository { if x, ok := x.GetRepository().(*OSPolicy_Resource_RepositoryResource_Yum); ok { return x.Yum } return nil } func (x *OSPolicy_Resource_RepositoryResource) GetZypper() *OSPolicy_Resource_RepositoryResource_ZypperRepository { if x, ok := x.GetRepository().(*OSPolicy_Resource_RepositoryResource_Zypper); ok { return x.Zypper } return nil } func (x *OSPolicy_Resource_RepositoryResource) GetGoo() *OSPolicy_Resource_RepositoryResource_GooRepository { if x, ok := x.GetRepository().(*OSPolicy_Resource_RepositoryResource_Goo); ok { return x.Goo } return nil } type isOSPolicy_Resource_RepositoryResource_Repository interface { isOSPolicy_Resource_RepositoryResource_Repository() } type OSPolicy_Resource_RepositoryResource_Apt struct { // An Apt Repository. Apt *OSPolicy_Resource_RepositoryResource_AptRepository `protobuf:"bytes,1,opt,name=apt,proto3,oneof"` } type OSPolicy_Resource_RepositoryResource_Yum struct { // A Yum Repository. Yum *OSPolicy_Resource_RepositoryResource_YumRepository `protobuf:"bytes,2,opt,name=yum,proto3,oneof"` } type OSPolicy_Resource_RepositoryResource_Zypper struct { // A Zypper Repository. Zypper *OSPolicy_Resource_RepositoryResource_ZypperRepository `protobuf:"bytes,3,opt,name=zypper,proto3,oneof"` } type OSPolicy_Resource_RepositoryResource_Goo struct { // A Goo Repository. Goo *OSPolicy_Resource_RepositoryResource_GooRepository `protobuf:"bytes,4,opt,name=goo,proto3,oneof"` } func (*OSPolicy_Resource_RepositoryResource_Apt) isOSPolicy_Resource_RepositoryResource_Repository() { } func (*OSPolicy_Resource_RepositoryResource_Yum) isOSPolicy_Resource_RepositoryResource_Repository() { } func (*OSPolicy_Resource_RepositoryResource_Zypper) isOSPolicy_Resource_RepositoryResource_Repository() { } func (*OSPolicy_Resource_RepositoryResource_Goo) isOSPolicy_Resource_RepositoryResource_Repository() { } // A resource that allows executing scripts on the VM. // // The `ExecResource` has 2 stages: `validate` and `enforce` and both stages // accept a script as an argument to execute. // // When the `ExecResource` is applied by the agent, it first executes the // script in the `validate` stage. The `validate` stage can signal that the // `ExecResource` is already in the desired state by returning an exit code // of `100`. If the `ExecResource` is not in the desired state, it should // return an exit code of `101`. Any other exit code returned by this stage // is considered an error. // // If the `ExecResource` is not in the desired state based on the exit code // from the `validate` stage, the agent proceeds to execute the script from // the `enforce` stage. If the `ExecResource` is already in the desired // state, the `enforce` stage will not be run. // Similar to `validate` stage, the `enforce` stage should return an exit // code of `100` to indicate that the resource in now in its desired state. // Any other exit code is considered an error. // // NOTE: An exit code of `100` was chosen over `0` (and `101` vs `1`) to // have an explicit indicator of `in desired state`, `not in desired state` // and errors. Because, for example, Powershell will always return an exit // code of `0` unless an `exit` statement is provided in the script. So, for // reasons of consistency and being explicit, exit codes `100` and `101` // were chosen. type OSPolicy_Resource_ExecResource struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. What to run to validate this resource is in the desired // state. An exit code of 100 indicates "in desired state", and exit code // of 101 indicates "not in desired state". Any other exit code indicates // a failure running validate. Validate *OSPolicy_Resource_ExecResource_Exec `protobuf:"bytes,1,opt,name=validate,proto3" json:"validate,omitempty"` // What to run to bring this resource into the desired state. // An exit code of 100 indicates "success", any other exit code indicates // a failure running enforce. Enforce *OSPolicy_Resource_ExecResource_Exec `protobuf:"bytes,2,opt,name=enforce,proto3" json:"enforce,omitempty"` } func (x *OSPolicy_Resource_ExecResource) Reset() { *x = OSPolicy_Resource_ExecResource{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicy_Resource_ExecResource) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicy_Resource_ExecResource) ProtoMessage() {} func (x *OSPolicy_Resource_ExecResource) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicy_Resource_ExecResource.ProtoReflect.Descriptor instead. func (*OSPolicy_Resource_ExecResource) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 1, 3} } func (x *OSPolicy_Resource_ExecResource) GetValidate() *OSPolicy_Resource_ExecResource_Exec { if x != nil { return x.Validate } return nil } func (x *OSPolicy_Resource_ExecResource) GetEnforce() *OSPolicy_Resource_ExecResource_Exec { if x != nil { return x.Enforce } return nil } // A resource that manages the state of a file. type OSPolicy_Resource_FileResource struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // The source for the contents of the file. // // Types that are assignable to Source: // *OSPolicy_Resource_FileResource_File // *OSPolicy_Resource_FileResource_Content Source isOSPolicy_Resource_FileResource_Source `protobuf_oneof:"source"` // Required. The absolute path of the file within the VM. Path string `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"` // Required. Desired state of the file. State OSPolicy_Resource_FileResource_DesiredState `protobuf:"varint,4,opt,name=state,proto3,enum=google.cloud.osconfig.v1.OSPolicy_Resource_FileResource_DesiredState" json:"state,omitempty"` // Consists of three octal digits which represent, in // order, the permissions of the owner, group, and other users for the // file (similarly to the numeric mode used in the linux chmod // utility). Each digit represents a three bit number with the 4 bit // corresponding to the read permissions, the 2 bit corresponds to the // write bit, and the one bit corresponds to the execute permission. // Default behavior is 755. // // Below are some examples of permissions and their associated values: // read, write, and execute: 7 // read and execute: 5 // read and write: 6 // read only: 4 Permissions string `protobuf:"bytes,5,opt,name=permissions,proto3" json:"permissions,omitempty"` } func (x *OSPolicy_Resource_FileResource) Reset() { *x = OSPolicy_Resource_FileResource{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicy_Resource_FileResource) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicy_Resource_FileResource) ProtoMessage() {} func (x *OSPolicy_Resource_FileResource) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicy_Resource_FileResource.ProtoReflect.Descriptor instead. func (*OSPolicy_Resource_FileResource) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 1, 4} } func (m *OSPolicy_Resource_FileResource) GetSource() isOSPolicy_Resource_FileResource_Source { if m != nil { return m.Source } return nil } func (x *OSPolicy_Resource_FileResource) GetFile() *OSPolicy_Resource_File { if x, ok := x.GetSource().(*OSPolicy_Resource_FileResource_File); ok { return x.File } return nil } func (x *OSPolicy_Resource_FileResource) GetContent() string { if x, ok := x.GetSource().(*OSPolicy_Resource_FileResource_Content); ok { return x.Content } return "" } func (x *OSPolicy_Resource_FileResource) GetPath() string { if x != nil { return x.Path } return "" } func (x *OSPolicy_Resource_FileResource) GetState() OSPolicy_Resource_FileResource_DesiredState { if x != nil { return x.State } return OSPolicy_Resource_FileResource_DESIRED_STATE_UNSPECIFIED } func (x *OSPolicy_Resource_FileResource) GetPermissions() string { if x != nil { return x.Permissions } return "" } type isOSPolicy_Resource_FileResource_Source interface { isOSPolicy_Resource_FileResource_Source() } type OSPolicy_Resource_FileResource_File struct { // A remote or local source. File *OSPolicy_Resource_File `protobuf:"bytes,1,opt,name=file,proto3,oneof"` } type OSPolicy_Resource_FileResource_Content struct { // A a file with this content. // The size of the content is limited to 1024 characters. Content string `protobuf:"bytes,2,opt,name=content,proto3,oneof"` } func (*OSPolicy_Resource_FileResource_File) isOSPolicy_Resource_FileResource_Source() {} func (*OSPolicy_Resource_FileResource_Content) isOSPolicy_Resource_FileResource_Source() {} // Specifies a file available via some URI. type OSPolicy_Resource_File_Remote struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. URI from which to fetch the object. It should contain both // the protocol and path following the format `{protocol}://{location}`. Uri string `protobuf:"bytes,1,opt,name=uri,proto3" json:"uri,omitempty"` // SHA256 checksum of the remote file. Sha256Checksum string `protobuf:"bytes,2,opt,name=sha256_checksum,json=sha256Checksum,proto3" json:"sha256_checksum,omitempty"` } func (x *OSPolicy_Resource_File_Remote) Reset() { *x = OSPolicy_Resource_File_Remote{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicy_Resource_File_Remote) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicy_Resource_File_Remote) ProtoMessage() {} func (x *OSPolicy_Resource_File_Remote) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicy_Resource_File_Remote.ProtoReflect.Descriptor instead. func (*OSPolicy_Resource_File_Remote) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 1, 0, 0} } func (x *OSPolicy_Resource_File_Remote) GetUri() string { if x != nil { return x.Uri } return "" } func (x *OSPolicy_Resource_File_Remote) GetSha256Checksum() string { if x != nil { return x.Sha256Checksum } return "" } // Specifies a file available as a Cloud Storage Object. type OSPolicy_Resource_File_Gcs struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. Bucket of the Cloud Storage object. Bucket string `protobuf:"bytes,1,opt,name=bucket,proto3" json:"bucket,omitempty"` // Required. Name of the Cloud Storage object. Object string `protobuf:"bytes,2,opt,name=object,proto3" json:"object,omitempty"` // Generation number of the Cloud Storage object. Generation int64 `protobuf:"varint,3,opt,name=generation,proto3" json:"generation,omitempty"` } func (x *OSPolicy_Resource_File_Gcs) Reset() { *x = OSPolicy_Resource_File_Gcs{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicy_Resource_File_Gcs) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicy_Resource_File_Gcs) ProtoMessage() {} func (x *OSPolicy_Resource_File_Gcs) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicy_Resource_File_Gcs.ProtoReflect.Descriptor instead. func (*OSPolicy_Resource_File_Gcs) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 1, 0, 1} } func (x *OSPolicy_Resource_File_Gcs) GetBucket() string { if x != nil { return x.Bucket } return "" } func (x *OSPolicy_Resource_File_Gcs) GetObject() string { if x != nil { return x.Object } return "" } func (x *OSPolicy_Resource_File_Gcs) GetGeneration() int64 { if x != nil { return x.Generation } return 0 } // A deb package file. dpkg packages only support INSTALLED state. type OSPolicy_Resource_PackageResource_Deb struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. A deb package. Source *OSPolicy_Resource_File `protobuf:"bytes,1,opt,name=source,proto3" json:"source,omitempty"` // Whether dependencies should also be installed. // - install when false: `dpkg -i package` // - install when true: `apt-get update && apt-get -y install // package.deb` PullDeps bool `protobuf:"varint,2,opt,name=pull_deps,json=pullDeps,proto3" json:"pull_deps,omitempty"` } func (x *OSPolicy_Resource_PackageResource_Deb) Reset() { *x = OSPolicy_Resource_PackageResource_Deb{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicy_Resource_PackageResource_Deb) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicy_Resource_PackageResource_Deb) ProtoMessage() {} func (x *OSPolicy_Resource_PackageResource_Deb) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicy_Resource_PackageResource_Deb.ProtoReflect.Descriptor instead. func (*OSPolicy_Resource_PackageResource_Deb) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 1, 1, 0} } func (x *OSPolicy_Resource_PackageResource_Deb) GetSource() *OSPolicy_Resource_File { if x != nil { return x.Source } return nil } func (x *OSPolicy_Resource_PackageResource_Deb) GetPullDeps() bool { if x != nil { return x.PullDeps } return false } // A package managed by APT. // - install: `apt-get update && apt-get -y install [name]` // - remove: `apt-get -y remove [name]` type OSPolicy_Resource_PackageResource_APT struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. Package name. Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } func (x *OSPolicy_Resource_PackageResource_APT) Reset() { *x = OSPolicy_Resource_PackageResource_APT{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicy_Resource_PackageResource_APT) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicy_Resource_PackageResource_APT) ProtoMessage() {} func (x *OSPolicy_Resource_PackageResource_APT) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicy_Resource_PackageResource_APT.ProtoReflect.Descriptor instead. func (*OSPolicy_Resource_PackageResource_APT) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 1, 1, 1} } func (x *OSPolicy_Resource_PackageResource_APT) GetName() string { if x != nil { return x.Name } return "" } // An RPM package file. RPM packages only support INSTALLED state. type OSPolicy_Resource_PackageResource_RPM struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. An rpm package. Source *OSPolicy_Resource_File `protobuf:"bytes,1,opt,name=source,proto3" json:"source,omitempty"` // Whether dependencies should also be installed. // - install when false: `rpm --upgrade --replacepkgs package.rpm` // - install when true: `yum -y install package.rpm` or // `zypper -y install package.rpm` PullDeps bool `protobuf:"varint,2,opt,name=pull_deps,json=pullDeps,proto3" json:"pull_deps,omitempty"` } func (x *OSPolicy_Resource_PackageResource_RPM) Reset() { *x = OSPolicy_Resource_PackageResource_RPM{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicy_Resource_PackageResource_RPM) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicy_Resource_PackageResource_RPM) ProtoMessage() {} func (x *OSPolicy_Resource_PackageResource_RPM) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicy_Resource_PackageResource_RPM.ProtoReflect.Descriptor instead. func (*OSPolicy_Resource_PackageResource_RPM) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 1, 1, 2} } func (x *OSPolicy_Resource_PackageResource_RPM) GetSource() *OSPolicy_Resource_File { if x != nil { return x.Source } return nil } func (x *OSPolicy_Resource_PackageResource_RPM) GetPullDeps() bool { if x != nil { return x.PullDeps } return false } // A package managed by YUM. // - install: `yum -y install package` // - remove: `yum -y remove package` type OSPolicy_Resource_PackageResource_YUM struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. Package name. Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } func (x *OSPolicy_Resource_PackageResource_YUM) Reset() { *x = OSPolicy_Resource_PackageResource_YUM{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicy_Resource_PackageResource_YUM) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicy_Resource_PackageResource_YUM) ProtoMessage() {} func (x *OSPolicy_Resource_PackageResource_YUM) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicy_Resource_PackageResource_YUM.ProtoReflect.Descriptor instead. func (*OSPolicy_Resource_PackageResource_YUM) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 1, 1, 3} } func (x *OSPolicy_Resource_PackageResource_YUM) GetName() string { if x != nil { return x.Name } return "" } // A package managed by Zypper. // - install: `zypper -y install package` // - remove: `zypper -y rm package` type OSPolicy_Resource_PackageResource_Zypper struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. Package name. Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } func (x *OSPolicy_Resource_PackageResource_Zypper) Reset() { *x = OSPolicy_Resource_PackageResource_Zypper{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicy_Resource_PackageResource_Zypper) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicy_Resource_PackageResource_Zypper) ProtoMessage() {} func (x *OSPolicy_Resource_PackageResource_Zypper) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicy_Resource_PackageResource_Zypper.ProtoReflect.Descriptor instead. func (*OSPolicy_Resource_PackageResource_Zypper) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 1, 1, 4} } func (x *OSPolicy_Resource_PackageResource_Zypper) GetName() string { if x != nil { return x.Name } return "" } // A package managed by GooGet. // - install: `googet -noconfirm install package` // - remove: `googet -noconfirm remove package` type OSPolicy_Resource_PackageResource_GooGet struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. Package name. Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } func (x *OSPolicy_Resource_PackageResource_GooGet) Reset() { *x = OSPolicy_Resource_PackageResource_GooGet{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicy_Resource_PackageResource_GooGet) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicy_Resource_PackageResource_GooGet) ProtoMessage() {} func (x *OSPolicy_Resource_PackageResource_GooGet) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicy_Resource_PackageResource_GooGet.ProtoReflect.Descriptor instead. func (*OSPolicy_Resource_PackageResource_GooGet) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 1, 1, 5} } func (x *OSPolicy_Resource_PackageResource_GooGet) GetName() string { if x != nil { return x.Name } return "" } // An MSI package. MSI packages only support INSTALLED state. type OSPolicy_Resource_PackageResource_MSI struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. The MSI package. Source *OSPolicy_Resource_File `protobuf:"bytes,1,opt,name=source,proto3" json:"source,omitempty"` // Additional properties to use during installation. // This should be in the format of Property=Setting. // Appended to the defaults of `ACTION=INSTALL // REBOOT=ReallySuppress`. Properties []string `protobuf:"bytes,2,rep,name=properties,proto3" json:"properties,omitempty"` } func (x *OSPolicy_Resource_PackageResource_MSI) Reset() { *x = OSPolicy_Resource_PackageResource_MSI{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicy_Resource_PackageResource_MSI) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicy_Resource_PackageResource_MSI) ProtoMessage() {} func (x *OSPolicy_Resource_PackageResource_MSI) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicy_Resource_PackageResource_MSI.ProtoReflect.Descriptor instead. func (*OSPolicy_Resource_PackageResource_MSI) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 1, 1, 6} } func (x *OSPolicy_Resource_PackageResource_MSI) GetSource() *OSPolicy_Resource_File { if x != nil { return x.Source } return nil } func (x *OSPolicy_Resource_PackageResource_MSI) GetProperties() []string { if x != nil { return x.Properties } return nil } // Represents a single apt package repository. These will be added to // a repo file that will be managed at // `/etc/apt/sources.list.d/google_osconfig.list`. type OSPolicy_Resource_RepositoryResource_AptRepository struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. Type of archive files in this repository. ArchiveType OSPolicy_Resource_RepositoryResource_AptRepository_ArchiveType `protobuf:"varint,1,opt,name=archive_type,json=archiveType,proto3,enum=google.cloud.osconfig.v1.OSPolicy_Resource_RepositoryResource_AptRepository_ArchiveType" json:"archive_type,omitempty"` // Required. URI for this repository. Uri string `protobuf:"bytes,2,opt,name=uri,proto3" json:"uri,omitempty"` // Required. Distribution of this repository. Distribution string `protobuf:"bytes,3,opt,name=distribution,proto3" json:"distribution,omitempty"` // Required. List of components for this repository. Must contain at // least one item. Components []string `protobuf:"bytes,4,rep,name=components,proto3" json:"components,omitempty"` // URI of the key file for this repository. The agent maintains a // keyring at `/etc/apt/trusted.gpg.d/osconfig_agent_managed.gpg`. GpgKey string `protobuf:"bytes,5,opt,name=gpg_key,json=gpgKey,proto3" json:"gpg_key,omitempty"` } func (x *OSPolicy_Resource_RepositoryResource_AptRepository) Reset() { *x = OSPolicy_Resource_RepositoryResource_AptRepository{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicy_Resource_RepositoryResource_AptRepository) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicy_Resource_RepositoryResource_AptRepository) ProtoMessage() {} func (x *OSPolicy_Resource_RepositoryResource_AptRepository) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicy_Resource_RepositoryResource_AptRepository.ProtoReflect.Descriptor instead. func (*OSPolicy_Resource_RepositoryResource_AptRepository) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 1, 2, 0} } func (x *OSPolicy_Resource_RepositoryResource_AptRepository) GetArchiveType() OSPolicy_Resource_RepositoryResource_AptRepository_ArchiveType { if x != nil { return x.ArchiveType } return OSPolicy_Resource_RepositoryResource_AptRepository_ARCHIVE_TYPE_UNSPECIFIED } func (x *OSPolicy_Resource_RepositoryResource_AptRepository) GetUri() string { if x != nil { return x.Uri } return "" } func (x *OSPolicy_Resource_RepositoryResource_AptRepository) GetDistribution() string { if x != nil { return x.Distribution } return "" } func (x *OSPolicy_Resource_RepositoryResource_AptRepository) GetComponents() []string { if x != nil { return x.Components } return nil } func (x *OSPolicy_Resource_RepositoryResource_AptRepository) GetGpgKey() string { if x != nil { return x.GpgKey } return "" } // Represents a single yum package repository. These are added to a // repo file that is managed at // `/etc/yum.repos.d/google_osconfig.repo`. type OSPolicy_Resource_RepositoryResource_YumRepository struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. A one word, unique name for this repository. This is the // `repo id` in the yum config file and also the `display_name` if // `display_name` is omitted. This id is also used as the unique // identifier when checking for resource conflicts. Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // The display name of the repository. DisplayName string `protobuf:"bytes,2,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` // Required. The location of the repository directory. BaseUrl string `protobuf:"bytes,3,opt,name=base_url,json=baseUrl,proto3" json:"base_url,omitempty"` // URIs of GPG keys. GpgKeys []string `protobuf:"bytes,4,rep,name=gpg_keys,json=gpgKeys,proto3" json:"gpg_keys,omitempty"` } func (x *OSPolicy_Resource_RepositoryResource_YumRepository) Reset() { *x = OSPolicy_Resource_RepositoryResource_YumRepository{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicy_Resource_RepositoryResource_YumRepository) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicy_Resource_RepositoryResource_YumRepository) ProtoMessage() {} func (x *OSPolicy_Resource_RepositoryResource_YumRepository) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicy_Resource_RepositoryResource_YumRepository.ProtoReflect.Descriptor instead. func (*OSPolicy_Resource_RepositoryResource_YumRepository) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 1, 2, 1} } func (x *OSPolicy_Resource_RepositoryResource_YumRepository) GetId() string { if x != nil { return x.Id } return "" } func (x *OSPolicy_Resource_RepositoryResource_YumRepository) GetDisplayName() string { if x != nil { return x.DisplayName } return "" } func (x *OSPolicy_Resource_RepositoryResource_YumRepository) GetBaseUrl() string { if x != nil { return x.BaseUrl } return "" } func (x *OSPolicy_Resource_RepositoryResource_YumRepository) GetGpgKeys() []string { if x != nil { return x.GpgKeys } return nil } // Represents a single zypper package repository. These are added to a // repo file that is managed at // `/etc/zypp/repos.d/google_osconfig.repo`. type OSPolicy_Resource_RepositoryResource_ZypperRepository struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. A one word, unique name for this repository. This is the // `repo id` in the zypper config file and also the `display_name` if // `display_name` is omitted. This id is also used as the unique // identifier when checking for GuestPolicy conflicts. Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // The display name of the repository. DisplayName string `protobuf:"bytes,2,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` // Required. The location of the repository directory. BaseUrl string `protobuf:"bytes,3,opt,name=base_url,json=baseUrl,proto3" json:"base_url,omitempty"` // URIs of GPG keys. GpgKeys []string `protobuf:"bytes,4,rep,name=gpg_keys,json=gpgKeys,proto3" json:"gpg_keys,omitempty"` } func (x *OSPolicy_Resource_RepositoryResource_ZypperRepository) Reset() { *x = OSPolicy_Resource_RepositoryResource_ZypperRepository{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicy_Resource_RepositoryResource_ZypperRepository) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicy_Resource_RepositoryResource_ZypperRepository) ProtoMessage() {} func (x *OSPolicy_Resource_RepositoryResource_ZypperRepository) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicy_Resource_RepositoryResource_ZypperRepository.ProtoReflect.Descriptor instead. func (*OSPolicy_Resource_RepositoryResource_ZypperRepository) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 1, 2, 2} } func (x *OSPolicy_Resource_RepositoryResource_ZypperRepository) GetId() string { if x != nil { return x.Id } return "" } func (x *OSPolicy_Resource_RepositoryResource_ZypperRepository) GetDisplayName() string { if x != nil { return x.DisplayName } return "" } func (x *OSPolicy_Resource_RepositoryResource_ZypperRepository) GetBaseUrl() string { if x != nil { return x.BaseUrl } return "" } func (x *OSPolicy_Resource_RepositoryResource_ZypperRepository) GetGpgKeys() []string { if x != nil { return x.GpgKeys } return nil } // Represents a Goo package repository. These are added to a repo file // that is managed at // `C:/ProgramData/GooGet/repos/google_osconfig.repo`. type OSPolicy_Resource_RepositoryResource_GooRepository struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. The name of the repository. Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // Required. The url of the repository. Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"` } func (x *OSPolicy_Resource_RepositoryResource_GooRepository) Reset() { *x = OSPolicy_Resource_RepositoryResource_GooRepository{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicy_Resource_RepositoryResource_GooRepository) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicy_Resource_RepositoryResource_GooRepository) ProtoMessage() {} func (x *OSPolicy_Resource_RepositoryResource_GooRepository) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicy_Resource_RepositoryResource_GooRepository.ProtoReflect.Descriptor instead. func (*OSPolicy_Resource_RepositoryResource_GooRepository) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 1, 2, 3} } func (x *OSPolicy_Resource_RepositoryResource_GooRepository) GetName() string { if x != nil { return x.Name } return "" } func (x *OSPolicy_Resource_RepositoryResource_GooRepository) GetUrl() string { if x != nil { return x.Url } return "" } // A file or script to execute. type OSPolicy_Resource_ExecResource_Exec struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // What to execute. // // Types that are assignable to Source: // *OSPolicy_Resource_ExecResource_Exec_File // *OSPolicy_Resource_ExecResource_Exec_Script Source isOSPolicy_Resource_ExecResource_Exec_Source `protobuf_oneof:"source"` // Optional arguments to pass to the source during execution. Args []string `protobuf:"bytes,3,rep,name=args,proto3" json:"args,omitempty"` // Required. The script interpreter to use. Interpreter OSPolicy_Resource_ExecResource_Exec_Interpreter `protobuf:"varint,4,opt,name=interpreter,proto3,enum=google.cloud.osconfig.v1.OSPolicy_Resource_ExecResource_Exec_Interpreter" json:"interpreter,omitempty"` // Only recorded for enforce Exec. // Path to an output file (that is created by this Exec) whose // content will be recorded in OSPolicyResourceCompliance after a // successful run. Absence or failure to read this file will result in // this ExecResource being non-compliant. Output file size is limited to // 100K bytes. OutputFilePath string `protobuf:"bytes,5,opt,name=output_file_path,json=outputFilePath,proto3" json:"output_file_path,omitempty"` } func (x *OSPolicy_Resource_ExecResource_Exec) Reset() { *x = OSPolicy_Resource_ExecResource_Exec{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicy_Resource_ExecResource_Exec) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicy_Resource_ExecResource_Exec) ProtoMessage() {} func (x *OSPolicy_Resource_ExecResource_Exec) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicy_Resource_ExecResource_Exec.ProtoReflect.Descriptor instead. func (*OSPolicy_Resource_ExecResource_Exec) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP(), []int{0, 1, 3, 0} } func (m *OSPolicy_Resource_ExecResource_Exec) GetSource() isOSPolicy_Resource_ExecResource_Exec_Source { if m != nil { return m.Source } return nil } func (x *OSPolicy_Resource_ExecResource_Exec) GetFile() *OSPolicy_Resource_File { if x, ok := x.GetSource().(*OSPolicy_Resource_ExecResource_Exec_File); ok { return x.File } return nil } func (x *OSPolicy_Resource_ExecResource_Exec) GetScript() string { if x, ok := x.GetSource().(*OSPolicy_Resource_ExecResource_Exec_Script); ok { return x.Script } return "" } func (x *OSPolicy_Resource_ExecResource_Exec) GetArgs() []string { if x != nil { return x.Args } return nil } func (x *OSPolicy_Resource_ExecResource_Exec) GetInterpreter() OSPolicy_Resource_ExecResource_Exec_Interpreter { if x != nil { return x.Interpreter } return OSPolicy_Resource_ExecResource_Exec_INTERPRETER_UNSPECIFIED } func (x *OSPolicy_Resource_ExecResource_Exec) GetOutputFilePath() string { if x != nil { return x.OutputFilePath } return "" } type isOSPolicy_Resource_ExecResource_Exec_Source interface { isOSPolicy_Resource_ExecResource_Exec_Source() } type OSPolicy_Resource_ExecResource_Exec_File struct { // A remote or local file. File *OSPolicy_Resource_File `protobuf:"bytes,1,opt,name=file,proto3,oneof"` } type OSPolicy_Resource_ExecResource_Exec_Script struct { // An inline script. // The size of the script is limited to 1024 characters. Script string `protobuf:"bytes,2,opt,name=script,proto3,oneof"` } func (*OSPolicy_Resource_ExecResource_Exec_File) isOSPolicy_Resource_ExecResource_Exec_Source() {} func (*OSPolicy_Resource_ExecResource_Exec_Script) isOSPolicy_Resource_ExecResource_Exec_Source() {} var File_google_cloud_osconfig_v1_os_policy_proto protoreflect.FileDescriptor var file_google_cloud_osconfig_v1_os_policy_proto_rawDesc = []byte{ 0x0a, 0x28, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x18, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe7, 0x25, 0x0a, 0x08, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x13, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x02, 0x69, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x5e, 0x0a, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x40, 0x0a, 0x1d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x6e, 0x6f, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x4e, 0x6f, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x1a, 0x59, 0x0a, 0x0f, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x0d, 0x6f, 0x73, 0x5f, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0b, 0x6f, 0x73, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6f, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0xe2, 0x20, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x13, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x02, 0x69, 0x64, 0x12, 0x4f, 0x0a, 0x03, 0x70, 0x6b, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x00, 0x52, 0x03, 0x70, 0x6b, 0x67, 0x12, 0x60, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x00, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x4e, 0x0a, 0x04, 0x65, 0x78, 0x65, 0x63, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x00, 0x52, 0x04, 0x65, 0x78, 0x65, 0x63, 0x12, 0x4e, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x00, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x1a, 0x9e, 0x03, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x51, 0x0a, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x12, 0x48, 0x0a, 0x03, 0x67, 0x63, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x2e, 0x47, 0x63, 0x73, 0x48, 0x00, 0x52, 0x03, 0x67, 0x63, 0x73, 0x12, 0x1f, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x49, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x1a, 0x48, 0x0a, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x12, 0x15, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x1a, 0x5f, 0x0a, 0x03, 0x47, 0x63, 0x73, 0x12, 0x1b, 0x0a, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x1b, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x1a, 0xa9, 0x0a, 0x0a, 0x0f, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x72, 0x0a, 0x0d, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x48, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0c, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x53, 0x0a, 0x03, 0x61, 0x70, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x41, 0x50, 0x54, 0x48, 0x00, 0x52, 0x03, 0x61, 0x70, 0x74, 0x12, 0x53, 0x0a, 0x03, 0x64, 0x65, 0x62, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x62, 0x48, 0x00, 0x52, 0x03, 0x64, 0x65, 0x62, 0x12, 0x53, 0x0a, 0x03, 0x79, 0x75, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x59, 0x55, 0x4d, 0x48, 0x00, 0x52, 0x03, 0x79, 0x75, 0x6d, 0x12, 0x5c, 0x0a, 0x06, 0x7a, 0x79, 0x70, 0x70, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x5a, 0x79, 0x70, 0x70, 0x65, 0x72, 0x48, 0x00, 0x52, 0x06, 0x7a, 0x79, 0x70, 0x70, 0x65, 0x72, 0x12, 0x53, 0x0a, 0x03, 0x72, 0x70, 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x50, 0x4d, 0x48, 0x00, 0x52, 0x03, 0x72, 0x70, 0x6d, 0x12, 0x5c, 0x0a, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x65, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x47, 0x6f, 0x6f, 0x47, 0x65, 0x74, 0x48, 0x00, 0x52, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x65, 0x74, 0x12, 0x53, 0x0a, 0x03, 0x6d, 0x73, 0x69, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x4d, 0x53, 0x49, 0x48, 0x00, 0x52, 0x03, 0x6d, 0x73, 0x69, 0x1a, 0x71, 0x0a, 0x03, 0x44, 0x65, 0x62, 0x12, 0x4d, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x75, 0x6c, 0x6c, 0x5f, 0x64, 0x65, 0x70, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x70, 0x75, 0x6c, 0x6c, 0x44, 0x65, 0x70, 0x73, 0x1a, 0x1e, 0x0a, 0x03, 0x41, 0x50, 0x54, 0x12, 0x17, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x1a, 0x71, 0x0a, 0x03, 0x52, 0x50, 0x4d, 0x12, 0x4d, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x75, 0x6c, 0x6c, 0x5f, 0x64, 0x65, 0x70, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x70, 0x75, 0x6c, 0x6c, 0x44, 0x65, 0x70, 0x73, 0x1a, 0x1e, 0x0a, 0x03, 0x59, 0x55, 0x4d, 0x12, 0x17, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x1a, 0x21, 0x0a, 0x06, 0x5a, 0x79, 0x70, 0x70, 0x65, 0x72, 0x12, 0x17, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x1a, 0x21, 0x0a, 0x06, 0x47, 0x6f, 0x6f, 0x47, 0x65, 0x74, 0x12, 0x17, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x1a, 0x74, 0x0a, 0x03, 0x4d, 0x53, 0x49, 0x12, 0x4d, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x49, 0x0a, 0x0c, 0x44, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x44, 0x45, 0x53, 0x49, 0x52, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x4d, 0x4f, 0x56, 0x45, 0x44, 0x10, 0x02, 0x42, 0x10, 0x0a, 0x0e, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x1a, 0xd7, 0x08, 0x0a, 0x12, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x60, 0x0a, 0x03, 0x61, 0x70, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x4c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x41, 0x70, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x48, 0x00, 0x52, 0x03, 0x61, 0x70, 0x74, 0x12, 0x60, 0x0a, 0x03, 0x79, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x4c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x59, 0x75, 0x6d, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x48, 0x00, 0x52, 0x03, 0x79, 0x75, 0x6d, 0x12, 0x69, 0x0a, 0x06, 0x7a, 0x79, 0x70, 0x70, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x4f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x5a, 0x79, 0x70, 0x70, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x48, 0x00, 0x52, 0x06, 0x7a, 0x79, 0x70, 0x70, 0x65, 0x72, 0x12, 0x60, 0x0a, 0x03, 0x67, 0x6f, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x4c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x47, 0x6f, 0x6f, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x48, 0x00, 0x52, 0x03, 0x67, 0x6f, 0x6f, 0x1a, 0xd3, 0x02, 0x0a, 0x0d, 0x41, 0x70, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x80, 0x01, 0x0a, 0x0c, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x58, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x41, 0x70, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x54, 0x79, 0x70, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0b, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x15, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x27, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x67, 0x70, 0x67, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x67, 0x70, 0x67, 0x4b, 0x65, 0x79, 0x22, 0x41, 0x0a, 0x0b, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x18, 0x41, 0x52, 0x43, 0x48, 0x49, 0x56, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x45, 0x42, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x42, 0x5f, 0x53, 0x52, 0x43, 0x10, 0x02, 0x1a, 0x82, 0x01, 0x0a, 0x0d, 0x59, 0x75, 0x6d, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x13, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x02, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x08, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x07, 0x62, 0x61, 0x73, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x70, 0x67, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x67, 0x70, 0x67, 0x4b, 0x65, 0x79, 0x73, 0x1a, 0x85, 0x01, 0x0a, 0x10, 0x5a, 0x79, 0x70, 0x70, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x13, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x02, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x08, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x07, 0x62, 0x61, 0x73, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x70, 0x67, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x67, 0x70, 0x67, 0x4b, 0x65, 0x79, 0x73, 0x1a, 0x3f, 0x0a, 0x0d, 0x47, 0x6f, 0x6f, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x17, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x15, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x42, 0x0c, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x1a, 0xbd, 0x04, 0x0a, 0x0c, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x5e, 0x0a, 0x08, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x08, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x12, 0x57, 0x0a, 0x07, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x52, 0x07, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x1a, 0xf3, 0x02, 0x0a, 0x04, 0x45, 0x78, 0x65, 0x63, 0x12, 0x46, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x06, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, 0x70, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x49, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x72, 0x12, 0x28, 0x0a, 0x10, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x22, 0x4f, 0x0a, 0x0b, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x17, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x50, 0x52, 0x45, 0x54, 0x45, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x48, 0x45, 0x4c, 0x4c, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x4f, 0x57, 0x45, 0x52, 0x53, 0x48, 0x45, 0x4c, 0x4c, 0x10, 0x03, 0x42, 0x08, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x1a, 0xf5, 0x02, 0x0a, 0x0c, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x46, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x17, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x60, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x45, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x5a, 0x0a, 0x0c, 0x44, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x44, 0x45, 0x53, 0x49, 0x52, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x52, 0x45, 0x53, 0x45, 0x4e, 0x54, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x42, 0x53, 0x45, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x4f, 0x4e, 0x54, 0x45, 0x4e, 0x54, 0x53, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x03, 0x42, 0x08, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x0f, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x1a, 0xc0, 0x01, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x5f, 0x0a, 0x11, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x10, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x4e, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0x3d, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x45, 0x4e, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x02, 0x42, 0xc5, 0x01, 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x42, 0x0d, 0x4f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x40, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x3b, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0xaa, 0x02, 0x18, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x18, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5c, 0x56, 0x31, 0xea, 0x02, 0x1b, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( file_google_cloud_osconfig_v1_os_policy_proto_rawDescOnce sync.Once file_google_cloud_osconfig_v1_os_policy_proto_rawDescData = file_google_cloud_osconfig_v1_os_policy_proto_rawDesc ) func file_google_cloud_osconfig_v1_os_policy_proto_rawDescGZIP() []byte { file_google_cloud_osconfig_v1_os_policy_proto_rawDescOnce.Do(func() { file_google_cloud_osconfig_v1_os_policy_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_cloud_osconfig_v1_os_policy_proto_rawDescData) }) return file_google_cloud_osconfig_v1_os_policy_proto_rawDescData } var file_google_cloud_osconfig_v1_os_policy_proto_enumTypes = make([]protoimpl.EnumInfo, 5) var file_google_cloud_osconfig_v1_os_policy_proto_msgTypes = make([]protoimpl.MessageInfo, 23) var file_google_cloud_osconfig_v1_os_policy_proto_goTypes = []interface{}{ (OSPolicy_Mode)(0), // 0: google.cloud.osconfig.v1.OSPolicy.Mode (OSPolicy_Resource_PackageResource_DesiredState)(0), // 1: google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.DesiredState (OSPolicy_Resource_RepositoryResource_AptRepository_ArchiveType)(0), // 2: google.cloud.osconfig.v1.OSPolicy.Resource.RepositoryResource.AptRepository.ArchiveType (OSPolicy_Resource_ExecResource_Exec_Interpreter)(0), // 3: google.cloud.osconfig.v1.OSPolicy.Resource.ExecResource.Exec.Interpreter (OSPolicy_Resource_FileResource_DesiredState)(0), // 4: google.cloud.osconfig.v1.OSPolicy.Resource.FileResource.DesiredState (*OSPolicy)(nil), // 5: google.cloud.osconfig.v1.OSPolicy (*OSPolicy_InventoryFilter)(nil), // 6: google.cloud.osconfig.v1.OSPolicy.InventoryFilter (*OSPolicy_Resource)(nil), // 7: google.cloud.osconfig.v1.OSPolicy.Resource (*OSPolicy_ResourceGroup)(nil), // 8: google.cloud.osconfig.v1.OSPolicy.ResourceGroup (*OSPolicy_Resource_File)(nil), // 9: google.cloud.osconfig.v1.OSPolicy.Resource.File (*OSPolicy_Resource_PackageResource)(nil), // 10: google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource (*OSPolicy_Resource_RepositoryResource)(nil), // 11: google.cloud.osconfig.v1.OSPolicy.Resource.RepositoryResource (*OSPolicy_Resource_ExecResource)(nil), // 12: google.cloud.osconfig.v1.OSPolicy.Resource.ExecResource (*OSPolicy_Resource_FileResource)(nil), // 13: google.cloud.osconfig.v1.OSPolicy.Resource.FileResource (*OSPolicy_Resource_File_Remote)(nil), // 14: google.cloud.osconfig.v1.OSPolicy.Resource.File.Remote (*OSPolicy_Resource_File_Gcs)(nil), // 15: google.cloud.osconfig.v1.OSPolicy.Resource.File.Gcs (*OSPolicy_Resource_PackageResource_Deb)(nil), // 16: google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.Deb (*OSPolicy_Resource_PackageResource_APT)(nil), // 17: google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.APT (*OSPolicy_Resource_PackageResource_RPM)(nil), // 18: google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.RPM (*OSPolicy_Resource_PackageResource_YUM)(nil), // 19: google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.YUM (*OSPolicy_Resource_PackageResource_Zypper)(nil), // 20: google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.Zypper (*OSPolicy_Resource_PackageResource_GooGet)(nil), // 21: google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.GooGet (*OSPolicy_Resource_PackageResource_MSI)(nil), // 22: google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.MSI (*OSPolicy_Resource_RepositoryResource_AptRepository)(nil), // 23: google.cloud.osconfig.v1.OSPolicy.Resource.RepositoryResource.AptRepository (*OSPolicy_Resource_RepositoryResource_YumRepository)(nil), // 24: google.cloud.osconfig.v1.OSPolicy.Resource.RepositoryResource.YumRepository (*OSPolicy_Resource_RepositoryResource_ZypperRepository)(nil), // 25: google.cloud.osconfig.v1.OSPolicy.Resource.RepositoryResource.ZypperRepository (*OSPolicy_Resource_RepositoryResource_GooRepository)(nil), // 26: google.cloud.osconfig.v1.OSPolicy.Resource.RepositoryResource.GooRepository (*OSPolicy_Resource_ExecResource_Exec)(nil), // 27: google.cloud.osconfig.v1.OSPolicy.Resource.ExecResource.Exec } var file_google_cloud_osconfig_v1_os_policy_proto_depIdxs = []int32{ 0, // 0: google.cloud.osconfig.v1.OSPolicy.mode:type_name -> google.cloud.osconfig.v1.OSPolicy.Mode 8, // 1: google.cloud.osconfig.v1.OSPolicy.resource_groups:type_name -> google.cloud.osconfig.v1.OSPolicy.ResourceGroup 10, // 2: google.cloud.osconfig.v1.OSPolicy.Resource.pkg:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource 11, // 3: google.cloud.osconfig.v1.OSPolicy.Resource.repository:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.RepositoryResource 12, // 4: google.cloud.osconfig.v1.OSPolicy.Resource.exec:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.ExecResource 13, // 5: google.cloud.osconfig.v1.OSPolicy.Resource.file:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.FileResource 6, // 6: google.cloud.osconfig.v1.OSPolicy.ResourceGroup.inventory_filters:type_name -> google.cloud.osconfig.v1.OSPolicy.InventoryFilter 7, // 7: google.cloud.osconfig.v1.OSPolicy.ResourceGroup.resources:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource 14, // 8: google.cloud.osconfig.v1.OSPolicy.Resource.File.remote:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.File.Remote 15, // 9: google.cloud.osconfig.v1.OSPolicy.Resource.File.gcs:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.File.Gcs 1, // 10: google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.desired_state:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.DesiredState 17, // 11: google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.apt:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.APT 16, // 12: google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.deb:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.Deb 19, // 13: google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.yum:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.YUM 20, // 14: google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.zypper:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.Zypper 18, // 15: google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.rpm:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.RPM 21, // 16: google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.googet:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.GooGet 22, // 17: google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.msi:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.MSI 23, // 18: google.cloud.osconfig.v1.OSPolicy.Resource.RepositoryResource.apt:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.RepositoryResource.AptRepository 24, // 19: google.cloud.osconfig.v1.OSPolicy.Resource.RepositoryResource.yum:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.RepositoryResource.YumRepository 25, // 20: google.cloud.osconfig.v1.OSPolicy.Resource.RepositoryResource.zypper:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.RepositoryResource.ZypperRepository 26, // 21: google.cloud.osconfig.v1.OSPolicy.Resource.RepositoryResource.goo:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.RepositoryResource.GooRepository 27, // 22: google.cloud.osconfig.v1.OSPolicy.Resource.ExecResource.validate:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.ExecResource.Exec 27, // 23: google.cloud.osconfig.v1.OSPolicy.Resource.ExecResource.enforce:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.ExecResource.Exec 9, // 24: google.cloud.osconfig.v1.OSPolicy.Resource.FileResource.file:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.File 4, // 25: google.cloud.osconfig.v1.OSPolicy.Resource.FileResource.state:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.FileResource.DesiredState 9, // 26: google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.Deb.source:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.File 9, // 27: google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.RPM.source:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.File 9, // 28: google.cloud.osconfig.v1.OSPolicy.Resource.PackageResource.MSI.source:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.File 2, // 29: google.cloud.osconfig.v1.OSPolicy.Resource.RepositoryResource.AptRepository.archive_type:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.RepositoryResource.AptRepository.ArchiveType 9, // 30: google.cloud.osconfig.v1.OSPolicy.Resource.ExecResource.Exec.file:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.File 3, // 31: google.cloud.osconfig.v1.OSPolicy.Resource.ExecResource.Exec.interpreter:type_name -> google.cloud.osconfig.v1.OSPolicy.Resource.ExecResource.Exec.Interpreter 32, // [32:32] is the sub-list for method output_type 32, // [32:32] is the sub-list for method input_type 32, // [32:32] is the sub-list for extension type_name 32, // [32:32] is the sub-list for extension extendee 0, // [0:32] is the sub-list for field type_name } func init() { file_google_cloud_osconfig_v1_os_policy_proto_init() } func file_google_cloud_osconfig_v1_os_policy_proto_init() { if File_google_cloud_osconfig_v1_os_policy_proto != nil { return } if !protoimpl.UnsafeEnabled { file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicy); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicy_InventoryFilter); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicy_Resource); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicy_ResourceGroup); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicy_Resource_File); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicy_Resource_PackageResource); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicy_Resource_RepositoryResource); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicy_Resource_ExecResource); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicy_Resource_FileResource); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicy_Resource_File_Remote); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicy_Resource_File_Gcs); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicy_Resource_PackageResource_Deb); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicy_Resource_PackageResource_APT); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicy_Resource_PackageResource_RPM); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicy_Resource_PackageResource_YUM); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicy_Resource_PackageResource_Zypper); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicy_Resource_PackageResource_GooGet); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicy_Resource_PackageResource_MSI); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicy_Resource_RepositoryResource_AptRepository); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicy_Resource_RepositoryResource_YumRepository); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicy_Resource_RepositoryResource_ZypperRepository); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicy_Resource_RepositoryResource_GooRepository); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicy_Resource_ExecResource_Exec); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[2].OneofWrappers = []interface{}{ (*OSPolicy_Resource_Pkg)(nil), (*OSPolicy_Resource_Repository)(nil), (*OSPolicy_Resource_Exec)(nil), (*OSPolicy_Resource_File_)(nil), } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[4].OneofWrappers = []interface{}{ (*OSPolicy_Resource_File_Remote_)(nil), (*OSPolicy_Resource_File_Gcs_)(nil), (*OSPolicy_Resource_File_LocalPath)(nil), } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[5].OneofWrappers = []interface{}{ (*OSPolicy_Resource_PackageResource_Apt)(nil), (*OSPolicy_Resource_PackageResource_Deb_)(nil), (*OSPolicy_Resource_PackageResource_Yum)(nil), (*OSPolicy_Resource_PackageResource_Zypper_)(nil), (*OSPolicy_Resource_PackageResource_Rpm)(nil), (*OSPolicy_Resource_PackageResource_Googet)(nil), (*OSPolicy_Resource_PackageResource_Msi)(nil), } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[6].OneofWrappers = []interface{}{ (*OSPolicy_Resource_RepositoryResource_Apt)(nil), (*OSPolicy_Resource_RepositoryResource_Yum)(nil), (*OSPolicy_Resource_RepositoryResource_Zypper)(nil), (*OSPolicy_Resource_RepositoryResource_Goo)(nil), } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[8].OneofWrappers = []interface{}{ (*OSPolicy_Resource_FileResource_File)(nil), (*OSPolicy_Resource_FileResource_Content)(nil), } file_google_cloud_osconfig_v1_os_policy_proto_msgTypes[22].OneofWrappers = []interface{}{ (*OSPolicy_Resource_ExecResource_Exec_File)(nil), (*OSPolicy_Resource_ExecResource_Exec_Script)(nil), } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_google_cloud_osconfig_v1_os_policy_proto_rawDesc, NumEnums: 5, NumMessages: 23, NumExtensions: 0, NumServices: 0, }, GoTypes: file_google_cloud_osconfig_v1_os_policy_proto_goTypes, DependencyIndexes: file_google_cloud_osconfig_v1_os_policy_proto_depIdxs, EnumInfos: file_google_cloud_osconfig_v1_os_policy_proto_enumTypes, MessageInfos: file_google_cloud_osconfig_v1_os_policy_proto_msgTypes, }.Build() File_google_cloud_osconfig_v1_os_policy_proto = out.File file_google_cloud_osconfig_v1_os_policy_proto_rawDesc = nil file_google_cloud_osconfig_v1_os_policy_proto_goTypes = nil file_google_cloud_osconfig_v1_os_policy_proto_depIdxs = nil } os_policy_assignment_reports.pb.go000066400000000000000000002051641477773331400411660ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/internal/google.golang.org/genproto/googleapis/cloud/osconfig/v1// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.25.0 // protoc v3.15.3 // source: google/cloud/osconfig/v1/os_policy_assignment_reports.proto package osconfig import ( proto "github.com/golang/protobuf/proto" _ "google.golang.org/genproto/googleapis/api/annotations" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" ) const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) // Verify that runtime/protoimpl is sufficiently up-to-date. _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) // This is a compile-time assertion that a sufficiently up-to-date version // of the legacy proto package is being used. const _ = proto.ProtoPackageIsVersion4 // Possible compliance states for an os policy. type OSPolicyAssignmentReport_OSPolicyCompliance_ComplianceState int32 const ( // The policy is in an unknown compliance state. // // Refer to the field `compliance_state_reason` to learn the exact reason // for the policy to be in this compliance state. OSPolicyAssignmentReport_OSPolicyCompliance_UNKNOWN OSPolicyAssignmentReport_OSPolicyCompliance_ComplianceState = 0 // Policy is compliant. // // The policy is compliant if all the underlying resources are also // compliant. OSPolicyAssignmentReport_OSPolicyCompliance_COMPLIANT OSPolicyAssignmentReport_OSPolicyCompliance_ComplianceState = 1 // Policy is non-compliant. // // The policy is non-compliant if one or more underlying resources are // non-compliant. OSPolicyAssignmentReport_OSPolicyCompliance_NON_COMPLIANT OSPolicyAssignmentReport_OSPolicyCompliance_ComplianceState = 2 ) // Enum value maps for OSPolicyAssignmentReport_OSPolicyCompliance_ComplianceState. var ( OSPolicyAssignmentReport_OSPolicyCompliance_ComplianceState_name = map[int32]string{ 0: "UNKNOWN", 1: "COMPLIANT", 2: "NON_COMPLIANT", } OSPolicyAssignmentReport_OSPolicyCompliance_ComplianceState_value = map[string]int32{ "UNKNOWN": 0, "COMPLIANT": 1, "NON_COMPLIANT": 2, } ) func (x OSPolicyAssignmentReport_OSPolicyCompliance_ComplianceState) Enum() *OSPolicyAssignmentReport_OSPolicyCompliance_ComplianceState { p := new(OSPolicyAssignmentReport_OSPolicyCompliance_ComplianceState) *p = x return p } func (x OSPolicyAssignmentReport_OSPolicyCompliance_ComplianceState) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (OSPolicyAssignmentReport_OSPolicyCompliance_ComplianceState) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_enumTypes[0].Descriptor() } func (OSPolicyAssignmentReport_OSPolicyCompliance_ComplianceState) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_enumTypes[0] } func (x OSPolicyAssignmentReport_OSPolicyCompliance_ComplianceState) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use OSPolicyAssignmentReport_OSPolicyCompliance_ComplianceState.Descriptor instead. func (OSPolicyAssignmentReport_OSPolicyCompliance_ComplianceState) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_rawDescGZIP(), []int{3, 0, 0} } // Possible compliance states for a resource. type OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ComplianceState int32 const ( // The resource is in an unknown compliance state. // // To get more details about why the policy is in this state, review // the output of the `compliance_state_reason` field. OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_UNKNOWN OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ComplianceState = 0 // Resource is compliant. OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_COMPLIANT OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ComplianceState = 1 // Resource is non-compliant. OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_NON_COMPLIANT OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ComplianceState = 2 ) // Enum value maps for OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ComplianceState. var ( OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ComplianceState_name = map[int32]string{ 0: "UNKNOWN", 1: "COMPLIANT", 2: "NON_COMPLIANT", } OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ComplianceState_value = map[string]int32{ "UNKNOWN": 0, "COMPLIANT": 1, "NON_COMPLIANT": 2, } ) func (x OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ComplianceState) Enum() *OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ComplianceState { p := new(OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ComplianceState) *p = x return p } func (x OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ComplianceState) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ComplianceState) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_enumTypes[1].Descriptor() } func (OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ComplianceState) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_enumTypes[1] } func (x OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ComplianceState) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ComplianceState.Descriptor instead. func (OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ComplianceState) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_rawDescGZIP(), []int{3, 0, 0, 0} } // Supported configuration step types type OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_Type int32 const ( // Default value. This value is unused. OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_TYPE_UNSPECIFIED OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_Type = 0 // Checks for resource conflicts such as schema errors. OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_VALIDATION OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_Type = 1 // Checks the current status of the desired state for a resource. OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_DESIRED_STATE_CHECK OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_Type = 2 // Enforces the desired state for a resource that is not in desired // state. OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_DESIRED_STATE_ENFORCEMENT OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_Type = 3 // Re-checks the status of the desired state. This check is done // for a resource after the enforcement of all OS policies. // // This step is used to determine the final desired state status for // the resource. It accounts for any resources that might have drifted // from their desired state due to side effects from executing other // resources. OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_DESIRED_STATE_CHECK_POST_ENFORCEMENT OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_Type = 4 ) // Enum value maps for OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_Type. var ( OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_Type_name = map[int32]string{ 0: "TYPE_UNSPECIFIED", 1: "VALIDATION", 2: "DESIRED_STATE_CHECK", 3: "DESIRED_STATE_ENFORCEMENT", 4: "DESIRED_STATE_CHECK_POST_ENFORCEMENT", } OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_Type_value = map[string]int32{ "TYPE_UNSPECIFIED": 0, "VALIDATION": 1, "DESIRED_STATE_CHECK": 2, "DESIRED_STATE_ENFORCEMENT": 3, "DESIRED_STATE_CHECK_POST_ENFORCEMENT": 4, } ) func (x OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_Type) Enum() *OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_Type { p := new(OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_Type) *p = x return p } func (x OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_Type) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_Type) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_enumTypes[2].Descriptor() } func (OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_Type) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_enumTypes[2] } func (x OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_Type) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_Type.Descriptor instead. func (OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_Type) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_rawDescGZIP(), []int{3, 0, 0, 0, 0} } // Get a report of the OS policy assignment for a VM instance. type GetOSPolicyAssignmentReportRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. API resource name for OS policy assignment report. // // Format: // `/projects/{project}/locations/{location}/instances/{instance}/osPolicyAssignments/{assignment}/report` // // For `{project}`, either `project-number` or `project-id` can be provided. // For `{instance_id}`, either Compute Engine `instance-id` or `instance-name` // can be provided. // For `{assignment_id}`, the OSPolicyAssignment id must be provided. Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } func (x *GetOSPolicyAssignmentReportRequest) Reset() { *x = GetOSPolicyAssignmentReportRequest{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *GetOSPolicyAssignmentReportRequest) String() string { return protoimpl.X.MessageStringOf(x) } func (*GetOSPolicyAssignmentReportRequest) ProtoMessage() {} func (x *GetOSPolicyAssignmentReportRequest) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use GetOSPolicyAssignmentReportRequest.ProtoReflect.Descriptor instead. func (*GetOSPolicyAssignmentReportRequest) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_rawDescGZIP(), []int{0} } func (x *GetOSPolicyAssignmentReportRequest) GetName() string { if x != nil { return x.Name } return "" } // List the OS policy assignment reports for VM instances. type ListOSPolicyAssignmentReportsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. The parent resource name. // // Format: // `projects/{project}/locations/{location}/instances/{instance}/osPolicyAssignments/{assignment}/reports` // // For `{project}`, either `project-number` or `project-id` can be provided. // For `{instance}`, either `instance-name`, `instance-id`, or `-` can be // provided. If '-' is provided, the response will include // OSPolicyAssignmentReports for all instances in the project/location. // For `{assignment}`, either `assignment-id` or `-` can be provided. If '-' // is provided, the response will include OSPolicyAssignmentReports for all // OSPolicyAssignments in the project/location. // Either {instance} or {assignment} must be `-`. // // For example: // `projects/{project}/locations/{location}/instances/{instance}/osPolicyAssignments/-/reports` // returns all reports for the instance // `projects/{project}/locations/{location}/instances/-/osPolicyAssignments/{assignment-id}/reports` // returns all the reports for the given assignment across all instances. // `projects/{project}/locations/{location}/instances/-/osPolicyAssignments/-/reports` // returns all the reports for all assignments across all instances. Parent string `protobuf:"bytes,1,opt,name=parent,proto3" json:"parent,omitempty"` // The maximum number of results to return. PageSize int32 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` // If provided, this field specifies the criteria that must be met by the // `OSPolicyAssignmentReport` API resource that is included in the response. Filter string `protobuf:"bytes,3,opt,name=filter,proto3" json:"filter,omitempty"` // A pagination token returned from a previous call to the // `ListOSPolicyAssignmentReports` method that indicates where this listing // should continue from. PageToken string `protobuf:"bytes,4,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"` } func (x *ListOSPolicyAssignmentReportsRequest) Reset() { *x = ListOSPolicyAssignmentReportsRequest{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *ListOSPolicyAssignmentReportsRequest) String() string { return protoimpl.X.MessageStringOf(x) } func (*ListOSPolicyAssignmentReportsRequest) ProtoMessage() {} func (x *ListOSPolicyAssignmentReportsRequest) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use ListOSPolicyAssignmentReportsRequest.ProtoReflect.Descriptor instead. func (*ListOSPolicyAssignmentReportsRequest) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_rawDescGZIP(), []int{1} } func (x *ListOSPolicyAssignmentReportsRequest) GetParent() string { if x != nil { return x.Parent } return "" } func (x *ListOSPolicyAssignmentReportsRequest) GetPageSize() int32 { if x != nil { return x.PageSize } return 0 } func (x *ListOSPolicyAssignmentReportsRequest) GetFilter() string { if x != nil { return x.Filter } return "" } func (x *ListOSPolicyAssignmentReportsRequest) GetPageToken() string { if x != nil { return x.PageToken } return "" } // A response message for listing OS Policy assignment reports including the // page of results and page token. type ListOSPolicyAssignmentReportsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // List of OS policy assignment reports. OsPolicyAssignmentReports []*OSPolicyAssignmentReport `protobuf:"bytes,1,rep,name=os_policy_assignment_reports,json=osPolicyAssignmentReports,proto3" json:"os_policy_assignment_reports,omitempty"` // The pagination token to retrieve the next page of OS policy assignment // report objects. NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` } func (x *ListOSPolicyAssignmentReportsResponse) Reset() { *x = ListOSPolicyAssignmentReportsResponse{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *ListOSPolicyAssignmentReportsResponse) String() string { return protoimpl.X.MessageStringOf(x) } func (*ListOSPolicyAssignmentReportsResponse) ProtoMessage() {} func (x *ListOSPolicyAssignmentReportsResponse) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use ListOSPolicyAssignmentReportsResponse.ProtoReflect.Descriptor instead. func (*ListOSPolicyAssignmentReportsResponse) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_rawDescGZIP(), []int{2} } func (x *ListOSPolicyAssignmentReportsResponse) GetOsPolicyAssignmentReports() []*OSPolicyAssignmentReport { if x != nil { return x.OsPolicyAssignmentReports } return nil } func (x *ListOSPolicyAssignmentReportsResponse) GetNextPageToken() string { if x != nil { return x.NextPageToken } return "" } // A report of the OS policy assignment status for a given instance. type OSPolicyAssignmentReport struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // The `OSPolicyAssignmentReport` API resource name. // // Format: // `projects/{project_number}/locations/{location}/instances/{instance_id}/osPolicyAssignments/{os_policy_assignment_id}/report` Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // The Compute Engine VM instance name. Instance string `protobuf:"bytes,2,opt,name=instance,proto3" json:"instance,omitempty"` // Reference to the `OSPolicyAssignment` API resource that the `OSPolicy` // belongs to. // // Format: // `projects/{project_number}/locations/{location}/osPolicyAssignments/{os_policy_assignment_id@revision_id}` OsPolicyAssignment string `protobuf:"bytes,3,opt,name=os_policy_assignment,json=osPolicyAssignment,proto3" json:"os_policy_assignment,omitempty"` // Compliance data for each `OSPolicy` that is applied to the VM. OsPolicyCompliances []*OSPolicyAssignmentReport_OSPolicyCompliance `protobuf:"bytes,4,rep,name=os_policy_compliances,json=osPolicyCompliances,proto3" json:"os_policy_compliances,omitempty"` // Timestamp for when the report was last generated. UpdateTime *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty"` // Unique identifier of the last attempted run to apply the OS policies // associated with this assignment on the VM. // // This ID is logged by the OS Config agent while applying the OS // policies associated with this assignment on the VM. // NOTE: If the service is unable to successfully connect to the agent for // this run, then this id will not be available in the agent logs. LastRunId string `protobuf:"bytes,6,opt,name=last_run_id,json=lastRunId,proto3" json:"last_run_id,omitempty"` } func (x *OSPolicyAssignmentReport) Reset() { *x = OSPolicyAssignmentReport{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicyAssignmentReport) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicyAssignmentReport) ProtoMessage() {} func (x *OSPolicyAssignmentReport) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicyAssignmentReport.ProtoReflect.Descriptor instead. func (*OSPolicyAssignmentReport) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_rawDescGZIP(), []int{3} } func (x *OSPolicyAssignmentReport) GetName() string { if x != nil { return x.Name } return "" } func (x *OSPolicyAssignmentReport) GetInstance() string { if x != nil { return x.Instance } return "" } func (x *OSPolicyAssignmentReport) GetOsPolicyAssignment() string { if x != nil { return x.OsPolicyAssignment } return "" } func (x *OSPolicyAssignmentReport) GetOsPolicyCompliances() []*OSPolicyAssignmentReport_OSPolicyCompliance { if x != nil { return x.OsPolicyCompliances } return nil } func (x *OSPolicyAssignmentReport) GetUpdateTime() *timestamppb.Timestamp { if x != nil { return x.UpdateTime } return nil } func (x *OSPolicyAssignmentReport) GetLastRunId() string { if x != nil { return x.LastRunId } return "" } // Compliance data for an OS policy type OSPolicyAssignmentReport_OSPolicyCompliance struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // The OS policy id OsPolicyId string `protobuf:"bytes,1,opt,name=os_policy_id,json=osPolicyId,proto3" json:"os_policy_id,omitempty"` // The compliance state of the OS policy. ComplianceState OSPolicyAssignmentReport_OSPolicyCompliance_ComplianceState `protobuf:"varint,2,opt,name=compliance_state,json=complianceState,proto3,enum=google.cloud.osconfig.v1.OSPolicyAssignmentReport_OSPolicyCompliance_ComplianceState" json:"compliance_state,omitempty"` // The reason for the OS policy to be in an unknown compliance state. // This field is always populated when `compliance_state` is `UNKNOWN`. // // If populated, the field can contain one of the following values: // // * `vm-not-running`: The VM was not running. // * `os-policies-not-supported-by-agent`: The version of the OS Config // agent running on the VM does not support running OS policies. // * `no-agent-detected`: The OS Config agent is not detected for the VM. // * `resource-execution-errors`: The OS Config agent encountered errors // while executing one or more resources in the policy. See // `os_policy_resource_compliances` for details. // * `task-timeout`: The task sent to the agent to apply the policy timed // out. // * `unexpected-agent-state`: The OS Config agent did not report the final // status of the task that attempted to apply the policy. Instead, the agent // unexpectedly started working on a different task. This mostly happens // when the agent or VM unexpectedly restarts while applying OS policies. // * `internal-service-errors`: Internal service errors were encountered // while attempting to apply the policy. ComplianceStateReason string `protobuf:"bytes,3,opt,name=compliance_state_reason,json=complianceStateReason,proto3" json:"compliance_state_reason,omitempty"` // Compliance data for each resource within the policy that is applied to // the VM. OsPolicyResourceCompliances []*OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance `protobuf:"bytes,4,rep,name=os_policy_resource_compliances,json=osPolicyResourceCompliances,proto3" json:"os_policy_resource_compliances,omitempty"` } func (x *OSPolicyAssignmentReport_OSPolicyCompliance) Reset() { *x = OSPolicyAssignmentReport_OSPolicyCompliance{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicyAssignmentReport_OSPolicyCompliance) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicyAssignmentReport_OSPolicyCompliance) ProtoMessage() {} func (x *OSPolicyAssignmentReport_OSPolicyCompliance) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicyAssignmentReport_OSPolicyCompliance.ProtoReflect.Descriptor instead. func (*OSPolicyAssignmentReport_OSPolicyCompliance) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_rawDescGZIP(), []int{3, 0} } func (x *OSPolicyAssignmentReport_OSPolicyCompliance) GetOsPolicyId() string { if x != nil { return x.OsPolicyId } return "" } func (x *OSPolicyAssignmentReport_OSPolicyCompliance) GetComplianceState() OSPolicyAssignmentReport_OSPolicyCompliance_ComplianceState { if x != nil { return x.ComplianceState } return OSPolicyAssignmentReport_OSPolicyCompliance_UNKNOWN } func (x *OSPolicyAssignmentReport_OSPolicyCompliance) GetComplianceStateReason() string { if x != nil { return x.ComplianceStateReason } return "" } func (x *OSPolicyAssignmentReport_OSPolicyCompliance) GetOsPolicyResourceCompliances() []*OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance { if x != nil { return x.OsPolicyResourceCompliances } return nil } // Compliance data for an OS policy resource. type OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // The ID of the OS policy resource. OsPolicyResourceId string `protobuf:"bytes,1,opt,name=os_policy_resource_id,json=osPolicyResourceId,proto3" json:"os_policy_resource_id,omitempty"` // Ordered list of configuration completed by the agent for the OS policy // resource. ConfigSteps []*OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep `protobuf:"bytes,2,rep,name=config_steps,json=configSteps,proto3" json:"config_steps,omitempty"` // The compliance state of the resource. ComplianceState OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ComplianceState `protobuf:"varint,3,opt,name=compliance_state,json=complianceState,proto3,enum=google.cloud.osconfig.v1.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ComplianceState" json:"compliance_state,omitempty"` // A reason for the resource to be in the given compliance state. // This field is always populated when `compliance_state` is `UNKNOWN`. // // The following values are supported when `compliance_state == UNKNOWN` // // * `execution-errors`: Errors were encountered by the agent while // executing the resource and the compliance state couldn't be // determined. // * `execution-skipped-by-agent`: Resource execution was skipped by the // agent because errors were encountered while executing prior resources // in the OS policy. // * `os-policy-execution-attempt-failed`: The execution of the OS policy // containing this resource failed and the compliance state couldn't be // determined. ComplianceStateReason string `protobuf:"bytes,4,opt,name=compliance_state_reason,json=complianceStateReason,proto3" json:"compliance_state_reason,omitempty"` // Resource specific output. // // Types that are assignable to Output: // *OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput_ Output isOSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_Output `protobuf_oneof:"output"` } func (x *OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance) Reset() { *x = OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance) ProtoMessage() {} func (x *OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance.ProtoReflect.Descriptor instead. func (*OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_rawDescGZIP(), []int{3, 0, 0} } func (x *OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance) GetOsPolicyResourceId() string { if x != nil { return x.OsPolicyResourceId } return "" } func (x *OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance) GetConfigSteps() []*OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep { if x != nil { return x.ConfigSteps } return nil } func (x *OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance) GetComplianceState() OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ComplianceState { if x != nil { return x.ComplianceState } return OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_UNKNOWN } func (x *OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance) GetComplianceStateReason() string { if x != nil { return x.ComplianceStateReason } return "" } func (m *OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance) GetOutput() isOSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_Output { if m != nil { return m.Output } return nil } func (x *OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance) GetExecResourceOutput() *OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput { if x, ok := x.GetOutput().(*OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput_); ok { return x.ExecResourceOutput } return nil } type isOSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_Output interface { isOSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_Output() } type OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput_ struct { // ExecResource specific output. ExecResourceOutput *OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput `protobuf:"bytes,5,opt,name=exec_resource_output,json=execResourceOutput,proto3,oneof"` } func (*OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput_) isOSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_Output() { } // Step performed by the OS Config agent for configuring an // `OSPolicy` resource to its desired state. type OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Configuration step type. Type OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_Type `protobuf:"varint,1,opt,name=type,proto3,enum=google.cloud.osconfig.v1.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_Type" json:"type,omitempty"` // An error message recorded during the execution of this step. // Only populated if errors were encountered during this step execution. ErrorMessage string `protobuf:"bytes,2,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` } func (x *OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep) Reset() { *x = OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep) ProtoMessage() { } func (x *OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep.ProtoReflect.Descriptor instead. func (*OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_rawDescGZIP(), []int{3, 0, 0, 0} } func (x *OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep) GetType() OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_Type { if x != nil { return x.Type } return OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_TYPE_UNSPECIFIED } func (x *OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep) GetErrorMessage() string { if x != nil { return x.ErrorMessage } return "" } // ExecResource specific output. type OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Output from enforcement phase output file (if run). // Output size is limited to 100K bytes. EnforcementOutput []byte `protobuf:"bytes,2,opt,name=enforcement_output,json=enforcementOutput,proto3" json:"enforcement_output,omitempty"` } func (x *OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput) Reset() { *x = OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput) ProtoMessage() { } func (x *OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput.ProtoReflect.Descriptor instead. func (*OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_rawDescGZIP(), []int{3, 0, 0, 1} } func (x *OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput) GetEnforcementOutput() []byte { if x != nil { return x.EnforcementOutput } return nil } var File_google_cloud_osconfig_v1_os_policy_assignment_reports_proto protoreflect.FileDescriptor var file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_rawDesc = []byte{ 0x0a, 0x3b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x18, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x72, 0x0a, 0x22, 0x47, 0x65, 0x74, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4c, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x38, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x32, 0x0a, 0x30, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xce, 0x01, 0x0a, 0x24, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x52, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x3a, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x34, 0x0a, 0x32, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xc4, 0x01, 0x0a, 0x25, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x73, 0x0a, 0x1c, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x19, 0x6f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xf3, 0x10, 0x0a, 0x18, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x61, 0x0a, 0x14, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2f, 0xfa, 0x41, 0x2c, 0x0a, 0x2a, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x12, 0x6f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x79, 0x0a, 0x15, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x13, 0x6f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x52, 0x75, 0x6e, 0x49, 0x64, 0x1a, 0xcc, 0x0c, 0x0a, 0x12, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x0c, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x49, 0x64, 0x12, 0x80, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x55, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0xa5, 0x01, 0x0a, 0x1e, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x60, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x1b, 0x6f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x1a, 0xee, 0x08, 0x0a, 0x1a, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x31, 0x0a, 0x15, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x6f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x9e, 0x01, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x7b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x65, 0x70, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x65, 0x70, 0x73, 0x12, 0x9b, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x70, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0xa7, 0x01, 0x0a, 0x14, 0x65, 0x78, 0x65, 0x63, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x73, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x48, 0x00, 0x52, 0x12, 0x65, 0x78, 0x65, 0x63, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x1a, 0xea, 0x02, 0x0a, 0x1a, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x65, 0x70, 0x12, 0x95, 0x01, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x80, 0x01, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x65, 0x70, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x8e, 0x01, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x44, 0x45, 0x53, 0x49, 0x52, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x19, 0x44, 0x45, 0x53, 0x49, 0x52, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x45, 0x4e, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x03, 0x12, 0x28, 0x0a, 0x24, 0x44, 0x45, 0x53, 0x49, 0x52, 0x45, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x5f, 0x45, 0x4e, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x04, 0x1a, 0x43, 0x0a, 0x12, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x2d, 0x0a, 0x12, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x40, 0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x49, 0x41, 0x4e, 0x54, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x4e, 0x4f, 0x4e, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x49, 0x41, 0x4e, 0x54, 0x10, 0x02, 0x42, 0x08, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x40, 0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x49, 0x41, 0x4e, 0x54, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x4e, 0x4f, 0x4e, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x49, 0x41, 0x4e, 0x54, 0x10, 0x02, 0x3a, 0x9c, 0x01, 0xea, 0x41, 0x98, 0x01, 0x0a, 0x30, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x64, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x7d, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7d, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x7d, 0x2f, 0x6f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x7d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0xed, 0x02, 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x42, 0x1e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x40, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x3b, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0xaa, 0x02, 0x18, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x18, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5c, 0x56, 0x31, 0xea, 0x02, 0x1b, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0xea, 0x41, 0x93, 0x01, 0x0a, 0x32, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x5d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x7d, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7d, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x7d, 0x2f, 0x6f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x7d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_rawDescOnce sync.Once file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_rawDescData = file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_rawDesc ) func file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_rawDescGZIP() []byte { file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_rawDescOnce.Do(func() { file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_rawDescData) }) return file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_rawDescData } var file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_enumTypes = make([]protoimpl.EnumInfo, 3) var file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes = make([]protoimpl.MessageInfo, 8) var file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_goTypes = []interface{}{ (OSPolicyAssignmentReport_OSPolicyCompliance_ComplianceState)(0), // 0: google.cloud.osconfig.v1.OSPolicyAssignmentReport.OSPolicyCompliance.ComplianceState (OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ComplianceState)(0), // 1: google.cloud.osconfig.v1.OSPolicyAssignmentReport.OSPolicyCompliance.OSPolicyResourceCompliance.ComplianceState (OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_Type)(0), // 2: google.cloud.osconfig.v1.OSPolicyAssignmentReport.OSPolicyCompliance.OSPolicyResourceCompliance.OSPolicyResourceConfigStep.Type (*GetOSPolicyAssignmentReportRequest)(nil), // 3: google.cloud.osconfig.v1.GetOSPolicyAssignmentReportRequest (*ListOSPolicyAssignmentReportsRequest)(nil), // 4: google.cloud.osconfig.v1.ListOSPolicyAssignmentReportsRequest (*ListOSPolicyAssignmentReportsResponse)(nil), // 5: google.cloud.osconfig.v1.ListOSPolicyAssignmentReportsResponse (*OSPolicyAssignmentReport)(nil), // 6: google.cloud.osconfig.v1.OSPolicyAssignmentReport (*OSPolicyAssignmentReport_OSPolicyCompliance)(nil), // 7: google.cloud.osconfig.v1.OSPolicyAssignmentReport.OSPolicyCompliance (*OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance)(nil), // 8: google.cloud.osconfig.v1.OSPolicyAssignmentReport.OSPolicyCompliance.OSPolicyResourceCompliance (*OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep)(nil), // 9: google.cloud.osconfig.v1.OSPolicyAssignmentReport.OSPolicyCompliance.OSPolicyResourceCompliance.OSPolicyResourceConfigStep (*OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput)(nil), // 10: google.cloud.osconfig.v1.OSPolicyAssignmentReport.OSPolicyCompliance.OSPolicyResourceCompliance.ExecResourceOutput (*timestamppb.Timestamp)(nil), // 11: google.protobuf.Timestamp } var file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_depIdxs = []int32{ 6, // 0: google.cloud.osconfig.v1.ListOSPolicyAssignmentReportsResponse.os_policy_assignment_reports:type_name -> google.cloud.osconfig.v1.OSPolicyAssignmentReport 7, // 1: google.cloud.osconfig.v1.OSPolicyAssignmentReport.os_policy_compliances:type_name -> google.cloud.osconfig.v1.OSPolicyAssignmentReport.OSPolicyCompliance 11, // 2: google.cloud.osconfig.v1.OSPolicyAssignmentReport.update_time:type_name -> google.protobuf.Timestamp 0, // 3: google.cloud.osconfig.v1.OSPolicyAssignmentReport.OSPolicyCompliance.compliance_state:type_name -> google.cloud.osconfig.v1.OSPolicyAssignmentReport.OSPolicyCompliance.ComplianceState 8, // 4: google.cloud.osconfig.v1.OSPolicyAssignmentReport.OSPolicyCompliance.os_policy_resource_compliances:type_name -> google.cloud.osconfig.v1.OSPolicyAssignmentReport.OSPolicyCompliance.OSPolicyResourceCompliance 9, // 5: google.cloud.osconfig.v1.OSPolicyAssignmentReport.OSPolicyCompliance.OSPolicyResourceCompliance.config_steps:type_name -> google.cloud.osconfig.v1.OSPolicyAssignmentReport.OSPolicyCompliance.OSPolicyResourceCompliance.OSPolicyResourceConfigStep 1, // 6: google.cloud.osconfig.v1.OSPolicyAssignmentReport.OSPolicyCompliance.OSPolicyResourceCompliance.compliance_state:type_name -> google.cloud.osconfig.v1.OSPolicyAssignmentReport.OSPolicyCompliance.OSPolicyResourceCompliance.ComplianceState 10, // 7: google.cloud.osconfig.v1.OSPolicyAssignmentReport.OSPolicyCompliance.OSPolicyResourceCompliance.exec_resource_output:type_name -> google.cloud.osconfig.v1.OSPolicyAssignmentReport.OSPolicyCompliance.OSPolicyResourceCompliance.ExecResourceOutput 2, // 8: google.cloud.osconfig.v1.OSPolicyAssignmentReport.OSPolicyCompliance.OSPolicyResourceCompliance.OSPolicyResourceConfigStep.type:type_name -> google.cloud.osconfig.v1.OSPolicyAssignmentReport.OSPolicyCompliance.OSPolicyResourceCompliance.OSPolicyResourceConfigStep.Type 9, // [9:9] is the sub-list for method output_type 9, // [9:9] is the sub-list for method input_type 9, // [9:9] is the sub-list for extension type_name 9, // [9:9] is the sub-list for extension extendee 0, // [0:9] is the sub-list for field type_name } func init() { file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_init() } func file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_init() { if File_google_cloud_osconfig_v1_os_policy_assignment_reports_proto != nil { return } if !protoimpl.UnsafeEnabled { file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetOSPolicyAssignmentReportRequest); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListOSPolicyAssignmentReportsRequest); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListOSPolicyAssignmentReportsResponse); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicyAssignmentReport); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicyAssignmentReport_OSPolicyCompliance); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } } file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes[5].OneofWrappers = []interface{}{ (*OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput_)(nil), } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_rawDesc, NumEnums: 3, NumMessages: 8, NumExtensions: 0, NumServices: 0, }, GoTypes: file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_goTypes, DependencyIndexes: file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_depIdxs, EnumInfos: file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_enumTypes, MessageInfos: file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_msgTypes, }.Build() File_google_cloud_osconfig_v1_os_policy_assignment_reports_proto = out.File file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_rawDesc = nil file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_goTypes = nil file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_depIdxs = nil } os_policy_assignments.pb.go000066400000000000000000002423101477773331400375650ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/internal/google.golang.org/genproto/googleapis/cloud/osconfig/v1// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.25.0 // protoc v3.15.3 // source: google/cloud/osconfig/v1/os_policy_assignments.proto package osconfig import ( proto "github.com/golang/protobuf/proto" _ "google.golang.org/genproto/googleapis/api/annotations" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" durationpb "google.golang.org/protobuf/types/known/durationpb" fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb" timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" ) const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) // Verify that runtime/protoimpl is sufficiently up-to-date. _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) // This is a compile-time assertion that a sufficiently up-to-date version // of the legacy proto package is being used. const _ = proto.ProtoPackageIsVersion4 // OS policy assignment rollout state type OSPolicyAssignment_RolloutState int32 const ( // Invalid value OSPolicyAssignment_ROLLOUT_STATE_UNSPECIFIED OSPolicyAssignment_RolloutState = 0 // The rollout is in progress. OSPolicyAssignment_IN_PROGRESS OSPolicyAssignment_RolloutState = 1 // The rollout is being cancelled. OSPolicyAssignment_CANCELLING OSPolicyAssignment_RolloutState = 2 // The rollout is cancelled. OSPolicyAssignment_CANCELLED OSPolicyAssignment_RolloutState = 3 // The rollout has completed successfully. OSPolicyAssignment_SUCCEEDED OSPolicyAssignment_RolloutState = 4 ) // Enum value maps for OSPolicyAssignment_RolloutState. var ( OSPolicyAssignment_RolloutState_name = map[int32]string{ 0: "ROLLOUT_STATE_UNSPECIFIED", 1: "IN_PROGRESS", 2: "CANCELLING", 3: "CANCELLED", 4: "SUCCEEDED", } OSPolicyAssignment_RolloutState_value = map[string]int32{ "ROLLOUT_STATE_UNSPECIFIED": 0, "IN_PROGRESS": 1, "CANCELLING": 2, "CANCELLED": 3, "SUCCEEDED": 4, } ) func (x OSPolicyAssignment_RolloutState) Enum() *OSPolicyAssignment_RolloutState { p := new(OSPolicyAssignment_RolloutState) *p = x return p } func (x OSPolicyAssignment_RolloutState) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (OSPolicyAssignment_RolloutState) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_os_policy_assignments_proto_enumTypes[0].Descriptor() } func (OSPolicyAssignment_RolloutState) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_os_policy_assignments_proto_enumTypes[0] } func (x OSPolicyAssignment_RolloutState) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use OSPolicyAssignment_RolloutState.Descriptor instead. func (OSPolicyAssignment_RolloutState) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDescGZIP(), []int{0, 0} } // The OS policy assignment API method. type OSPolicyAssignmentOperationMetadata_APIMethod int32 const ( // Invalid value OSPolicyAssignmentOperationMetadata_API_METHOD_UNSPECIFIED OSPolicyAssignmentOperationMetadata_APIMethod = 0 // Create OS policy assignment API method OSPolicyAssignmentOperationMetadata_CREATE OSPolicyAssignmentOperationMetadata_APIMethod = 1 // Update OS policy assignment API method OSPolicyAssignmentOperationMetadata_UPDATE OSPolicyAssignmentOperationMetadata_APIMethod = 2 // Delete OS policy assignment API method OSPolicyAssignmentOperationMetadata_DELETE OSPolicyAssignmentOperationMetadata_APIMethod = 3 ) // Enum value maps for OSPolicyAssignmentOperationMetadata_APIMethod. var ( OSPolicyAssignmentOperationMetadata_APIMethod_name = map[int32]string{ 0: "API_METHOD_UNSPECIFIED", 1: "CREATE", 2: "UPDATE", 3: "DELETE", } OSPolicyAssignmentOperationMetadata_APIMethod_value = map[string]int32{ "API_METHOD_UNSPECIFIED": 0, "CREATE": 1, "UPDATE": 2, "DELETE": 3, } ) func (x OSPolicyAssignmentOperationMetadata_APIMethod) Enum() *OSPolicyAssignmentOperationMetadata_APIMethod { p := new(OSPolicyAssignmentOperationMetadata_APIMethod) *p = x return p } func (x OSPolicyAssignmentOperationMetadata_APIMethod) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (OSPolicyAssignmentOperationMetadata_APIMethod) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_os_policy_assignments_proto_enumTypes[1].Descriptor() } func (OSPolicyAssignmentOperationMetadata_APIMethod) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_os_policy_assignments_proto_enumTypes[1] } func (x OSPolicyAssignmentOperationMetadata_APIMethod) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use OSPolicyAssignmentOperationMetadata_APIMethod.Descriptor instead. func (OSPolicyAssignmentOperationMetadata_APIMethod) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDescGZIP(), []int{1, 0} } // State of the rollout type OSPolicyAssignmentOperationMetadata_RolloutState int32 const ( // Invalid value OSPolicyAssignmentOperationMetadata_ROLLOUT_STATE_UNSPECIFIED OSPolicyAssignmentOperationMetadata_RolloutState = 0 // The rollout is in progress. OSPolicyAssignmentOperationMetadata_IN_PROGRESS OSPolicyAssignmentOperationMetadata_RolloutState = 1 // The rollout is being cancelled. OSPolicyAssignmentOperationMetadata_CANCELLING OSPolicyAssignmentOperationMetadata_RolloutState = 2 // The rollout is cancelled. OSPolicyAssignmentOperationMetadata_CANCELLED OSPolicyAssignmentOperationMetadata_RolloutState = 3 // The rollout has completed successfully. OSPolicyAssignmentOperationMetadata_SUCCEEDED OSPolicyAssignmentOperationMetadata_RolloutState = 4 ) // Enum value maps for OSPolicyAssignmentOperationMetadata_RolloutState. var ( OSPolicyAssignmentOperationMetadata_RolloutState_name = map[int32]string{ 0: "ROLLOUT_STATE_UNSPECIFIED", 1: "IN_PROGRESS", 2: "CANCELLING", 3: "CANCELLED", 4: "SUCCEEDED", } OSPolicyAssignmentOperationMetadata_RolloutState_value = map[string]int32{ "ROLLOUT_STATE_UNSPECIFIED": 0, "IN_PROGRESS": 1, "CANCELLING": 2, "CANCELLED": 3, "SUCCEEDED": 4, } ) func (x OSPolicyAssignmentOperationMetadata_RolloutState) Enum() *OSPolicyAssignmentOperationMetadata_RolloutState { p := new(OSPolicyAssignmentOperationMetadata_RolloutState) *p = x return p } func (x OSPolicyAssignmentOperationMetadata_RolloutState) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (OSPolicyAssignmentOperationMetadata_RolloutState) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_os_policy_assignments_proto_enumTypes[2].Descriptor() } func (OSPolicyAssignmentOperationMetadata_RolloutState) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_os_policy_assignments_proto_enumTypes[2] } func (x OSPolicyAssignmentOperationMetadata_RolloutState) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use OSPolicyAssignmentOperationMetadata_RolloutState.Descriptor instead. func (OSPolicyAssignmentOperationMetadata_RolloutState) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDescGZIP(), []int{1, 1} } // OS policy assignment is an API resource that is used to // apply a set of OS policies to a dynamically targeted group of Compute Engine // VM instances. // // An OS policy is used to define the desired state configuration for a // Compute Engine VM instance through a set of configuration resources that // provide capabilities such as installing or removing software packages, or // executing a script. // // For more information, see [OS policy and OS policy // assignment](https://cloud.google.com/compute/docs/os-configuration-management/working-with-os-policies). type OSPolicyAssignment struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Resource name. // // Format: // `projects/{project_number}/locations/{location}/osPolicyAssignments/{os_policy_assignment_id}` // // This field is ignored when you create an OS policy assignment. Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // OS policy assignment description. // Length of the description is limited to 1024 characters. Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // Required. List of OS policies to be applied to the VMs. OsPolicies []*OSPolicy `protobuf:"bytes,3,rep,name=os_policies,json=osPolicies,proto3" json:"os_policies,omitempty"` // Required. Filter to select VMs. InstanceFilter *OSPolicyAssignment_InstanceFilter `protobuf:"bytes,4,opt,name=instance_filter,json=instanceFilter,proto3" json:"instance_filter,omitempty"` // Required. Rollout to deploy the OS policy assignment. // A rollout is triggered in the following situations: // 1) OSPolicyAssignment is created. // 2) OSPolicyAssignment is updated and the update contains changes to one of // the following fields: // - instance_filter // - os_policies // 3) OSPolicyAssignment is deleted. Rollout *OSPolicyAssignment_Rollout `protobuf:"bytes,5,opt,name=rollout,proto3" json:"rollout,omitempty"` // Output only. The assignment revision ID // A new revision is committed whenever a rollout is triggered for a OS policy // assignment RevisionId string `protobuf:"bytes,6,opt,name=revision_id,json=revisionId,proto3" json:"revision_id,omitempty"` // Output only. The timestamp that the revision was created. RevisionCreateTime *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=revision_create_time,json=revisionCreateTime,proto3" json:"revision_create_time,omitempty"` // The etag for this OS policy assignment. // If this is provided on update, it must match the server's etag. Etag string `protobuf:"bytes,8,opt,name=etag,proto3" json:"etag,omitempty"` // Output only. OS policy assignment rollout state RolloutState OSPolicyAssignment_RolloutState `protobuf:"varint,9,opt,name=rollout_state,json=rolloutState,proto3,enum=google.cloud.osconfig.v1.OSPolicyAssignment_RolloutState" json:"rollout_state,omitempty"` // Output only. Indicates that this revision has been successfully rolled out // in this zone and new VMs will be assigned OS policies from this revision. // // For a given OS policy assignment, there is only one revision with a value // of `true` for this field. Baseline bool `protobuf:"varint,10,opt,name=baseline,proto3" json:"baseline,omitempty"` // Output only. Indicates that this revision deletes the OS policy assignment. Deleted bool `protobuf:"varint,11,opt,name=deleted,proto3" json:"deleted,omitempty"` // Output only. Indicates that reconciliation is in progress for the revision. // This value is `true` when the `rollout_state` is one of: // * IN_PROGRESS // * CANCELLING Reconciling bool `protobuf:"varint,12,opt,name=reconciling,proto3" json:"reconciling,omitempty"` // Output only. Server generated unique id for the OS policy assignment // resource. Uid string `protobuf:"bytes,13,opt,name=uid,proto3" json:"uid,omitempty"` } func (x *OSPolicyAssignment) Reset() { *x = OSPolicyAssignment{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicyAssignment) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicyAssignment) ProtoMessage() {} func (x *OSPolicyAssignment) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicyAssignment.ProtoReflect.Descriptor instead. func (*OSPolicyAssignment) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDescGZIP(), []int{0} } func (x *OSPolicyAssignment) GetName() string { if x != nil { return x.Name } return "" } func (x *OSPolicyAssignment) GetDescription() string { if x != nil { return x.Description } return "" } func (x *OSPolicyAssignment) GetOsPolicies() []*OSPolicy { if x != nil { return x.OsPolicies } return nil } func (x *OSPolicyAssignment) GetInstanceFilter() *OSPolicyAssignment_InstanceFilter { if x != nil { return x.InstanceFilter } return nil } func (x *OSPolicyAssignment) GetRollout() *OSPolicyAssignment_Rollout { if x != nil { return x.Rollout } return nil } func (x *OSPolicyAssignment) GetRevisionId() string { if x != nil { return x.RevisionId } return "" } func (x *OSPolicyAssignment) GetRevisionCreateTime() *timestamppb.Timestamp { if x != nil { return x.RevisionCreateTime } return nil } func (x *OSPolicyAssignment) GetEtag() string { if x != nil { return x.Etag } return "" } func (x *OSPolicyAssignment) GetRolloutState() OSPolicyAssignment_RolloutState { if x != nil { return x.RolloutState } return OSPolicyAssignment_ROLLOUT_STATE_UNSPECIFIED } func (x *OSPolicyAssignment) GetBaseline() bool { if x != nil { return x.Baseline } return false } func (x *OSPolicyAssignment) GetDeleted() bool { if x != nil { return x.Deleted } return false } func (x *OSPolicyAssignment) GetReconciling() bool { if x != nil { return x.Reconciling } return false } func (x *OSPolicyAssignment) GetUid() string { if x != nil { return x.Uid } return "" } // OS policy assignment operation metadata provided by OS policy assignment API // methods that return long running operations. type OSPolicyAssignmentOperationMetadata struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Reference to the `OSPolicyAssignment` API resource. // // Format: // `projects/{project_number}/locations/{location}/osPolicyAssignments/{os_policy_assignment_id@revision_id}` OsPolicyAssignment string `protobuf:"bytes,1,opt,name=os_policy_assignment,json=osPolicyAssignment,proto3" json:"os_policy_assignment,omitempty"` // The OS policy assignment API method. ApiMethod OSPolicyAssignmentOperationMetadata_APIMethod `protobuf:"varint,2,opt,name=api_method,json=apiMethod,proto3,enum=google.cloud.osconfig.v1.OSPolicyAssignmentOperationMetadata_APIMethod" json:"api_method,omitempty"` // State of the rollout RolloutState OSPolicyAssignmentOperationMetadata_RolloutState `protobuf:"varint,3,opt,name=rollout_state,json=rolloutState,proto3,enum=google.cloud.osconfig.v1.OSPolicyAssignmentOperationMetadata_RolloutState" json:"rollout_state,omitempty"` // Rollout start time RolloutStartTime *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=rollout_start_time,json=rolloutStartTime,proto3" json:"rollout_start_time,omitempty"` // Rollout update time RolloutUpdateTime *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=rollout_update_time,json=rolloutUpdateTime,proto3" json:"rollout_update_time,omitempty"` } func (x *OSPolicyAssignmentOperationMetadata) Reset() { *x = OSPolicyAssignmentOperationMetadata{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicyAssignmentOperationMetadata) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicyAssignmentOperationMetadata) ProtoMessage() {} func (x *OSPolicyAssignmentOperationMetadata) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicyAssignmentOperationMetadata.ProtoReflect.Descriptor instead. func (*OSPolicyAssignmentOperationMetadata) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDescGZIP(), []int{1} } func (x *OSPolicyAssignmentOperationMetadata) GetOsPolicyAssignment() string { if x != nil { return x.OsPolicyAssignment } return "" } func (x *OSPolicyAssignmentOperationMetadata) GetApiMethod() OSPolicyAssignmentOperationMetadata_APIMethod { if x != nil { return x.ApiMethod } return OSPolicyAssignmentOperationMetadata_API_METHOD_UNSPECIFIED } func (x *OSPolicyAssignmentOperationMetadata) GetRolloutState() OSPolicyAssignmentOperationMetadata_RolloutState { if x != nil { return x.RolloutState } return OSPolicyAssignmentOperationMetadata_ROLLOUT_STATE_UNSPECIFIED } func (x *OSPolicyAssignmentOperationMetadata) GetRolloutStartTime() *timestamppb.Timestamp { if x != nil { return x.RolloutStartTime } return nil } func (x *OSPolicyAssignmentOperationMetadata) GetRolloutUpdateTime() *timestamppb.Timestamp { if x != nil { return x.RolloutUpdateTime } return nil } // A request message to create an OS policy assignment type CreateOSPolicyAssignmentRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. The parent resource name in the form: // projects/{project}/locations/{location} Parent string `protobuf:"bytes,1,opt,name=parent,proto3" json:"parent,omitempty"` // Required. The OS policy assignment to be created. OsPolicyAssignment *OSPolicyAssignment `protobuf:"bytes,2,opt,name=os_policy_assignment,json=osPolicyAssignment,proto3" json:"os_policy_assignment,omitempty"` // Required. The logical name of the OS policy assignment in the project // with the following restrictions: // // * Must contain only lowercase letters, numbers, and hyphens. // * Must start with a letter. // * Must be between 1-63 characters. // * Must end with a number or a letter. // * Must be unique within the project. OsPolicyAssignmentId string `protobuf:"bytes,3,opt,name=os_policy_assignment_id,json=osPolicyAssignmentId,proto3" json:"os_policy_assignment_id,omitempty"` } func (x *CreateOSPolicyAssignmentRequest) Reset() { *x = CreateOSPolicyAssignmentRequest{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *CreateOSPolicyAssignmentRequest) String() string { return protoimpl.X.MessageStringOf(x) } func (*CreateOSPolicyAssignmentRequest) ProtoMessage() {} func (x *CreateOSPolicyAssignmentRequest) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use CreateOSPolicyAssignmentRequest.ProtoReflect.Descriptor instead. func (*CreateOSPolicyAssignmentRequest) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDescGZIP(), []int{2} } func (x *CreateOSPolicyAssignmentRequest) GetParent() string { if x != nil { return x.Parent } return "" } func (x *CreateOSPolicyAssignmentRequest) GetOsPolicyAssignment() *OSPolicyAssignment { if x != nil { return x.OsPolicyAssignment } return nil } func (x *CreateOSPolicyAssignmentRequest) GetOsPolicyAssignmentId() string { if x != nil { return x.OsPolicyAssignmentId } return "" } // A request message to update an OS policy assignment type UpdateOSPolicyAssignmentRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. The updated OS policy assignment. OsPolicyAssignment *OSPolicyAssignment `protobuf:"bytes,1,opt,name=os_policy_assignment,json=osPolicyAssignment,proto3" json:"os_policy_assignment,omitempty"` // Optional. Field mask that controls which fields of the assignment should be // updated. UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,2,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"` } func (x *UpdateOSPolicyAssignmentRequest) Reset() { *x = UpdateOSPolicyAssignmentRequest{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *UpdateOSPolicyAssignmentRequest) String() string { return protoimpl.X.MessageStringOf(x) } func (*UpdateOSPolicyAssignmentRequest) ProtoMessage() {} func (x *UpdateOSPolicyAssignmentRequest) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use UpdateOSPolicyAssignmentRequest.ProtoReflect.Descriptor instead. func (*UpdateOSPolicyAssignmentRequest) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDescGZIP(), []int{3} } func (x *UpdateOSPolicyAssignmentRequest) GetOsPolicyAssignment() *OSPolicyAssignment { if x != nil { return x.OsPolicyAssignment } return nil } func (x *UpdateOSPolicyAssignmentRequest) GetUpdateMask() *fieldmaskpb.FieldMask { if x != nil { return x.UpdateMask } return nil } // A request message to get an OS policy assignment type GetOSPolicyAssignmentRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. The resource name of OS policy assignment. // // Format: // `projects/{project}/locations/{location}/osPolicyAssignments/{os_policy_assignment}@{revisionId}` Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } func (x *GetOSPolicyAssignmentRequest) Reset() { *x = GetOSPolicyAssignmentRequest{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *GetOSPolicyAssignmentRequest) String() string { return protoimpl.X.MessageStringOf(x) } func (*GetOSPolicyAssignmentRequest) ProtoMessage() {} func (x *GetOSPolicyAssignmentRequest) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use GetOSPolicyAssignmentRequest.ProtoReflect.Descriptor instead. func (*GetOSPolicyAssignmentRequest) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDescGZIP(), []int{4} } func (x *GetOSPolicyAssignmentRequest) GetName() string { if x != nil { return x.Name } return "" } // A request message to list OS policy assignments for a parent resource type ListOSPolicyAssignmentsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. The parent resource name. Parent string `protobuf:"bytes,1,opt,name=parent,proto3" json:"parent,omitempty"` // The maximum number of assignments to return. PageSize int32 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` // A pagination token returned from a previous call to // `ListOSPolicyAssignments` that indicates where this listing should continue // from. PageToken string `protobuf:"bytes,3,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"` } func (x *ListOSPolicyAssignmentsRequest) Reset() { *x = ListOSPolicyAssignmentsRequest{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *ListOSPolicyAssignmentsRequest) String() string { return protoimpl.X.MessageStringOf(x) } func (*ListOSPolicyAssignmentsRequest) ProtoMessage() {} func (x *ListOSPolicyAssignmentsRequest) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use ListOSPolicyAssignmentsRequest.ProtoReflect.Descriptor instead. func (*ListOSPolicyAssignmentsRequest) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDescGZIP(), []int{5} } func (x *ListOSPolicyAssignmentsRequest) GetParent() string { if x != nil { return x.Parent } return "" } func (x *ListOSPolicyAssignmentsRequest) GetPageSize() int32 { if x != nil { return x.PageSize } return 0 } func (x *ListOSPolicyAssignmentsRequest) GetPageToken() string { if x != nil { return x.PageToken } return "" } // A response message for listing all assignments under given parent. type ListOSPolicyAssignmentsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // The list of assignments OsPolicyAssignments []*OSPolicyAssignment `protobuf:"bytes,1,rep,name=os_policy_assignments,json=osPolicyAssignments,proto3" json:"os_policy_assignments,omitempty"` // The pagination token to retrieve the next page of OS policy assignments. NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` } func (x *ListOSPolicyAssignmentsResponse) Reset() { *x = ListOSPolicyAssignmentsResponse{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *ListOSPolicyAssignmentsResponse) String() string { return protoimpl.X.MessageStringOf(x) } func (*ListOSPolicyAssignmentsResponse) ProtoMessage() {} func (x *ListOSPolicyAssignmentsResponse) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use ListOSPolicyAssignmentsResponse.ProtoReflect.Descriptor instead. func (*ListOSPolicyAssignmentsResponse) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDescGZIP(), []int{6} } func (x *ListOSPolicyAssignmentsResponse) GetOsPolicyAssignments() []*OSPolicyAssignment { if x != nil { return x.OsPolicyAssignments } return nil } func (x *ListOSPolicyAssignmentsResponse) GetNextPageToken() string { if x != nil { return x.NextPageToken } return "" } // A request message to list revisions for a OS policy assignment type ListOSPolicyAssignmentRevisionsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. The name of the OS policy assignment to list revisions for. Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // The maximum number of revisions to return. PageSize int32 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` // A pagination token returned from a previous call to // `ListOSPolicyAssignmentRevisions` that indicates where this listing should // continue from. PageToken string `protobuf:"bytes,3,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"` } func (x *ListOSPolicyAssignmentRevisionsRequest) Reset() { *x = ListOSPolicyAssignmentRevisionsRequest{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *ListOSPolicyAssignmentRevisionsRequest) String() string { return protoimpl.X.MessageStringOf(x) } func (*ListOSPolicyAssignmentRevisionsRequest) ProtoMessage() {} func (x *ListOSPolicyAssignmentRevisionsRequest) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use ListOSPolicyAssignmentRevisionsRequest.ProtoReflect.Descriptor instead. func (*ListOSPolicyAssignmentRevisionsRequest) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDescGZIP(), []int{7} } func (x *ListOSPolicyAssignmentRevisionsRequest) GetName() string { if x != nil { return x.Name } return "" } func (x *ListOSPolicyAssignmentRevisionsRequest) GetPageSize() int32 { if x != nil { return x.PageSize } return 0 } func (x *ListOSPolicyAssignmentRevisionsRequest) GetPageToken() string { if x != nil { return x.PageToken } return "" } // A response message for listing all revisions for a OS policy assignment. type ListOSPolicyAssignmentRevisionsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // The OS policy assignment revisions OsPolicyAssignments []*OSPolicyAssignment `protobuf:"bytes,1,rep,name=os_policy_assignments,json=osPolicyAssignments,proto3" json:"os_policy_assignments,omitempty"` // The pagination token to retrieve the next page of OS policy assignment // revisions. NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` } func (x *ListOSPolicyAssignmentRevisionsResponse) Reset() { *x = ListOSPolicyAssignmentRevisionsResponse{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *ListOSPolicyAssignmentRevisionsResponse) String() string { return protoimpl.X.MessageStringOf(x) } func (*ListOSPolicyAssignmentRevisionsResponse) ProtoMessage() {} func (x *ListOSPolicyAssignmentRevisionsResponse) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use ListOSPolicyAssignmentRevisionsResponse.ProtoReflect.Descriptor instead. func (*ListOSPolicyAssignmentRevisionsResponse) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDescGZIP(), []int{8} } func (x *ListOSPolicyAssignmentRevisionsResponse) GetOsPolicyAssignments() []*OSPolicyAssignment { if x != nil { return x.OsPolicyAssignments } return nil } func (x *ListOSPolicyAssignmentRevisionsResponse) GetNextPageToken() string { if x != nil { return x.NextPageToken } return "" } // A request message for deleting a OS policy assignment. type DeleteOSPolicyAssignmentRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. The name of the OS policy assignment to be deleted Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } func (x *DeleteOSPolicyAssignmentRequest) Reset() { *x = DeleteOSPolicyAssignmentRequest{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *DeleteOSPolicyAssignmentRequest) String() string { return protoimpl.X.MessageStringOf(x) } func (*DeleteOSPolicyAssignmentRequest) ProtoMessage() {} func (x *DeleteOSPolicyAssignmentRequest) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use DeleteOSPolicyAssignmentRequest.ProtoReflect.Descriptor instead. func (*DeleteOSPolicyAssignmentRequest) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDescGZIP(), []int{9} } func (x *DeleteOSPolicyAssignmentRequest) GetName() string { if x != nil { return x.Name } return "" } // Message representing label set. // - A label is a key value pair set for a VM. // - A LabelSet is a set of labels. // - Labels within a LabelSet are ANDed. In other words, a LabelSet is // applicable for a VM only if it matches all the labels in the // LabelSet. // - Example: A LabelSet with 2 labels: `env=prod` and `type=webserver` will // only be applicable for those VMs with both labels // present. type OSPolicyAssignment_LabelSet struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Labels are identified by key/value pairs in this map. // A VM should contain all the key/value pairs specified in this // map to be selected. Labels map[string]string `protobuf:"bytes,1,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *OSPolicyAssignment_LabelSet) Reset() { *x = OSPolicyAssignment_LabelSet{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicyAssignment_LabelSet) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicyAssignment_LabelSet) ProtoMessage() {} func (x *OSPolicyAssignment_LabelSet) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicyAssignment_LabelSet.ProtoReflect.Descriptor instead. func (*OSPolicyAssignment_LabelSet) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDescGZIP(), []int{0, 0} } func (x *OSPolicyAssignment_LabelSet) GetLabels() map[string]string { if x != nil { return x.Labels } return nil } // Filters to select target VMs for an assignment. // // If more than one filter criteria is specified below, a VM will be selected // if and only if it satisfies all of them. type OSPolicyAssignment_InstanceFilter struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Target all VMs in the project. If true, no other criteria is // permitted. All bool `protobuf:"varint,1,opt,name=all,proto3" json:"all,omitempty"` // List of label sets used for VM inclusion. // // If the list has more than one `LabelSet`, the VM is included if any // of the label sets are applicable for the VM. InclusionLabels []*OSPolicyAssignment_LabelSet `protobuf:"bytes,2,rep,name=inclusion_labels,json=inclusionLabels,proto3" json:"inclusion_labels,omitempty"` // List of label sets used for VM exclusion. // // If the list has more than one label set, the VM is excluded if any // of the label sets are applicable for the VM. ExclusionLabels []*OSPolicyAssignment_LabelSet `protobuf:"bytes,3,rep,name=exclusion_labels,json=exclusionLabels,proto3" json:"exclusion_labels,omitempty"` // List of inventories to select VMs. // // A VM is selected if its inventory data matches at least one of the // following inventories. Inventories []*OSPolicyAssignment_InstanceFilter_Inventory `protobuf:"bytes,4,rep,name=inventories,proto3" json:"inventories,omitempty"` } func (x *OSPolicyAssignment_InstanceFilter) Reset() { *x = OSPolicyAssignment_InstanceFilter{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicyAssignment_InstanceFilter) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicyAssignment_InstanceFilter) ProtoMessage() {} func (x *OSPolicyAssignment_InstanceFilter) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicyAssignment_InstanceFilter.ProtoReflect.Descriptor instead. func (*OSPolicyAssignment_InstanceFilter) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDescGZIP(), []int{0, 1} } func (x *OSPolicyAssignment_InstanceFilter) GetAll() bool { if x != nil { return x.All } return false } func (x *OSPolicyAssignment_InstanceFilter) GetInclusionLabels() []*OSPolicyAssignment_LabelSet { if x != nil { return x.InclusionLabels } return nil } func (x *OSPolicyAssignment_InstanceFilter) GetExclusionLabels() []*OSPolicyAssignment_LabelSet { if x != nil { return x.ExclusionLabels } return nil } func (x *OSPolicyAssignment_InstanceFilter) GetInventories() []*OSPolicyAssignment_InstanceFilter_Inventory { if x != nil { return x.Inventories } return nil } // Message to configure the rollout at the zonal level for the OS policy // assignment. type OSPolicyAssignment_Rollout struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. The maximum number (or percentage) of VMs per zone to disrupt // at any given moment. DisruptionBudget *FixedOrPercent `protobuf:"bytes,1,opt,name=disruption_budget,json=disruptionBudget,proto3" json:"disruption_budget,omitempty"` // Required. This determines the minimum duration of time to wait after the // configuration changes are applied through the current rollout. A // VM continues to count towards the `disruption_budget` at least // until this duration of time has passed after configuration changes are // applied. MinWaitDuration *durationpb.Duration `protobuf:"bytes,2,opt,name=min_wait_duration,json=minWaitDuration,proto3" json:"min_wait_duration,omitempty"` } func (x *OSPolicyAssignment_Rollout) Reset() { *x = OSPolicyAssignment_Rollout{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicyAssignment_Rollout) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicyAssignment_Rollout) ProtoMessage() {} func (x *OSPolicyAssignment_Rollout) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicyAssignment_Rollout.ProtoReflect.Descriptor instead. func (*OSPolicyAssignment_Rollout) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDescGZIP(), []int{0, 2} } func (x *OSPolicyAssignment_Rollout) GetDisruptionBudget() *FixedOrPercent { if x != nil { return x.DisruptionBudget } return nil } func (x *OSPolicyAssignment_Rollout) GetMinWaitDuration() *durationpb.Duration { if x != nil { return x.MinWaitDuration } return nil } // VM inventory details. type OSPolicyAssignment_InstanceFilter_Inventory struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. The OS short name OsShortName string `protobuf:"bytes,1,opt,name=os_short_name,json=osShortName,proto3" json:"os_short_name,omitempty"` // The OS version // // Prefix matches are supported if asterisk(*) is provided as the // last character. For example, to match all versions with a major // version of `7`, specify the following value for this field `7.*` // // An empty string matches all OS versions. OsVersion string `protobuf:"bytes,2,opt,name=os_version,json=osVersion,proto3" json:"os_version,omitempty"` } func (x *OSPolicyAssignment_InstanceFilter_Inventory) Reset() { *x = OSPolicyAssignment_InstanceFilter_Inventory{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OSPolicyAssignment_InstanceFilter_Inventory) String() string { return protoimpl.X.MessageStringOf(x) } func (*OSPolicyAssignment_InstanceFilter_Inventory) ProtoMessage() {} func (x *OSPolicyAssignment_InstanceFilter_Inventory) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OSPolicyAssignment_InstanceFilter_Inventory.ProtoReflect.Descriptor instead. func (*OSPolicyAssignment_InstanceFilter_Inventory) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDescGZIP(), []int{0, 1, 0} } func (x *OSPolicyAssignment_InstanceFilter_Inventory) GetOsShortName() string { if x != nil { return x.OsShortName } return "" } func (x *OSPolicyAssignment_InstanceFilter_Inventory) GetOsVersion() string { if x != nil { return x.OsVersion } return "" } var File_google_cloud_osconfig_v1_os_policy_assignments_proto protoreflect.FileDescriptor var file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDesc = []byte{ 0x0a, 0x34, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x18, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x28, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb7, 0x0d, 0x0a, 0x12, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x48, 0x0a, 0x0b, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0a, 0x6f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x69, 0x0a, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x53, 0x0a, 0x07, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x07, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x12, 0x24, 0x0a, 0x0b, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x51, 0x0a, 0x14, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x03, 0xe0, 0x41, 0x03, 0x52, 0x12, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x74, 0x61, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x74, 0x61, 0x67, 0x12, 0x63, 0x0a, 0x0d, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x03, 0x52, 0x0c, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x08, 0x62, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x42, 0x03, 0xe0, 0x41, 0x03, 0x52, 0x08, 0x62, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1d, 0x0a, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x42, 0x03, 0xe0, 0x41, 0x03, 0x52, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x25, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x63, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x42, 0x03, 0xe0, 0x41, 0x03, 0x52, 0x0b, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x63, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x12, 0x15, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x03, 0x52, 0x03, 0x75, 0x69, 0x64, 0x1a, 0xa0, 0x01, 0x0a, 0x08, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x53, 0x65, 0x74, 0x12, 0x59, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x53, 0x65, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0xa4, 0x03, 0x0a, 0x0e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x6c, 0x6c, 0x12, 0x60, 0x0a, 0x10, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x53, 0x65, 0x74, 0x52, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x60, 0x0a, 0x10, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x53, 0x65, 0x74, 0x52, 0x0f, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x67, 0x0a, 0x0b, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2e, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x0b, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x1a, 0x53, 0x0a, 0x09, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x27, 0x0a, 0x0d, 0x6f, 0x73, 0x5f, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0b, 0x6f, 0x73, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6f, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0xb1, 0x01, 0x0a, 0x07, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x12, 0x5a, 0x0a, 0x11, 0x64, 0x69, 0x73, 0x72, 0x75, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x78, 0x65, 0x64, 0x4f, 0x72, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x10, 0x64, 0x69, 0x73, 0x72, 0x75, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x75, 0x64, 0x67, 0x65, 0x74, 0x12, 0x4a, 0x0a, 0x11, 0x6d, 0x69, 0x6e, 0x5f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0f, 0x6d, 0x69, 0x6e, 0x57, 0x61, 0x69, 0x74, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x6c, 0x0a, 0x0c, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x4f, 0x4c, 0x4c, 0x4f, 0x55, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x4c, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x55, 0x43, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, 0x04, 0x3a, 0x84, 0x01, 0xea, 0x41, 0x80, 0x01, 0x0a, 0x2a, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x52, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x7d, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7d, 0x2f, 0x6f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x7d, 0x22, 0xb2, 0x05, 0x0a, 0x23, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x61, 0x0a, 0x14, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2f, 0xfa, 0x41, 0x2c, 0x0a, 0x2a, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x12, 0x6f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x66, 0x0a, 0x0a, 0x61, 0x70, 0x69, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x47, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x50, 0x49, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x09, 0x61, 0x70, 0x69, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x6f, 0x0a, 0x0d, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x4a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0c, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x48, 0x0a, 0x12, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x10, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x53, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x4a, 0x0a, 0x13, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x11, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x4b, 0x0a, 0x09, 0x41, 0x50, 0x49, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x50, 0x49, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x03, 0x22, 0x6c, 0x0a, 0x0c, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x4f, 0x4c, 0x4c, 0x4f, 0x55, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x4c, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x55, 0x43, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, 0x04, 0x22, 0x85, 0x02, 0x0a, 0x1f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x41, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x29, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x23, 0x0a, 0x21, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x63, 0x0a, 0x14, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x12, 0x6f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x3a, 0x0a, 0x17, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x14, 0x6f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0xc8, 0x01, 0x0a, 0x1f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x63, 0x0a, 0x14, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x12, 0x6f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x40, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x66, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x46, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x32, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x2c, 0x0a, 0x2a, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x9f, 0x01, 0x0a, 0x1e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x41, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x29, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x23, 0x0a, 0x21, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xab, 0x01, 0x0a, 0x1f, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x15, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x13, 0x6f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xac, 0x01, 0x0a, 0x26, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x46, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x32, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x2c, 0x0a, 0x2a, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xb3, 0x01, 0x0a, 0x27, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x15, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x13, 0x6f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x69, 0x0a, 0x1f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x46, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x32, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x2c, 0x0a, 0x2a, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0xd0, 0x01, 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x42, 0x18, 0x4f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x40, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x3b, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0xaa, 0x02, 0x18, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x18, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5c, 0x56, 0x31, 0xea, 0x02, 0x1b, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDescOnce sync.Once file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDescData = file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDesc ) func file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDescGZIP() []byte { file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDescOnce.Do(func() { file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDescData) }) return file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDescData } var file_google_cloud_osconfig_v1_os_policy_assignments_proto_enumTypes = make([]protoimpl.EnumInfo, 3) var file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes = make([]protoimpl.MessageInfo, 15) var file_google_cloud_osconfig_v1_os_policy_assignments_proto_goTypes = []interface{}{ (OSPolicyAssignment_RolloutState)(0), // 0: google.cloud.osconfig.v1.OSPolicyAssignment.RolloutState (OSPolicyAssignmentOperationMetadata_APIMethod)(0), // 1: google.cloud.osconfig.v1.OSPolicyAssignmentOperationMetadata.APIMethod (OSPolicyAssignmentOperationMetadata_RolloutState)(0), // 2: google.cloud.osconfig.v1.OSPolicyAssignmentOperationMetadata.RolloutState (*OSPolicyAssignment)(nil), // 3: google.cloud.osconfig.v1.OSPolicyAssignment (*OSPolicyAssignmentOperationMetadata)(nil), // 4: google.cloud.osconfig.v1.OSPolicyAssignmentOperationMetadata (*CreateOSPolicyAssignmentRequest)(nil), // 5: google.cloud.osconfig.v1.CreateOSPolicyAssignmentRequest (*UpdateOSPolicyAssignmentRequest)(nil), // 6: google.cloud.osconfig.v1.UpdateOSPolicyAssignmentRequest (*GetOSPolicyAssignmentRequest)(nil), // 7: google.cloud.osconfig.v1.GetOSPolicyAssignmentRequest (*ListOSPolicyAssignmentsRequest)(nil), // 8: google.cloud.osconfig.v1.ListOSPolicyAssignmentsRequest (*ListOSPolicyAssignmentsResponse)(nil), // 9: google.cloud.osconfig.v1.ListOSPolicyAssignmentsResponse (*ListOSPolicyAssignmentRevisionsRequest)(nil), // 10: google.cloud.osconfig.v1.ListOSPolicyAssignmentRevisionsRequest (*ListOSPolicyAssignmentRevisionsResponse)(nil), // 11: google.cloud.osconfig.v1.ListOSPolicyAssignmentRevisionsResponse (*DeleteOSPolicyAssignmentRequest)(nil), // 12: google.cloud.osconfig.v1.DeleteOSPolicyAssignmentRequest (*OSPolicyAssignment_LabelSet)(nil), // 13: google.cloud.osconfig.v1.OSPolicyAssignment.LabelSet (*OSPolicyAssignment_InstanceFilter)(nil), // 14: google.cloud.osconfig.v1.OSPolicyAssignment.InstanceFilter (*OSPolicyAssignment_Rollout)(nil), // 15: google.cloud.osconfig.v1.OSPolicyAssignment.Rollout nil, // 16: google.cloud.osconfig.v1.OSPolicyAssignment.LabelSet.LabelsEntry (*OSPolicyAssignment_InstanceFilter_Inventory)(nil), // 17: google.cloud.osconfig.v1.OSPolicyAssignment.InstanceFilter.Inventory (*OSPolicy)(nil), // 18: google.cloud.osconfig.v1.OSPolicy (*timestamppb.Timestamp)(nil), // 19: google.protobuf.Timestamp (*fieldmaskpb.FieldMask)(nil), // 20: google.protobuf.FieldMask (*FixedOrPercent)(nil), // 21: google.cloud.osconfig.v1.FixedOrPercent (*durationpb.Duration)(nil), // 22: google.protobuf.Duration } var file_google_cloud_osconfig_v1_os_policy_assignments_proto_depIdxs = []int32{ 18, // 0: google.cloud.osconfig.v1.OSPolicyAssignment.os_policies:type_name -> google.cloud.osconfig.v1.OSPolicy 14, // 1: google.cloud.osconfig.v1.OSPolicyAssignment.instance_filter:type_name -> google.cloud.osconfig.v1.OSPolicyAssignment.InstanceFilter 15, // 2: google.cloud.osconfig.v1.OSPolicyAssignment.rollout:type_name -> google.cloud.osconfig.v1.OSPolicyAssignment.Rollout 19, // 3: google.cloud.osconfig.v1.OSPolicyAssignment.revision_create_time:type_name -> google.protobuf.Timestamp 0, // 4: google.cloud.osconfig.v1.OSPolicyAssignment.rollout_state:type_name -> google.cloud.osconfig.v1.OSPolicyAssignment.RolloutState 1, // 5: google.cloud.osconfig.v1.OSPolicyAssignmentOperationMetadata.api_method:type_name -> google.cloud.osconfig.v1.OSPolicyAssignmentOperationMetadata.APIMethod 2, // 6: google.cloud.osconfig.v1.OSPolicyAssignmentOperationMetadata.rollout_state:type_name -> google.cloud.osconfig.v1.OSPolicyAssignmentOperationMetadata.RolloutState 19, // 7: google.cloud.osconfig.v1.OSPolicyAssignmentOperationMetadata.rollout_start_time:type_name -> google.protobuf.Timestamp 19, // 8: google.cloud.osconfig.v1.OSPolicyAssignmentOperationMetadata.rollout_update_time:type_name -> google.protobuf.Timestamp 3, // 9: google.cloud.osconfig.v1.CreateOSPolicyAssignmentRequest.os_policy_assignment:type_name -> google.cloud.osconfig.v1.OSPolicyAssignment 3, // 10: google.cloud.osconfig.v1.UpdateOSPolicyAssignmentRequest.os_policy_assignment:type_name -> google.cloud.osconfig.v1.OSPolicyAssignment 20, // 11: google.cloud.osconfig.v1.UpdateOSPolicyAssignmentRequest.update_mask:type_name -> google.protobuf.FieldMask 3, // 12: google.cloud.osconfig.v1.ListOSPolicyAssignmentsResponse.os_policy_assignments:type_name -> google.cloud.osconfig.v1.OSPolicyAssignment 3, // 13: google.cloud.osconfig.v1.ListOSPolicyAssignmentRevisionsResponse.os_policy_assignments:type_name -> google.cloud.osconfig.v1.OSPolicyAssignment 16, // 14: google.cloud.osconfig.v1.OSPolicyAssignment.LabelSet.labels:type_name -> google.cloud.osconfig.v1.OSPolicyAssignment.LabelSet.LabelsEntry 13, // 15: google.cloud.osconfig.v1.OSPolicyAssignment.InstanceFilter.inclusion_labels:type_name -> google.cloud.osconfig.v1.OSPolicyAssignment.LabelSet 13, // 16: google.cloud.osconfig.v1.OSPolicyAssignment.InstanceFilter.exclusion_labels:type_name -> google.cloud.osconfig.v1.OSPolicyAssignment.LabelSet 17, // 17: google.cloud.osconfig.v1.OSPolicyAssignment.InstanceFilter.inventories:type_name -> google.cloud.osconfig.v1.OSPolicyAssignment.InstanceFilter.Inventory 21, // 18: google.cloud.osconfig.v1.OSPolicyAssignment.Rollout.disruption_budget:type_name -> google.cloud.osconfig.v1.FixedOrPercent 22, // 19: google.cloud.osconfig.v1.OSPolicyAssignment.Rollout.min_wait_duration:type_name -> google.protobuf.Duration 20, // [20:20] is the sub-list for method output_type 20, // [20:20] is the sub-list for method input_type 20, // [20:20] is the sub-list for extension type_name 20, // [20:20] is the sub-list for extension extendee 0, // [0:20] is the sub-list for field type_name } func init() { file_google_cloud_osconfig_v1_os_policy_assignments_proto_init() } func file_google_cloud_osconfig_v1_os_policy_assignments_proto_init() { if File_google_cloud_osconfig_v1_os_policy_assignments_proto != nil { return } file_google_cloud_osconfig_v1_os_policy_proto_init() file_google_cloud_osconfig_v1_osconfig_common_proto_init() if !protoimpl.UnsafeEnabled { file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicyAssignment); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicyAssignmentOperationMetadata); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreateOSPolicyAssignmentRequest); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UpdateOSPolicyAssignmentRequest); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetOSPolicyAssignmentRequest); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListOSPolicyAssignmentsRequest); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListOSPolicyAssignmentsResponse); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListOSPolicyAssignmentRevisionsRequest); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListOSPolicyAssignmentRevisionsResponse); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DeleteOSPolicyAssignmentRequest); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicyAssignment_LabelSet); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicyAssignment_InstanceFilter); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicyAssignment_Rollout); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSPolicyAssignment_InstanceFilter_Inventory); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDesc, NumEnums: 3, NumMessages: 15, NumExtensions: 0, NumServices: 0, }, GoTypes: file_google_cloud_osconfig_v1_os_policy_assignments_proto_goTypes, DependencyIndexes: file_google_cloud_osconfig_v1_os_policy_assignments_proto_depIdxs, EnumInfos: file_google_cloud_osconfig_v1_os_policy_assignments_proto_enumTypes, MessageInfos: file_google_cloud_osconfig_v1_os_policy_assignments_proto_msgTypes, }.Build() File_google_cloud_osconfig_v1_os_policy_assignments_proto = out.File file_google_cloud_osconfig_v1_os_policy_assignments_proto_rawDesc = nil file_google_cloud_osconfig_v1_os_policy_assignments_proto_goTypes = nil file_google_cloud_osconfig_v1_os_policy_assignments_proto_depIdxs = nil } osconfig_common.pb.go000066400000000000000000000207511477773331400363340ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/internal/google.golang.org/genproto/googleapis/cloud/osconfig/v1// Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.25.0 // protoc v3.15.3 // source: google/cloud/osconfig/v1/osconfig_common.proto package osconfig import ( proto "github.com/golang/protobuf/proto" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" ) const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) // Verify that runtime/protoimpl is sufficiently up-to-date. _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) // This is a compile-time assertion that a sufficiently up-to-date version // of the legacy proto package is being used. const _ = proto.ProtoPackageIsVersion4 // Message encapsulating a value that can be either absolute ("fixed") or // relative ("percent") to a value. type FixedOrPercent struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Type of the value. // // Types that are assignable to Mode: // *FixedOrPercent_Fixed // *FixedOrPercent_Percent Mode isFixedOrPercent_Mode `protobuf_oneof:"mode"` } func (x *FixedOrPercent) Reset() { *x = FixedOrPercent{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_osconfig_common_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *FixedOrPercent) String() string { return protoimpl.X.MessageStringOf(x) } func (*FixedOrPercent) ProtoMessage() {} func (x *FixedOrPercent) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_osconfig_common_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use FixedOrPercent.ProtoReflect.Descriptor instead. func (*FixedOrPercent) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_osconfig_common_proto_rawDescGZIP(), []int{0} } func (m *FixedOrPercent) GetMode() isFixedOrPercent_Mode { if m != nil { return m.Mode } return nil } func (x *FixedOrPercent) GetFixed() int32 { if x, ok := x.GetMode().(*FixedOrPercent_Fixed); ok { return x.Fixed } return 0 } func (x *FixedOrPercent) GetPercent() int32 { if x, ok := x.GetMode().(*FixedOrPercent_Percent); ok { return x.Percent } return 0 } type isFixedOrPercent_Mode interface { isFixedOrPercent_Mode() } type FixedOrPercent_Fixed struct { // Specifies a fixed value. Fixed int32 `protobuf:"varint,1,opt,name=fixed,proto3,oneof"` } type FixedOrPercent_Percent struct { // Specifies the relative value defined as a percentage, which will be // multiplied by a reference value. Percent int32 `protobuf:"varint,2,opt,name=percent,proto3,oneof"` } func (*FixedOrPercent_Fixed) isFixedOrPercent_Mode() {} func (*FixedOrPercent_Percent) isFixedOrPercent_Mode() {} var File_google_cloud_osconfig_v1_osconfig_common_proto protoreflect.FileDescriptor var file_google_cloud_osconfig_v1_osconfig_common_proto_rawDesc = []byte{ 0x0a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x18, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x22, 0x4c, 0x0a, 0x0e, 0x46, 0x69, 0x78, 0x65, 0x64, 0x4f, 0x72, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x05, 0x66, 0x69, 0x78, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x05, 0x66, 0x69, 0x78, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x07, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x07, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x42, 0x06, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x42, 0xbc, 0x01, 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x42, 0x06, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5a, 0x40, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x3b, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0xaa, 0x02, 0x18, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x18, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5c, 0x56, 0x31, 0xea, 0x02, 0x1b, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( file_google_cloud_osconfig_v1_osconfig_common_proto_rawDescOnce sync.Once file_google_cloud_osconfig_v1_osconfig_common_proto_rawDescData = file_google_cloud_osconfig_v1_osconfig_common_proto_rawDesc ) func file_google_cloud_osconfig_v1_osconfig_common_proto_rawDescGZIP() []byte { file_google_cloud_osconfig_v1_osconfig_common_proto_rawDescOnce.Do(func() { file_google_cloud_osconfig_v1_osconfig_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_cloud_osconfig_v1_osconfig_common_proto_rawDescData) }) return file_google_cloud_osconfig_v1_osconfig_common_proto_rawDescData } var file_google_cloud_osconfig_v1_osconfig_common_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_google_cloud_osconfig_v1_osconfig_common_proto_goTypes = []interface{}{ (*FixedOrPercent)(nil), // 0: google.cloud.osconfig.v1.FixedOrPercent } var file_google_cloud_osconfig_v1_osconfig_common_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for method output_type 0, // [0:0] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name } func init() { file_google_cloud_osconfig_v1_osconfig_common_proto_init() } func file_google_cloud_osconfig_v1_osconfig_common_proto_init() { if File_google_cloud_osconfig_v1_osconfig_common_proto != nil { return } if !protoimpl.UnsafeEnabled { file_google_cloud_osconfig_v1_osconfig_common_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*FixedOrPercent); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } } file_google_cloud_osconfig_v1_osconfig_common_proto_msgTypes[0].OneofWrappers = []interface{}{ (*FixedOrPercent_Fixed)(nil), (*FixedOrPercent_Percent)(nil), } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_google_cloud_osconfig_v1_osconfig_common_proto_rawDesc, NumEnums: 0, NumMessages: 1, NumExtensions: 0, NumServices: 0, }, GoTypes: file_google_cloud_osconfig_v1_osconfig_common_proto_goTypes, DependencyIndexes: file_google_cloud_osconfig_v1_osconfig_common_proto_depIdxs, MessageInfos: file_google_cloud_osconfig_v1_osconfig_common_proto_msgTypes, }.Build() File_google_cloud_osconfig_v1_osconfig_common_proto = out.File file_google_cloud_osconfig_v1_osconfig_common_proto_rawDesc = nil file_google_cloud_osconfig_v1_osconfig_common_proto_goTypes = nil file_google_cloud_osconfig_v1_osconfig_common_proto_depIdxs = nil } osconfig_service.pb.go000066400000000000000000001134441477773331400365060ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/internal/google.golang.org/genproto/googleapis/cloud/osconfig/v1// Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.25.0 // protoc v3.15.3 // source: google/cloud/osconfig/v1/osconfig_service.proto package osconfig import ( context "context" proto "github.com/golang/protobuf/proto" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" emptypb "google.golang.org/protobuf/types/known/emptypb" reflect "reflect" ) const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) // Verify that runtime/protoimpl is sufficiently up-to-date. _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) // This is a compile-time assertion that a sufficiently up-to-date version // of the legacy proto package is being used. const _ = proto.ProtoPackageIsVersion4 var File_google_cloud_osconfig_v1_osconfig_service_proto protoreflect.FileDescriptor var file_google_cloud_osconfig_v1_osconfig_service_proto_rawDesc = []byte{ 0x0a, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x18, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x30, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x29, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6a, 0x6f, 0x62, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0xbe, 0x0d, 0x0a, 0x0f, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x9d, 0x01, 0x0a, 0x0f, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x12, 0x30, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x22, 0x34, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x22, 0x29, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x73, 0x3a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x91, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x12, 0x2c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x23, 0x12, 0x21, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x73, 0x2f, 0x2a, 0x7d, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x9a, 0x01, 0x0a, 0x0e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x12, 0x2f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x22, 0x33, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2d, 0x22, 0x28, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x3a, 0x01, 0x2a, 0x12, 0xa4, 0x01, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x73, 0x12, 0x2e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x32, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x23, 0x12, 0x21, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x73, 0xda, 0x41, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0xe0, 0x01, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x3c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x44, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x35, 0x12, 0x33, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0xda, 0x41, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0xec, 0x01, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x36, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x70, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3c, 0x22, 0x28, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x3a, 0x10, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0xda, 0x41, 0x2b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2c, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x2c, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x12, 0xad, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x37, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x12, 0x28, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0xc0, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x35, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x12, 0x28, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0xda, 0x41, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0xa0, 0x01, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x36, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x37, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x2a, 0x28, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x1a, 0x4b, 0xca, 0x41, 0x17, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0xd2, 0x41, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2d, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x42, 0xdc, 0x02, 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x42, 0x0d, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x5a, 0x40, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x3b, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0xaa, 0x02, 0x18, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x18, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5c, 0x56, 0x31, 0xea, 0x02, 0x1b, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0xea, 0x41, 0x95, 0x01, 0x0a, 0x1f, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x34, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x7d, 0x2f, 0x7a, 0x6f, 0x6e, 0x65, 0x73, 0x2f, 0x7b, 0x7a, 0x6f, 0x6e, 0x65, 0x7d, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x7d, 0x12, 0x3c, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x7d, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7d, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x7d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var file_google_cloud_osconfig_v1_osconfig_service_proto_goTypes = []interface{}{ (*ExecutePatchJobRequest)(nil), // 0: google.cloud.osconfig.v1.ExecutePatchJobRequest (*GetPatchJobRequest)(nil), // 1: google.cloud.osconfig.v1.GetPatchJobRequest (*CancelPatchJobRequest)(nil), // 2: google.cloud.osconfig.v1.CancelPatchJobRequest (*ListPatchJobsRequest)(nil), // 3: google.cloud.osconfig.v1.ListPatchJobsRequest (*ListPatchJobInstanceDetailsRequest)(nil), // 4: google.cloud.osconfig.v1.ListPatchJobInstanceDetailsRequest (*CreatePatchDeploymentRequest)(nil), // 5: google.cloud.osconfig.v1.CreatePatchDeploymentRequest (*GetPatchDeploymentRequest)(nil), // 6: google.cloud.osconfig.v1.GetPatchDeploymentRequest (*ListPatchDeploymentsRequest)(nil), // 7: google.cloud.osconfig.v1.ListPatchDeploymentsRequest (*DeletePatchDeploymentRequest)(nil), // 8: google.cloud.osconfig.v1.DeletePatchDeploymentRequest (*PatchJob)(nil), // 9: google.cloud.osconfig.v1.PatchJob (*ListPatchJobsResponse)(nil), // 10: google.cloud.osconfig.v1.ListPatchJobsResponse (*ListPatchJobInstanceDetailsResponse)(nil), // 11: google.cloud.osconfig.v1.ListPatchJobInstanceDetailsResponse (*PatchDeployment)(nil), // 12: google.cloud.osconfig.v1.PatchDeployment (*ListPatchDeploymentsResponse)(nil), // 13: google.cloud.osconfig.v1.ListPatchDeploymentsResponse (*emptypb.Empty)(nil), // 14: google.protobuf.Empty } var file_google_cloud_osconfig_v1_osconfig_service_proto_depIdxs = []int32{ 0, // 0: google.cloud.osconfig.v1.OsConfigService.ExecutePatchJob:input_type -> google.cloud.osconfig.v1.ExecutePatchJobRequest 1, // 1: google.cloud.osconfig.v1.OsConfigService.GetPatchJob:input_type -> google.cloud.osconfig.v1.GetPatchJobRequest 2, // 2: google.cloud.osconfig.v1.OsConfigService.CancelPatchJob:input_type -> google.cloud.osconfig.v1.CancelPatchJobRequest 3, // 3: google.cloud.osconfig.v1.OsConfigService.ListPatchJobs:input_type -> google.cloud.osconfig.v1.ListPatchJobsRequest 4, // 4: google.cloud.osconfig.v1.OsConfigService.ListPatchJobInstanceDetails:input_type -> google.cloud.osconfig.v1.ListPatchJobInstanceDetailsRequest 5, // 5: google.cloud.osconfig.v1.OsConfigService.CreatePatchDeployment:input_type -> google.cloud.osconfig.v1.CreatePatchDeploymentRequest 6, // 6: google.cloud.osconfig.v1.OsConfigService.GetPatchDeployment:input_type -> google.cloud.osconfig.v1.GetPatchDeploymentRequest 7, // 7: google.cloud.osconfig.v1.OsConfigService.ListPatchDeployments:input_type -> google.cloud.osconfig.v1.ListPatchDeploymentsRequest 8, // 8: google.cloud.osconfig.v1.OsConfigService.DeletePatchDeployment:input_type -> google.cloud.osconfig.v1.DeletePatchDeploymentRequest 9, // 9: google.cloud.osconfig.v1.OsConfigService.ExecutePatchJob:output_type -> google.cloud.osconfig.v1.PatchJob 9, // 10: google.cloud.osconfig.v1.OsConfigService.GetPatchJob:output_type -> google.cloud.osconfig.v1.PatchJob 9, // 11: google.cloud.osconfig.v1.OsConfigService.CancelPatchJob:output_type -> google.cloud.osconfig.v1.PatchJob 10, // 12: google.cloud.osconfig.v1.OsConfigService.ListPatchJobs:output_type -> google.cloud.osconfig.v1.ListPatchJobsResponse 11, // 13: google.cloud.osconfig.v1.OsConfigService.ListPatchJobInstanceDetails:output_type -> google.cloud.osconfig.v1.ListPatchJobInstanceDetailsResponse 12, // 14: google.cloud.osconfig.v1.OsConfigService.CreatePatchDeployment:output_type -> google.cloud.osconfig.v1.PatchDeployment 12, // 15: google.cloud.osconfig.v1.OsConfigService.GetPatchDeployment:output_type -> google.cloud.osconfig.v1.PatchDeployment 13, // 16: google.cloud.osconfig.v1.OsConfigService.ListPatchDeployments:output_type -> google.cloud.osconfig.v1.ListPatchDeploymentsResponse 14, // 17: google.cloud.osconfig.v1.OsConfigService.DeletePatchDeployment:output_type -> google.protobuf.Empty 9, // [9:18] is the sub-list for method output_type 0, // [0:9] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name } func init() { file_google_cloud_osconfig_v1_osconfig_service_proto_init() } func file_google_cloud_osconfig_v1_osconfig_service_proto_init() { if File_google_cloud_osconfig_v1_osconfig_service_proto != nil { return } file_google_cloud_osconfig_v1_patch_deployments_proto_init() file_google_cloud_osconfig_v1_patch_jobs_proto_init() type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_google_cloud_osconfig_v1_osconfig_service_proto_rawDesc, NumEnums: 0, NumMessages: 0, NumExtensions: 0, NumServices: 1, }, GoTypes: file_google_cloud_osconfig_v1_osconfig_service_proto_goTypes, DependencyIndexes: file_google_cloud_osconfig_v1_osconfig_service_proto_depIdxs, }.Build() File_google_cloud_osconfig_v1_osconfig_service_proto = out.File file_google_cloud_osconfig_v1_osconfig_service_proto_rawDesc = nil file_google_cloud_osconfig_v1_osconfig_service_proto_goTypes = nil file_google_cloud_osconfig_v1_osconfig_service_proto_depIdxs = nil } // Reference imports to suppress errors if they are not otherwise used. var _ context.Context var _ grpc.ClientConnInterface // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. const _ = grpc.SupportPackageIsVersion6 // OsConfigServiceClient is the client API for OsConfigService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type OsConfigServiceClient interface { // Patch VM instances by creating and running a patch job. ExecutePatchJob(ctx context.Context, in *ExecutePatchJobRequest, opts ...grpc.CallOption) (*PatchJob, error) // Get the patch job. This can be used to track the progress of an // ongoing patch job or review the details of completed jobs. GetPatchJob(ctx context.Context, in *GetPatchJobRequest, opts ...grpc.CallOption) (*PatchJob, error) // Cancel a patch job. The patch job must be active. Canceled patch jobs // cannot be restarted. CancelPatchJob(ctx context.Context, in *CancelPatchJobRequest, opts ...grpc.CallOption) (*PatchJob, error) // Get a list of patch jobs. ListPatchJobs(ctx context.Context, in *ListPatchJobsRequest, opts ...grpc.CallOption) (*ListPatchJobsResponse, error) // Get a list of instance details for a given patch job. ListPatchJobInstanceDetails(ctx context.Context, in *ListPatchJobInstanceDetailsRequest, opts ...grpc.CallOption) (*ListPatchJobInstanceDetailsResponse, error) // Create an OS Config patch deployment. CreatePatchDeployment(ctx context.Context, in *CreatePatchDeploymentRequest, opts ...grpc.CallOption) (*PatchDeployment, error) // Get an OS Config patch deployment. GetPatchDeployment(ctx context.Context, in *GetPatchDeploymentRequest, opts ...grpc.CallOption) (*PatchDeployment, error) // Get a page of OS Config patch deployments. ListPatchDeployments(ctx context.Context, in *ListPatchDeploymentsRequest, opts ...grpc.CallOption) (*ListPatchDeploymentsResponse, error) // Delete an OS Config patch deployment. DeletePatchDeployment(ctx context.Context, in *DeletePatchDeploymentRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) } type osConfigServiceClient struct { cc grpc.ClientConnInterface } func NewOsConfigServiceClient(cc grpc.ClientConnInterface) OsConfigServiceClient { return &osConfigServiceClient{cc} } func (c *osConfigServiceClient) ExecutePatchJob(ctx context.Context, in *ExecutePatchJobRequest, opts ...grpc.CallOption) (*PatchJob, error) { out := new(PatchJob) err := c.cc.Invoke(ctx, "/google.cloud.osconfig.v1.OsConfigService/ExecutePatchJob", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *osConfigServiceClient) GetPatchJob(ctx context.Context, in *GetPatchJobRequest, opts ...grpc.CallOption) (*PatchJob, error) { out := new(PatchJob) err := c.cc.Invoke(ctx, "/google.cloud.osconfig.v1.OsConfigService/GetPatchJob", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *osConfigServiceClient) CancelPatchJob(ctx context.Context, in *CancelPatchJobRequest, opts ...grpc.CallOption) (*PatchJob, error) { out := new(PatchJob) err := c.cc.Invoke(ctx, "/google.cloud.osconfig.v1.OsConfigService/CancelPatchJob", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *osConfigServiceClient) ListPatchJobs(ctx context.Context, in *ListPatchJobsRequest, opts ...grpc.CallOption) (*ListPatchJobsResponse, error) { out := new(ListPatchJobsResponse) err := c.cc.Invoke(ctx, "/google.cloud.osconfig.v1.OsConfigService/ListPatchJobs", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *osConfigServiceClient) ListPatchJobInstanceDetails(ctx context.Context, in *ListPatchJobInstanceDetailsRequest, opts ...grpc.CallOption) (*ListPatchJobInstanceDetailsResponse, error) { out := new(ListPatchJobInstanceDetailsResponse) err := c.cc.Invoke(ctx, "/google.cloud.osconfig.v1.OsConfigService/ListPatchJobInstanceDetails", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *osConfigServiceClient) CreatePatchDeployment(ctx context.Context, in *CreatePatchDeploymentRequest, opts ...grpc.CallOption) (*PatchDeployment, error) { out := new(PatchDeployment) err := c.cc.Invoke(ctx, "/google.cloud.osconfig.v1.OsConfigService/CreatePatchDeployment", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *osConfigServiceClient) GetPatchDeployment(ctx context.Context, in *GetPatchDeploymentRequest, opts ...grpc.CallOption) (*PatchDeployment, error) { out := new(PatchDeployment) err := c.cc.Invoke(ctx, "/google.cloud.osconfig.v1.OsConfigService/GetPatchDeployment", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *osConfigServiceClient) ListPatchDeployments(ctx context.Context, in *ListPatchDeploymentsRequest, opts ...grpc.CallOption) (*ListPatchDeploymentsResponse, error) { out := new(ListPatchDeploymentsResponse) err := c.cc.Invoke(ctx, "/google.cloud.osconfig.v1.OsConfigService/ListPatchDeployments", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *osConfigServiceClient) DeletePatchDeployment(ctx context.Context, in *DeletePatchDeploymentRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) err := c.cc.Invoke(ctx, "/google.cloud.osconfig.v1.OsConfigService/DeletePatchDeployment", in, out, opts...) if err != nil { return nil, err } return out, nil } // OsConfigServiceServer is the server API for OsConfigService service. type OsConfigServiceServer interface { // Patch VM instances by creating and running a patch job. ExecutePatchJob(context.Context, *ExecutePatchJobRequest) (*PatchJob, error) // Get the patch job. This can be used to track the progress of an // ongoing patch job or review the details of completed jobs. GetPatchJob(context.Context, *GetPatchJobRequest) (*PatchJob, error) // Cancel a patch job. The patch job must be active. Canceled patch jobs // cannot be restarted. CancelPatchJob(context.Context, *CancelPatchJobRequest) (*PatchJob, error) // Get a list of patch jobs. ListPatchJobs(context.Context, *ListPatchJobsRequest) (*ListPatchJobsResponse, error) // Get a list of instance details for a given patch job. ListPatchJobInstanceDetails(context.Context, *ListPatchJobInstanceDetailsRequest) (*ListPatchJobInstanceDetailsResponse, error) // Create an OS Config patch deployment. CreatePatchDeployment(context.Context, *CreatePatchDeploymentRequest) (*PatchDeployment, error) // Get an OS Config patch deployment. GetPatchDeployment(context.Context, *GetPatchDeploymentRequest) (*PatchDeployment, error) // Get a page of OS Config patch deployments. ListPatchDeployments(context.Context, *ListPatchDeploymentsRequest) (*ListPatchDeploymentsResponse, error) // Delete an OS Config patch deployment. DeletePatchDeployment(context.Context, *DeletePatchDeploymentRequest) (*emptypb.Empty, error) } // UnimplementedOsConfigServiceServer can be embedded to have forward compatible implementations. type UnimplementedOsConfigServiceServer struct { } func (*UnimplementedOsConfigServiceServer) ExecutePatchJob(context.Context, *ExecutePatchJobRequest) (*PatchJob, error) { return nil, status.Errorf(codes.Unimplemented, "method ExecutePatchJob not implemented") } func (*UnimplementedOsConfigServiceServer) GetPatchJob(context.Context, *GetPatchJobRequest) (*PatchJob, error) { return nil, status.Errorf(codes.Unimplemented, "method GetPatchJob not implemented") } func (*UnimplementedOsConfigServiceServer) CancelPatchJob(context.Context, *CancelPatchJobRequest) (*PatchJob, error) { return nil, status.Errorf(codes.Unimplemented, "method CancelPatchJob not implemented") } func (*UnimplementedOsConfigServiceServer) ListPatchJobs(context.Context, *ListPatchJobsRequest) (*ListPatchJobsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListPatchJobs not implemented") } func (*UnimplementedOsConfigServiceServer) ListPatchJobInstanceDetails(context.Context, *ListPatchJobInstanceDetailsRequest) (*ListPatchJobInstanceDetailsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListPatchJobInstanceDetails not implemented") } func (*UnimplementedOsConfigServiceServer) CreatePatchDeployment(context.Context, *CreatePatchDeploymentRequest) (*PatchDeployment, error) { return nil, status.Errorf(codes.Unimplemented, "method CreatePatchDeployment not implemented") } func (*UnimplementedOsConfigServiceServer) GetPatchDeployment(context.Context, *GetPatchDeploymentRequest) (*PatchDeployment, error) { return nil, status.Errorf(codes.Unimplemented, "method GetPatchDeployment not implemented") } func (*UnimplementedOsConfigServiceServer) ListPatchDeployments(context.Context, *ListPatchDeploymentsRequest) (*ListPatchDeploymentsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListPatchDeployments not implemented") } func (*UnimplementedOsConfigServiceServer) DeletePatchDeployment(context.Context, *DeletePatchDeploymentRequest) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method DeletePatchDeployment not implemented") } func RegisterOsConfigServiceServer(s *grpc.Server, srv OsConfigServiceServer) { s.RegisterService(&_OsConfigService_serviceDesc, srv) } func _OsConfigService_ExecutePatchJob_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ExecutePatchJobRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(OsConfigServiceServer).ExecutePatchJob(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/google.cloud.osconfig.v1.OsConfigService/ExecutePatchJob", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OsConfigServiceServer).ExecutePatchJob(ctx, req.(*ExecutePatchJobRequest)) } return interceptor(ctx, in, info, handler) } func _OsConfigService_GetPatchJob_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetPatchJobRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(OsConfigServiceServer).GetPatchJob(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/google.cloud.osconfig.v1.OsConfigService/GetPatchJob", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OsConfigServiceServer).GetPatchJob(ctx, req.(*GetPatchJobRequest)) } return interceptor(ctx, in, info, handler) } func _OsConfigService_CancelPatchJob_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(CancelPatchJobRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(OsConfigServiceServer).CancelPatchJob(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/google.cloud.osconfig.v1.OsConfigService/CancelPatchJob", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OsConfigServiceServer).CancelPatchJob(ctx, req.(*CancelPatchJobRequest)) } return interceptor(ctx, in, info, handler) } func _OsConfigService_ListPatchJobs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListPatchJobsRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(OsConfigServiceServer).ListPatchJobs(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/google.cloud.osconfig.v1.OsConfigService/ListPatchJobs", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OsConfigServiceServer).ListPatchJobs(ctx, req.(*ListPatchJobsRequest)) } return interceptor(ctx, in, info, handler) } func _OsConfigService_ListPatchJobInstanceDetails_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListPatchJobInstanceDetailsRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(OsConfigServiceServer).ListPatchJobInstanceDetails(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/google.cloud.osconfig.v1.OsConfigService/ListPatchJobInstanceDetails", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OsConfigServiceServer).ListPatchJobInstanceDetails(ctx, req.(*ListPatchJobInstanceDetailsRequest)) } return interceptor(ctx, in, info, handler) } func _OsConfigService_CreatePatchDeployment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(CreatePatchDeploymentRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(OsConfigServiceServer).CreatePatchDeployment(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/google.cloud.osconfig.v1.OsConfigService/CreatePatchDeployment", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OsConfigServiceServer).CreatePatchDeployment(ctx, req.(*CreatePatchDeploymentRequest)) } return interceptor(ctx, in, info, handler) } func _OsConfigService_GetPatchDeployment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetPatchDeploymentRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(OsConfigServiceServer).GetPatchDeployment(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/google.cloud.osconfig.v1.OsConfigService/GetPatchDeployment", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OsConfigServiceServer).GetPatchDeployment(ctx, req.(*GetPatchDeploymentRequest)) } return interceptor(ctx, in, info, handler) } func _OsConfigService_ListPatchDeployments_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListPatchDeploymentsRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(OsConfigServiceServer).ListPatchDeployments(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/google.cloud.osconfig.v1.OsConfigService/ListPatchDeployments", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OsConfigServiceServer).ListPatchDeployments(ctx, req.(*ListPatchDeploymentsRequest)) } return interceptor(ctx, in, info, handler) } func _OsConfigService_DeletePatchDeployment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(DeletePatchDeploymentRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(OsConfigServiceServer).DeletePatchDeployment(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/google.cloud.osconfig.v1.OsConfigService/DeletePatchDeployment", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OsConfigServiceServer).DeletePatchDeployment(ctx, req.(*DeletePatchDeploymentRequest)) } return interceptor(ctx, in, info, handler) } var _OsConfigService_serviceDesc = grpc.ServiceDesc{ ServiceName: "google.cloud.osconfig.v1.OsConfigService", HandlerType: (*OsConfigServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "ExecutePatchJob", Handler: _OsConfigService_ExecutePatchJob_Handler, }, { MethodName: "GetPatchJob", Handler: _OsConfigService_GetPatchJob_Handler, }, { MethodName: "CancelPatchJob", Handler: _OsConfigService_CancelPatchJob_Handler, }, { MethodName: "ListPatchJobs", Handler: _OsConfigService_ListPatchJobs_Handler, }, { MethodName: "ListPatchJobInstanceDetails", Handler: _OsConfigService_ListPatchJobInstanceDetails_Handler, }, { MethodName: "CreatePatchDeployment", Handler: _OsConfigService_CreatePatchDeployment_Handler, }, { MethodName: "GetPatchDeployment", Handler: _OsConfigService_GetPatchDeployment_Handler, }, { MethodName: "ListPatchDeployments", Handler: _OsConfigService_ListPatchDeployments_Handler, }, { MethodName: "DeletePatchDeployment", Handler: _OsConfigService_DeletePatchDeployment_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "google/cloud/osconfig/v1/osconfig_service.proto", } osconfig_zonal_service.pb.go000066400000000000000000001643251477773331400377150ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/internal/google.golang.org/genproto/googleapis/cloud/osconfig/v1// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.25.0 // protoc v3.15.3 // source: google/cloud/osconfig/v1/osconfig_zonal_service.proto package osconfig import ( context "context" reflect "reflect" longrunning "cloud.google.com/go/longrunning/autogen/longrunningpb" proto "github.com/golang/protobuf/proto" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" ) const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) // Verify that runtime/protoimpl is sufficiently up-to-date. _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) // This is a compile-time assertion that a sufficiently up-to-date version // of the legacy proto package is being used. const _ = proto.ProtoPackageIsVersion4 var File_google_cloud_osconfig_v1_osconfig_zonal_service_proto protoreflect.FileDescriptor var file_google_cloud_osconfig_v1_osconfig_zonal_service_proto_rawDesc = []byte{ 0x0a, 0x35, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x7a, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x18, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x28, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x3b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x34, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x23, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x6c, 0x6f, 0x6e, 0x67, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x2f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0xac, 0x17, 0x0a, 0x14, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5a, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xbe, 0x02, 0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x39, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x6e, 0x67, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xc7, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4f, 0x22, 0x37, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x6f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x3a, 0x14, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0xda, 0x41, 0x33, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2c, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2c, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0xca, 0x41, 0x39, 0x0a, 0x12, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x23, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0xc0, 0x02, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x39, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x6e, 0x67, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xc9, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x64, 0x32, 0x4c, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x2f, 0x6f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x14, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0xda, 0x41, 0x20, 0x6f, 0x73, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0xca, 0x41, 0x39, 0x0a, 0x12, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x23, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0xc5, 0x01, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x36, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x46, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x39, 0x12, 0x37, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x2f, 0x6f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0xd8, 0x01, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x38, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x48, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x39, 0x12, 0x37, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x6f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0xda, 0x41, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0xfc, 0x01, 0x0a, 0x1f, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x40, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x41, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x54, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x47, 0x12, 0x45, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x2f, 0x6f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0xfc, 0x01, 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x39, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x6e, 0x67, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x85, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x39, 0x2a, 0x37, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x2f, 0x6f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0xca, 0x41, 0x3c, 0x0a, 0x15, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x23, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0xea, 0x01, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x3c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x59, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4c, 0x12, 0x4a, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x6f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x7d, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x80, 0x02, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x3e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4f, 0x12, 0x4d, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x6f, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0xda, 0x41, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0xaa, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x46, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x39, 0x12, 0x37, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x7d, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0xc4, 0x01, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x30, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3d, 0x12, 0x3b, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0xda, 0x41, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0xd2, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x37, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x50, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x43, 0x12, 0x41, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x76, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x7d, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0xe8, 0x01, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x39, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x55, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x46, 0x12, 0x44, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x2a, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x76, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0xda, 0x41, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x1a, 0x4b, 0xca, 0x41, 0x17, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0xd2, 0x41, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2d, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x42, 0xd1, 0x01, 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x42, 0x19, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5a, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x40, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x3b, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0xaa, 0x02, 0x18, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x18, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5c, 0x56, 0x31, 0xea, 0x02, 0x1b, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var file_google_cloud_osconfig_v1_osconfig_zonal_service_proto_goTypes = []interface{}{ (*CreateOSPolicyAssignmentRequest)(nil), // 0: google.cloud.osconfig.v1.CreateOSPolicyAssignmentRequest (*UpdateOSPolicyAssignmentRequest)(nil), // 1: google.cloud.osconfig.v1.UpdateOSPolicyAssignmentRequest (*GetOSPolicyAssignmentRequest)(nil), // 2: google.cloud.osconfig.v1.GetOSPolicyAssignmentRequest (*ListOSPolicyAssignmentsRequest)(nil), // 3: google.cloud.osconfig.v1.ListOSPolicyAssignmentsRequest (*ListOSPolicyAssignmentRevisionsRequest)(nil), // 4: google.cloud.osconfig.v1.ListOSPolicyAssignmentRevisionsRequest (*DeleteOSPolicyAssignmentRequest)(nil), // 5: google.cloud.osconfig.v1.DeleteOSPolicyAssignmentRequest (*GetOSPolicyAssignmentReportRequest)(nil), // 6: google.cloud.osconfig.v1.GetOSPolicyAssignmentReportRequest (*ListOSPolicyAssignmentReportsRequest)(nil), // 7: google.cloud.osconfig.v1.ListOSPolicyAssignmentReportsRequest (*GetInventoryRequest)(nil), // 8: google.cloud.osconfig.v1.GetInventoryRequest (*ListInventoriesRequest)(nil), // 9: google.cloud.osconfig.v1.ListInventoriesRequest (*GetVulnerabilityReportRequest)(nil), // 10: google.cloud.osconfig.v1.GetVulnerabilityReportRequest (*ListVulnerabilityReportsRequest)(nil), // 11: google.cloud.osconfig.v1.ListVulnerabilityReportsRequest (*longrunning.Operation)(nil), // 12: google.longrunning.Operation (*OSPolicyAssignment)(nil), // 13: google.cloud.osconfig.v1.OSPolicyAssignment (*ListOSPolicyAssignmentsResponse)(nil), // 14: google.cloud.osconfig.v1.ListOSPolicyAssignmentsResponse (*ListOSPolicyAssignmentRevisionsResponse)(nil), // 15: google.cloud.osconfig.v1.ListOSPolicyAssignmentRevisionsResponse (*OSPolicyAssignmentReport)(nil), // 16: google.cloud.osconfig.v1.OSPolicyAssignmentReport (*ListOSPolicyAssignmentReportsResponse)(nil), // 17: google.cloud.osconfig.v1.ListOSPolicyAssignmentReportsResponse (*Inventory)(nil), // 18: google.cloud.osconfig.v1.Inventory (*ListInventoriesResponse)(nil), // 19: google.cloud.osconfig.v1.ListInventoriesResponse (*VulnerabilityReport)(nil), // 20: google.cloud.osconfig.v1.VulnerabilityReport (*ListVulnerabilityReportsResponse)(nil), // 21: google.cloud.osconfig.v1.ListVulnerabilityReportsResponse } var file_google_cloud_osconfig_v1_osconfig_zonal_service_proto_depIdxs = []int32{ 0, // 0: google.cloud.osconfig.v1.OsConfigZonalService.CreateOSPolicyAssignment:input_type -> google.cloud.osconfig.v1.CreateOSPolicyAssignmentRequest 1, // 1: google.cloud.osconfig.v1.OsConfigZonalService.UpdateOSPolicyAssignment:input_type -> google.cloud.osconfig.v1.UpdateOSPolicyAssignmentRequest 2, // 2: google.cloud.osconfig.v1.OsConfigZonalService.GetOSPolicyAssignment:input_type -> google.cloud.osconfig.v1.GetOSPolicyAssignmentRequest 3, // 3: google.cloud.osconfig.v1.OsConfigZonalService.ListOSPolicyAssignments:input_type -> google.cloud.osconfig.v1.ListOSPolicyAssignmentsRequest 4, // 4: google.cloud.osconfig.v1.OsConfigZonalService.ListOSPolicyAssignmentRevisions:input_type -> google.cloud.osconfig.v1.ListOSPolicyAssignmentRevisionsRequest 5, // 5: google.cloud.osconfig.v1.OsConfigZonalService.DeleteOSPolicyAssignment:input_type -> google.cloud.osconfig.v1.DeleteOSPolicyAssignmentRequest 6, // 6: google.cloud.osconfig.v1.OsConfigZonalService.GetOSPolicyAssignmentReport:input_type -> google.cloud.osconfig.v1.GetOSPolicyAssignmentReportRequest 7, // 7: google.cloud.osconfig.v1.OsConfigZonalService.ListOSPolicyAssignmentReports:input_type -> google.cloud.osconfig.v1.ListOSPolicyAssignmentReportsRequest 8, // 8: google.cloud.osconfig.v1.OsConfigZonalService.GetInventory:input_type -> google.cloud.osconfig.v1.GetInventoryRequest 9, // 9: google.cloud.osconfig.v1.OsConfigZonalService.ListInventories:input_type -> google.cloud.osconfig.v1.ListInventoriesRequest 10, // 10: google.cloud.osconfig.v1.OsConfigZonalService.GetVulnerabilityReport:input_type -> google.cloud.osconfig.v1.GetVulnerabilityReportRequest 11, // 11: google.cloud.osconfig.v1.OsConfigZonalService.ListVulnerabilityReports:input_type -> google.cloud.osconfig.v1.ListVulnerabilityReportsRequest 12, // 12: google.cloud.osconfig.v1.OsConfigZonalService.CreateOSPolicyAssignment:output_type -> google.longrunning.Operation 12, // 13: google.cloud.osconfig.v1.OsConfigZonalService.UpdateOSPolicyAssignment:output_type -> google.longrunning.Operation 13, // 14: google.cloud.osconfig.v1.OsConfigZonalService.GetOSPolicyAssignment:output_type -> google.cloud.osconfig.v1.OSPolicyAssignment 14, // 15: google.cloud.osconfig.v1.OsConfigZonalService.ListOSPolicyAssignments:output_type -> google.cloud.osconfig.v1.ListOSPolicyAssignmentsResponse 15, // 16: google.cloud.osconfig.v1.OsConfigZonalService.ListOSPolicyAssignmentRevisions:output_type -> google.cloud.osconfig.v1.ListOSPolicyAssignmentRevisionsResponse 12, // 17: google.cloud.osconfig.v1.OsConfigZonalService.DeleteOSPolicyAssignment:output_type -> google.longrunning.Operation 16, // 18: google.cloud.osconfig.v1.OsConfigZonalService.GetOSPolicyAssignmentReport:output_type -> google.cloud.osconfig.v1.OSPolicyAssignmentReport 17, // 19: google.cloud.osconfig.v1.OsConfigZonalService.ListOSPolicyAssignmentReports:output_type -> google.cloud.osconfig.v1.ListOSPolicyAssignmentReportsResponse 18, // 20: google.cloud.osconfig.v1.OsConfigZonalService.GetInventory:output_type -> google.cloud.osconfig.v1.Inventory 19, // 21: google.cloud.osconfig.v1.OsConfigZonalService.ListInventories:output_type -> google.cloud.osconfig.v1.ListInventoriesResponse 20, // 22: google.cloud.osconfig.v1.OsConfigZonalService.GetVulnerabilityReport:output_type -> google.cloud.osconfig.v1.VulnerabilityReport 21, // 23: google.cloud.osconfig.v1.OsConfigZonalService.ListVulnerabilityReports:output_type -> google.cloud.osconfig.v1.ListVulnerabilityReportsResponse 12, // [12:24] is the sub-list for method output_type 0, // [0:12] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name } func init() { file_google_cloud_osconfig_v1_osconfig_zonal_service_proto_init() } func file_google_cloud_osconfig_v1_osconfig_zonal_service_proto_init() { if File_google_cloud_osconfig_v1_osconfig_zonal_service_proto != nil { return } file_google_cloud_osconfig_v1_inventory_proto_init() file_google_cloud_osconfig_v1_os_policy_assignment_reports_proto_init() file_google_cloud_osconfig_v1_os_policy_assignments_proto_init() file_google_cloud_osconfig_v1_vulnerability_proto_init() type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_google_cloud_osconfig_v1_osconfig_zonal_service_proto_rawDesc, NumEnums: 0, NumMessages: 0, NumExtensions: 0, NumServices: 1, }, GoTypes: file_google_cloud_osconfig_v1_osconfig_zonal_service_proto_goTypes, DependencyIndexes: file_google_cloud_osconfig_v1_osconfig_zonal_service_proto_depIdxs, }.Build() File_google_cloud_osconfig_v1_osconfig_zonal_service_proto = out.File file_google_cloud_osconfig_v1_osconfig_zonal_service_proto_rawDesc = nil file_google_cloud_osconfig_v1_osconfig_zonal_service_proto_goTypes = nil file_google_cloud_osconfig_v1_osconfig_zonal_service_proto_depIdxs = nil } // Reference imports to suppress errors if they are not otherwise used. var _ context.Context var _ grpc.ClientConnInterface // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. const _ = grpc.SupportPackageIsVersion6 // OsConfigZonalServiceClient is the client API for OsConfigZonalService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type OsConfigZonalServiceClient interface { // Create an OS policy assignment. // // This method also creates the first revision of the OS policy assignment. // // This method returns a long running operation (LRO) that contains the // rollout details. The rollout can be cancelled by cancelling the LRO. // // For more information, see [Method: // projects.locations.osPolicyAssignments.operations.cancel](https://cloud.google.com/compute/docs/osconfig/rest/v1/projects.locations.osPolicyAssignments.operations/cancel). CreateOSPolicyAssignment(ctx context.Context, in *CreateOSPolicyAssignmentRequest, opts ...grpc.CallOption) (*longrunning.Operation, error) // Update an existing OS policy assignment. // // This method creates a new revision of the OS policy assignment. // // This method returns a long running operation (LRO) that contains the // rollout details. The rollout can be cancelled by cancelling the LRO. // // For more information, see [Method: // projects.locations.osPolicyAssignments.operations.cancel](https://cloud.google.com/compute/docs/osconfig/rest/v1/projects.locations.osPolicyAssignments.operations/cancel). UpdateOSPolicyAssignment(ctx context.Context, in *UpdateOSPolicyAssignmentRequest, opts ...grpc.CallOption) (*longrunning.Operation, error) // Retrieve an existing OS policy assignment. // // This method always returns the latest revision. In order to retrieve a // previous revision of the assignment, also provide the revision ID in the // `name` parameter. GetOSPolicyAssignment(ctx context.Context, in *GetOSPolicyAssignmentRequest, opts ...grpc.CallOption) (*OSPolicyAssignment, error) // List the OS policy assignments under the parent resource. // // For each OS policy assignment, the latest revision is returned. ListOSPolicyAssignments(ctx context.Context, in *ListOSPolicyAssignmentsRequest, opts ...grpc.CallOption) (*ListOSPolicyAssignmentsResponse, error) // List the OS policy assignment revisions for a given OS policy assignment. ListOSPolicyAssignmentRevisions(ctx context.Context, in *ListOSPolicyAssignmentRevisionsRequest, opts ...grpc.CallOption) (*ListOSPolicyAssignmentRevisionsResponse, error) // Delete the OS policy assignment. // // This method creates a new revision of the OS policy assignment. // // This method returns a long running operation (LRO) that contains the // rollout details. The rollout can be cancelled by cancelling the LRO. // // If the LRO completes and is not cancelled, all revisions associated with // the OS policy assignment are deleted. // // For more information, see [Method: // projects.locations.osPolicyAssignments.operations.cancel](https://cloud.google.com/compute/docs/osconfig/rest/v1/projects.locations.osPolicyAssignments.operations/cancel). DeleteOSPolicyAssignment(ctx context.Context, in *DeleteOSPolicyAssignmentRequest, opts ...grpc.CallOption) (*longrunning.Operation, error) // Get the OS policy asssignment report for the specified Compute Engine VM // instance. GetOSPolicyAssignmentReport(ctx context.Context, in *GetOSPolicyAssignmentReportRequest, opts ...grpc.CallOption) (*OSPolicyAssignmentReport, error) // List OS policy asssignment reports for all Compute Engine VM instances in // the specified zone. ListOSPolicyAssignmentReports(ctx context.Context, in *ListOSPolicyAssignmentReportsRequest, opts ...grpc.CallOption) (*ListOSPolicyAssignmentReportsResponse, error) // Get inventory data for the specified VM instance. If the VM has no // associated inventory, the message `NOT_FOUND` is returned. GetInventory(ctx context.Context, in *GetInventoryRequest, opts ...grpc.CallOption) (*Inventory, error) // List inventory data for all VM instances in the specified zone. ListInventories(ctx context.Context, in *ListInventoriesRequest, opts ...grpc.CallOption) (*ListInventoriesResponse, error) // Gets the vulnerability report for the specified VM instance. Only VMs with // inventory data have vulnerability reports associated with them. GetVulnerabilityReport(ctx context.Context, in *GetVulnerabilityReportRequest, opts ...grpc.CallOption) (*VulnerabilityReport, error) // List vulnerability reports for all VM instances in the specified zone. ListVulnerabilityReports(ctx context.Context, in *ListVulnerabilityReportsRequest, opts ...grpc.CallOption) (*ListVulnerabilityReportsResponse, error) } type osConfigZonalServiceClient struct { cc grpc.ClientConnInterface } func NewOsConfigZonalServiceClient(cc grpc.ClientConnInterface) OsConfigZonalServiceClient { return &osConfigZonalServiceClient{cc} } func (c *osConfigZonalServiceClient) CreateOSPolicyAssignment(ctx context.Context, in *CreateOSPolicyAssignmentRequest, opts ...grpc.CallOption) (*longrunning.Operation, error) { out := new(longrunning.Operation) err := c.cc.Invoke(ctx, "/google.cloud.osconfig.v1.OsConfigZonalService/CreateOSPolicyAssignment", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *osConfigZonalServiceClient) UpdateOSPolicyAssignment(ctx context.Context, in *UpdateOSPolicyAssignmentRequest, opts ...grpc.CallOption) (*longrunning.Operation, error) { out := new(longrunning.Operation) err := c.cc.Invoke(ctx, "/google.cloud.osconfig.v1.OsConfigZonalService/UpdateOSPolicyAssignment", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *osConfigZonalServiceClient) GetOSPolicyAssignment(ctx context.Context, in *GetOSPolicyAssignmentRequest, opts ...grpc.CallOption) (*OSPolicyAssignment, error) { out := new(OSPolicyAssignment) err := c.cc.Invoke(ctx, "/google.cloud.osconfig.v1.OsConfigZonalService/GetOSPolicyAssignment", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *osConfigZonalServiceClient) ListOSPolicyAssignments(ctx context.Context, in *ListOSPolicyAssignmentsRequest, opts ...grpc.CallOption) (*ListOSPolicyAssignmentsResponse, error) { out := new(ListOSPolicyAssignmentsResponse) err := c.cc.Invoke(ctx, "/google.cloud.osconfig.v1.OsConfigZonalService/ListOSPolicyAssignments", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *osConfigZonalServiceClient) ListOSPolicyAssignmentRevisions(ctx context.Context, in *ListOSPolicyAssignmentRevisionsRequest, opts ...grpc.CallOption) (*ListOSPolicyAssignmentRevisionsResponse, error) { out := new(ListOSPolicyAssignmentRevisionsResponse) err := c.cc.Invoke(ctx, "/google.cloud.osconfig.v1.OsConfigZonalService/ListOSPolicyAssignmentRevisions", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *osConfigZonalServiceClient) DeleteOSPolicyAssignment(ctx context.Context, in *DeleteOSPolicyAssignmentRequest, opts ...grpc.CallOption) (*longrunning.Operation, error) { out := new(longrunning.Operation) err := c.cc.Invoke(ctx, "/google.cloud.osconfig.v1.OsConfigZonalService/DeleteOSPolicyAssignment", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *osConfigZonalServiceClient) GetOSPolicyAssignmentReport(ctx context.Context, in *GetOSPolicyAssignmentReportRequest, opts ...grpc.CallOption) (*OSPolicyAssignmentReport, error) { out := new(OSPolicyAssignmentReport) err := c.cc.Invoke(ctx, "/google.cloud.osconfig.v1.OsConfigZonalService/GetOSPolicyAssignmentReport", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *osConfigZonalServiceClient) ListOSPolicyAssignmentReports(ctx context.Context, in *ListOSPolicyAssignmentReportsRequest, opts ...grpc.CallOption) (*ListOSPolicyAssignmentReportsResponse, error) { out := new(ListOSPolicyAssignmentReportsResponse) err := c.cc.Invoke(ctx, "/google.cloud.osconfig.v1.OsConfigZonalService/ListOSPolicyAssignmentReports", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *osConfigZonalServiceClient) GetInventory(ctx context.Context, in *GetInventoryRequest, opts ...grpc.CallOption) (*Inventory, error) { out := new(Inventory) err := c.cc.Invoke(ctx, "/google.cloud.osconfig.v1.OsConfigZonalService/GetInventory", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *osConfigZonalServiceClient) ListInventories(ctx context.Context, in *ListInventoriesRequest, opts ...grpc.CallOption) (*ListInventoriesResponse, error) { out := new(ListInventoriesResponse) err := c.cc.Invoke(ctx, "/google.cloud.osconfig.v1.OsConfigZonalService/ListInventories", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *osConfigZonalServiceClient) GetVulnerabilityReport(ctx context.Context, in *GetVulnerabilityReportRequest, opts ...grpc.CallOption) (*VulnerabilityReport, error) { out := new(VulnerabilityReport) err := c.cc.Invoke(ctx, "/google.cloud.osconfig.v1.OsConfigZonalService/GetVulnerabilityReport", in, out, opts...) if err != nil { return nil, err } return out, nil } func (c *osConfigZonalServiceClient) ListVulnerabilityReports(ctx context.Context, in *ListVulnerabilityReportsRequest, opts ...grpc.CallOption) (*ListVulnerabilityReportsResponse, error) { out := new(ListVulnerabilityReportsResponse) err := c.cc.Invoke(ctx, "/google.cloud.osconfig.v1.OsConfigZonalService/ListVulnerabilityReports", in, out, opts...) if err != nil { return nil, err } return out, nil } // OsConfigZonalServiceServer is the server API for OsConfigZonalService service. type OsConfigZonalServiceServer interface { // Create an OS policy assignment. // // This method also creates the first revision of the OS policy assignment. // // This method returns a long running operation (LRO) that contains the // rollout details. The rollout can be cancelled by cancelling the LRO. // // For more information, see [Method: // projects.locations.osPolicyAssignments.operations.cancel](https://cloud.google.com/compute/docs/osconfig/rest/v1/projects.locations.osPolicyAssignments.operations/cancel). CreateOSPolicyAssignment(context.Context, *CreateOSPolicyAssignmentRequest) (*longrunning.Operation, error) // Update an existing OS policy assignment. // // This method creates a new revision of the OS policy assignment. // // This method returns a long running operation (LRO) that contains the // rollout details. The rollout can be cancelled by cancelling the LRO. // // For more information, see [Method: // projects.locations.osPolicyAssignments.operations.cancel](https://cloud.google.com/compute/docs/osconfig/rest/v1/projects.locations.osPolicyAssignments.operations/cancel). UpdateOSPolicyAssignment(context.Context, *UpdateOSPolicyAssignmentRequest) (*longrunning.Operation, error) // Retrieve an existing OS policy assignment. // // This method always returns the latest revision. In order to retrieve a // previous revision of the assignment, also provide the revision ID in the // `name` parameter. GetOSPolicyAssignment(context.Context, *GetOSPolicyAssignmentRequest) (*OSPolicyAssignment, error) // List the OS policy assignments under the parent resource. // // For each OS policy assignment, the latest revision is returned. ListOSPolicyAssignments(context.Context, *ListOSPolicyAssignmentsRequest) (*ListOSPolicyAssignmentsResponse, error) // List the OS policy assignment revisions for a given OS policy assignment. ListOSPolicyAssignmentRevisions(context.Context, *ListOSPolicyAssignmentRevisionsRequest) (*ListOSPolicyAssignmentRevisionsResponse, error) // Delete the OS policy assignment. // // This method creates a new revision of the OS policy assignment. // // This method returns a long running operation (LRO) that contains the // rollout details. The rollout can be cancelled by cancelling the LRO. // // If the LRO completes and is not cancelled, all revisions associated with // the OS policy assignment are deleted. // // For more information, see [Method: // projects.locations.osPolicyAssignments.operations.cancel](https://cloud.google.com/compute/docs/osconfig/rest/v1/projects.locations.osPolicyAssignments.operations/cancel). DeleteOSPolicyAssignment(context.Context, *DeleteOSPolicyAssignmentRequest) (*longrunning.Operation, error) // Get the OS policy asssignment report for the specified Compute Engine VM // instance. GetOSPolicyAssignmentReport(context.Context, *GetOSPolicyAssignmentReportRequest) (*OSPolicyAssignmentReport, error) // List OS policy asssignment reports for all Compute Engine VM instances in // the specified zone. ListOSPolicyAssignmentReports(context.Context, *ListOSPolicyAssignmentReportsRequest) (*ListOSPolicyAssignmentReportsResponse, error) // Get inventory data for the specified VM instance. If the VM has no // associated inventory, the message `NOT_FOUND` is returned. GetInventory(context.Context, *GetInventoryRequest) (*Inventory, error) // List inventory data for all VM instances in the specified zone. ListInventories(context.Context, *ListInventoriesRequest) (*ListInventoriesResponse, error) // Gets the vulnerability report for the specified VM instance. Only VMs with // inventory data have vulnerability reports associated with them. GetVulnerabilityReport(context.Context, *GetVulnerabilityReportRequest) (*VulnerabilityReport, error) // List vulnerability reports for all VM instances in the specified zone. ListVulnerabilityReports(context.Context, *ListVulnerabilityReportsRequest) (*ListVulnerabilityReportsResponse, error) } // UnimplementedOsConfigZonalServiceServer can be embedded to have forward compatible implementations. type UnimplementedOsConfigZonalServiceServer struct { } func (*UnimplementedOsConfigZonalServiceServer) CreateOSPolicyAssignment(context.Context, *CreateOSPolicyAssignmentRequest) (*longrunning.Operation, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateOSPolicyAssignment not implemented") } func (*UnimplementedOsConfigZonalServiceServer) UpdateOSPolicyAssignment(context.Context, *UpdateOSPolicyAssignmentRequest) (*longrunning.Operation, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateOSPolicyAssignment not implemented") } func (*UnimplementedOsConfigZonalServiceServer) GetOSPolicyAssignment(context.Context, *GetOSPolicyAssignmentRequest) (*OSPolicyAssignment, error) { return nil, status.Errorf(codes.Unimplemented, "method GetOSPolicyAssignment not implemented") } func (*UnimplementedOsConfigZonalServiceServer) ListOSPolicyAssignments(context.Context, *ListOSPolicyAssignmentsRequest) (*ListOSPolicyAssignmentsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListOSPolicyAssignments not implemented") } func (*UnimplementedOsConfigZonalServiceServer) ListOSPolicyAssignmentRevisions(context.Context, *ListOSPolicyAssignmentRevisionsRequest) (*ListOSPolicyAssignmentRevisionsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListOSPolicyAssignmentRevisions not implemented") } func (*UnimplementedOsConfigZonalServiceServer) DeleteOSPolicyAssignment(context.Context, *DeleteOSPolicyAssignmentRequest) (*longrunning.Operation, error) { return nil, status.Errorf(codes.Unimplemented, "method DeleteOSPolicyAssignment not implemented") } func (*UnimplementedOsConfigZonalServiceServer) GetOSPolicyAssignmentReport(context.Context, *GetOSPolicyAssignmentReportRequest) (*OSPolicyAssignmentReport, error) { return nil, status.Errorf(codes.Unimplemented, "method GetOSPolicyAssignmentReport not implemented") } func (*UnimplementedOsConfigZonalServiceServer) ListOSPolicyAssignmentReports(context.Context, *ListOSPolicyAssignmentReportsRequest) (*ListOSPolicyAssignmentReportsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListOSPolicyAssignmentReports not implemented") } func (*UnimplementedOsConfigZonalServiceServer) GetInventory(context.Context, *GetInventoryRequest) (*Inventory, error) { return nil, status.Errorf(codes.Unimplemented, "method GetInventory not implemented") } func (*UnimplementedOsConfigZonalServiceServer) ListInventories(context.Context, *ListInventoriesRequest) (*ListInventoriesResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListInventories not implemented") } func (*UnimplementedOsConfigZonalServiceServer) GetVulnerabilityReport(context.Context, *GetVulnerabilityReportRequest) (*VulnerabilityReport, error) { return nil, status.Errorf(codes.Unimplemented, "method GetVulnerabilityReport not implemented") } func (*UnimplementedOsConfigZonalServiceServer) ListVulnerabilityReports(context.Context, *ListVulnerabilityReportsRequest) (*ListVulnerabilityReportsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListVulnerabilityReports not implemented") } func RegisterOsConfigZonalServiceServer(s *grpc.Server, srv OsConfigZonalServiceServer) { s.RegisterService(&_OsConfigZonalService_serviceDesc, srv) } func _OsConfigZonalService_CreateOSPolicyAssignment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(CreateOSPolicyAssignmentRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(OsConfigZonalServiceServer).CreateOSPolicyAssignment(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/google.cloud.osconfig.v1.OsConfigZonalService/CreateOSPolicyAssignment", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OsConfigZonalServiceServer).CreateOSPolicyAssignment(ctx, req.(*CreateOSPolicyAssignmentRequest)) } return interceptor(ctx, in, info, handler) } func _OsConfigZonalService_UpdateOSPolicyAssignment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(UpdateOSPolicyAssignmentRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(OsConfigZonalServiceServer).UpdateOSPolicyAssignment(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/google.cloud.osconfig.v1.OsConfigZonalService/UpdateOSPolicyAssignment", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OsConfigZonalServiceServer).UpdateOSPolicyAssignment(ctx, req.(*UpdateOSPolicyAssignmentRequest)) } return interceptor(ctx, in, info, handler) } func _OsConfigZonalService_GetOSPolicyAssignment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetOSPolicyAssignmentRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(OsConfigZonalServiceServer).GetOSPolicyAssignment(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/google.cloud.osconfig.v1.OsConfigZonalService/GetOSPolicyAssignment", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OsConfigZonalServiceServer).GetOSPolicyAssignment(ctx, req.(*GetOSPolicyAssignmentRequest)) } return interceptor(ctx, in, info, handler) } func _OsConfigZonalService_ListOSPolicyAssignments_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListOSPolicyAssignmentsRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(OsConfigZonalServiceServer).ListOSPolicyAssignments(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/google.cloud.osconfig.v1.OsConfigZonalService/ListOSPolicyAssignments", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OsConfigZonalServiceServer).ListOSPolicyAssignments(ctx, req.(*ListOSPolicyAssignmentsRequest)) } return interceptor(ctx, in, info, handler) } func _OsConfigZonalService_ListOSPolicyAssignmentRevisions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListOSPolicyAssignmentRevisionsRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(OsConfigZonalServiceServer).ListOSPolicyAssignmentRevisions(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/google.cloud.osconfig.v1.OsConfigZonalService/ListOSPolicyAssignmentRevisions", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OsConfigZonalServiceServer).ListOSPolicyAssignmentRevisions(ctx, req.(*ListOSPolicyAssignmentRevisionsRequest)) } return interceptor(ctx, in, info, handler) } func _OsConfigZonalService_DeleteOSPolicyAssignment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(DeleteOSPolicyAssignmentRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(OsConfigZonalServiceServer).DeleteOSPolicyAssignment(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/google.cloud.osconfig.v1.OsConfigZonalService/DeleteOSPolicyAssignment", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OsConfigZonalServiceServer).DeleteOSPolicyAssignment(ctx, req.(*DeleteOSPolicyAssignmentRequest)) } return interceptor(ctx, in, info, handler) } func _OsConfigZonalService_GetOSPolicyAssignmentReport_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetOSPolicyAssignmentReportRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(OsConfigZonalServiceServer).GetOSPolicyAssignmentReport(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/google.cloud.osconfig.v1.OsConfigZonalService/GetOSPolicyAssignmentReport", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OsConfigZonalServiceServer).GetOSPolicyAssignmentReport(ctx, req.(*GetOSPolicyAssignmentReportRequest)) } return interceptor(ctx, in, info, handler) } func _OsConfigZonalService_ListOSPolicyAssignmentReports_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListOSPolicyAssignmentReportsRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(OsConfigZonalServiceServer).ListOSPolicyAssignmentReports(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/google.cloud.osconfig.v1.OsConfigZonalService/ListOSPolicyAssignmentReports", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OsConfigZonalServiceServer).ListOSPolicyAssignmentReports(ctx, req.(*ListOSPolicyAssignmentReportsRequest)) } return interceptor(ctx, in, info, handler) } func _OsConfigZonalService_GetInventory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetInventoryRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(OsConfigZonalServiceServer).GetInventory(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/google.cloud.osconfig.v1.OsConfigZonalService/GetInventory", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OsConfigZonalServiceServer).GetInventory(ctx, req.(*GetInventoryRequest)) } return interceptor(ctx, in, info, handler) } func _OsConfigZonalService_ListInventories_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListInventoriesRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(OsConfigZonalServiceServer).ListInventories(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/google.cloud.osconfig.v1.OsConfigZonalService/ListInventories", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OsConfigZonalServiceServer).ListInventories(ctx, req.(*ListInventoriesRequest)) } return interceptor(ctx, in, info, handler) } func _OsConfigZonalService_GetVulnerabilityReport_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetVulnerabilityReportRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(OsConfigZonalServiceServer).GetVulnerabilityReport(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/google.cloud.osconfig.v1.OsConfigZonalService/GetVulnerabilityReport", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OsConfigZonalServiceServer).GetVulnerabilityReport(ctx, req.(*GetVulnerabilityReportRequest)) } return interceptor(ctx, in, info, handler) } func _OsConfigZonalService_ListVulnerabilityReports_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListVulnerabilityReportsRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(OsConfigZonalServiceServer).ListVulnerabilityReports(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, FullMethod: "/google.cloud.osconfig.v1.OsConfigZonalService/ListVulnerabilityReports", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OsConfigZonalServiceServer).ListVulnerabilityReports(ctx, req.(*ListVulnerabilityReportsRequest)) } return interceptor(ctx, in, info, handler) } var _OsConfigZonalService_serviceDesc = grpc.ServiceDesc{ ServiceName: "google.cloud.osconfig.v1.OsConfigZonalService", HandlerType: (*OsConfigZonalServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "CreateOSPolicyAssignment", Handler: _OsConfigZonalService_CreateOSPolicyAssignment_Handler, }, { MethodName: "UpdateOSPolicyAssignment", Handler: _OsConfigZonalService_UpdateOSPolicyAssignment_Handler, }, { MethodName: "GetOSPolicyAssignment", Handler: _OsConfigZonalService_GetOSPolicyAssignment_Handler, }, { MethodName: "ListOSPolicyAssignments", Handler: _OsConfigZonalService_ListOSPolicyAssignments_Handler, }, { MethodName: "ListOSPolicyAssignmentRevisions", Handler: _OsConfigZonalService_ListOSPolicyAssignmentRevisions_Handler, }, { MethodName: "DeleteOSPolicyAssignment", Handler: _OsConfigZonalService_DeleteOSPolicyAssignment_Handler, }, { MethodName: "GetOSPolicyAssignmentReport", Handler: _OsConfigZonalService_GetOSPolicyAssignmentReport_Handler, }, { MethodName: "ListOSPolicyAssignmentReports", Handler: _OsConfigZonalService_ListOSPolicyAssignmentReports_Handler, }, { MethodName: "GetInventory", Handler: _OsConfigZonalService_GetInventory_Handler, }, { MethodName: "ListInventories", Handler: _OsConfigZonalService_ListInventories_Handler, }, { MethodName: "GetVulnerabilityReport", Handler: _OsConfigZonalService_GetVulnerabilityReport_Handler, }, { MethodName: "ListVulnerabilityReports", Handler: _OsConfigZonalService_ListVulnerabilityReports_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "google/cloud/osconfig/v1/osconfig_zonal_service.proto", } patch_deployments.pb.go000066400000000000000000001735241477773331400367060ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/internal/google.golang.org/genproto/googleapis/cloud/osconfig/v1// Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.25.0 // protoc v3.15.3 // source: google/cloud/osconfig/v1/patch_deployments.proto package osconfig import ( proto "github.com/golang/protobuf/proto" _ "google.golang.org/genproto/googleapis/api/annotations" datetime "google.golang.org/genproto/googleapis/type/datetime" dayofweek "google.golang.org/genproto/googleapis/type/dayofweek" timeofday "google.golang.org/genproto/googleapis/type/timeofday" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" durationpb "google.golang.org/protobuf/types/known/durationpb" timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" ) const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) // Verify that runtime/protoimpl is sufficiently up-to-date. _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) // This is a compile-time assertion that a sufficiently up-to-date version // of the legacy proto package is being used. const _ = proto.ProtoPackageIsVersion4 // Specifies the frequency of the recurring patch deployments. type RecurringSchedule_Frequency int32 const ( // Invalid. A frequency must be specified. RecurringSchedule_FREQUENCY_UNSPECIFIED RecurringSchedule_Frequency = 0 // Indicates that the frequency should be expressed in terms of // weeks. RecurringSchedule_WEEKLY RecurringSchedule_Frequency = 1 // Indicates that the frequency should be expressed in terms of // months. RecurringSchedule_MONTHLY RecurringSchedule_Frequency = 2 ) // Enum value maps for RecurringSchedule_Frequency. var ( RecurringSchedule_Frequency_name = map[int32]string{ 0: "FREQUENCY_UNSPECIFIED", 1: "WEEKLY", 2: "MONTHLY", } RecurringSchedule_Frequency_value = map[string]int32{ "FREQUENCY_UNSPECIFIED": 0, "WEEKLY": 1, "MONTHLY": 2, } ) func (x RecurringSchedule_Frequency) Enum() *RecurringSchedule_Frequency { p := new(RecurringSchedule_Frequency) *p = x return p } func (x RecurringSchedule_Frequency) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (RecurringSchedule_Frequency) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_patch_deployments_proto_enumTypes[0].Descriptor() } func (RecurringSchedule_Frequency) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_patch_deployments_proto_enumTypes[0] } func (x RecurringSchedule_Frequency) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use RecurringSchedule_Frequency.Descriptor instead. func (RecurringSchedule_Frequency) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_deployments_proto_rawDescGZIP(), []int{2, 0} } // Patch deployments are configurations that individual patch jobs use to // complete a patch. These configurations include instance filter, package // repository settings, and a schedule. For more information about creating and // managing patch deployments, see [Scheduling patch // jobs](https://cloud.google.com/compute/docs/os-patch-management/schedule-patch-jobs). type PatchDeployment struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Unique name for the patch deployment resource in a project. The patch // deployment name is in the form: // `projects/{project_id}/patchDeployments/{patch_deployment_id}`. // This field is ignored when you create a new patch deployment. Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // Optional. Description of the patch deployment. Length of the description is // limited to 1024 characters. Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // Required. VM instances to patch. InstanceFilter *PatchInstanceFilter `protobuf:"bytes,3,opt,name=instance_filter,json=instanceFilter,proto3" json:"instance_filter,omitempty"` // Optional. Patch configuration that is applied. PatchConfig *PatchConfig `protobuf:"bytes,4,opt,name=patch_config,json=patchConfig,proto3" json:"patch_config,omitempty"` // Optional. Duration of the patch. After the duration ends, the patch times // out. Duration *durationpb.Duration `protobuf:"bytes,5,opt,name=duration,proto3" json:"duration,omitempty"` // Schedule for the patch. // // Types that are assignable to Schedule: // *PatchDeployment_OneTimeSchedule // *PatchDeployment_RecurringSchedule Schedule isPatchDeployment_Schedule `protobuf_oneof:"schedule"` // Output only. Time the patch deployment was created. Timestamp is in // [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) text format. CreateTime *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"` // Output only. Time the patch deployment was last updated. Timestamp is in // [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) text format. UpdateTime *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty"` // Output only. The last time a patch job was started by this deployment. // Timestamp is in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) text // format. LastExecuteTime *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=last_execute_time,json=lastExecuteTime,proto3" json:"last_execute_time,omitempty"` // Optional. Rollout strategy of the patch job. Rollout *PatchRollout `protobuf:"bytes,11,opt,name=rollout,proto3" json:"rollout,omitempty"` } func (x *PatchDeployment) Reset() { *x = PatchDeployment{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *PatchDeployment) String() string { return protoimpl.X.MessageStringOf(x) } func (*PatchDeployment) ProtoMessage() {} func (x *PatchDeployment) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use PatchDeployment.ProtoReflect.Descriptor instead. func (*PatchDeployment) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_deployments_proto_rawDescGZIP(), []int{0} } func (x *PatchDeployment) GetName() string { if x != nil { return x.Name } return "" } func (x *PatchDeployment) GetDescription() string { if x != nil { return x.Description } return "" } func (x *PatchDeployment) GetInstanceFilter() *PatchInstanceFilter { if x != nil { return x.InstanceFilter } return nil } func (x *PatchDeployment) GetPatchConfig() *PatchConfig { if x != nil { return x.PatchConfig } return nil } func (x *PatchDeployment) GetDuration() *durationpb.Duration { if x != nil { return x.Duration } return nil } func (m *PatchDeployment) GetSchedule() isPatchDeployment_Schedule { if m != nil { return m.Schedule } return nil } func (x *PatchDeployment) GetOneTimeSchedule() *OneTimeSchedule { if x, ok := x.GetSchedule().(*PatchDeployment_OneTimeSchedule); ok { return x.OneTimeSchedule } return nil } func (x *PatchDeployment) GetRecurringSchedule() *RecurringSchedule { if x, ok := x.GetSchedule().(*PatchDeployment_RecurringSchedule); ok { return x.RecurringSchedule } return nil } func (x *PatchDeployment) GetCreateTime() *timestamppb.Timestamp { if x != nil { return x.CreateTime } return nil } func (x *PatchDeployment) GetUpdateTime() *timestamppb.Timestamp { if x != nil { return x.UpdateTime } return nil } func (x *PatchDeployment) GetLastExecuteTime() *timestamppb.Timestamp { if x != nil { return x.LastExecuteTime } return nil } func (x *PatchDeployment) GetRollout() *PatchRollout { if x != nil { return x.Rollout } return nil } type isPatchDeployment_Schedule interface { isPatchDeployment_Schedule() } type PatchDeployment_OneTimeSchedule struct { // Required. Schedule a one-time execution. OneTimeSchedule *OneTimeSchedule `protobuf:"bytes,6,opt,name=one_time_schedule,json=oneTimeSchedule,proto3,oneof"` } type PatchDeployment_RecurringSchedule struct { // Required. Schedule recurring executions. RecurringSchedule *RecurringSchedule `protobuf:"bytes,7,opt,name=recurring_schedule,json=recurringSchedule,proto3,oneof"` } func (*PatchDeployment_OneTimeSchedule) isPatchDeployment_Schedule() {} func (*PatchDeployment_RecurringSchedule) isPatchDeployment_Schedule() {} // Sets the time for a one time patch deployment. Timestamp is in // [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) text format. type OneTimeSchedule struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. The desired patch job execution time. ExecuteTime *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=execute_time,json=executeTime,proto3" json:"execute_time,omitempty"` } func (x *OneTimeSchedule) Reset() { *x = OneTimeSchedule{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *OneTimeSchedule) String() string { return protoimpl.X.MessageStringOf(x) } func (*OneTimeSchedule) ProtoMessage() {} func (x *OneTimeSchedule) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use OneTimeSchedule.ProtoReflect.Descriptor instead. func (*OneTimeSchedule) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_deployments_proto_rawDescGZIP(), []int{1} } func (x *OneTimeSchedule) GetExecuteTime() *timestamppb.Timestamp { if x != nil { return x.ExecuteTime } return nil } // Sets the time for recurring patch deployments. type RecurringSchedule struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. Defines the time zone that `time_of_day` is relative to. // The rules for daylight saving time are determined by the chosen time zone. TimeZone *datetime.TimeZone `protobuf:"bytes,1,opt,name=time_zone,json=timeZone,proto3" json:"time_zone,omitempty"` // Optional. The time that the recurring schedule becomes effective. // Defaults to `create_time` of the patch deployment. StartTime *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` // Optional. The end time at which a recurring patch deployment schedule is no // longer active. EndTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"` // Required. Time of the day to run a recurring deployment. TimeOfDay *timeofday.TimeOfDay `protobuf:"bytes,4,opt,name=time_of_day,json=timeOfDay,proto3" json:"time_of_day,omitempty"` // Required. The frequency unit of this recurring schedule. Frequency RecurringSchedule_Frequency `protobuf:"varint,5,opt,name=frequency,proto3,enum=google.cloud.osconfig.v1.RecurringSchedule_Frequency" json:"frequency,omitempty"` // Configurations for this recurring schedule. // Configurations must match frequency. // // Types that are assignable to ScheduleConfig: // *RecurringSchedule_Weekly // *RecurringSchedule_Monthly ScheduleConfig isRecurringSchedule_ScheduleConfig `protobuf_oneof:"schedule_config"` // Output only. The time the last patch job ran successfully. LastExecuteTime *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=last_execute_time,json=lastExecuteTime,proto3" json:"last_execute_time,omitempty"` // Output only. The time the next patch job is scheduled to run. NextExecuteTime *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=next_execute_time,json=nextExecuteTime,proto3" json:"next_execute_time,omitempty"` } func (x *RecurringSchedule) Reset() { *x = RecurringSchedule{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *RecurringSchedule) String() string { return protoimpl.X.MessageStringOf(x) } func (*RecurringSchedule) ProtoMessage() {} func (x *RecurringSchedule) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use RecurringSchedule.ProtoReflect.Descriptor instead. func (*RecurringSchedule) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_deployments_proto_rawDescGZIP(), []int{2} } func (x *RecurringSchedule) GetTimeZone() *datetime.TimeZone { if x != nil { return x.TimeZone } return nil } func (x *RecurringSchedule) GetStartTime() *timestamppb.Timestamp { if x != nil { return x.StartTime } return nil } func (x *RecurringSchedule) GetEndTime() *timestamppb.Timestamp { if x != nil { return x.EndTime } return nil } func (x *RecurringSchedule) GetTimeOfDay() *timeofday.TimeOfDay { if x != nil { return x.TimeOfDay } return nil } func (x *RecurringSchedule) GetFrequency() RecurringSchedule_Frequency { if x != nil { return x.Frequency } return RecurringSchedule_FREQUENCY_UNSPECIFIED } func (m *RecurringSchedule) GetScheduleConfig() isRecurringSchedule_ScheduleConfig { if m != nil { return m.ScheduleConfig } return nil } func (x *RecurringSchedule) GetWeekly() *WeeklySchedule { if x, ok := x.GetScheduleConfig().(*RecurringSchedule_Weekly); ok { return x.Weekly } return nil } func (x *RecurringSchedule) GetMonthly() *MonthlySchedule { if x, ok := x.GetScheduleConfig().(*RecurringSchedule_Monthly); ok { return x.Monthly } return nil } func (x *RecurringSchedule) GetLastExecuteTime() *timestamppb.Timestamp { if x != nil { return x.LastExecuteTime } return nil } func (x *RecurringSchedule) GetNextExecuteTime() *timestamppb.Timestamp { if x != nil { return x.NextExecuteTime } return nil } type isRecurringSchedule_ScheduleConfig interface { isRecurringSchedule_ScheduleConfig() } type RecurringSchedule_Weekly struct { // Required. Schedule with weekly executions. Weekly *WeeklySchedule `protobuf:"bytes,6,opt,name=weekly,proto3,oneof"` } type RecurringSchedule_Monthly struct { // Required. Schedule with monthly executions. Monthly *MonthlySchedule `protobuf:"bytes,7,opt,name=monthly,proto3,oneof"` } func (*RecurringSchedule_Weekly) isRecurringSchedule_ScheduleConfig() {} func (*RecurringSchedule_Monthly) isRecurringSchedule_ScheduleConfig() {} // Represents a weekly schedule. type WeeklySchedule struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. Day of the week. DayOfWeek dayofweek.DayOfWeek `protobuf:"varint,1,opt,name=day_of_week,json=dayOfWeek,proto3,enum=google.type.DayOfWeek" json:"day_of_week,omitempty"` } func (x *WeeklySchedule) Reset() { *x = WeeklySchedule{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *WeeklySchedule) String() string { return protoimpl.X.MessageStringOf(x) } func (*WeeklySchedule) ProtoMessage() {} func (x *WeeklySchedule) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use WeeklySchedule.ProtoReflect.Descriptor instead. func (*WeeklySchedule) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_deployments_proto_rawDescGZIP(), []int{3} } func (x *WeeklySchedule) GetDayOfWeek() dayofweek.DayOfWeek { if x != nil { return x.DayOfWeek } return dayofweek.DayOfWeek_DAY_OF_WEEK_UNSPECIFIED } // Represents a monthly schedule. An example of a valid monthly schedule is // "on the third Tuesday of the month" or "on the 15th of the month". type MonthlySchedule struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // One day in a month. // // Types that are assignable to DayOfMonth: // *MonthlySchedule_WeekDayOfMonth // *MonthlySchedule_MonthDay DayOfMonth isMonthlySchedule_DayOfMonth `protobuf_oneof:"day_of_month"` } func (x *MonthlySchedule) Reset() { *x = MonthlySchedule{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *MonthlySchedule) String() string { return protoimpl.X.MessageStringOf(x) } func (*MonthlySchedule) ProtoMessage() {} func (x *MonthlySchedule) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use MonthlySchedule.ProtoReflect.Descriptor instead. func (*MonthlySchedule) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_deployments_proto_rawDescGZIP(), []int{4} } func (m *MonthlySchedule) GetDayOfMonth() isMonthlySchedule_DayOfMonth { if m != nil { return m.DayOfMonth } return nil } func (x *MonthlySchedule) GetWeekDayOfMonth() *WeekDayOfMonth { if x, ok := x.GetDayOfMonth().(*MonthlySchedule_WeekDayOfMonth); ok { return x.WeekDayOfMonth } return nil } func (x *MonthlySchedule) GetMonthDay() int32 { if x, ok := x.GetDayOfMonth().(*MonthlySchedule_MonthDay); ok { return x.MonthDay } return 0 } type isMonthlySchedule_DayOfMonth interface { isMonthlySchedule_DayOfMonth() } type MonthlySchedule_WeekDayOfMonth struct { // Required. Week day in a month. WeekDayOfMonth *WeekDayOfMonth `protobuf:"bytes,1,opt,name=week_day_of_month,json=weekDayOfMonth,proto3,oneof"` } type MonthlySchedule_MonthDay struct { // Required. One day of the month. 1-31 indicates the 1st to the 31st day. // -1 indicates the last day of the month. Months without the target day // will be skipped. For example, a schedule to run "every month on the 31st" // will not run in February, April, June, etc. MonthDay int32 `protobuf:"varint,2,opt,name=month_day,json=monthDay,proto3,oneof"` } func (*MonthlySchedule_WeekDayOfMonth) isMonthlySchedule_DayOfMonth() {} func (*MonthlySchedule_MonthDay) isMonthlySchedule_DayOfMonth() {} // Represents one week day in a month. An example is "the 4th Sunday". type WeekDayOfMonth struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. Week number in a month. 1-4 indicates the 1st to 4th week of the // month. -1 indicates the last week of the month. WeekOrdinal int32 `protobuf:"varint,1,opt,name=week_ordinal,json=weekOrdinal,proto3" json:"week_ordinal,omitempty"` // Required. A day of the week. DayOfWeek dayofweek.DayOfWeek `protobuf:"varint,2,opt,name=day_of_week,json=dayOfWeek,proto3,enum=google.type.DayOfWeek" json:"day_of_week,omitempty"` } func (x *WeekDayOfMonth) Reset() { *x = WeekDayOfMonth{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *WeekDayOfMonth) String() string { return protoimpl.X.MessageStringOf(x) } func (*WeekDayOfMonth) ProtoMessage() {} func (x *WeekDayOfMonth) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use WeekDayOfMonth.ProtoReflect.Descriptor instead. func (*WeekDayOfMonth) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_deployments_proto_rawDescGZIP(), []int{5} } func (x *WeekDayOfMonth) GetWeekOrdinal() int32 { if x != nil { return x.WeekOrdinal } return 0 } func (x *WeekDayOfMonth) GetDayOfWeek() dayofweek.DayOfWeek { if x != nil { return x.DayOfWeek } return dayofweek.DayOfWeek_DAY_OF_WEEK_UNSPECIFIED } // A request message for creating a patch deployment. type CreatePatchDeploymentRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. The project to apply this patch deployment to in the form // `projects/*`. Parent string `protobuf:"bytes,1,opt,name=parent,proto3" json:"parent,omitempty"` // Required. A name for the patch deployment in the project. When creating a // name the following rules apply: // * Must contain only lowercase letters, numbers, and hyphens. // * Must start with a letter. // * Must be between 1-63 characters. // * Must end with a number or a letter. // * Must be unique within the project. PatchDeploymentId string `protobuf:"bytes,2,opt,name=patch_deployment_id,json=patchDeploymentId,proto3" json:"patch_deployment_id,omitempty"` // Required. The patch deployment to create. PatchDeployment *PatchDeployment `protobuf:"bytes,3,opt,name=patch_deployment,json=patchDeployment,proto3" json:"patch_deployment,omitempty"` } func (x *CreatePatchDeploymentRequest) Reset() { *x = CreatePatchDeploymentRequest{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *CreatePatchDeploymentRequest) String() string { return protoimpl.X.MessageStringOf(x) } func (*CreatePatchDeploymentRequest) ProtoMessage() {} func (x *CreatePatchDeploymentRequest) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use CreatePatchDeploymentRequest.ProtoReflect.Descriptor instead. func (*CreatePatchDeploymentRequest) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_deployments_proto_rawDescGZIP(), []int{6} } func (x *CreatePatchDeploymentRequest) GetParent() string { if x != nil { return x.Parent } return "" } func (x *CreatePatchDeploymentRequest) GetPatchDeploymentId() string { if x != nil { return x.PatchDeploymentId } return "" } func (x *CreatePatchDeploymentRequest) GetPatchDeployment() *PatchDeployment { if x != nil { return x.PatchDeployment } return nil } // A request message for retrieving a patch deployment. type GetPatchDeploymentRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. The resource name of the patch deployment in the form // `projects/*/patchDeployments/*`. Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } func (x *GetPatchDeploymentRequest) Reset() { *x = GetPatchDeploymentRequest{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *GetPatchDeploymentRequest) String() string { return protoimpl.X.MessageStringOf(x) } func (*GetPatchDeploymentRequest) ProtoMessage() {} func (x *GetPatchDeploymentRequest) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use GetPatchDeploymentRequest.ProtoReflect.Descriptor instead. func (*GetPatchDeploymentRequest) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_deployments_proto_rawDescGZIP(), []int{7} } func (x *GetPatchDeploymentRequest) GetName() string { if x != nil { return x.Name } return "" } // A request message for listing patch deployments. type ListPatchDeploymentsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. The resource name of the parent in the form `projects/*`. Parent string `protobuf:"bytes,1,opt,name=parent,proto3" json:"parent,omitempty"` // Optional. The maximum number of patch deployments to return. Default is // 100. PageSize int32 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` // Optional. A pagination token returned from a previous call to // ListPatchDeployments that indicates where this listing should continue // from. PageToken string `protobuf:"bytes,3,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"` } func (x *ListPatchDeploymentsRequest) Reset() { *x = ListPatchDeploymentsRequest{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *ListPatchDeploymentsRequest) String() string { return protoimpl.X.MessageStringOf(x) } func (*ListPatchDeploymentsRequest) ProtoMessage() {} func (x *ListPatchDeploymentsRequest) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use ListPatchDeploymentsRequest.ProtoReflect.Descriptor instead. func (*ListPatchDeploymentsRequest) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_deployments_proto_rawDescGZIP(), []int{8} } func (x *ListPatchDeploymentsRequest) GetParent() string { if x != nil { return x.Parent } return "" } func (x *ListPatchDeploymentsRequest) GetPageSize() int32 { if x != nil { return x.PageSize } return 0 } func (x *ListPatchDeploymentsRequest) GetPageToken() string { if x != nil { return x.PageToken } return "" } // A response message for listing patch deployments. type ListPatchDeploymentsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // The list of patch deployments. PatchDeployments []*PatchDeployment `protobuf:"bytes,1,rep,name=patch_deployments,json=patchDeployments,proto3" json:"patch_deployments,omitempty"` // A pagination token that can be used to get the next page of patch // deployments. NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` } func (x *ListPatchDeploymentsResponse) Reset() { *x = ListPatchDeploymentsResponse{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *ListPatchDeploymentsResponse) String() string { return protoimpl.X.MessageStringOf(x) } func (*ListPatchDeploymentsResponse) ProtoMessage() {} func (x *ListPatchDeploymentsResponse) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use ListPatchDeploymentsResponse.ProtoReflect.Descriptor instead. func (*ListPatchDeploymentsResponse) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_deployments_proto_rawDescGZIP(), []int{9} } func (x *ListPatchDeploymentsResponse) GetPatchDeployments() []*PatchDeployment { if x != nil { return x.PatchDeployments } return nil } func (x *ListPatchDeploymentsResponse) GetNextPageToken() string { if x != nil { return x.NextPageToken } return "" } // A request message for deleting a patch deployment. type DeletePatchDeploymentRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. The resource name of the patch deployment in the form // `projects/*/patchDeployments/*`. Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } func (x *DeletePatchDeploymentRequest) Reset() { *x = DeletePatchDeploymentRequest{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *DeletePatchDeploymentRequest) String() string { return protoimpl.X.MessageStringOf(x) } func (*DeletePatchDeploymentRequest) ProtoMessage() {} func (x *DeletePatchDeploymentRequest) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use DeletePatchDeploymentRequest.ProtoReflect.Descriptor instead. func (*DeletePatchDeploymentRequest) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_deployments_proto_rawDescGZIP(), []int{10} } func (x *DeletePatchDeploymentRequest) GetName() string { if x != nil { return x.Name } return "" } var File_google_cloud_osconfig_v1_patch_deployments_proto protoreflect.FileDescriptor var file_google_cloud_osconfig_v1_patch_deployments_proto_rawDesc = []byte{ 0x0a, 0x30, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x18, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x29, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6a, 0x6f, 0x62, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1a, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x2f, 0x64, 0x61, 0x74, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x2f, 0x64, 0x61, 0x79, 0x6f, 0x66, 0x77, 0x65, 0x65, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x66, 0x64, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xff, 0x06, 0x0a, 0x0f, 0x50, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x5b, 0x0a, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x4d, 0x0a, 0x0c, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0b, 0x70, 0x61, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3a, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x5c, 0x0a, 0x11, 0x6f, 0x6e, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x6e, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x48, 0x00, 0x52, 0x0f, 0x6f, 0x6e, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x61, 0x0a, 0x12, 0x72, 0x65, 0x63, 0x75, 0x72, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x63, 0x75, 0x72, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x48, 0x00, 0x52, 0x11, 0x72, 0x65, 0x63, 0x75, 0x72, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x40, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x03, 0xe0, 0x41, 0x03, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x40, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x03, 0xe0, 0x41, 0x03, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x4b, 0x0a, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x03, 0xe0, 0x41, 0x03, 0x52, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x45, 0x0a, 0x07, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x07, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x3a, 0x64, 0xea, 0x41, 0x61, 0x0a, 0x27, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x36, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x7d, 0x2f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x7d, 0x42, 0x0a, 0x0a, 0x08, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x22, 0x55, 0x0a, 0x0f, 0x4f, 0x6e, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x42, 0x0a, 0x0c, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22, 0xe2, 0x05, 0x0a, 0x11, 0x52, 0x65, 0x63, 0x75, 0x72, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x37, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x5a, 0x6f, 0x6e, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x5a, 0x6f, 0x6e, 0x65, 0x12, 0x3e, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6f, 0x66, 0x5f, 0x64, 0x61, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x4f, 0x66, 0x44, 0x61, 0x79, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x4f, 0x66, 0x44, 0x61, 0x79, 0x12, 0x58, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x35, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x63, 0x75, 0x72, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x47, 0x0a, 0x06, 0x77, 0x65, 0x65, 0x6b, 0x6c, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x65, 0x65, 0x6b, 0x6c, 0x79, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x48, 0x00, 0x52, 0x06, 0x77, 0x65, 0x65, 0x6b, 0x6c, 0x79, 0x12, 0x4a, 0x0a, 0x07, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x6c, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x6c, 0x79, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x48, 0x00, 0x52, 0x07, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x6c, 0x79, 0x12, 0x4b, 0x0a, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x03, 0xe0, 0x41, 0x03, 0x52, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x4b, 0x0a, 0x11, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x03, 0xe0, 0x41, 0x03, 0x52, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x3f, 0x0a, 0x09, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x19, 0x0a, 0x15, 0x46, 0x52, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x57, 0x45, 0x45, 0x4b, 0x4c, 0x59, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x4d, 0x4f, 0x4e, 0x54, 0x48, 0x4c, 0x59, 0x10, 0x02, 0x42, 0x11, 0x0a, 0x0f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x4d, 0x0a, 0x0e, 0x57, 0x65, 0x65, 0x6b, 0x6c, 0x79, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x64, 0x61, 0x79, 0x5f, 0x6f, 0x66, 0x5f, 0x77, 0x65, 0x65, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x44, 0x61, 0x79, 0x4f, 0x66, 0x57, 0x65, 0x65, 0x6b, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x09, 0x64, 0x61, 0x79, 0x4f, 0x66, 0x57, 0x65, 0x65, 0x6b, 0x22, 0xa1, 0x01, 0x0a, 0x0f, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x6c, 0x79, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x5a, 0x0a, 0x11, 0x77, 0x65, 0x65, 0x6b, 0x5f, 0x64, 0x61, 0x79, 0x5f, 0x6f, 0x66, 0x5f, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x65, 0x65, 0x6b, 0x44, 0x61, 0x79, 0x4f, 0x66, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x48, 0x00, 0x52, 0x0e, 0x77, 0x65, 0x65, 0x6b, 0x44, 0x61, 0x79, 0x4f, 0x66, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x12, 0x22, 0x0a, 0x09, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x5f, 0x64, 0x61, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x48, 0x00, 0x52, 0x08, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x44, 0x61, 0x79, 0x42, 0x0e, 0x0a, 0x0c, 0x64, 0x61, 0x79, 0x5f, 0x6f, 0x66, 0x5f, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x22, 0x75, 0x0a, 0x0e, 0x57, 0x65, 0x65, 0x6b, 0x44, 0x61, 0x79, 0x4f, 0x66, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x12, 0x26, 0x0a, 0x0c, 0x77, 0x65, 0x65, 0x6b, 0x5f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0b, 0x77, 0x65, 0x65, 0x6b, 0x4f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x12, 0x3b, 0x0a, 0x0b, 0x64, 0x61, 0x79, 0x5f, 0x6f, 0x66, 0x5f, 0x77, 0x65, 0x65, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x44, 0x61, 0x79, 0x4f, 0x66, 0x57, 0x65, 0x65, 0x6b, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x09, 0x64, 0x61, 0x79, 0x4f, 0x66, 0x57, 0x65, 0x65, 0x6b, 0x22, 0xfb, 0x01, 0x0a, 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4b, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x33, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x2d, 0x0a, 0x2b, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x33, 0x0a, 0x13, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x11, 0x70, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x59, 0x0a, 0x10, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x60, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x43, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2f, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x29, 0x0a, 0x27, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xb0, 0x01, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4b, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x33, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x2d, 0x0a, 0x2b, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x20, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x9e, 0x01, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x11, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x10, 0x70, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x63, 0x0a, 0x1c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x43, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2f, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x29, 0x0a, 0x27, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0xc6, 0x01, 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x42, 0x10, 0x50, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5a, 0x40, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x3b, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0xaa, 0x02, 0x18, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x18, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5c, 0x56, 0x31, 0xea, 0x02, 0x1b, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( file_google_cloud_osconfig_v1_patch_deployments_proto_rawDescOnce sync.Once file_google_cloud_osconfig_v1_patch_deployments_proto_rawDescData = file_google_cloud_osconfig_v1_patch_deployments_proto_rawDesc ) func file_google_cloud_osconfig_v1_patch_deployments_proto_rawDescGZIP() []byte { file_google_cloud_osconfig_v1_patch_deployments_proto_rawDescOnce.Do(func() { file_google_cloud_osconfig_v1_patch_deployments_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_cloud_osconfig_v1_patch_deployments_proto_rawDescData) }) return file_google_cloud_osconfig_v1_patch_deployments_proto_rawDescData } var file_google_cloud_osconfig_v1_patch_deployments_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_google_cloud_osconfig_v1_patch_deployments_proto_goTypes = []interface{}{ (RecurringSchedule_Frequency)(0), // 0: google.cloud.osconfig.v1.RecurringSchedule.Frequency (*PatchDeployment)(nil), // 1: google.cloud.osconfig.v1.PatchDeployment (*OneTimeSchedule)(nil), // 2: google.cloud.osconfig.v1.OneTimeSchedule (*RecurringSchedule)(nil), // 3: google.cloud.osconfig.v1.RecurringSchedule (*WeeklySchedule)(nil), // 4: google.cloud.osconfig.v1.WeeklySchedule (*MonthlySchedule)(nil), // 5: google.cloud.osconfig.v1.MonthlySchedule (*WeekDayOfMonth)(nil), // 6: google.cloud.osconfig.v1.WeekDayOfMonth (*CreatePatchDeploymentRequest)(nil), // 7: google.cloud.osconfig.v1.CreatePatchDeploymentRequest (*GetPatchDeploymentRequest)(nil), // 8: google.cloud.osconfig.v1.GetPatchDeploymentRequest (*ListPatchDeploymentsRequest)(nil), // 9: google.cloud.osconfig.v1.ListPatchDeploymentsRequest (*ListPatchDeploymentsResponse)(nil), // 10: google.cloud.osconfig.v1.ListPatchDeploymentsResponse (*DeletePatchDeploymentRequest)(nil), // 11: google.cloud.osconfig.v1.DeletePatchDeploymentRequest (*PatchInstanceFilter)(nil), // 12: google.cloud.osconfig.v1.PatchInstanceFilter (*PatchConfig)(nil), // 13: google.cloud.osconfig.v1.PatchConfig (*durationpb.Duration)(nil), // 14: google.protobuf.Duration (*timestamppb.Timestamp)(nil), // 15: google.protobuf.Timestamp (*PatchRollout)(nil), // 16: google.cloud.osconfig.v1.PatchRollout (*datetime.TimeZone)(nil), // 17: google.type.TimeZone (*timeofday.TimeOfDay)(nil), // 18: google.type.TimeOfDay (dayofweek.DayOfWeek)(0), // 19: google.type.DayOfWeek } var file_google_cloud_osconfig_v1_patch_deployments_proto_depIdxs = []int32{ 12, // 0: google.cloud.osconfig.v1.PatchDeployment.instance_filter:type_name -> google.cloud.osconfig.v1.PatchInstanceFilter 13, // 1: google.cloud.osconfig.v1.PatchDeployment.patch_config:type_name -> google.cloud.osconfig.v1.PatchConfig 14, // 2: google.cloud.osconfig.v1.PatchDeployment.duration:type_name -> google.protobuf.Duration 2, // 3: google.cloud.osconfig.v1.PatchDeployment.one_time_schedule:type_name -> google.cloud.osconfig.v1.OneTimeSchedule 3, // 4: google.cloud.osconfig.v1.PatchDeployment.recurring_schedule:type_name -> google.cloud.osconfig.v1.RecurringSchedule 15, // 5: google.cloud.osconfig.v1.PatchDeployment.create_time:type_name -> google.protobuf.Timestamp 15, // 6: google.cloud.osconfig.v1.PatchDeployment.update_time:type_name -> google.protobuf.Timestamp 15, // 7: google.cloud.osconfig.v1.PatchDeployment.last_execute_time:type_name -> google.protobuf.Timestamp 16, // 8: google.cloud.osconfig.v1.PatchDeployment.rollout:type_name -> google.cloud.osconfig.v1.PatchRollout 15, // 9: google.cloud.osconfig.v1.OneTimeSchedule.execute_time:type_name -> google.protobuf.Timestamp 17, // 10: google.cloud.osconfig.v1.RecurringSchedule.time_zone:type_name -> google.type.TimeZone 15, // 11: google.cloud.osconfig.v1.RecurringSchedule.start_time:type_name -> google.protobuf.Timestamp 15, // 12: google.cloud.osconfig.v1.RecurringSchedule.end_time:type_name -> google.protobuf.Timestamp 18, // 13: google.cloud.osconfig.v1.RecurringSchedule.time_of_day:type_name -> google.type.TimeOfDay 0, // 14: google.cloud.osconfig.v1.RecurringSchedule.frequency:type_name -> google.cloud.osconfig.v1.RecurringSchedule.Frequency 4, // 15: google.cloud.osconfig.v1.RecurringSchedule.weekly:type_name -> google.cloud.osconfig.v1.WeeklySchedule 5, // 16: google.cloud.osconfig.v1.RecurringSchedule.monthly:type_name -> google.cloud.osconfig.v1.MonthlySchedule 15, // 17: google.cloud.osconfig.v1.RecurringSchedule.last_execute_time:type_name -> google.protobuf.Timestamp 15, // 18: google.cloud.osconfig.v1.RecurringSchedule.next_execute_time:type_name -> google.protobuf.Timestamp 19, // 19: google.cloud.osconfig.v1.WeeklySchedule.day_of_week:type_name -> google.type.DayOfWeek 6, // 20: google.cloud.osconfig.v1.MonthlySchedule.week_day_of_month:type_name -> google.cloud.osconfig.v1.WeekDayOfMonth 19, // 21: google.cloud.osconfig.v1.WeekDayOfMonth.day_of_week:type_name -> google.type.DayOfWeek 1, // 22: google.cloud.osconfig.v1.CreatePatchDeploymentRequest.patch_deployment:type_name -> google.cloud.osconfig.v1.PatchDeployment 1, // 23: google.cloud.osconfig.v1.ListPatchDeploymentsResponse.patch_deployments:type_name -> google.cloud.osconfig.v1.PatchDeployment 24, // [24:24] is the sub-list for method output_type 24, // [24:24] is the sub-list for method input_type 24, // [24:24] is the sub-list for extension type_name 24, // [24:24] is the sub-list for extension extendee 0, // [0:24] is the sub-list for field type_name } func init() { file_google_cloud_osconfig_v1_patch_deployments_proto_init() } func file_google_cloud_osconfig_v1_patch_deployments_proto_init() { if File_google_cloud_osconfig_v1_patch_deployments_proto != nil { return } file_google_cloud_osconfig_v1_patch_jobs_proto_init() if !protoimpl.UnsafeEnabled { file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PatchDeployment); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OneTimeSchedule); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RecurringSchedule); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WeeklySchedule); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MonthlySchedule); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WeekDayOfMonth); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreatePatchDeploymentRequest); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetPatchDeploymentRequest); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListPatchDeploymentsRequest); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListPatchDeploymentsResponse); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DeletePatchDeploymentRequest); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } } file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[0].OneofWrappers = []interface{}{ (*PatchDeployment_OneTimeSchedule)(nil), (*PatchDeployment_RecurringSchedule)(nil), } file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[2].OneofWrappers = []interface{}{ (*RecurringSchedule_Weekly)(nil), (*RecurringSchedule_Monthly)(nil), } file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes[4].OneofWrappers = []interface{}{ (*MonthlySchedule_WeekDayOfMonth)(nil), (*MonthlySchedule_MonthDay)(nil), } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_google_cloud_osconfig_v1_patch_deployments_proto_rawDesc, NumEnums: 1, NumMessages: 11, NumExtensions: 0, NumServices: 0, }, GoTypes: file_google_cloud_osconfig_v1_patch_deployments_proto_goTypes, DependencyIndexes: file_google_cloud_osconfig_v1_patch_deployments_proto_depIdxs, EnumInfos: file_google_cloud_osconfig_v1_patch_deployments_proto_enumTypes, MessageInfos: file_google_cloud_osconfig_v1_patch_deployments_proto_msgTypes, }.Build() File_google_cloud_osconfig_v1_patch_deployments_proto = out.File file_google_cloud_osconfig_v1_patch_deployments_proto_rawDesc = nil file_google_cloud_osconfig_v1_patch_deployments_proto_goTypes = nil file_google_cloud_osconfig_v1_patch_deployments_proto_depIdxs = nil } patch_jobs.pb.go000066400000000000000000004273271477773331400353030ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/internal/google.golang.org/genproto/googleapis/cloud/osconfig/v1// Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.25.0 // protoc v3.15.3 // source: google/cloud/osconfig/v1/patch_jobs.proto package osconfig import ( proto "github.com/golang/protobuf/proto" _ "google.golang.org/genproto/googleapis/api/annotations" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" durationpb "google.golang.org/protobuf/types/known/durationpb" timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" ) const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) // Verify that runtime/protoimpl is sufficiently up-to-date. _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) // This is a compile-time assertion that a sufficiently up-to-date version // of the legacy proto package is being used. const _ = proto.ProtoPackageIsVersion4 // Enumeration of the various states a patch job passes through as it // executes. type PatchJob_State int32 const ( // State must be specified. PatchJob_STATE_UNSPECIFIED PatchJob_State = 0 // The patch job was successfully initiated. PatchJob_STARTED PatchJob_State = 1 // The patch job is looking up instances to run the patch on. PatchJob_INSTANCE_LOOKUP PatchJob_State = 2 // Instances are being patched. PatchJob_PATCHING PatchJob_State = 3 // Patch job completed successfully. PatchJob_SUCCEEDED PatchJob_State = 4 // Patch job completed but there were errors. PatchJob_COMPLETED_WITH_ERRORS PatchJob_State = 5 // The patch job was canceled. PatchJob_CANCELED PatchJob_State = 6 // The patch job timed out. PatchJob_TIMED_OUT PatchJob_State = 7 ) // Enum value maps for PatchJob_State. var ( PatchJob_State_name = map[int32]string{ 0: "STATE_UNSPECIFIED", 1: "STARTED", 2: "INSTANCE_LOOKUP", 3: "PATCHING", 4: "SUCCEEDED", 5: "COMPLETED_WITH_ERRORS", 6: "CANCELED", 7: "TIMED_OUT", } PatchJob_State_value = map[string]int32{ "STATE_UNSPECIFIED": 0, "STARTED": 1, "INSTANCE_LOOKUP": 2, "PATCHING": 3, "SUCCEEDED": 4, "COMPLETED_WITH_ERRORS": 5, "CANCELED": 6, "TIMED_OUT": 7, } ) func (x PatchJob_State) Enum() *PatchJob_State { p := new(PatchJob_State) *p = x return p } func (x PatchJob_State) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (PatchJob_State) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_patch_jobs_proto_enumTypes[0].Descriptor() } func (PatchJob_State) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_patch_jobs_proto_enumTypes[0] } func (x PatchJob_State) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use PatchJob_State.Descriptor instead. func (PatchJob_State) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{7, 0} } // Post-patch reboot settings. type PatchConfig_RebootConfig int32 const ( // The default behavior is DEFAULT. PatchConfig_REBOOT_CONFIG_UNSPECIFIED PatchConfig_RebootConfig = 0 // The agent decides if a reboot is necessary by checking signals such as // registry keys on Windows or `/var/run/reboot-required` on APT based // systems. On RPM based systems, a set of core system package install times // are compared with system boot time. PatchConfig_DEFAULT PatchConfig_RebootConfig = 1 // Always reboot the machine after the update completes. PatchConfig_ALWAYS PatchConfig_RebootConfig = 2 // Never reboot the machine after the update completes. PatchConfig_NEVER PatchConfig_RebootConfig = 3 ) // Enum value maps for PatchConfig_RebootConfig. var ( PatchConfig_RebootConfig_name = map[int32]string{ 0: "REBOOT_CONFIG_UNSPECIFIED", 1: "DEFAULT", 2: "ALWAYS", 3: "NEVER", } PatchConfig_RebootConfig_value = map[string]int32{ "REBOOT_CONFIG_UNSPECIFIED": 0, "DEFAULT": 1, "ALWAYS": 2, "NEVER": 3, } ) func (x PatchConfig_RebootConfig) Enum() *PatchConfig_RebootConfig { p := new(PatchConfig_RebootConfig) *p = x return p } func (x PatchConfig_RebootConfig) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (PatchConfig_RebootConfig) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_patch_jobs_proto_enumTypes[1].Descriptor() } func (PatchConfig_RebootConfig) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_patch_jobs_proto_enumTypes[1] } func (x PatchConfig_RebootConfig) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use PatchConfig_RebootConfig.Descriptor instead. func (PatchConfig_RebootConfig) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{8, 0} } // Patch state of an instance. type Instance_PatchState int32 const ( // Unspecified. Instance_PATCH_STATE_UNSPECIFIED Instance_PatchState = 0 // The instance is not yet notified. Instance_PENDING Instance_PatchState = 1 // Instance is inactive and cannot be patched. Instance_INACTIVE Instance_PatchState = 2 // The instance is notified that it should be patched. Instance_NOTIFIED Instance_PatchState = 3 // The instance has started the patching process. Instance_STARTED Instance_PatchState = 4 // The instance is downloading patches. Instance_DOWNLOADING_PATCHES Instance_PatchState = 5 // The instance is applying patches. Instance_APPLYING_PATCHES Instance_PatchState = 6 // The instance is rebooting. Instance_REBOOTING Instance_PatchState = 7 // The instance has completed applying patches. Instance_SUCCEEDED Instance_PatchState = 8 // The instance has completed applying patches but a reboot is required. Instance_SUCCEEDED_REBOOT_REQUIRED Instance_PatchState = 9 // The instance has failed to apply the patch. Instance_FAILED Instance_PatchState = 10 // The instance acked the notification and will start shortly. Instance_ACKED Instance_PatchState = 11 // The instance exceeded the time out while applying the patch. Instance_TIMED_OUT Instance_PatchState = 12 // The instance is running the pre-patch step. Instance_RUNNING_PRE_PATCH_STEP Instance_PatchState = 13 // The instance is running the post-patch step. Instance_RUNNING_POST_PATCH_STEP Instance_PatchState = 14 // The service could not detect the presence of the agent. Check to ensure // that the agent is installed, running, and able to communicate with the // service. Instance_NO_AGENT_DETECTED Instance_PatchState = 15 ) // Enum value maps for Instance_PatchState. var ( Instance_PatchState_name = map[int32]string{ 0: "PATCH_STATE_UNSPECIFIED", 1: "PENDING", 2: "INACTIVE", 3: "NOTIFIED", 4: "STARTED", 5: "DOWNLOADING_PATCHES", 6: "APPLYING_PATCHES", 7: "REBOOTING", 8: "SUCCEEDED", 9: "SUCCEEDED_REBOOT_REQUIRED", 10: "FAILED", 11: "ACKED", 12: "TIMED_OUT", 13: "RUNNING_PRE_PATCH_STEP", 14: "RUNNING_POST_PATCH_STEP", 15: "NO_AGENT_DETECTED", } Instance_PatchState_value = map[string]int32{ "PATCH_STATE_UNSPECIFIED": 0, "PENDING": 1, "INACTIVE": 2, "NOTIFIED": 3, "STARTED": 4, "DOWNLOADING_PATCHES": 5, "APPLYING_PATCHES": 6, "REBOOTING": 7, "SUCCEEDED": 8, "SUCCEEDED_REBOOT_REQUIRED": 9, "FAILED": 10, "ACKED": 11, "TIMED_OUT": 12, "RUNNING_PRE_PATCH_STEP": 13, "RUNNING_POST_PATCH_STEP": 14, "NO_AGENT_DETECTED": 15, } ) func (x Instance_PatchState) Enum() *Instance_PatchState { p := new(Instance_PatchState) *p = x return p } func (x Instance_PatchState) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (Instance_PatchState) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_patch_jobs_proto_enumTypes[2].Descriptor() } func (Instance_PatchState) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_patch_jobs_proto_enumTypes[2] } func (x Instance_PatchState) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use Instance_PatchState.Descriptor instead. func (Instance_PatchState) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{9, 0} } // Apt patch type. type AptSettings_Type int32 const ( // By default, upgrade will be performed. AptSettings_TYPE_UNSPECIFIED AptSettings_Type = 0 // Runs `apt-get dist-upgrade`. AptSettings_DIST AptSettings_Type = 1 // Runs `apt-get upgrade`. AptSettings_UPGRADE AptSettings_Type = 2 ) // Enum value maps for AptSettings_Type. var ( AptSettings_Type_name = map[int32]string{ 0: "TYPE_UNSPECIFIED", 1: "DIST", 2: "UPGRADE", } AptSettings_Type_value = map[string]int32{ "TYPE_UNSPECIFIED": 0, "DIST": 1, "UPGRADE": 2, } ) func (x AptSettings_Type) Enum() *AptSettings_Type { p := new(AptSettings_Type) *p = x return p } func (x AptSettings_Type) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (AptSettings_Type) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_patch_jobs_proto_enumTypes[3].Descriptor() } func (AptSettings_Type) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_patch_jobs_proto_enumTypes[3] } func (x AptSettings_Type) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use AptSettings_Type.Descriptor instead. func (AptSettings_Type) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{11, 0} } // Microsoft Windows update classifications as defined in // [1] // https://support.microsoft.com/en-us/help/824684/description-of-the-standard-terminology-that-is-used-to-describe-micro type WindowsUpdateSettings_Classification int32 const ( // Invalid. If classifications are included, they must be specified. WindowsUpdateSettings_CLASSIFICATION_UNSPECIFIED WindowsUpdateSettings_Classification = 0 // "A widely released fix for a specific problem that addresses a critical, // non-security-related bug." [1] WindowsUpdateSettings_CRITICAL WindowsUpdateSettings_Classification = 1 // "A widely released fix for a product-specific, security-related // vulnerability. Security vulnerabilities are rated by their severity. The // severity rating is indicated in the Microsoft security bulletin as // critical, important, moderate, or low." [1] WindowsUpdateSettings_SECURITY WindowsUpdateSettings_Classification = 2 // "A widely released and frequent software update that contains additions // to a product's definition database. Definition databases are often used // to detect objects that have specific attributes, such as malicious code, // phishing websites, or junk mail." [1] WindowsUpdateSettings_DEFINITION WindowsUpdateSettings_Classification = 3 // "Software that controls the input and output of a device." [1] WindowsUpdateSettings_DRIVER WindowsUpdateSettings_Classification = 4 // "New product functionality that is first distributed outside the context // of a product release and that is typically included in the next full // product release." [1] WindowsUpdateSettings_FEATURE_PACK WindowsUpdateSettings_Classification = 5 // "A tested, cumulative set of all hotfixes, security updates, critical // updates, and updates. Additionally, service packs may contain additional // fixes for problems that are found internally since the release of the // product. Service packs my also contain a limited number of // customer-requested design changes or features." [1] WindowsUpdateSettings_SERVICE_PACK WindowsUpdateSettings_Classification = 6 // "A utility or feature that helps complete a task or set of tasks." [1] WindowsUpdateSettings_TOOL WindowsUpdateSettings_Classification = 7 // "A tested, cumulative set of hotfixes, security updates, critical // updates, and updates that are packaged together for easy deployment. A // rollup generally targets a specific area, such as security, or a // component of a product, such as Internet Information Services (IIS)." [1] WindowsUpdateSettings_UPDATE_ROLLUP WindowsUpdateSettings_Classification = 8 // "A widely released fix for a specific problem. An update addresses a // noncritical, non-security-related bug." [1] WindowsUpdateSettings_UPDATE WindowsUpdateSettings_Classification = 9 ) // Enum value maps for WindowsUpdateSettings_Classification. var ( WindowsUpdateSettings_Classification_name = map[int32]string{ 0: "CLASSIFICATION_UNSPECIFIED", 1: "CRITICAL", 2: "SECURITY", 3: "DEFINITION", 4: "DRIVER", 5: "FEATURE_PACK", 6: "SERVICE_PACK", 7: "TOOL", 8: "UPDATE_ROLLUP", 9: "UPDATE", } WindowsUpdateSettings_Classification_value = map[string]int32{ "CLASSIFICATION_UNSPECIFIED": 0, "CRITICAL": 1, "SECURITY": 2, "DEFINITION": 3, "DRIVER": 4, "FEATURE_PACK": 5, "SERVICE_PACK": 6, "TOOL": 7, "UPDATE_ROLLUP": 8, "UPDATE": 9, } ) func (x WindowsUpdateSettings_Classification) Enum() *WindowsUpdateSettings_Classification { p := new(WindowsUpdateSettings_Classification) *p = x return p } func (x WindowsUpdateSettings_Classification) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (WindowsUpdateSettings_Classification) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_patch_jobs_proto_enumTypes[4].Descriptor() } func (WindowsUpdateSettings_Classification) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_patch_jobs_proto_enumTypes[4] } func (x WindowsUpdateSettings_Classification) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use WindowsUpdateSettings_Classification.Descriptor instead. func (WindowsUpdateSettings_Classification) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{15, 0} } // The interpreter used to execute the a file. type ExecStepConfig_Interpreter int32 const ( // Invalid for a Windows ExecStepConfig. For a Linux ExecStepConfig, the // interpreter will be parsed from the shebang line of the script if // unspecified. ExecStepConfig_INTERPRETER_UNSPECIFIED ExecStepConfig_Interpreter = 0 // Indicates that the script is run with `/bin/sh` on Linux and `cmd` // on Windows. ExecStepConfig_SHELL ExecStepConfig_Interpreter = 1 // Indicates that the file is run with PowerShell flags // `-NonInteractive`, `-NoProfile`, and `-ExecutionPolicy Bypass`. ExecStepConfig_POWERSHELL ExecStepConfig_Interpreter = 2 ) // Enum value maps for ExecStepConfig_Interpreter. var ( ExecStepConfig_Interpreter_name = map[int32]string{ 0: "INTERPRETER_UNSPECIFIED", 1: "SHELL", 2: "POWERSHELL", } ExecStepConfig_Interpreter_value = map[string]int32{ "INTERPRETER_UNSPECIFIED": 0, "SHELL": 1, "POWERSHELL": 2, } ) func (x ExecStepConfig_Interpreter) Enum() *ExecStepConfig_Interpreter { p := new(ExecStepConfig_Interpreter) *p = x return p } func (x ExecStepConfig_Interpreter) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (ExecStepConfig_Interpreter) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_patch_jobs_proto_enumTypes[5].Descriptor() } func (ExecStepConfig_Interpreter) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_patch_jobs_proto_enumTypes[5] } func (x ExecStepConfig_Interpreter) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use ExecStepConfig_Interpreter.Descriptor instead. func (ExecStepConfig_Interpreter) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{17, 0} } // Type of the rollout. type PatchRollout_Mode int32 const ( // Mode must be specified. PatchRollout_MODE_UNSPECIFIED PatchRollout_Mode = 0 // Patches are applied one zone at a time. The patch job begins in the // region with the lowest number of targeted VMs. Within the region, // patching begins in the zone with the lowest number of targeted VMs. If // multiple regions (or zones within a region) have the same number of // targeted VMs, a tie-breaker is achieved by sorting the regions or zones // in alphabetical order. PatchRollout_ZONE_BY_ZONE PatchRollout_Mode = 1 // Patches are applied to VMs in all zones at the same time. PatchRollout_CONCURRENT_ZONES PatchRollout_Mode = 2 ) // Enum value maps for PatchRollout_Mode. var ( PatchRollout_Mode_name = map[int32]string{ 0: "MODE_UNSPECIFIED", 1: "ZONE_BY_ZONE", 2: "CONCURRENT_ZONES", } PatchRollout_Mode_value = map[string]int32{ "MODE_UNSPECIFIED": 0, "ZONE_BY_ZONE": 1, "CONCURRENT_ZONES": 2, } ) func (x PatchRollout_Mode) Enum() *PatchRollout_Mode { p := new(PatchRollout_Mode) *p = x return p } func (x PatchRollout_Mode) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (PatchRollout_Mode) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_patch_jobs_proto_enumTypes[6].Descriptor() } func (PatchRollout_Mode) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_patch_jobs_proto_enumTypes[6] } func (x PatchRollout_Mode) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use PatchRollout_Mode.Descriptor instead. func (PatchRollout_Mode) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{20, 0} } // A request message to initiate patching across Compute Engine // instances. type ExecutePatchJobRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. The project in which to run this patch in the form `projects/*` Parent string `protobuf:"bytes,1,opt,name=parent,proto3" json:"parent,omitempty"` // Description of the patch job. Length of the description is limited // to 1024 characters. Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // Required. Instances to patch, either explicitly or filtered by some // criteria such as zone or labels. InstanceFilter *PatchInstanceFilter `protobuf:"bytes,7,opt,name=instance_filter,json=instanceFilter,proto3" json:"instance_filter,omitempty"` // Patch configuration being applied. If omitted, instances are // patched using the default configurations. PatchConfig *PatchConfig `protobuf:"bytes,4,opt,name=patch_config,json=patchConfig,proto3" json:"patch_config,omitempty"` // Duration of the patch job. After the duration ends, the patch job // times out. Duration *durationpb.Duration `protobuf:"bytes,5,opt,name=duration,proto3" json:"duration,omitempty"` // If this patch is a dry-run only, instances are contacted but // will do nothing. DryRun bool `protobuf:"varint,6,opt,name=dry_run,json=dryRun,proto3" json:"dry_run,omitempty"` // Display name for this patch job. This does not have to be unique. DisplayName string `protobuf:"bytes,8,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` // Rollout strategy of the patch job. Rollout *PatchRollout `protobuf:"bytes,9,opt,name=rollout,proto3" json:"rollout,omitempty"` } func (x *ExecutePatchJobRequest) Reset() { *x = ExecutePatchJobRequest{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *ExecutePatchJobRequest) String() string { return protoimpl.X.MessageStringOf(x) } func (*ExecutePatchJobRequest) ProtoMessage() {} func (x *ExecutePatchJobRequest) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use ExecutePatchJobRequest.ProtoReflect.Descriptor instead. func (*ExecutePatchJobRequest) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{0} } func (x *ExecutePatchJobRequest) GetParent() string { if x != nil { return x.Parent } return "" } func (x *ExecutePatchJobRequest) GetDescription() string { if x != nil { return x.Description } return "" } func (x *ExecutePatchJobRequest) GetInstanceFilter() *PatchInstanceFilter { if x != nil { return x.InstanceFilter } return nil } func (x *ExecutePatchJobRequest) GetPatchConfig() *PatchConfig { if x != nil { return x.PatchConfig } return nil } func (x *ExecutePatchJobRequest) GetDuration() *durationpb.Duration { if x != nil { return x.Duration } return nil } func (x *ExecutePatchJobRequest) GetDryRun() bool { if x != nil { return x.DryRun } return false } func (x *ExecutePatchJobRequest) GetDisplayName() string { if x != nil { return x.DisplayName } return "" } func (x *ExecutePatchJobRequest) GetRollout() *PatchRollout { if x != nil { return x.Rollout } return nil } // Request to get an active or completed patch job. type GetPatchJobRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. Name of the patch in the form `projects/*/patchJobs/*` Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } func (x *GetPatchJobRequest) Reset() { *x = GetPatchJobRequest{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *GetPatchJobRequest) String() string { return protoimpl.X.MessageStringOf(x) } func (*GetPatchJobRequest) ProtoMessage() {} func (x *GetPatchJobRequest) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use GetPatchJobRequest.ProtoReflect.Descriptor instead. func (*GetPatchJobRequest) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{1} } func (x *GetPatchJobRequest) GetName() string { if x != nil { return x.Name } return "" } // Request to list details for all instances that are part of a patch job. type ListPatchJobInstanceDetailsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. The parent for the instances are in the form of // `projects/*/patchJobs/*`. Parent string `protobuf:"bytes,1,opt,name=parent,proto3" json:"parent,omitempty"` // The maximum number of instance details records to return. Default is 100. PageSize int32 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` // A pagination token returned from a previous call // that indicates where this listing should continue from. PageToken string `protobuf:"bytes,3,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"` // A filter expression that filters results listed in the response. This // field supports filtering results by instance zone, name, state, or // `failure_reason`. Filter string `protobuf:"bytes,4,opt,name=filter,proto3" json:"filter,omitempty"` } func (x *ListPatchJobInstanceDetailsRequest) Reset() { *x = ListPatchJobInstanceDetailsRequest{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *ListPatchJobInstanceDetailsRequest) String() string { return protoimpl.X.MessageStringOf(x) } func (*ListPatchJobInstanceDetailsRequest) ProtoMessage() {} func (x *ListPatchJobInstanceDetailsRequest) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use ListPatchJobInstanceDetailsRequest.ProtoReflect.Descriptor instead. func (*ListPatchJobInstanceDetailsRequest) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{2} } func (x *ListPatchJobInstanceDetailsRequest) GetParent() string { if x != nil { return x.Parent } return "" } func (x *ListPatchJobInstanceDetailsRequest) GetPageSize() int32 { if x != nil { return x.PageSize } return 0 } func (x *ListPatchJobInstanceDetailsRequest) GetPageToken() string { if x != nil { return x.PageToken } return "" } func (x *ListPatchJobInstanceDetailsRequest) GetFilter() string { if x != nil { return x.Filter } return "" } // A response message for listing the instances details for a patch job. type ListPatchJobInstanceDetailsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // A list of instance status. PatchJobInstanceDetails []*PatchJobInstanceDetails `protobuf:"bytes,1,rep,name=patch_job_instance_details,json=patchJobInstanceDetails,proto3" json:"patch_job_instance_details,omitempty"` // A pagination token that can be used to get the next page of results. NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` } func (x *ListPatchJobInstanceDetailsResponse) Reset() { *x = ListPatchJobInstanceDetailsResponse{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *ListPatchJobInstanceDetailsResponse) String() string { return protoimpl.X.MessageStringOf(x) } func (*ListPatchJobInstanceDetailsResponse) ProtoMessage() {} func (x *ListPatchJobInstanceDetailsResponse) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use ListPatchJobInstanceDetailsResponse.ProtoReflect.Descriptor instead. func (*ListPatchJobInstanceDetailsResponse) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{3} } func (x *ListPatchJobInstanceDetailsResponse) GetPatchJobInstanceDetails() []*PatchJobInstanceDetails { if x != nil { return x.PatchJobInstanceDetails } return nil } func (x *ListPatchJobInstanceDetailsResponse) GetNextPageToken() string { if x != nil { return x.NextPageToken } return "" } // Patch details for a VM instance. For more information about reviewing VM // instance details, see // [Listing all VM instance details for a specific patch // job](https://cloud.google.com/compute/docs/os-patch-management/manage-patch-jobs#list-instance-details). type PatchJobInstanceDetails struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // The instance name in the form `projects/*/zones/*/instances/*` Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // The unique identifier for the instance. This identifier is // defined by the server. InstanceSystemId string `protobuf:"bytes,2,opt,name=instance_system_id,json=instanceSystemId,proto3" json:"instance_system_id,omitempty"` // Current state of instance patch. State Instance_PatchState `protobuf:"varint,3,opt,name=state,proto3,enum=google.cloud.osconfig.v1.Instance_PatchState" json:"state,omitempty"` // If the patch fails, this field provides the reason. FailureReason string `protobuf:"bytes,4,opt,name=failure_reason,json=failureReason,proto3" json:"failure_reason,omitempty"` // The number of times the agent that the agent attempts to apply the patch. AttemptCount int64 `protobuf:"varint,5,opt,name=attempt_count,json=attemptCount,proto3" json:"attempt_count,omitempty"` } func (x *PatchJobInstanceDetails) Reset() { *x = PatchJobInstanceDetails{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *PatchJobInstanceDetails) String() string { return protoimpl.X.MessageStringOf(x) } func (*PatchJobInstanceDetails) ProtoMessage() {} func (x *PatchJobInstanceDetails) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use PatchJobInstanceDetails.ProtoReflect.Descriptor instead. func (*PatchJobInstanceDetails) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{4} } func (x *PatchJobInstanceDetails) GetName() string { if x != nil { return x.Name } return "" } func (x *PatchJobInstanceDetails) GetInstanceSystemId() string { if x != nil { return x.InstanceSystemId } return "" } func (x *PatchJobInstanceDetails) GetState() Instance_PatchState { if x != nil { return x.State } return Instance_PATCH_STATE_UNSPECIFIED } func (x *PatchJobInstanceDetails) GetFailureReason() string { if x != nil { return x.FailureReason } return "" } func (x *PatchJobInstanceDetails) GetAttemptCount() int64 { if x != nil { return x.AttemptCount } return 0 } // A request message for listing patch jobs. type ListPatchJobsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. In the form of `projects/*` Parent string `protobuf:"bytes,1,opt,name=parent,proto3" json:"parent,omitempty"` // The maximum number of instance status to return. PageSize int32 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` // A pagination token returned from a previous call // that indicates where this listing should continue from. PageToken string `protobuf:"bytes,3,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"` // If provided, this field specifies the criteria that must be met by patch // jobs to be included in the response. // Currently, filtering is only available on the patch_deployment field. Filter string `protobuf:"bytes,4,opt,name=filter,proto3" json:"filter,omitempty"` } func (x *ListPatchJobsRequest) Reset() { *x = ListPatchJobsRequest{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *ListPatchJobsRequest) String() string { return protoimpl.X.MessageStringOf(x) } func (*ListPatchJobsRequest) ProtoMessage() {} func (x *ListPatchJobsRequest) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use ListPatchJobsRequest.ProtoReflect.Descriptor instead. func (*ListPatchJobsRequest) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{5} } func (x *ListPatchJobsRequest) GetParent() string { if x != nil { return x.Parent } return "" } func (x *ListPatchJobsRequest) GetPageSize() int32 { if x != nil { return x.PageSize } return 0 } func (x *ListPatchJobsRequest) GetPageToken() string { if x != nil { return x.PageToken } return "" } func (x *ListPatchJobsRequest) GetFilter() string { if x != nil { return x.Filter } return "" } // A response message for listing patch jobs. type ListPatchJobsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // The list of patch jobs. PatchJobs []*PatchJob `protobuf:"bytes,1,rep,name=patch_jobs,json=patchJobs,proto3" json:"patch_jobs,omitempty"` // A pagination token that can be used to get the next page of results. NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` } func (x *ListPatchJobsResponse) Reset() { *x = ListPatchJobsResponse{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *ListPatchJobsResponse) String() string { return protoimpl.X.MessageStringOf(x) } func (*ListPatchJobsResponse) ProtoMessage() {} func (x *ListPatchJobsResponse) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use ListPatchJobsResponse.ProtoReflect.Descriptor instead. func (*ListPatchJobsResponse) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{6} } func (x *ListPatchJobsResponse) GetPatchJobs() []*PatchJob { if x != nil { return x.PatchJobs } return nil } func (x *ListPatchJobsResponse) GetNextPageToken() string { if x != nil { return x.NextPageToken } return "" } // A high level representation of a patch job that is either in progress // or has completed. // // Instance details are not included in the job. To paginate through instance // details, use ListPatchJobInstanceDetails. // // For more information about patch jobs, see // [Creating patch // jobs](https://cloud.google.com/compute/docs/os-patch-management/create-patch-job). type PatchJob struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Unique identifier for this patch job in the form // `projects/*/patchJobs/*` Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // Display name for this patch job. This is not a unique identifier. DisplayName string `protobuf:"bytes,14,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` // Description of the patch job. Length of the description is limited // to 1024 characters. Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // Time this patch job was created. CreateTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"` // Last time this patch job was updated. UpdateTime *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty"` // The current state of the PatchJob. State PatchJob_State `protobuf:"varint,5,opt,name=state,proto3,enum=google.cloud.osconfig.v1.PatchJob_State" json:"state,omitempty"` // Instances to patch. InstanceFilter *PatchInstanceFilter `protobuf:"bytes,13,opt,name=instance_filter,json=instanceFilter,proto3" json:"instance_filter,omitempty"` // Patch configuration being applied. PatchConfig *PatchConfig `protobuf:"bytes,7,opt,name=patch_config,json=patchConfig,proto3" json:"patch_config,omitempty"` // Duration of the patch job. After the duration ends, the // patch job times out. Duration *durationpb.Duration `protobuf:"bytes,8,opt,name=duration,proto3" json:"duration,omitempty"` // Summary of instance details. InstanceDetailsSummary *PatchJob_InstanceDetailsSummary `protobuf:"bytes,9,opt,name=instance_details_summary,json=instanceDetailsSummary,proto3" json:"instance_details_summary,omitempty"` // If this patch job is a dry run, the agent reports that it has // finished without running any updates on the VM instance. DryRun bool `protobuf:"varint,10,opt,name=dry_run,json=dryRun,proto3" json:"dry_run,omitempty"` // If this patch job failed, this message provides information about the // failure. ErrorMessage string `protobuf:"bytes,11,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` // Reflects the overall progress of the patch job in the range of // 0.0 being no progress to 100.0 being complete. PercentComplete float64 `protobuf:"fixed64,12,opt,name=percent_complete,json=percentComplete,proto3" json:"percent_complete,omitempty"` // Output only. Name of the patch deployment that created this patch job. PatchDeployment string `protobuf:"bytes,15,opt,name=patch_deployment,json=patchDeployment,proto3" json:"patch_deployment,omitempty"` // Rollout strategy being applied. Rollout *PatchRollout `protobuf:"bytes,16,opt,name=rollout,proto3" json:"rollout,omitempty"` } func (x *PatchJob) Reset() { *x = PatchJob{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *PatchJob) String() string { return protoimpl.X.MessageStringOf(x) } func (*PatchJob) ProtoMessage() {} func (x *PatchJob) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use PatchJob.ProtoReflect.Descriptor instead. func (*PatchJob) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{7} } func (x *PatchJob) GetName() string { if x != nil { return x.Name } return "" } func (x *PatchJob) GetDisplayName() string { if x != nil { return x.DisplayName } return "" } func (x *PatchJob) GetDescription() string { if x != nil { return x.Description } return "" } func (x *PatchJob) GetCreateTime() *timestamppb.Timestamp { if x != nil { return x.CreateTime } return nil } func (x *PatchJob) GetUpdateTime() *timestamppb.Timestamp { if x != nil { return x.UpdateTime } return nil } func (x *PatchJob) GetState() PatchJob_State { if x != nil { return x.State } return PatchJob_STATE_UNSPECIFIED } func (x *PatchJob) GetInstanceFilter() *PatchInstanceFilter { if x != nil { return x.InstanceFilter } return nil } func (x *PatchJob) GetPatchConfig() *PatchConfig { if x != nil { return x.PatchConfig } return nil } func (x *PatchJob) GetDuration() *durationpb.Duration { if x != nil { return x.Duration } return nil } func (x *PatchJob) GetInstanceDetailsSummary() *PatchJob_InstanceDetailsSummary { if x != nil { return x.InstanceDetailsSummary } return nil } func (x *PatchJob) GetDryRun() bool { if x != nil { return x.DryRun } return false } func (x *PatchJob) GetErrorMessage() string { if x != nil { return x.ErrorMessage } return "" } func (x *PatchJob) GetPercentComplete() float64 { if x != nil { return x.PercentComplete } return 0 } func (x *PatchJob) GetPatchDeployment() string { if x != nil { return x.PatchDeployment } return "" } func (x *PatchJob) GetRollout() *PatchRollout { if x != nil { return x.Rollout } return nil } // Patch configuration specifications. Contains details on how to apply the // patch(es) to a VM instance. type PatchConfig struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Post-patch reboot settings. RebootConfig PatchConfig_RebootConfig `protobuf:"varint,1,opt,name=reboot_config,json=rebootConfig,proto3,enum=google.cloud.osconfig.v1.PatchConfig_RebootConfig" json:"reboot_config,omitempty"` // Apt update settings. Use this setting to override the default `apt` patch // rules. Apt *AptSettings `protobuf:"bytes,3,opt,name=apt,proto3" json:"apt,omitempty"` // Yum update settings. Use this setting to override the default `yum` patch // rules. Yum *YumSettings `protobuf:"bytes,4,opt,name=yum,proto3" json:"yum,omitempty"` // Goo update settings. Use this setting to override the default `goo` patch // rules. Goo *GooSettings `protobuf:"bytes,5,opt,name=goo,proto3" json:"goo,omitempty"` // Zypper update settings. Use this setting to override the default `zypper` // patch rules. Zypper *ZypperSettings `protobuf:"bytes,6,opt,name=zypper,proto3" json:"zypper,omitempty"` // Windows update settings. Use this override the default windows patch rules. WindowsUpdate *WindowsUpdateSettings `protobuf:"bytes,7,opt,name=windows_update,json=windowsUpdate,proto3" json:"windows_update,omitempty"` // The `ExecStep` to run before the patch update. PreStep *ExecStep `protobuf:"bytes,8,opt,name=pre_step,json=preStep,proto3" json:"pre_step,omitempty"` // The `ExecStep` to run after the patch update. PostStep *ExecStep `protobuf:"bytes,9,opt,name=post_step,json=postStep,proto3" json:"post_step,omitempty"` } func (x *PatchConfig) Reset() { *x = PatchConfig{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *PatchConfig) String() string { return protoimpl.X.MessageStringOf(x) } func (*PatchConfig) ProtoMessage() {} func (x *PatchConfig) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use PatchConfig.ProtoReflect.Descriptor instead. func (*PatchConfig) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{8} } func (x *PatchConfig) GetRebootConfig() PatchConfig_RebootConfig { if x != nil { return x.RebootConfig } return PatchConfig_REBOOT_CONFIG_UNSPECIFIED } func (x *PatchConfig) GetApt() *AptSettings { if x != nil { return x.Apt } return nil } func (x *PatchConfig) GetYum() *YumSettings { if x != nil { return x.Yum } return nil } func (x *PatchConfig) GetGoo() *GooSettings { if x != nil { return x.Goo } return nil } func (x *PatchConfig) GetZypper() *ZypperSettings { if x != nil { return x.Zypper } return nil } func (x *PatchConfig) GetWindowsUpdate() *WindowsUpdateSettings { if x != nil { return x.WindowsUpdate } return nil } func (x *PatchConfig) GetPreStep() *ExecStep { if x != nil { return x.PreStep } return nil } func (x *PatchConfig) GetPostStep() *ExecStep { if x != nil { return x.PostStep } return nil } // Namespace for instance state enums. type Instance struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields } func (x *Instance) Reset() { *x = Instance{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *Instance) String() string { return protoimpl.X.MessageStringOf(x) } func (*Instance) ProtoMessage() {} func (x *Instance) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use Instance.ProtoReflect.Descriptor instead. func (*Instance) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{9} } // Message for canceling a patch job. type CancelPatchJobRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. Name of the patch in the form `projects/*/patchJobs/*` Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } func (x *CancelPatchJobRequest) Reset() { *x = CancelPatchJobRequest{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *CancelPatchJobRequest) String() string { return protoimpl.X.MessageStringOf(x) } func (*CancelPatchJobRequest) ProtoMessage() {} func (x *CancelPatchJobRequest) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use CancelPatchJobRequest.ProtoReflect.Descriptor instead. func (*CancelPatchJobRequest) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{10} } func (x *CancelPatchJobRequest) GetName() string { if x != nil { return x.Name } return "" } // Apt patching is completed by executing `apt-get update && apt-get // upgrade`. Additional options can be set to control how this is executed. type AptSettings struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // By changing the type to DIST, the patching is performed // using `apt-get dist-upgrade` instead. Type AptSettings_Type `protobuf:"varint,1,opt,name=type,proto3,enum=google.cloud.osconfig.v1.AptSettings_Type" json:"type,omitempty"` // List of packages to exclude from update. These packages will be excluded Excludes []string `protobuf:"bytes,2,rep,name=excludes,proto3" json:"excludes,omitempty"` // An exclusive list of packages to be updated. These are the only packages // that will be updated. If these packages are not installed, they will be // ignored. This field cannot be specified with any other patch configuration // fields. ExclusivePackages []string `protobuf:"bytes,3,rep,name=exclusive_packages,json=exclusivePackages,proto3" json:"exclusive_packages,omitempty"` } func (x *AptSettings) Reset() { *x = AptSettings{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *AptSettings) String() string { return protoimpl.X.MessageStringOf(x) } func (*AptSettings) ProtoMessage() {} func (x *AptSettings) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use AptSettings.ProtoReflect.Descriptor instead. func (*AptSettings) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{11} } func (x *AptSettings) GetType() AptSettings_Type { if x != nil { return x.Type } return AptSettings_TYPE_UNSPECIFIED } func (x *AptSettings) GetExcludes() []string { if x != nil { return x.Excludes } return nil } func (x *AptSettings) GetExclusivePackages() []string { if x != nil { return x.ExclusivePackages } return nil } // Yum patching is performed by executing `yum update`. Additional options // can be set to control how this is executed. // // Note that not all settings are supported on all platforms. type YumSettings struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Adds the `--security` flag to `yum update`. Not supported on // all platforms. Security bool `protobuf:"varint,1,opt,name=security,proto3" json:"security,omitempty"` // Will cause patch to run `yum update-minimal` instead. Minimal bool `protobuf:"varint,2,opt,name=minimal,proto3" json:"minimal,omitempty"` // List of packages to exclude from update. These packages are excluded by // using the yum `--exclude` flag. Excludes []string `protobuf:"bytes,3,rep,name=excludes,proto3" json:"excludes,omitempty"` // An exclusive list of packages to be updated. These are the only packages // that will be updated. If these packages are not installed, they will be // ignored. This field must not be specified with any other patch // configuration fields. ExclusivePackages []string `protobuf:"bytes,4,rep,name=exclusive_packages,json=exclusivePackages,proto3" json:"exclusive_packages,omitempty"` } func (x *YumSettings) Reset() { *x = YumSettings{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *YumSettings) String() string { return protoimpl.X.MessageStringOf(x) } func (*YumSettings) ProtoMessage() {} func (x *YumSettings) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use YumSettings.ProtoReflect.Descriptor instead. func (*YumSettings) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{12} } func (x *YumSettings) GetSecurity() bool { if x != nil { return x.Security } return false } func (x *YumSettings) GetMinimal() bool { if x != nil { return x.Minimal } return false } func (x *YumSettings) GetExcludes() []string { if x != nil { return x.Excludes } return nil } func (x *YumSettings) GetExclusivePackages() []string { if x != nil { return x.ExclusivePackages } return nil } // Googet patching is performed by running `googet update`. type GooSettings struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields } func (x *GooSettings) Reset() { *x = GooSettings{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *GooSettings) String() string { return protoimpl.X.MessageStringOf(x) } func (*GooSettings) ProtoMessage() {} func (x *GooSettings) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use GooSettings.ProtoReflect.Descriptor instead. func (*GooSettings) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{13} } // Zypper patching is performed by running `zypper patch`. // See also https://en.opensuse.org/SDB:Zypper_manual. type ZypperSettings struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Adds the `--with-optional` flag to `zypper patch`. WithOptional bool `protobuf:"varint,1,opt,name=with_optional,json=withOptional,proto3" json:"with_optional,omitempty"` // Adds the `--with-update` flag, to `zypper patch`. WithUpdate bool `protobuf:"varint,2,opt,name=with_update,json=withUpdate,proto3" json:"with_update,omitempty"` // Install only patches with these categories. // Common categories include security, recommended, and feature. Categories []string `protobuf:"bytes,3,rep,name=categories,proto3" json:"categories,omitempty"` // Install only patches with these severities. // Common severities include critical, important, moderate, and low. Severities []string `protobuf:"bytes,4,rep,name=severities,proto3" json:"severities,omitempty"` // List of patches to exclude from update. Excludes []string `protobuf:"bytes,5,rep,name=excludes,proto3" json:"excludes,omitempty"` // An exclusive list of patches to be updated. These are the only patches // that will be installed using 'zypper patch patch:' command. // This field must not be used with any other patch configuration fields. ExclusivePatches []string `protobuf:"bytes,6,rep,name=exclusive_patches,json=exclusivePatches,proto3" json:"exclusive_patches,omitempty"` } func (x *ZypperSettings) Reset() { *x = ZypperSettings{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *ZypperSettings) String() string { return protoimpl.X.MessageStringOf(x) } func (*ZypperSettings) ProtoMessage() {} func (x *ZypperSettings) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use ZypperSettings.ProtoReflect.Descriptor instead. func (*ZypperSettings) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{14} } func (x *ZypperSettings) GetWithOptional() bool { if x != nil { return x.WithOptional } return false } func (x *ZypperSettings) GetWithUpdate() bool { if x != nil { return x.WithUpdate } return false } func (x *ZypperSettings) GetCategories() []string { if x != nil { return x.Categories } return nil } func (x *ZypperSettings) GetSeverities() []string { if x != nil { return x.Severities } return nil } func (x *ZypperSettings) GetExcludes() []string { if x != nil { return x.Excludes } return nil } func (x *ZypperSettings) GetExclusivePatches() []string { if x != nil { return x.ExclusivePatches } return nil } // Windows patching is performed using the Windows Update Agent. type WindowsUpdateSettings struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Only apply updates of these windows update classifications. If empty, all // updates are applied. Classifications []WindowsUpdateSettings_Classification `protobuf:"varint,1,rep,packed,name=classifications,proto3,enum=google.cloud.osconfig.v1.WindowsUpdateSettings_Classification" json:"classifications,omitempty"` // List of KBs to exclude from update. Excludes []string `protobuf:"bytes,2,rep,name=excludes,proto3" json:"excludes,omitempty"` // An exclusive list of kbs to be updated. These are the only patches // that will be updated. This field must not be used with other // patch configurations. ExclusivePatches []string `protobuf:"bytes,3,rep,name=exclusive_patches,json=exclusivePatches,proto3" json:"exclusive_patches,omitempty"` } func (x *WindowsUpdateSettings) Reset() { *x = WindowsUpdateSettings{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *WindowsUpdateSettings) String() string { return protoimpl.X.MessageStringOf(x) } func (*WindowsUpdateSettings) ProtoMessage() {} func (x *WindowsUpdateSettings) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use WindowsUpdateSettings.ProtoReflect.Descriptor instead. func (*WindowsUpdateSettings) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{15} } func (x *WindowsUpdateSettings) GetClassifications() []WindowsUpdateSettings_Classification { if x != nil { return x.Classifications } return nil } func (x *WindowsUpdateSettings) GetExcludes() []string { if x != nil { return x.Excludes } return nil } func (x *WindowsUpdateSettings) GetExclusivePatches() []string { if x != nil { return x.ExclusivePatches } return nil } // A step that runs an executable for a PatchJob. type ExecStep struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // The ExecStepConfig for all Linux VMs targeted by the PatchJob. LinuxExecStepConfig *ExecStepConfig `protobuf:"bytes,1,opt,name=linux_exec_step_config,json=linuxExecStepConfig,proto3" json:"linux_exec_step_config,omitempty"` // The ExecStepConfig for all Windows VMs targeted by the PatchJob. WindowsExecStepConfig *ExecStepConfig `protobuf:"bytes,2,opt,name=windows_exec_step_config,json=windowsExecStepConfig,proto3" json:"windows_exec_step_config,omitempty"` } func (x *ExecStep) Reset() { *x = ExecStep{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *ExecStep) String() string { return protoimpl.X.MessageStringOf(x) } func (*ExecStep) ProtoMessage() {} func (x *ExecStep) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use ExecStep.ProtoReflect.Descriptor instead. func (*ExecStep) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{16} } func (x *ExecStep) GetLinuxExecStepConfig() *ExecStepConfig { if x != nil { return x.LinuxExecStepConfig } return nil } func (x *ExecStep) GetWindowsExecStepConfig() *ExecStepConfig { if x != nil { return x.WindowsExecStepConfig } return nil } // Common configurations for an ExecStep. type ExecStepConfig struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Location of the executable. // // Types that are assignable to Executable: // *ExecStepConfig_LocalPath // *ExecStepConfig_GcsObject Executable isExecStepConfig_Executable `protobuf_oneof:"executable"` // Defaults to [0]. A list of possible return values that the // execution can return to indicate a success. AllowedSuccessCodes []int32 `protobuf:"varint,3,rep,packed,name=allowed_success_codes,json=allowedSuccessCodes,proto3" json:"allowed_success_codes,omitempty"` // The script interpreter to use to run the script. If no interpreter is // specified the script will be executed directly, which will likely // only succeed for scripts with [shebang lines] // (https://en.wikipedia.org/wiki/Shebang_\(Unix\)). Interpreter ExecStepConfig_Interpreter `protobuf:"varint,4,opt,name=interpreter,proto3,enum=google.cloud.osconfig.v1.ExecStepConfig_Interpreter" json:"interpreter,omitempty"` } func (x *ExecStepConfig) Reset() { *x = ExecStepConfig{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *ExecStepConfig) String() string { return protoimpl.X.MessageStringOf(x) } func (*ExecStepConfig) ProtoMessage() {} func (x *ExecStepConfig) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use ExecStepConfig.ProtoReflect.Descriptor instead. func (*ExecStepConfig) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{17} } func (m *ExecStepConfig) GetExecutable() isExecStepConfig_Executable { if m != nil { return m.Executable } return nil } func (x *ExecStepConfig) GetLocalPath() string { if x, ok := x.GetExecutable().(*ExecStepConfig_LocalPath); ok { return x.LocalPath } return "" } func (x *ExecStepConfig) GetGcsObject() *GcsObject { if x, ok := x.GetExecutable().(*ExecStepConfig_GcsObject); ok { return x.GcsObject } return nil } func (x *ExecStepConfig) GetAllowedSuccessCodes() []int32 { if x != nil { return x.AllowedSuccessCodes } return nil } func (x *ExecStepConfig) GetInterpreter() ExecStepConfig_Interpreter { if x != nil { return x.Interpreter } return ExecStepConfig_INTERPRETER_UNSPECIFIED } type isExecStepConfig_Executable interface { isExecStepConfig_Executable() } type ExecStepConfig_LocalPath struct { // An absolute path to the executable on the VM. LocalPath string `protobuf:"bytes,1,opt,name=local_path,json=localPath,proto3,oneof"` } type ExecStepConfig_GcsObject struct { // A Cloud Storage object containing the executable. GcsObject *GcsObject `protobuf:"bytes,2,opt,name=gcs_object,json=gcsObject,proto3,oneof"` } func (*ExecStepConfig_LocalPath) isExecStepConfig_Executable() {} func (*ExecStepConfig_GcsObject) isExecStepConfig_Executable() {} // Cloud Storage object representation. type GcsObject struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. Bucket of the Cloud Storage object. Bucket string `protobuf:"bytes,1,opt,name=bucket,proto3" json:"bucket,omitempty"` // Required. Name of the Cloud Storage object. Object string `protobuf:"bytes,2,opt,name=object,proto3" json:"object,omitempty"` // Required. Generation number of the Cloud Storage object. This is used to // ensure that the ExecStep specified by this PatchJob does not change. GenerationNumber int64 `protobuf:"varint,3,opt,name=generation_number,json=generationNumber,proto3" json:"generation_number,omitempty"` } func (x *GcsObject) Reset() { *x = GcsObject{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *GcsObject) String() string { return protoimpl.X.MessageStringOf(x) } func (*GcsObject) ProtoMessage() {} func (x *GcsObject) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use GcsObject.ProtoReflect.Descriptor instead. func (*GcsObject) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{18} } func (x *GcsObject) GetBucket() string { if x != nil { return x.Bucket } return "" } func (x *GcsObject) GetObject() string { if x != nil { return x.Object } return "" } func (x *GcsObject) GetGenerationNumber() int64 { if x != nil { return x.GenerationNumber } return 0 } // A filter to target VM instances for patching. The targeted // VMs must meet all criteria specified. So if both labels and zones are // specified, the patch job targets only VMs with those labels and in those // zones. type PatchInstanceFilter struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Target all VM instances in the project. If true, no other criteria is // permitted. All bool `protobuf:"varint,1,opt,name=all,proto3" json:"all,omitempty"` // Targets VM instances matching ANY of these GroupLabels. This allows // targeting of disparate groups of VM instances. GroupLabels []*PatchInstanceFilter_GroupLabel `protobuf:"bytes,2,rep,name=group_labels,json=groupLabels,proto3" json:"group_labels,omitempty"` // Targets VM instances in ANY of these zones. Leave empty to target VM // instances in any zone. Zones []string `protobuf:"bytes,3,rep,name=zones,proto3" json:"zones,omitempty"` // Targets any of the VM instances specified. Instances are specified by their // URI in the form `zones/[ZONE]/instances/[INSTANCE_NAME]`, // `projects/[PROJECT_ID]/zones/[ZONE]/instances/[INSTANCE_NAME]`, or // `https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances/[INSTANCE_NAME]` Instances []string `protobuf:"bytes,4,rep,name=instances,proto3" json:"instances,omitempty"` // Targets VMs whose name starts with one of these prefixes. Similar to // labels, this is another way to group VMs when targeting configs, for // example prefix="prod-". InstanceNamePrefixes []string `protobuf:"bytes,5,rep,name=instance_name_prefixes,json=instanceNamePrefixes,proto3" json:"instance_name_prefixes,omitempty"` } func (x *PatchInstanceFilter) Reset() { *x = PatchInstanceFilter{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *PatchInstanceFilter) String() string { return protoimpl.X.MessageStringOf(x) } func (*PatchInstanceFilter) ProtoMessage() {} func (x *PatchInstanceFilter) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use PatchInstanceFilter.ProtoReflect.Descriptor instead. func (*PatchInstanceFilter) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{19} } func (x *PatchInstanceFilter) GetAll() bool { if x != nil { return x.All } return false } func (x *PatchInstanceFilter) GetGroupLabels() []*PatchInstanceFilter_GroupLabel { if x != nil { return x.GroupLabels } return nil } func (x *PatchInstanceFilter) GetZones() []string { if x != nil { return x.Zones } return nil } func (x *PatchInstanceFilter) GetInstances() []string { if x != nil { return x.Instances } return nil } func (x *PatchInstanceFilter) GetInstanceNamePrefixes() []string { if x != nil { return x.InstanceNamePrefixes } return nil } // Patch rollout configuration specifications. Contains details on the // concurrency control when applying patch(es) to all targeted VMs. type PatchRollout struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Mode of the patch rollout. Mode PatchRollout_Mode `protobuf:"varint,1,opt,name=mode,proto3,enum=google.cloud.osconfig.v1.PatchRollout_Mode" json:"mode,omitempty"` // The maximum number (or percentage) of VMs per zone to disrupt at any given // moment. The number of VMs calculated from multiplying the percentage by the // total number of VMs in a zone is rounded up. // // During patching, a VM is considered disrupted from the time the agent is // notified to begin until patching has completed. This disruption time // includes the time to complete reboot and any post-patch steps. // // A VM contributes to the disruption budget if its patching operation fails // either when applying the patches, running pre or post patch steps, or if it // fails to respond with a success notification before timing out. VMs that // are not running or do not have an active agent do not count toward this // disruption budget. // // For zone-by-zone rollouts, if the disruption budget in a zone is exceeded, // the patch job stops, because continuing to the next zone requires // completion of the patch process in the previous zone. // // For example, if the disruption budget has a fixed value of `10`, and 8 VMs // fail to patch in the current zone, the patch job continues to patch 2 VMs // at a time until the zone is completed. When that zone is completed // successfully, patching begins with 10 VMs at a time in the next zone. If 10 // VMs in the next zone fail to patch, the patch job stops. DisruptionBudget *FixedOrPercent `protobuf:"bytes,2,opt,name=disruption_budget,json=disruptionBudget,proto3" json:"disruption_budget,omitempty"` } func (x *PatchRollout) Reset() { *x = PatchRollout{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *PatchRollout) String() string { return protoimpl.X.MessageStringOf(x) } func (*PatchRollout) ProtoMessage() {} func (x *PatchRollout) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use PatchRollout.ProtoReflect.Descriptor instead. func (*PatchRollout) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{20} } func (x *PatchRollout) GetMode() PatchRollout_Mode { if x != nil { return x.Mode } return PatchRollout_MODE_UNSPECIFIED } func (x *PatchRollout) GetDisruptionBudget() *FixedOrPercent { if x != nil { return x.DisruptionBudget } return nil } // A summary of the current patch state across all instances that this patch // job affects. Contains counts of instances in different states. These states // map to `InstancePatchState`. List patch job instance details to see the // specific states of each instance. type PatchJob_InstanceDetailsSummary struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Number of instances pending patch job. PendingInstanceCount int64 `protobuf:"varint,1,opt,name=pending_instance_count,json=pendingInstanceCount,proto3" json:"pending_instance_count,omitempty"` // Number of instances that are inactive. InactiveInstanceCount int64 `protobuf:"varint,2,opt,name=inactive_instance_count,json=inactiveInstanceCount,proto3" json:"inactive_instance_count,omitempty"` // Number of instances notified about patch job. NotifiedInstanceCount int64 `protobuf:"varint,3,opt,name=notified_instance_count,json=notifiedInstanceCount,proto3" json:"notified_instance_count,omitempty"` // Number of instances that have started. StartedInstanceCount int64 `protobuf:"varint,4,opt,name=started_instance_count,json=startedInstanceCount,proto3" json:"started_instance_count,omitempty"` // Number of instances that are downloading patches. DownloadingPatchesInstanceCount int64 `protobuf:"varint,5,opt,name=downloading_patches_instance_count,json=downloadingPatchesInstanceCount,proto3" json:"downloading_patches_instance_count,omitempty"` // Number of instances that are applying patches. ApplyingPatchesInstanceCount int64 `protobuf:"varint,6,opt,name=applying_patches_instance_count,json=applyingPatchesInstanceCount,proto3" json:"applying_patches_instance_count,omitempty"` // Number of instances rebooting. RebootingInstanceCount int64 `protobuf:"varint,7,opt,name=rebooting_instance_count,json=rebootingInstanceCount,proto3" json:"rebooting_instance_count,omitempty"` // Number of instances that have completed successfully. SucceededInstanceCount int64 `protobuf:"varint,8,opt,name=succeeded_instance_count,json=succeededInstanceCount,proto3" json:"succeeded_instance_count,omitempty"` // Number of instances that require reboot. SucceededRebootRequiredInstanceCount int64 `protobuf:"varint,9,opt,name=succeeded_reboot_required_instance_count,json=succeededRebootRequiredInstanceCount,proto3" json:"succeeded_reboot_required_instance_count,omitempty"` // Number of instances that failed. FailedInstanceCount int64 `protobuf:"varint,10,opt,name=failed_instance_count,json=failedInstanceCount,proto3" json:"failed_instance_count,omitempty"` // Number of instances that have acked and will start shortly. AckedInstanceCount int64 `protobuf:"varint,11,opt,name=acked_instance_count,json=ackedInstanceCount,proto3" json:"acked_instance_count,omitempty"` // Number of instances that exceeded the time out while applying the patch. TimedOutInstanceCount int64 `protobuf:"varint,12,opt,name=timed_out_instance_count,json=timedOutInstanceCount,proto3" json:"timed_out_instance_count,omitempty"` // Number of instances that are running the pre-patch step. PrePatchStepInstanceCount int64 `protobuf:"varint,13,opt,name=pre_patch_step_instance_count,json=prePatchStepInstanceCount,proto3" json:"pre_patch_step_instance_count,omitempty"` // Number of instances that are running the post-patch step. PostPatchStepInstanceCount int64 `protobuf:"varint,14,opt,name=post_patch_step_instance_count,json=postPatchStepInstanceCount,proto3" json:"post_patch_step_instance_count,omitempty"` // Number of instances that do not appear to be running the agent. Check to // ensure that the agent is installed, running, and able to communicate with // the service. NoAgentDetectedInstanceCount int64 `protobuf:"varint,15,opt,name=no_agent_detected_instance_count,json=noAgentDetectedInstanceCount,proto3" json:"no_agent_detected_instance_count,omitempty"` } func (x *PatchJob_InstanceDetailsSummary) Reset() { *x = PatchJob_InstanceDetailsSummary{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *PatchJob_InstanceDetailsSummary) String() string { return protoimpl.X.MessageStringOf(x) } func (*PatchJob_InstanceDetailsSummary) ProtoMessage() {} func (x *PatchJob_InstanceDetailsSummary) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use PatchJob_InstanceDetailsSummary.ProtoReflect.Descriptor instead. func (*PatchJob_InstanceDetailsSummary) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{7, 0} } func (x *PatchJob_InstanceDetailsSummary) GetPendingInstanceCount() int64 { if x != nil { return x.PendingInstanceCount } return 0 } func (x *PatchJob_InstanceDetailsSummary) GetInactiveInstanceCount() int64 { if x != nil { return x.InactiveInstanceCount } return 0 } func (x *PatchJob_InstanceDetailsSummary) GetNotifiedInstanceCount() int64 { if x != nil { return x.NotifiedInstanceCount } return 0 } func (x *PatchJob_InstanceDetailsSummary) GetStartedInstanceCount() int64 { if x != nil { return x.StartedInstanceCount } return 0 } func (x *PatchJob_InstanceDetailsSummary) GetDownloadingPatchesInstanceCount() int64 { if x != nil { return x.DownloadingPatchesInstanceCount } return 0 } func (x *PatchJob_InstanceDetailsSummary) GetApplyingPatchesInstanceCount() int64 { if x != nil { return x.ApplyingPatchesInstanceCount } return 0 } func (x *PatchJob_InstanceDetailsSummary) GetRebootingInstanceCount() int64 { if x != nil { return x.RebootingInstanceCount } return 0 } func (x *PatchJob_InstanceDetailsSummary) GetSucceededInstanceCount() int64 { if x != nil { return x.SucceededInstanceCount } return 0 } func (x *PatchJob_InstanceDetailsSummary) GetSucceededRebootRequiredInstanceCount() int64 { if x != nil { return x.SucceededRebootRequiredInstanceCount } return 0 } func (x *PatchJob_InstanceDetailsSummary) GetFailedInstanceCount() int64 { if x != nil { return x.FailedInstanceCount } return 0 } func (x *PatchJob_InstanceDetailsSummary) GetAckedInstanceCount() int64 { if x != nil { return x.AckedInstanceCount } return 0 } func (x *PatchJob_InstanceDetailsSummary) GetTimedOutInstanceCount() int64 { if x != nil { return x.TimedOutInstanceCount } return 0 } func (x *PatchJob_InstanceDetailsSummary) GetPrePatchStepInstanceCount() int64 { if x != nil { return x.PrePatchStepInstanceCount } return 0 } func (x *PatchJob_InstanceDetailsSummary) GetPostPatchStepInstanceCount() int64 { if x != nil { return x.PostPatchStepInstanceCount } return 0 } func (x *PatchJob_InstanceDetailsSummary) GetNoAgentDetectedInstanceCount() int64 { if x != nil { return x.NoAgentDetectedInstanceCount } return 0 } // Targets a group of VM instances by using their [assigned // labels](https://cloud.google.com/compute/docs/labeling-resources). Labels // are key-value pairs. A `GroupLabel` is a combination of labels // that is used to target VMs for a patch job. // // For example, a patch job can target VMs that have the following // `GroupLabel`: `{"env":"test", "app":"web"}`. This means that the patch job // is applied to VMs that have both the labels `env=test` and `app=web`. type PatchInstanceFilter_GroupLabel struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Compute Engine instance labels that must be present for a VM // instance to be targeted by this filter. Labels map[string]string `protobuf:"bytes,1,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *PatchInstanceFilter_GroupLabel) Reset() { *x = PatchInstanceFilter_GroupLabel{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *PatchInstanceFilter_GroupLabel) String() string { return protoimpl.X.MessageStringOf(x) } func (*PatchInstanceFilter_GroupLabel) ProtoMessage() {} func (x *PatchInstanceFilter_GroupLabel) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use PatchInstanceFilter_GroupLabel.ProtoReflect.Descriptor instead. func (*PatchInstanceFilter_GroupLabel) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP(), []int{19, 0} } func (x *PatchInstanceFilter_GroupLabel) GetLabels() map[string]string { if x != nil { return x.Labels } return nil } var File_google_cloud_osconfig_v1_patch_jobs_proto protoreflect.FileDescriptor var file_google_cloud_osconfig_v1_patch_jobs_proto_rawDesc = []byte{ 0x0a, 0x29, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6a, 0x6f, 0x62, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x18, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe3, 0x03, 0x0a, 0x16, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4b, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x33, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x2d, 0x0a, 0x2b, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x5b, 0x0a, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x48, 0x0a, 0x0c, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0b, 0x70, 0x61, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x35, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x40, 0x0a, 0x07, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x52, 0x07, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x22, 0x52, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x28, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x22, 0x0a, 0x20, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xba, 0x01, 0x0a, 0x22, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x28, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x22, 0x0a, 0x20, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0xbd, 0x01, 0x0a, 0x23, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x1a, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x17, 0x70, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x92, 0x02, 0x0a, 0x17, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x38, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x24, 0xfa, 0x41, 0x21, 0x0a, 0x1f, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x43, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xb7, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4b, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x33, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x2d, 0x0a, 0x2b, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x82, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0a, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6a, 0x6f, 0x62, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x09, 0x70, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x9f, 0x10, 0x0a, 0x08, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3b, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x56, 0x0a, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x48, 0x0a, 0x0c, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0b, 0x70, 0x61, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x35, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x73, 0x0a, 0x18, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x16, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x5a, 0x0a, 0x10, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2f, 0xe0, 0x41, 0x03, 0xfa, 0x41, 0x29, 0x0a, 0x27, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x0f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x40, 0x0a, 0x07, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x52, 0x07, 0x72, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x1a, 0xc1, 0x07, 0x0a, 0x16, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x34, 0x0a, 0x16, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x14, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x36, 0x0a, 0x17, 0x69, 0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x69, 0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x36, 0x0a, 0x17, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x34, 0x0a, 0x16, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x14, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x4b, 0x0a, 0x22, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x45, 0x0a, 0x1f, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1c, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x69, 0x6e, 0x67, 0x50, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x38, 0x0a, 0x18, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x16, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x38, 0x0a, 0x18, 0x73, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x16, 0x73, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x56, 0x0a, 0x28, 0x73, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x24, 0x73, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x52, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x32, 0x0a, 0x15, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x13, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x30, 0x0a, 0x14, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x37, 0x0a, 0x18, 0x74, 0x69, 0x6d, 0x65, 0x64, 0x5f, 0x6f, 0x75, 0x74, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x74, 0x69, 0x6d, 0x65, 0x64, 0x4f, 0x75, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x40, 0x0a, 0x1d, 0x70, 0x72, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x03, 0x52, 0x19, 0x70, 0x72, 0x65, 0x50, 0x61, 0x74, 0x63, 0x68, 0x53, 0x74, 0x65, 0x70, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x42, 0x0a, 0x1e, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1a, 0x70, 0x6f, 0x73, 0x74, 0x50, 0x61, 0x74, 0x63, 0x68, 0x53, 0x74, 0x65, 0x70, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x46, 0x0a, 0x20, 0x6e, 0x6f, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x64, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1c, 0x6e, 0x6f, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x95, 0x01, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x54, 0x41, 0x52, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x4c, 0x4f, 0x4f, 0x4b, 0x55, 0x50, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x41, 0x54, 0x43, 0x48, 0x49, 0x4e, 0x47, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x55, 0x43, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, 0x04, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x53, 0x10, 0x05, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x45, 0x44, 0x10, 0x06, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x49, 0x4d, 0x45, 0x44, 0x5f, 0x4f, 0x55, 0x54, 0x10, 0x07, 0x3a, 0x4f, 0xea, 0x41, 0x4c, 0x0a, 0x20, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x12, 0x28, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x7d, 0x2f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x73, 0x2f, 0x7b, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6a, 0x6f, 0x62, 0x7d, 0x22, 0xfe, 0x04, 0x0a, 0x0b, 0x50, 0x61, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x57, 0x0a, 0x0d, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x32, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x52, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0c, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x37, 0x0a, 0x03, 0x61, 0x70, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x70, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x03, 0x61, 0x70, 0x74, 0x12, 0x37, 0x0a, 0x03, 0x79, 0x75, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x59, 0x75, 0x6d, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x03, 0x79, 0x75, 0x6d, 0x12, 0x37, 0x0a, 0x03, 0x67, 0x6f, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6f, 0x6f, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x03, 0x67, 0x6f, 0x6f, 0x12, 0x40, 0x0a, 0x06, 0x7a, 0x79, 0x70, 0x70, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x5a, 0x79, 0x70, 0x70, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x06, 0x7a, 0x79, 0x70, 0x70, 0x65, 0x72, 0x12, 0x56, 0x0a, 0x0e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x0d, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x3d, 0x0a, 0x08, 0x70, 0x72, 0x65, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x53, 0x74, 0x65, 0x70, 0x52, 0x07, 0x70, 0x72, 0x65, 0x53, 0x74, 0x65, 0x70, 0x12, 0x3f, 0x0a, 0x09, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x53, 0x74, 0x65, 0x70, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x22, 0x51, 0x0a, 0x0c, 0x52, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x42, 0x4f, 0x4f, 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x4c, 0x57, 0x41, 0x59, 0x53, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x4e, 0x45, 0x56, 0x45, 0x52, 0x10, 0x03, 0x22, 0xce, 0x02, 0x0a, 0x08, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x22, 0xc1, 0x02, 0x0a, 0x0a, 0x50, 0x61, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x50, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x4e, 0x4f, 0x54, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x54, 0x41, 0x52, 0x54, 0x45, 0x44, 0x10, 0x04, 0x12, 0x17, 0x0a, 0x13, 0x44, 0x4f, 0x57, 0x4e, 0x4c, 0x4f, 0x41, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x50, 0x41, 0x54, 0x43, 0x48, 0x45, 0x53, 0x10, 0x05, 0x12, 0x14, 0x0a, 0x10, 0x41, 0x50, 0x50, 0x4c, 0x59, 0x49, 0x4e, 0x47, 0x5f, 0x50, 0x41, 0x54, 0x43, 0x48, 0x45, 0x53, 0x10, 0x06, 0x12, 0x0d, 0x0a, 0x09, 0x52, 0x45, 0x42, 0x4f, 0x4f, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x07, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x55, 0x43, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, 0x08, 0x12, 0x1d, 0x0a, 0x19, 0x53, 0x55, 0x43, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x5f, 0x52, 0x45, 0x42, 0x4f, 0x4f, 0x54, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x44, 0x10, 0x09, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x0a, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x43, 0x4b, 0x45, 0x44, 0x10, 0x0b, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x49, 0x4d, 0x45, 0x44, 0x5f, 0x4f, 0x55, 0x54, 0x10, 0x0c, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x5f, 0x50, 0x52, 0x45, 0x5f, 0x50, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x10, 0x0d, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x5f, 0x50, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x10, 0x0e, 0x12, 0x15, 0x0a, 0x11, 0x4e, 0x4f, 0x5f, 0x41, 0x47, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x54, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x0f, 0x22, 0x55, 0x0a, 0x15, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x28, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x22, 0x0a, 0x20, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xcd, 0x01, 0x0a, 0x0b, 0x41, 0x70, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x3e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x70, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x22, 0x33, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x49, 0x53, 0x54, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x50, 0x47, 0x52, 0x41, 0x44, 0x45, 0x10, 0x02, 0x22, 0x8e, 0x01, 0x0a, 0x0b, 0x59, 0x75, 0x6d, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x22, 0x0d, 0x0a, 0x0b, 0x47, 0x6f, 0x6f, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0xdf, 0x01, 0x0a, 0x0e, 0x5a, 0x79, 0x70, 0x70, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x77, 0x69, 0x74, 0x68, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x77, 0x69, 0x74, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x50, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x22, 0x82, 0x03, 0x0a, 0x15, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x68, 0x0a, 0x0f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x3e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x50, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x22, 0xb5, 0x01, 0x0a, 0x0e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x1a, 0x43, 0x4c, 0x41, 0x53, 0x53, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x52, 0x49, 0x54, 0x49, 0x43, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x45, 0x43, 0x55, 0x52, 0x49, 0x54, 0x59, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x45, 0x46, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x52, 0x49, 0x56, 0x45, 0x52, 0x10, 0x04, 0x12, 0x10, 0x0a, 0x0c, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x10, 0x05, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x10, 0x06, 0x12, 0x08, 0x0a, 0x04, 0x54, 0x4f, 0x4f, 0x4c, 0x10, 0x07, 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x52, 0x4f, 0x4c, 0x4c, 0x55, 0x50, 0x10, 0x08, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x09, 0x22, 0xcc, 0x01, 0x0a, 0x08, 0x45, 0x78, 0x65, 0x63, 0x53, 0x74, 0x65, 0x70, 0x12, 0x5d, 0x0a, 0x16, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x53, 0x74, 0x65, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x13, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x45, 0x78, 0x65, 0x63, 0x53, 0x74, 0x65, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x61, 0x0a, 0x18, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x53, 0x74, 0x65, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x15, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x45, 0x78, 0x65, 0x63, 0x53, 0x74, 0x65, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0xd8, 0x02, 0x0a, 0x0e, 0x45, 0x78, 0x65, 0x63, 0x53, 0x74, 0x65, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1f, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x12, 0x44, 0x0a, 0x0a, 0x67, 0x63, 0x73, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x63, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x48, 0x00, 0x52, 0x09, 0x67, 0x63, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x32, 0x0a, 0x15, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x05, 0x52, 0x13, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x56, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x53, 0x74, 0x65, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x72, 0x52, 0x0b, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x72, 0x22, 0x45, 0x0a, 0x0b, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x17, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x50, 0x52, 0x45, 0x54, 0x45, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x48, 0x45, 0x4c, 0x4c, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x4f, 0x57, 0x45, 0x52, 0x53, 0x48, 0x45, 0x4c, 0x4c, 0x10, 0x02, 0x42, 0x0c, 0x0a, 0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x77, 0x0a, 0x09, 0x47, 0x63, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1b, 0x0a, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x1b, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x30, 0x0a, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x10, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x96, 0x03, 0x0a, 0x13, 0x50, 0x61, 0x74, 0x63, 0x68, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x6c, 0x6c, 0x12, 0x5b, 0x0a, 0x0c, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x52, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x7a, 0x6f, 0x6e, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x7a, 0x6f, 0x6e, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x14, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x65, 0x73, 0x1a, 0xa5, 0x01, 0x0a, 0x0a, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x5c, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x44, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xec, 0x01, 0x0a, 0x0c, 0x50, 0x61, 0x74, 0x63, 0x68, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x12, 0x3f, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x52, 0x6f, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x55, 0x0a, 0x11, 0x64, 0x69, 0x73, 0x72, 0x75, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x78, 0x65, 0x64, 0x4f, 0x72, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x52, 0x10, 0x64, 0x69, 0x73, 0x72, 0x75, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x75, 0x64, 0x67, 0x65, 0x74, 0x22, 0x44, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x5a, 0x4f, 0x4e, 0x45, 0x5f, 0x42, 0x59, 0x5f, 0x5a, 0x4f, 0x4e, 0x45, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x4f, 0x4e, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e, 0x54, 0x5f, 0x5a, 0x4f, 0x4e, 0x45, 0x53, 0x10, 0x02, 0x42, 0xbf, 0x01, 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x42, 0x09, 0x50, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x73, 0x5a, 0x40, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x3b, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0xaa, 0x02, 0x18, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x18, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5c, 0x56, 0x31, 0xea, 0x02, 0x1b, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescOnce sync.Once file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescData = file_google_cloud_osconfig_v1_patch_jobs_proto_rawDesc ) func file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescGZIP() []byte { file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescOnce.Do(func() { file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescData) }) return file_google_cloud_osconfig_v1_patch_jobs_proto_rawDescData } var file_google_cloud_osconfig_v1_patch_jobs_proto_enumTypes = make([]protoimpl.EnumInfo, 7) var file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes = make([]protoimpl.MessageInfo, 24) var file_google_cloud_osconfig_v1_patch_jobs_proto_goTypes = []interface{}{ (PatchJob_State)(0), // 0: google.cloud.osconfig.v1.PatchJob.State (PatchConfig_RebootConfig)(0), // 1: google.cloud.osconfig.v1.PatchConfig.RebootConfig (Instance_PatchState)(0), // 2: google.cloud.osconfig.v1.Instance.PatchState (AptSettings_Type)(0), // 3: google.cloud.osconfig.v1.AptSettings.Type (WindowsUpdateSettings_Classification)(0), // 4: google.cloud.osconfig.v1.WindowsUpdateSettings.Classification (ExecStepConfig_Interpreter)(0), // 5: google.cloud.osconfig.v1.ExecStepConfig.Interpreter (PatchRollout_Mode)(0), // 6: google.cloud.osconfig.v1.PatchRollout.Mode (*ExecutePatchJobRequest)(nil), // 7: google.cloud.osconfig.v1.ExecutePatchJobRequest (*GetPatchJobRequest)(nil), // 8: google.cloud.osconfig.v1.GetPatchJobRequest (*ListPatchJobInstanceDetailsRequest)(nil), // 9: google.cloud.osconfig.v1.ListPatchJobInstanceDetailsRequest (*ListPatchJobInstanceDetailsResponse)(nil), // 10: google.cloud.osconfig.v1.ListPatchJobInstanceDetailsResponse (*PatchJobInstanceDetails)(nil), // 11: google.cloud.osconfig.v1.PatchJobInstanceDetails (*ListPatchJobsRequest)(nil), // 12: google.cloud.osconfig.v1.ListPatchJobsRequest (*ListPatchJobsResponse)(nil), // 13: google.cloud.osconfig.v1.ListPatchJobsResponse (*PatchJob)(nil), // 14: google.cloud.osconfig.v1.PatchJob (*PatchConfig)(nil), // 15: google.cloud.osconfig.v1.PatchConfig (*Instance)(nil), // 16: google.cloud.osconfig.v1.Instance (*CancelPatchJobRequest)(nil), // 17: google.cloud.osconfig.v1.CancelPatchJobRequest (*AptSettings)(nil), // 18: google.cloud.osconfig.v1.AptSettings (*YumSettings)(nil), // 19: google.cloud.osconfig.v1.YumSettings (*GooSettings)(nil), // 20: google.cloud.osconfig.v1.GooSettings (*ZypperSettings)(nil), // 21: google.cloud.osconfig.v1.ZypperSettings (*WindowsUpdateSettings)(nil), // 22: google.cloud.osconfig.v1.WindowsUpdateSettings (*ExecStep)(nil), // 23: google.cloud.osconfig.v1.ExecStep (*ExecStepConfig)(nil), // 24: google.cloud.osconfig.v1.ExecStepConfig (*GcsObject)(nil), // 25: google.cloud.osconfig.v1.GcsObject (*PatchInstanceFilter)(nil), // 26: google.cloud.osconfig.v1.PatchInstanceFilter (*PatchRollout)(nil), // 27: google.cloud.osconfig.v1.PatchRollout (*PatchJob_InstanceDetailsSummary)(nil), // 28: google.cloud.osconfig.v1.PatchJob.InstanceDetailsSummary (*PatchInstanceFilter_GroupLabel)(nil), // 29: google.cloud.osconfig.v1.PatchInstanceFilter.GroupLabel nil, // 30: google.cloud.osconfig.v1.PatchInstanceFilter.GroupLabel.LabelsEntry (*durationpb.Duration)(nil), // 31: google.protobuf.Duration (*timestamppb.Timestamp)(nil), // 32: google.protobuf.Timestamp (*FixedOrPercent)(nil), // 33: google.cloud.osconfig.v1.FixedOrPercent } var file_google_cloud_osconfig_v1_patch_jobs_proto_depIdxs = []int32{ 26, // 0: google.cloud.osconfig.v1.ExecutePatchJobRequest.instance_filter:type_name -> google.cloud.osconfig.v1.PatchInstanceFilter 15, // 1: google.cloud.osconfig.v1.ExecutePatchJobRequest.patch_config:type_name -> google.cloud.osconfig.v1.PatchConfig 31, // 2: google.cloud.osconfig.v1.ExecutePatchJobRequest.duration:type_name -> google.protobuf.Duration 27, // 3: google.cloud.osconfig.v1.ExecutePatchJobRequest.rollout:type_name -> google.cloud.osconfig.v1.PatchRollout 11, // 4: google.cloud.osconfig.v1.ListPatchJobInstanceDetailsResponse.patch_job_instance_details:type_name -> google.cloud.osconfig.v1.PatchJobInstanceDetails 2, // 5: google.cloud.osconfig.v1.PatchJobInstanceDetails.state:type_name -> google.cloud.osconfig.v1.Instance.PatchState 14, // 6: google.cloud.osconfig.v1.ListPatchJobsResponse.patch_jobs:type_name -> google.cloud.osconfig.v1.PatchJob 32, // 7: google.cloud.osconfig.v1.PatchJob.create_time:type_name -> google.protobuf.Timestamp 32, // 8: google.cloud.osconfig.v1.PatchJob.update_time:type_name -> google.protobuf.Timestamp 0, // 9: google.cloud.osconfig.v1.PatchJob.state:type_name -> google.cloud.osconfig.v1.PatchJob.State 26, // 10: google.cloud.osconfig.v1.PatchJob.instance_filter:type_name -> google.cloud.osconfig.v1.PatchInstanceFilter 15, // 11: google.cloud.osconfig.v1.PatchJob.patch_config:type_name -> google.cloud.osconfig.v1.PatchConfig 31, // 12: google.cloud.osconfig.v1.PatchJob.duration:type_name -> google.protobuf.Duration 28, // 13: google.cloud.osconfig.v1.PatchJob.instance_details_summary:type_name -> google.cloud.osconfig.v1.PatchJob.InstanceDetailsSummary 27, // 14: google.cloud.osconfig.v1.PatchJob.rollout:type_name -> google.cloud.osconfig.v1.PatchRollout 1, // 15: google.cloud.osconfig.v1.PatchConfig.reboot_config:type_name -> google.cloud.osconfig.v1.PatchConfig.RebootConfig 18, // 16: google.cloud.osconfig.v1.PatchConfig.apt:type_name -> google.cloud.osconfig.v1.AptSettings 19, // 17: google.cloud.osconfig.v1.PatchConfig.yum:type_name -> google.cloud.osconfig.v1.YumSettings 20, // 18: google.cloud.osconfig.v1.PatchConfig.goo:type_name -> google.cloud.osconfig.v1.GooSettings 21, // 19: google.cloud.osconfig.v1.PatchConfig.zypper:type_name -> google.cloud.osconfig.v1.ZypperSettings 22, // 20: google.cloud.osconfig.v1.PatchConfig.windows_update:type_name -> google.cloud.osconfig.v1.WindowsUpdateSettings 23, // 21: google.cloud.osconfig.v1.PatchConfig.pre_step:type_name -> google.cloud.osconfig.v1.ExecStep 23, // 22: google.cloud.osconfig.v1.PatchConfig.post_step:type_name -> google.cloud.osconfig.v1.ExecStep 3, // 23: google.cloud.osconfig.v1.AptSettings.type:type_name -> google.cloud.osconfig.v1.AptSettings.Type 4, // 24: google.cloud.osconfig.v1.WindowsUpdateSettings.classifications:type_name -> google.cloud.osconfig.v1.WindowsUpdateSettings.Classification 24, // 25: google.cloud.osconfig.v1.ExecStep.linux_exec_step_config:type_name -> google.cloud.osconfig.v1.ExecStepConfig 24, // 26: google.cloud.osconfig.v1.ExecStep.windows_exec_step_config:type_name -> google.cloud.osconfig.v1.ExecStepConfig 25, // 27: google.cloud.osconfig.v1.ExecStepConfig.gcs_object:type_name -> google.cloud.osconfig.v1.GcsObject 5, // 28: google.cloud.osconfig.v1.ExecStepConfig.interpreter:type_name -> google.cloud.osconfig.v1.ExecStepConfig.Interpreter 29, // 29: google.cloud.osconfig.v1.PatchInstanceFilter.group_labels:type_name -> google.cloud.osconfig.v1.PatchInstanceFilter.GroupLabel 6, // 30: google.cloud.osconfig.v1.PatchRollout.mode:type_name -> google.cloud.osconfig.v1.PatchRollout.Mode 33, // 31: google.cloud.osconfig.v1.PatchRollout.disruption_budget:type_name -> google.cloud.osconfig.v1.FixedOrPercent 30, // 32: google.cloud.osconfig.v1.PatchInstanceFilter.GroupLabel.labels:type_name -> google.cloud.osconfig.v1.PatchInstanceFilter.GroupLabel.LabelsEntry 33, // [33:33] is the sub-list for method output_type 33, // [33:33] is the sub-list for method input_type 33, // [33:33] is the sub-list for extension type_name 33, // [33:33] is the sub-list for extension extendee 0, // [0:33] is the sub-list for field type_name } func init() { file_google_cloud_osconfig_v1_patch_jobs_proto_init() } func file_google_cloud_osconfig_v1_patch_jobs_proto_init() { if File_google_cloud_osconfig_v1_patch_jobs_proto != nil { return } file_google_cloud_osconfig_v1_osconfig_common_proto_init() if !protoimpl.UnsafeEnabled { file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ExecutePatchJobRequest); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetPatchJobRequest); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListPatchJobInstanceDetailsRequest); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListPatchJobInstanceDetailsResponse); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PatchJobInstanceDetails); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListPatchJobsRequest); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListPatchJobsResponse); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PatchJob); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PatchConfig); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Instance); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CancelPatchJobRequest); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AptSettings); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*YumSettings); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GooSettings); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ZypperSettings); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WindowsUpdateSettings); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ExecStep); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ExecStepConfig); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GcsObject); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PatchInstanceFilter); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PatchRollout); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PatchJob_InstanceDetailsSummary); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PatchInstanceFilter_GroupLabel); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } } file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes[17].OneofWrappers = []interface{}{ (*ExecStepConfig_LocalPath)(nil), (*ExecStepConfig_GcsObject)(nil), } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_google_cloud_osconfig_v1_patch_jobs_proto_rawDesc, NumEnums: 7, NumMessages: 24, NumExtensions: 0, NumServices: 0, }, GoTypes: file_google_cloud_osconfig_v1_patch_jobs_proto_goTypes, DependencyIndexes: file_google_cloud_osconfig_v1_patch_jobs_proto_depIdxs, EnumInfos: file_google_cloud_osconfig_v1_patch_jobs_proto_enumTypes, MessageInfos: file_google_cloud_osconfig_v1_patch_jobs_proto_msgTypes, }.Build() File_google_cloud_osconfig_v1_patch_jobs_proto = out.File file_google_cloud_osconfig_v1_patch_jobs_proto_rawDesc = nil file_google_cloud_osconfig_v1_patch_jobs_proto_goTypes = nil file_google_cloud_osconfig_v1_patch_jobs_proto_depIdxs = nil } vulnerability.pb.go000066400000000000000000002027411477773331400360470ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/internal/google.golang.org/genproto/googleapis/cloud/osconfig/v1// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.25.0 // protoc v3.15.3 // source: google/cloud/osconfig/v1/vulnerability.proto package osconfig import ( proto "github.com/golang/protobuf/proto" _ "google.golang.org/genproto/googleapis/api/annotations" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" ) const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) // Verify that runtime/protoimpl is sufficiently up-to-date. _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) // This is a compile-time assertion that a sufficiently up-to-date version // of the legacy proto package is being used. const _ = proto.ProtoPackageIsVersion4 // This metric reflects the context by which vulnerability exploitation is // possible. type CVSSv3_AttackVector int32 const ( // Invalid value. CVSSv3_ATTACK_VECTOR_UNSPECIFIED CVSSv3_AttackVector = 0 // The vulnerable component is bound to the network stack and the set of // possible attackers extends beyond the other options listed below, up to // and including the entire Internet. CVSSv3_ATTACK_VECTOR_NETWORK CVSSv3_AttackVector = 1 // The vulnerable component is bound to the network stack, but the attack is // limited at the protocol level to a logically adjacent topology. CVSSv3_ATTACK_VECTOR_ADJACENT CVSSv3_AttackVector = 2 // The vulnerable component is not bound to the network stack and the // attacker's path is via read/write/execute capabilities. CVSSv3_ATTACK_VECTOR_LOCAL CVSSv3_AttackVector = 3 // The attack requires the attacker to physically touch or manipulate the // vulnerable component. CVSSv3_ATTACK_VECTOR_PHYSICAL CVSSv3_AttackVector = 4 ) // Enum value maps for CVSSv3_AttackVector. var ( CVSSv3_AttackVector_name = map[int32]string{ 0: "ATTACK_VECTOR_UNSPECIFIED", 1: "ATTACK_VECTOR_NETWORK", 2: "ATTACK_VECTOR_ADJACENT", 3: "ATTACK_VECTOR_LOCAL", 4: "ATTACK_VECTOR_PHYSICAL", } CVSSv3_AttackVector_value = map[string]int32{ "ATTACK_VECTOR_UNSPECIFIED": 0, "ATTACK_VECTOR_NETWORK": 1, "ATTACK_VECTOR_ADJACENT": 2, "ATTACK_VECTOR_LOCAL": 3, "ATTACK_VECTOR_PHYSICAL": 4, } ) func (x CVSSv3_AttackVector) Enum() *CVSSv3_AttackVector { p := new(CVSSv3_AttackVector) *p = x return p } func (x CVSSv3_AttackVector) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (CVSSv3_AttackVector) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_vulnerability_proto_enumTypes[0].Descriptor() } func (CVSSv3_AttackVector) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_vulnerability_proto_enumTypes[0] } func (x CVSSv3_AttackVector) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use CVSSv3_AttackVector.Descriptor instead. func (CVSSv3_AttackVector) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_vulnerability_proto_rawDescGZIP(), []int{4, 0} } // This metric describes the conditions beyond the attacker's control that // must exist in order to exploit the vulnerability. type CVSSv3_AttackComplexity int32 const ( // Invalid value. CVSSv3_ATTACK_COMPLEXITY_UNSPECIFIED CVSSv3_AttackComplexity = 0 // Specialized access conditions or extenuating circumstances do not exist. // An attacker can expect repeatable success when attacking the vulnerable // component. CVSSv3_ATTACK_COMPLEXITY_LOW CVSSv3_AttackComplexity = 1 // A successful attack depends on conditions beyond the attacker's control. // That is, a successful attack cannot be accomplished at will, but requires // the attacker to invest in some measurable amount of effort in preparation // or execution against the vulnerable component before a successful attack // can be expected. CVSSv3_ATTACK_COMPLEXITY_HIGH CVSSv3_AttackComplexity = 2 ) // Enum value maps for CVSSv3_AttackComplexity. var ( CVSSv3_AttackComplexity_name = map[int32]string{ 0: "ATTACK_COMPLEXITY_UNSPECIFIED", 1: "ATTACK_COMPLEXITY_LOW", 2: "ATTACK_COMPLEXITY_HIGH", } CVSSv3_AttackComplexity_value = map[string]int32{ "ATTACK_COMPLEXITY_UNSPECIFIED": 0, "ATTACK_COMPLEXITY_LOW": 1, "ATTACK_COMPLEXITY_HIGH": 2, } ) func (x CVSSv3_AttackComplexity) Enum() *CVSSv3_AttackComplexity { p := new(CVSSv3_AttackComplexity) *p = x return p } func (x CVSSv3_AttackComplexity) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (CVSSv3_AttackComplexity) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_vulnerability_proto_enumTypes[1].Descriptor() } func (CVSSv3_AttackComplexity) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_vulnerability_proto_enumTypes[1] } func (x CVSSv3_AttackComplexity) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use CVSSv3_AttackComplexity.Descriptor instead. func (CVSSv3_AttackComplexity) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_vulnerability_proto_rawDescGZIP(), []int{4, 1} } // This metric describes the level of privileges an attacker must possess // before successfully exploiting the vulnerability. type CVSSv3_PrivilegesRequired int32 const ( // Invalid value. CVSSv3_PRIVILEGES_REQUIRED_UNSPECIFIED CVSSv3_PrivilegesRequired = 0 // The attacker is unauthorized prior to attack, and therefore does not // require any access to settings or files of the vulnerable system to // carry out an attack. CVSSv3_PRIVILEGES_REQUIRED_NONE CVSSv3_PrivilegesRequired = 1 // The attacker requires privileges that provide basic user capabilities // that could normally affect only settings and files owned by a user. // Alternatively, an attacker with Low privileges has the ability to access // only non-sensitive resources. CVSSv3_PRIVILEGES_REQUIRED_LOW CVSSv3_PrivilegesRequired = 2 // The attacker requires privileges that provide significant (e.g., // administrative) control over the vulnerable component allowing access to // component-wide settings and files. CVSSv3_PRIVILEGES_REQUIRED_HIGH CVSSv3_PrivilegesRequired = 3 ) // Enum value maps for CVSSv3_PrivilegesRequired. var ( CVSSv3_PrivilegesRequired_name = map[int32]string{ 0: "PRIVILEGES_REQUIRED_UNSPECIFIED", 1: "PRIVILEGES_REQUIRED_NONE", 2: "PRIVILEGES_REQUIRED_LOW", 3: "PRIVILEGES_REQUIRED_HIGH", } CVSSv3_PrivilegesRequired_value = map[string]int32{ "PRIVILEGES_REQUIRED_UNSPECIFIED": 0, "PRIVILEGES_REQUIRED_NONE": 1, "PRIVILEGES_REQUIRED_LOW": 2, "PRIVILEGES_REQUIRED_HIGH": 3, } ) func (x CVSSv3_PrivilegesRequired) Enum() *CVSSv3_PrivilegesRequired { p := new(CVSSv3_PrivilegesRequired) *p = x return p } func (x CVSSv3_PrivilegesRequired) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (CVSSv3_PrivilegesRequired) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_vulnerability_proto_enumTypes[2].Descriptor() } func (CVSSv3_PrivilegesRequired) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_vulnerability_proto_enumTypes[2] } func (x CVSSv3_PrivilegesRequired) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use CVSSv3_PrivilegesRequired.Descriptor instead. func (CVSSv3_PrivilegesRequired) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_vulnerability_proto_rawDescGZIP(), []int{4, 2} } // This metric captures the requirement for a human user, other than the // attacker, to participate in the successful compromise of the vulnerable // component. type CVSSv3_UserInteraction int32 const ( // Invalid value. CVSSv3_USER_INTERACTION_UNSPECIFIED CVSSv3_UserInteraction = 0 // The vulnerable system can be exploited without interaction from any user. CVSSv3_USER_INTERACTION_NONE CVSSv3_UserInteraction = 1 // Successful exploitation of this vulnerability requires a user to take // some action before the vulnerability can be exploited. CVSSv3_USER_INTERACTION_REQUIRED CVSSv3_UserInteraction = 2 ) // Enum value maps for CVSSv3_UserInteraction. var ( CVSSv3_UserInteraction_name = map[int32]string{ 0: "USER_INTERACTION_UNSPECIFIED", 1: "USER_INTERACTION_NONE", 2: "USER_INTERACTION_REQUIRED", } CVSSv3_UserInteraction_value = map[string]int32{ "USER_INTERACTION_UNSPECIFIED": 0, "USER_INTERACTION_NONE": 1, "USER_INTERACTION_REQUIRED": 2, } ) func (x CVSSv3_UserInteraction) Enum() *CVSSv3_UserInteraction { p := new(CVSSv3_UserInteraction) *p = x return p } func (x CVSSv3_UserInteraction) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (CVSSv3_UserInteraction) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_vulnerability_proto_enumTypes[3].Descriptor() } func (CVSSv3_UserInteraction) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_vulnerability_proto_enumTypes[3] } func (x CVSSv3_UserInteraction) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use CVSSv3_UserInteraction.Descriptor instead. func (CVSSv3_UserInteraction) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_vulnerability_proto_rawDescGZIP(), []int{4, 3} } // The Scope metric captures whether a vulnerability in one vulnerable // component impacts resources in components beyond its security scope. type CVSSv3_Scope int32 const ( // Invalid value. CVSSv3_SCOPE_UNSPECIFIED CVSSv3_Scope = 0 // An exploited vulnerability can only affect resources managed by the same // security authority. CVSSv3_SCOPE_UNCHANGED CVSSv3_Scope = 1 // An exploited vulnerability can affect resources beyond the security scope // managed by the security authority of the vulnerable component. CVSSv3_SCOPE_CHANGED CVSSv3_Scope = 2 ) // Enum value maps for CVSSv3_Scope. var ( CVSSv3_Scope_name = map[int32]string{ 0: "SCOPE_UNSPECIFIED", 1: "SCOPE_UNCHANGED", 2: "SCOPE_CHANGED", } CVSSv3_Scope_value = map[string]int32{ "SCOPE_UNSPECIFIED": 0, "SCOPE_UNCHANGED": 1, "SCOPE_CHANGED": 2, } ) func (x CVSSv3_Scope) Enum() *CVSSv3_Scope { p := new(CVSSv3_Scope) *p = x return p } func (x CVSSv3_Scope) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (CVSSv3_Scope) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_vulnerability_proto_enumTypes[4].Descriptor() } func (CVSSv3_Scope) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_vulnerability_proto_enumTypes[4] } func (x CVSSv3_Scope) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use CVSSv3_Scope.Descriptor instead. func (CVSSv3_Scope) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_vulnerability_proto_rawDescGZIP(), []int{4, 4} } // The Impact metrics capture the effects of a successfully exploited // vulnerability on the component that suffers the worst outcome that is most // directly and predictably associated with the attack. type CVSSv3_Impact int32 const ( // Invalid value. CVSSv3_IMPACT_UNSPECIFIED CVSSv3_Impact = 0 // High impact. CVSSv3_IMPACT_HIGH CVSSv3_Impact = 1 // Low impact. CVSSv3_IMPACT_LOW CVSSv3_Impact = 2 // No impact. CVSSv3_IMPACT_NONE CVSSv3_Impact = 3 ) // Enum value maps for CVSSv3_Impact. var ( CVSSv3_Impact_name = map[int32]string{ 0: "IMPACT_UNSPECIFIED", 1: "IMPACT_HIGH", 2: "IMPACT_LOW", 3: "IMPACT_NONE", } CVSSv3_Impact_value = map[string]int32{ "IMPACT_UNSPECIFIED": 0, "IMPACT_HIGH": 1, "IMPACT_LOW": 2, "IMPACT_NONE": 3, } ) func (x CVSSv3_Impact) Enum() *CVSSv3_Impact { p := new(CVSSv3_Impact) *p = x return p } func (x CVSSv3_Impact) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (CVSSv3_Impact) Descriptor() protoreflect.EnumDescriptor { return file_google_cloud_osconfig_v1_vulnerability_proto_enumTypes[5].Descriptor() } func (CVSSv3_Impact) Type() protoreflect.EnumType { return &file_google_cloud_osconfig_v1_vulnerability_proto_enumTypes[5] } func (x CVSSv3_Impact) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Use CVSSv3_Impact.Descriptor instead. func (CVSSv3_Impact) EnumDescriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_vulnerability_proto_rawDescGZIP(), []int{4, 5} } // This API resource represents the vulnerability report for a specified // Compute Engine virtual machine (VM) instance at a given point in time. // // For more information, see [Vulnerability // reports](https://cloud.google.com/compute/docs/instances/os-inventory-management#vulnerability-reports). type VulnerabilityReport struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Output only. The `vulnerabilityReport` API resource name. // // Format: // `projects/{project_number}/locations/{location}/instances/{instance_id}/vulnerabilityReport` Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // Output only. List of vulnerabilities affecting the VM. Vulnerabilities []*VulnerabilityReport_Vulnerability `protobuf:"bytes,2,rep,name=vulnerabilities,proto3" json:"vulnerabilities,omitempty"` // Output only. The timestamp for when the last vulnerability report was generated for the // VM. UpdateTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty"` } func (x *VulnerabilityReport) Reset() { *x = VulnerabilityReport{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *VulnerabilityReport) String() string { return protoimpl.X.MessageStringOf(x) } func (*VulnerabilityReport) ProtoMessage() {} func (x *VulnerabilityReport) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use VulnerabilityReport.ProtoReflect.Descriptor instead. func (*VulnerabilityReport) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_vulnerability_proto_rawDescGZIP(), []int{0} } func (x *VulnerabilityReport) GetName() string { if x != nil { return x.Name } return "" } func (x *VulnerabilityReport) GetVulnerabilities() []*VulnerabilityReport_Vulnerability { if x != nil { return x.Vulnerabilities } return nil } func (x *VulnerabilityReport) GetUpdateTime() *timestamppb.Timestamp { if x != nil { return x.UpdateTime } return nil } // A request message for getting the vulnerability report for the specified VM. type GetVulnerabilityReportRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. API resource name for vulnerability resource. // // Format: // `projects/{project}/locations/{location}/instances/{instance}/vulnerabilityReport` // // For `{project}`, either `project-number` or `project-id` can be provided. // For `{instance}`, either Compute Engine `instance-id` or `instance-name` // can be provided. Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } func (x *GetVulnerabilityReportRequest) Reset() { *x = GetVulnerabilityReportRequest{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *GetVulnerabilityReportRequest) String() string { return protoimpl.X.MessageStringOf(x) } func (*GetVulnerabilityReportRequest) ProtoMessage() {} func (x *GetVulnerabilityReportRequest) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use GetVulnerabilityReportRequest.ProtoReflect.Descriptor instead. func (*GetVulnerabilityReportRequest) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_vulnerability_proto_rawDescGZIP(), []int{1} } func (x *GetVulnerabilityReportRequest) GetName() string { if x != nil { return x.Name } return "" } // A request message for listing vulnerability reports for all VM instances in // the specified location. type ListVulnerabilityReportsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Required. The parent resource name. // // Format: `projects/{project}/locations/{location}/instances/-` // // For `{project}`, either `project-number` or `project-id` can be provided. Parent string `protobuf:"bytes,1,opt,name=parent,proto3" json:"parent,omitempty"` // The maximum number of results to return. PageSize int32 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` // A pagination token returned from a previous call to // `ListVulnerabilityReports` that indicates where this listing // should continue from. PageToken string `protobuf:"bytes,3,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"` // If provided, this field specifies the criteria that must be met by a // `vulnerabilityReport` API resource to be included in the response. Filter string `protobuf:"bytes,4,opt,name=filter,proto3" json:"filter,omitempty"` } func (x *ListVulnerabilityReportsRequest) Reset() { *x = ListVulnerabilityReportsRequest{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *ListVulnerabilityReportsRequest) String() string { return protoimpl.X.MessageStringOf(x) } func (*ListVulnerabilityReportsRequest) ProtoMessage() {} func (x *ListVulnerabilityReportsRequest) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use ListVulnerabilityReportsRequest.ProtoReflect.Descriptor instead. func (*ListVulnerabilityReportsRequest) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_vulnerability_proto_rawDescGZIP(), []int{2} } func (x *ListVulnerabilityReportsRequest) GetParent() string { if x != nil { return x.Parent } return "" } func (x *ListVulnerabilityReportsRequest) GetPageSize() int32 { if x != nil { return x.PageSize } return 0 } func (x *ListVulnerabilityReportsRequest) GetPageToken() string { if x != nil { return x.PageToken } return "" } func (x *ListVulnerabilityReportsRequest) GetFilter() string { if x != nil { return x.Filter } return "" } // A response message for listing vulnerability reports for all VM instances in // the specified location. type ListVulnerabilityReportsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // List of vulnerabilityReport objects. VulnerabilityReports []*VulnerabilityReport `protobuf:"bytes,1,rep,name=vulnerability_reports,json=vulnerabilityReports,proto3" json:"vulnerability_reports,omitempty"` // The pagination token to retrieve the next page of vulnerabilityReports // object. NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` } func (x *ListVulnerabilityReportsResponse) Reset() { *x = ListVulnerabilityReportsResponse{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *ListVulnerabilityReportsResponse) String() string { return protoimpl.X.MessageStringOf(x) } func (*ListVulnerabilityReportsResponse) ProtoMessage() {} func (x *ListVulnerabilityReportsResponse) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use ListVulnerabilityReportsResponse.ProtoReflect.Descriptor instead. func (*ListVulnerabilityReportsResponse) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_vulnerability_proto_rawDescGZIP(), []int{3} } func (x *ListVulnerabilityReportsResponse) GetVulnerabilityReports() []*VulnerabilityReport { if x != nil { return x.VulnerabilityReports } return nil } func (x *ListVulnerabilityReportsResponse) GetNextPageToken() string { if x != nil { return x.NextPageToken } return "" } // Common Vulnerability Scoring System version 3. // For details, see https://www.first.org/cvss/specification-document type CVSSv3 struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // The base score is a function of the base metric scores. // https://www.first.org/cvss/specification-document#Base-Metrics BaseScore float32 `protobuf:"fixed32,1,opt,name=base_score,json=baseScore,proto3" json:"base_score,omitempty"` // The Exploitability sub-score equation is derived from the Base // Exploitability metrics. // https://www.first.org/cvss/specification-document#2-1-Exploitability-Metrics ExploitabilityScore float32 `protobuf:"fixed32,2,opt,name=exploitability_score,json=exploitabilityScore,proto3" json:"exploitability_score,omitempty"` // The Impact sub-score equation is derived from the Base Impact metrics. ImpactScore float32 `protobuf:"fixed32,3,opt,name=impact_score,json=impactScore,proto3" json:"impact_score,omitempty"` // This metric reflects the context by which vulnerability exploitation is // possible. AttackVector CVSSv3_AttackVector `protobuf:"varint,5,opt,name=attack_vector,json=attackVector,proto3,enum=google.cloud.osconfig.v1.CVSSv3_AttackVector" json:"attack_vector,omitempty"` // This metric describes the conditions beyond the attacker's control that // must exist in order to exploit the vulnerability. AttackComplexity CVSSv3_AttackComplexity `protobuf:"varint,6,opt,name=attack_complexity,json=attackComplexity,proto3,enum=google.cloud.osconfig.v1.CVSSv3_AttackComplexity" json:"attack_complexity,omitempty"` // This metric describes the level of privileges an attacker must possess // before successfully exploiting the vulnerability. PrivilegesRequired CVSSv3_PrivilegesRequired `protobuf:"varint,7,opt,name=privileges_required,json=privilegesRequired,proto3,enum=google.cloud.osconfig.v1.CVSSv3_PrivilegesRequired" json:"privileges_required,omitempty"` // This metric captures the requirement for a human user, other than the // attacker, to participate in the successful compromise of the vulnerable // component. UserInteraction CVSSv3_UserInteraction `protobuf:"varint,8,opt,name=user_interaction,json=userInteraction,proto3,enum=google.cloud.osconfig.v1.CVSSv3_UserInteraction" json:"user_interaction,omitempty"` // The Scope metric captures whether a vulnerability in one vulnerable // component impacts resources in components beyond its security scope. Scope CVSSv3_Scope `protobuf:"varint,9,opt,name=scope,proto3,enum=google.cloud.osconfig.v1.CVSSv3_Scope" json:"scope,omitempty"` // This metric measures the impact to the confidentiality of the information // resources managed by a software component due to a successfully exploited // vulnerability. ConfidentialityImpact CVSSv3_Impact `protobuf:"varint,10,opt,name=confidentiality_impact,json=confidentialityImpact,proto3,enum=google.cloud.osconfig.v1.CVSSv3_Impact" json:"confidentiality_impact,omitempty"` // This metric measures the impact to integrity of a successfully exploited // vulnerability. IntegrityImpact CVSSv3_Impact `protobuf:"varint,11,opt,name=integrity_impact,json=integrityImpact,proto3,enum=google.cloud.osconfig.v1.CVSSv3_Impact" json:"integrity_impact,omitempty"` // This metric measures the impact to the availability of the impacted // component resulting from a successfully exploited vulnerability. AvailabilityImpact CVSSv3_Impact `protobuf:"varint,12,opt,name=availability_impact,json=availabilityImpact,proto3,enum=google.cloud.osconfig.v1.CVSSv3_Impact" json:"availability_impact,omitempty"` } func (x *CVSSv3) Reset() { *x = CVSSv3{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *CVSSv3) String() string { return protoimpl.X.MessageStringOf(x) } func (*CVSSv3) ProtoMessage() {} func (x *CVSSv3) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use CVSSv3.ProtoReflect.Descriptor instead. func (*CVSSv3) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_vulnerability_proto_rawDescGZIP(), []int{4} } func (x *CVSSv3) GetBaseScore() float32 { if x != nil { return x.BaseScore } return 0 } func (x *CVSSv3) GetExploitabilityScore() float32 { if x != nil { return x.ExploitabilityScore } return 0 } func (x *CVSSv3) GetImpactScore() float32 { if x != nil { return x.ImpactScore } return 0 } func (x *CVSSv3) GetAttackVector() CVSSv3_AttackVector { if x != nil { return x.AttackVector } return CVSSv3_ATTACK_VECTOR_UNSPECIFIED } func (x *CVSSv3) GetAttackComplexity() CVSSv3_AttackComplexity { if x != nil { return x.AttackComplexity } return CVSSv3_ATTACK_COMPLEXITY_UNSPECIFIED } func (x *CVSSv3) GetPrivilegesRequired() CVSSv3_PrivilegesRequired { if x != nil { return x.PrivilegesRequired } return CVSSv3_PRIVILEGES_REQUIRED_UNSPECIFIED } func (x *CVSSv3) GetUserInteraction() CVSSv3_UserInteraction { if x != nil { return x.UserInteraction } return CVSSv3_USER_INTERACTION_UNSPECIFIED } func (x *CVSSv3) GetScope() CVSSv3_Scope { if x != nil { return x.Scope } return CVSSv3_SCOPE_UNSPECIFIED } func (x *CVSSv3) GetConfidentialityImpact() CVSSv3_Impact { if x != nil { return x.ConfidentialityImpact } return CVSSv3_IMPACT_UNSPECIFIED } func (x *CVSSv3) GetIntegrityImpact() CVSSv3_Impact { if x != nil { return x.IntegrityImpact } return CVSSv3_IMPACT_UNSPECIFIED } func (x *CVSSv3) GetAvailabilityImpact() CVSSv3_Impact { if x != nil { return x.AvailabilityImpact } return CVSSv3_IMPACT_UNSPECIFIED } // A vulnerability affecting the VM instance. type VulnerabilityReport_Vulnerability struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Contains metadata as per the upstream feed of the operating system and // NVD. Details *VulnerabilityReport_Vulnerability_Details `protobuf:"bytes,1,opt,name=details,proto3" json:"details,omitempty"` // Corresponds to the `INSTALLED_PACKAGE` inventory item on the VM. // This field displays the inventory items affected by this vulnerability. // If the vulnerability report was not updated after the VM inventory // update, these values might not display in VM inventory. For some distros, // this field may be empty. InstalledInventoryItemIds []string `protobuf:"bytes,2,rep,name=installed_inventory_item_ids,json=installedInventoryItemIds,proto3" json:"installed_inventory_item_ids,omitempty"` // Corresponds to the `AVAILABLE_PACKAGE` inventory item on the VM. // If the vulnerability report was not updated after the VM inventory // update, these values might not display in VM inventory. If there is no // available fix, the field is empty. The `inventory_item` value specifies // the latest `SoftwarePackage` available to the VM that fixes the // vulnerability. AvailableInventoryItemIds []string `protobuf:"bytes,3,rep,name=available_inventory_item_ids,json=availableInventoryItemIds,proto3" json:"available_inventory_item_ids,omitempty"` // The timestamp for when the vulnerability was first detected. CreateTime *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"` // The timestamp for when the vulnerability was last modified. UpdateTime *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty"` } func (x *VulnerabilityReport_Vulnerability) Reset() { *x = VulnerabilityReport_Vulnerability{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *VulnerabilityReport_Vulnerability) String() string { return protoimpl.X.MessageStringOf(x) } func (*VulnerabilityReport_Vulnerability) ProtoMessage() {} func (x *VulnerabilityReport_Vulnerability) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use VulnerabilityReport_Vulnerability.ProtoReflect.Descriptor instead. func (*VulnerabilityReport_Vulnerability) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_vulnerability_proto_rawDescGZIP(), []int{0, 0} } func (x *VulnerabilityReport_Vulnerability) GetDetails() *VulnerabilityReport_Vulnerability_Details { if x != nil { return x.Details } return nil } func (x *VulnerabilityReport_Vulnerability) GetInstalledInventoryItemIds() []string { if x != nil { return x.InstalledInventoryItemIds } return nil } func (x *VulnerabilityReport_Vulnerability) GetAvailableInventoryItemIds() []string { if x != nil { return x.AvailableInventoryItemIds } return nil } func (x *VulnerabilityReport_Vulnerability) GetCreateTime() *timestamppb.Timestamp { if x != nil { return x.CreateTime } return nil } func (x *VulnerabilityReport_Vulnerability) GetUpdateTime() *timestamppb.Timestamp { if x != nil { return x.UpdateTime } return nil } // Contains metadata information for the vulnerability. This information is // collected from the upstream feed of the operating system. type VulnerabilityReport_Vulnerability_Details struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // The CVE of the vulnerability. CVE cannot be // empty and the combination of should be unique // across vulnerabilities for a VM. Cve string `protobuf:"bytes,1,opt,name=cve,proto3" json:"cve,omitempty"` // The CVSS V2 score of this vulnerability. CVSS V2 score is on a scale of // 0 - 10 where 0 indicates low severity and 10 indicates high severity. CvssV2Score float32 `protobuf:"fixed32,2,opt,name=cvss_v2_score,json=cvssV2Score,proto3" json:"cvss_v2_score,omitempty"` // The full description of the CVSSv3 for this vulnerability from NVD. CvssV3 *CVSSv3 `protobuf:"bytes,3,opt,name=cvss_v3,json=cvssV3,proto3" json:"cvss_v3,omitempty"` // Assigned severity/impact ranking from the distro. Severity string `protobuf:"bytes,4,opt,name=severity,proto3" json:"severity,omitempty"` // The note or description describing the vulnerability from the distro. Description string `protobuf:"bytes,5,opt,name=description,proto3" json:"description,omitempty"` // Corresponds to the references attached to the `VulnerabilityDetails`. References []*VulnerabilityReport_Vulnerability_Details_Reference `protobuf:"bytes,6,rep,name=references,proto3" json:"references,omitempty"` } func (x *VulnerabilityReport_Vulnerability_Details) Reset() { *x = VulnerabilityReport_Vulnerability_Details{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *VulnerabilityReport_Vulnerability_Details) String() string { return protoimpl.X.MessageStringOf(x) } func (*VulnerabilityReport_Vulnerability_Details) ProtoMessage() {} func (x *VulnerabilityReport_Vulnerability_Details) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use VulnerabilityReport_Vulnerability_Details.ProtoReflect.Descriptor instead. func (*VulnerabilityReport_Vulnerability_Details) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_vulnerability_proto_rawDescGZIP(), []int{0, 0, 0} } func (x *VulnerabilityReport_Vulnerability_Details) GetCve() string { if x != nil { return x.Cve } return "" } func (x *VulnerabilityReport_Vulnerability_Details) GetCvssV2Score() float32 { if x != nil { return x.CvssV2Score } return 0 } func (x *VulnerabilityReport_Vulnerability_Details) GetCvssV3() *CVSSv3 { if x != nil { return x.CvssV3 } return nil } func (x *VulnerabilityReport_Vulnerability_Details) GetSeverity() string { if x != nil { return x.Severity } return "" } func (x *VulnerabilityReport_Vulnerability_Details) GetDescription() string { if x != nil { return x.Description } return "" } func (x *VulnerabilityReport_Vulnerability_Details) GetReferences() []*VulnerabilityReport_Vulnerability_Details_Reference { if x != nil { return x.References } return nil } // A reference for this vulnerability. type VulnerabilityReport_Vulnerability_Details_Reference struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // The url of the reference. Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"` // The source of the reference e.g. NVD. Source string `protobuf:"bytes,2,opt,name=source,proto3" json:"source,omitempty"` } func (x *VulnerabilityReport_Vulnerability_Details_Reference) Reset() { *x = VulnerabilityReport_Vulnerability_Details_Reference{} if protoimpl.UnsafeEnabled { mi := &file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *VulnerabilityReport_Vulnerability_Details_Reference) String() string { return protoimpl.X.MessageStringOf(x) } func (*VulnerabilityReport_Vulnerability_Details_Reference) ProtoMessage() {} func (x *VulnerabilityReport_Vulnerability_Details_Reference) ProtoReflect() protoreflect.Message { mi := &file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use VulnerabilityReport_Vulnerability_Details_Reference.ProtoReflect.Descriptor instead. func (*VulnerabilityReport_Vulnerability_Details_Reference) Descriptor() ([]byte, []int) { return file_google_cloud_osconfig_v1_vulnerability_proto_rawDescGZIP(), []int{0, 0, 0, 0} } func (x *VulnerabilityReport_Vulnerability_Details_Reference) GetUrl() string { if x != nil { return x.Url } return "" } func (x *VulnerabilityReport_Vulnerability_Details_Reference) GetSource() string { if x != nil { return x.Source } return "" } var File_google_cloud_osconfig_v1_vulnerability_proto protoreflect.FileDescriptor var file_google_cloud_osconfig_v1_vulnerability_proto_rawDesc = []byte{ 0x0a, 0x2c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x18, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xaf, 0x08, 0x0a, 0x13, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x17, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x03, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x6a, 0x0a, 0x0f, 0x76, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x42, 0x03, 0xe0, 0x41, 0x03, 0x52, 0x0f, 0x76, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x40, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x03, 0xe0, 0x41, 0x03, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x1a, 0xcb, 0x05, 0x0a, 0x0d, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x5d, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x43, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x2e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x3f, 0x0a, 0x1c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x19, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x49, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x73, 0x12, 0x3f, 0x0a, 0x1c, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x19, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x49, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x1a, 0xde, 0x02, 0x0a, 0x07, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x76, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x63, 0x76, 0x65, 0x12, 0x22, 0x0a, 0x0d, 0x63, 0x76, 0x73, 0x73, 0x5f, 0x76, 0x32, 0x5f, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0b, 0x63, 0x76, 0x73, 0x73, 0x56, 0x32, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x39, 0x0a, 0x07, 0x63, 0x76, 0x73, 0x73, 0x5f, 0x76, 0x33, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x56, 0x53, 0x53, 0x76, 0x33, 0x52, 0x06, 0x63, 0x76, 0x73, 0x73, 0x56, 0x33, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x6d, 0x0a, 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x4d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x2e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0a, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x1a, 0x35, 0x0a, 0x09, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a, 0x82, 0x01, 0xea, 0x41, 0x7f, 0x0a, 0x2b, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x50, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x7d, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7d, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x7d, 0x2f, 0x76, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x68, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x47, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x33, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x2d, 0x0a, 0x2b, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xb6, 0x01, 0x0a, 0x1f, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x27, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x21, 0x0a, 0x1f, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0xae, 0x01, 0x0a, 0x20, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x15, 0x76, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x14, 0x76, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xea, 0x0b, 0x0a, 0x06, 0x43, 0x56, 0x53, 0x53, 0x76, 0x33, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x02, 0x52, 0x09, 0x62, 0x61, 0x73, 0x65, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x31, 0x0a, 0x14, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x69, 0x74, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, 0x52, 0x13, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x69, 0x74, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x5f, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0b, 0x69, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x52, 0x0a, 0x0d, 0x61, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x56, 0x53, 0x53, 0x76, 0x33, 0x2e, 0x41, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x0c, 0x61, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x5e, 0x0a, 0x11, 0x61, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x78, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x31, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x56, 0x53, 0x53, 0x76, 0x33, 0x2e, 0x41, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x78, 0x69, 0x74, 0x79, 0x52, 0x10, 0x61, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x78, 0x69, 0x74, 0x79, 0x12, 0x64, 0x0a, 0x13, 0x70, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x56, 0x53, 0x53, 0x76, 0x33, 0x2e, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x52, 0x12, 0x70, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x5b, 0x0a, 0x10, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x30, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x56, 0x53, 0x53, 0x76, 0x33, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x75, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3c, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x56, 0x53, 0x53, 0x76, 0x33, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x5e, 0x0a, 0x16, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x56, 0x53, 0x53, 0x76, 0x33, 0x2e, 0x49, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x52, 0x15, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x49, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x12, 0x52, 0x0a, 0x10, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x56, 0x53, 0x53, 0x76, 0x33, 0x2e, 0x49, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x52, 0x0f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x49, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x12, 0x58, 0x0a, 0x13, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x56, 0x53, 0x53, 0x76, 0x33, 0x2e, 0x49, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x52, 0x12, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x49, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x22, 0x99, 0x01, 0x0a, 0x0c, 0x41, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x19, 0x41, 0x54, 0x54, 0x41, 0x43, 0x4b, 0x5f, 0x56, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x54, 0x54, 0x41, 0x43, 0x4b, 0x5f, 0x56, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x5f, 0x4e, 0x45, 0x54, 0x57, 0x4f, 0x52, 0x4b, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x54, 0x54, 0x41, 0x43, 0x4b, 0x5f, 0x56, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x5f, 0x41, 0x44, 0x4a, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x54, 0x54, 0x41, 0x43, 0x4b, 0x5f, 0x56, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x5f, 0x4c, 0x4f, 0x43, 0x41, 0x4c, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x54, 0x54, 0x41, 0x43, 0x4b, 0x5f, 0x56, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x5f, 0x50, 0x48, 0x59, 0x53, 0x49, 0x43, 0x41, 0x4c, 0x10, 0x04, 0x22, 0x6c, 0x0a, 0x10, 0x41, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x78, 0x69, 0x74, 0x79, 0x12, 0x21, 0x0a, 0x1d, 0x41, 0x54, 0x54, 0x41, 0x43, 0x4b, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x58, 0x49, 0x54, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x54, 0x54, 0x41, 0x43, 0x4b, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x58, 0x49, 0x54, 0x59, 0x5f, 0x4c, 0x4f, 0x57, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x54, 0x54, 0x41, 0x43, 0x4b, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x58, 0x49, 0x54, 0x59, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x10, 0x02, 0x22, 0x92, 0x01, 0x0a, 0x12, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x23, 0x0a, 0x1f, 0x50, 0x52, 0x49, 0x56, 0x49, 0x4c, 0x45, 0x47, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x50, 0x52, 0x49, 0x56, 0x49, 0x4c, 0x45, 0x47, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x44, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x50, 0x52, 0x49, 0x56, 0x49, 0x4c, 0x45, 0x47, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x44, 0x5f, 0x4c, 0x4f, 0x57, 0x10, 0x02, 0x12, 0x1c, 0x0a, 0x18, 0x50, 0x52, 0x49, 0x56, 0x49, 0x4c, 0x45, 0x47, 0x45, 0x53, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x44, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x10, 0x03, 0x22, 0x6d, 0x0a, 0x0f, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x1c, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x44, 0x10, 0x02, 0x22, 0x46, 0x0a, 0x05, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x43, 0x4f, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x43, 0x4f, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x44, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x43, 0x4f, 0x50, 0x45, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x44, 0x10, 0x02, 0x22, 0x52, 0x0a, 0x06, 0x49, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x12, 0x16, 0x0a, 0x12, 0x49, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x4c, 0x4f, 0x57, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x4d, 0x50, 0x41, 0x43, 0x54, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x03, 0x42, 0xca, 0x01, 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x42, 0x12, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x40, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x3b, 0x6f, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0xaa, 0x02, 0x18, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x18, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x5c, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5c, 0x56, 0x31, 0xea, 0x02, 0x1b, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x3a, 0x3a, 0x4f, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( file_google_cloud_osconfig_v1_vulnerability_proto_rawDescOnce sync.Once file_google_cloud_osconfig_v1_vulnerability_proto_rawDescData = file_google_cloud_osconfig_v1_vulnerability_proto_rawDesc ) func file_google_cloud_osconfig_v1_vulnerability_proto_rawDescGZIP() []byte { file_google_cloud_osconfig_v1_vulnerability_proto_rawDescOnce.Do(func() { file_google_cloud_osconfig_v1_vulnerability_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_cloud_osconfig_v1_vulnerability_proto_rawDescData) }) return file_google_cloud_osconfig_v1_vulnerability_proto_rawDescData } var file_google_cloud_osconfig_v1_vulnerability_proto_enumTypes = make([]protoimpl.EnumInfo, 6) var file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes = make([]protoimpl.MessageInfo, 8) var file_google_cloud_osconfig_v1_vulnerability_proto_goTypes = []interface{}{ (CVSSv3_AttackVector)(0), // 0: google.cloud.osconfig.v1.CVSSv3.AttackVector (CVSSv3_AttackComplexity)(0), // 1: google.cloud.osconfig.v1.CVSSv3.AttackComplexity (CVSSv3_PrivilegesRequired)(0), // 2: google.cloud.osconfig.v1.CVSSv3.PrivilegesRequired (CVSSv3_UserInteraction)(0), // 3: google.cloud.osconfig.v1.CVSSv3.UserInteraction (CVSSv3_Scope)(0), // 4: google.cloud.osconfig.v1.CVSSv3.Scope (CVSSv3_Impact)(0), // 5: google.cloud.osconfig.v1.CVSSv3.Impact (*VulnerabilityReport)(nil), // 6: google.cloud.osconfig.v1.VulnerabilityReport (*GetVulnerabilityReportRequest)(nil), // 7: google.cloud.osconfig.v1.GetVulnerabilityReportRequest (*ListVulnerabilityReportsRequest)(nil), // 8: google.cloud.osconfig.v1.ListVulnerabilityReportsRequest (*ListVulnerabilityReportsResponse)(nil), // 9: google.cloud.osconfig.v1.ListVulnerabilityReportsResponse (*CVSSv3)(nil), // 10: google.cloud.osconfig.v1.CVSSv3 (*VulnerabilityReport_Vulnerability)(nil), // 11: google.cloud.osconfig.v1.VulnerabilityReport.Vulnerability (*VulnerabilityReport_Vulnerability_Details)(nil), // 12: google.cloud.osconfig.v1.VulnerabilityReport.Vulnerability.Details (*VulnerabilityReport_Vulnerability_Details_Reference)(nil), // 13: google.cloud.osconfig.v1.VulnerabilityReport.Vulnerability.Details.Reference (*timestamppb.Timestamp)(nil), // 14: google.protobuf.Timestamp } var file_google_cloud_osconfig_v1_vulnerability_proto_depIdxs = []int32{ 11, // 0: google.cloud.osconfig.v1.VulnerabilityReport.vulnerabilities:type_name -> google.cloud.osconfig.v1.VulnerabilityReport.Vulnerability 14, // 1: google.cloud.osconfig.v1.VulnerabilityReport.update_time:type_name -> google.protobuf.Timestamp 6, // 2: google.cloud.osconfig.v1.ListVulnerabilityReportsResponse.vulnerability_reports:type_name -> google.cloud.osconfig.v1.VulnerabilityReport 0, // 3: google.cloud.osconfig.v1.CVSSv3.attack_vector:type_name -> google.cloud.osconfig.v1.CVSSv3.AttackVector 1, // 4: google.cloud.osconfig.v1.CVSSv3.attack_complexity:type_name -> google.cloud.osconfig.v1.CVSSv3.AttackComplexity 2, // 5: google.cloud.osconfig.v1.CVSSv3.privileges_required:type_name -> google.cloud.osconfig.v1.CVSSv3.PrivilegesRequired 3, // 6: google.cloud.osconfig.v1.CVSSv3.user_interaction:type_name -> google.cloud.osconfig.v1.CVSSv3.UserInteraction 4, // 7: google.cloud.osconfig.v1.CVSSv3.scope:type_name -> google.cloud.osconfig.v1.CVSSv3.Scope 5, // 8: google.cloud.osconfig.v1.CVSSv3.confidentiality_impact:type_name -> google.cloud.osconfig.v1.CVSSv3.Impact 5, // 9: google.cloud.osconfig.v1.CVSSv3.integrity_impact:type_name -> google.cloud.osconfig.v1.CVSSv3.Impact 5, // 10: google.cloud.osconfig.v1.CVSSv3.availability_impact:type_name -> google.cloud.osconfig.v1.CVSSv3.Impact 12, // 11: google.cloud.osconfig.v1.VulnerabilityReport.Vulnerability.details:type_name -> google.cloud.osconfig.v1.VulnerabilityReport.Vulnerability.Details 14, // 12: google.cloud.osconfig.v1.VulnerabilityReport.Vulnerability.create_time:type_name -> google.protobuf.Timestamp 14, // 13: google.cloud.osconfig.v1.VulnerabilityReport.Vulnerability.update_time:type_name -> google.protobuf.Timestamp 10, // 14: google.cloud.osconfig.v1.VulnerabilityReport.Vulnerability.Details.cvss_v3:type_name -> google.cloud.osconfig.v1.CVSSv3 13, // 15: google.cloud.osconfig.v1.VulnerabilityReport.Vulnerability.Details.references:type_name -> google.cloud.osconfig.v1.VulnerabilityReport.Vulnerability.Details.Reference 16, // [16:16] is the sub-list for method output_type 16, // [16:16] is the sub-list for method input_type 16, // [16:16] is the sub-list for extension type_name 16, // [16:16] is the sub-list for extension extendee 0, // [0:16] is the sub-list for field type_name } func init() { file_google_cloud_osconfig_v1_vulnerability_proto_init() } func file_google_cloud_osconfig_v1_vulnerability_proto_init() { if File_google_cloud_osconfig_v1_vulnerability_proto != nil { return } if !protoimpl.UnsafeEnabled { file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VulnerabilityReport); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetVulnerabilityReportRequest); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListVulnerabilityReportsRequest); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListVulnerabilityReportsResponse); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CVSSv3); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VulnerabilityReport_Vulnerability); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VulnerabilityReport_Vulnerability_Details); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VulnerabilityReport_Vulnerability_Details_Reference); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_google_cloud_osconfig_v1_vulnerability_proto_rawDesc, NumEnums: 6, NumMessages: 8, NumExtensions: 0, NumServices: 0, }, GoTypes: file_google_cloud_osconfig_v1_vulnerability_proto_goTypes, DependencyIndexes: file_google_cloud_osconfig_v1_vulnerability_proto_depIdxs, EnumInfos: file_google_cloud_osconfig_v1_vulnerability_proto_enumTypes, MessageInfos: file_google_cloud_osconfig_v1_vulnerability_proto_msgTypes, }.Build() File_google_cloud_osconfig_v1_vulnerability_proto = out.File file_google_cloud_osconfig_v1_vulnerability_proto_rawDesc = nil file_google_cloud_osconfig_v1_vulnerability_proto_goTypes = nil file_google_cloud_osconfig_v1_vulnerability_proto_depIdxs = nil } osconfig-20250416.02/e2e_tests/main.go000066400000000000000000000070421477773331400172010ustar00rootroot00000000000000// Copyright 2018 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import ( "bytes" "context" "encoding/xml" "fmt" "io" "io/ioutil" "log" "os" "path/filepath" "regexp" "sync" "github.com/GoogleCloudPlatform/compute-image-tools/go/e2e_test_utils/junitxml" "github.com/GoogleCloudPlatform/guest-logging-go/logger" "github.com/GoogleCloudPlatform/osconfig/e2e_tests/config" gcpclients "github.com/GoogleCloudPlatform/osconfig/e2e_tests/gcp_clients" "github.com/GoogleCloudPlatform/osconfig/e2e_tests/test_suites/guestpolicies" "github.com/GoogleCloudPlatform/osconfig/e2e_tests/test_suites/inventory" "github.com/GoogleCloudPlatform/osconfig/e2e_tests/test_suites/inventoryreporting" "github.com/GoogleCloudPlatform/osconfig/e2e_tests/test_suites/ospolicies" "github.com/GoogleCloudPlatform/osconfig/e2e_tests/test_suites/patch" _ "google.golang.org/genproto/googleapis/rpc/errdetails" ) var testFunctions = []func(context.Context, *sync.WaitGroup, chan *junitxml.TestSuite, *log.Logger, *regexp.Regexp, *regexp.Regexp){ ospolicies.TestSuite, guestpolicies.TestSuite, inventory.TestSuite, inventoryreporting.TestSuite, patch.TestSuite, } type logWriter struct { log *log.Logger } func (l *logWriter) Write(b []byte) (int, error) { l.log.Print(string(b)) return len(b), nil } func main() { ctx := context.Background() if err := gcpclients.PopulateClients(ctx); err != nil { log.Fatal(err) } testLogger := log.New(os.Stdout, "[OsConfigTests] ", 0) testLogger.Println("Starting...") // Initialize logger for any shared function calls. opts := logger.LogOpts{LoggerName: "OsConfigTests", Debug: true, Writers: []io.Writer{&logWriter{log: testLogger}}, DisableCloudLogging: true, DisableLocalLogging: true} logger.Init(ctx, opts) tests := make(chan *junitxml.TestSuite) var wg sync.WaitGroup for _, tf := range testFunctions { wg.Add(1) go tf(ctx, &wg, tests, testLogger, config.TestSuiteFilter(), config.TestCaseFilter()) } go func() { wg.Wait() close(tests) }() var testSuites []*junitxml.TestSuite for ret := range tests { testSuites = append(testSuites, ret) testSuiteOutPath := filepath.Join(*config.OutDir, fmt.Sprintf("junit_%s.xml", ret.Name)) if err := os.MkdirAll(filepath.Dir(testSuiteOutPath), 0770); err != nil { testLogger.Fatal(err) } testLogger.Printf("Creating junit xml file: %s", testSuiteOutPath) d, err := xml.MarshalIndent(ret, " ", " ") if err != nil { testLogger.Fatal(err) } if err := ioutil.WriteFile(testSuiteOutPath, d, 0644); err != nil { testLogger.Fatal(err) } } var buf bytes.Buffer for _, ts := range testSuites { if ts.Failures > 0 { buf.WriteString(fmt.Sprintf("TestSuite %q has errors:\n", ts.Name)) for _, tc := range ts.TestCase { if tc.Failure != nil { buf.WriteString(fmt.Sprintf(" - %q: %s\n", tc.Name, tc.Failure.FailMessage)) } } } } if buf.Len() > 0 { testLogger.Fatalf("%sExiting with exit code 1", buf.String()) } testLogger.Print("All test cases completed successfully.") } osconfig-20250416.02/e2e_tests/osconfig_server/000077500000000000000000000000001477773331400211205ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/osconfig_server/osconfig_data_builder.go000066400000000000000000000067241477773331400257660ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package osconfigserver import ( "fmt" "cloud.google.com/go/osconfig/apiv1beta/osconfigpb" ) // BuildPackagePolicy creates an package policy. func BuildPackagePolicy(installs, removes, upgrades []string) []*osconfigpb.Package { var pkgs []*osconfigpb.Package for _, p := range installs { pkgs = append(pkgs, &osconfigpb.Package{ DesiredState: osconfigpb.DesiredState_INSTALLED, Name: p, }) } for _, p := range removes { pkgs = append(pkgs, &osconfigpb.Package{ DesiredState: osconfigpb.DesiredState_REMOVED, Name: p, }) } for _, p := range upgrades { pkgs = append(pkgs, &osconfigpb.Package{ DesiredState: osconfigpb.DesiredState_UPDATED, Name: p, }) } return pkgs } // BuildAptRepository create an apt repository object func BuildAptRepository(archiveType osconfigpb.AptRepository_ArchiveType, uri, distribution, keyuri string, components []string) *osconfigpb.PackageRepository_Apt { return &osconfigpb.PackageRepository_Apt{ Apt: &osconfigpb.AptRepository{ ArchiveType: archiveType, Uri: uri, Distribution: distribution, Components: components, GpgKey: keyuri, }, } } // BuildYumRepository create an yum repository object func BuildYumRepository(id, name, baseURL string, gpgkeys []string) *osconfigpb.PackageRepository_Yum { return &osconfigpb.PackageRepository_Yum{ Yum: &osconfigpb.YumRepository{ Id: id, DisplayName: name, BaseUrl: baseURL, GpgKeys: gpgkeys, }, } } // BuildZypperRepository create an zypper repository object func BuildZypperRepository(id, name, baseURL string, gpgkeys []string) *osconfigpb.PackageRepository_Zypper { return &osconfigpb.PackageRepository_Zypper{ Zypper: &osconfigpb.ZypperRepository{ Id: id, DisplayName: name, BaseUrl: baseURL, GpgKeys: gpgkeys, }, } } // BuildGooRepository create an googet repository object func BuildGooRepository(name, url string) *osconfigpb.PackageRepository_Goo { return &osconfigpb.PackageRepository_Goo{ Goo: &osconfigpb.GooRepository{ Name: name, Url: url, }, } } // BuildInstanceFilterExpression creates an instance filter expression to // be used by Assignment func BuildInstanceFilterExpression(instance string) string { return fmt.Sprintf("instance.name==\"%s\"", instance) } // BuildPackage creates an os config package func BuildPackage(name string) *osconfigpb.Package { return &osconfigpb.Package{ Name: name, } } // BuildSoftwareRecipe create a SoftwareRecipe with the specified name, version, artifacts, and installSteps func BuildSoftwareRecipe(name, version string, artifacts []*osconfigpb.SoftwareRecipe_Artifact, installSteps []*osconfigpb.SoftwareRecipe_Step) *osconfigpb.SoftwareRecipe { return &osconfigpb.SoftwareRecipe{ Name: name, Version: version, Artifacts: artifacts, InstallSteps: installSteps, } } osconfig-20250416.02/e2e_tests/test_config/000077500000000000000000000000001477773331400202275ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/test_config/project_config.go000066400000000000000000000055271477773331400235620ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package testconfig import ( "math/rand" "sync" "time" "github.com/GoogleCloudPlatform/osconfig/e2e_tests/config" ) // Project is details of test Project. type Project struct { sync.Mutex TestProjectID string ServiceAccountEmail string ServiceAccountScopes []string testZones map[string]int zoneIndices []string } var mx sync.Mutex var projects = make(map[string]*Project) // GetProject creates a test Project to be used. func GetProject() *Project { projectIDs := config.Projects() projectID := projectIDs[rand.Intn(len(projectIDs))] mx.Lock() defer mx.Unlock() p, ok := projects[projectID] if ok { return p } testZones := map[string]int{} var zoneIndices []string for k, v := range config.Zones() { testZones[k] = v zoneIndices = append(zoneIndices, k) } p = &Project{ TestProjectID: projectID, testZones: testZones, zoneIndices: zoneIndices, ServiceAccountEmail: "default", ServiceAccountScopes: []string{ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", }, } projects[projectID] = p return p } // AcquireZone returns a random zone that still has capacity, or waits until there is one. func (p *Project) AcquireZone() string { timer := time.NewTimer(30 * time.Minute) for { p.Lock() zc := len(p.zoneIndices) if zc == 0 { p.Unlock() select { case <-timer.C: return "Not enough zone quota sepcified. Specify additional quota in `test_zones`." default: time.Sleep(10 * time.Second) continue } } // Pick a random zone. zi := rand.Intn(zc) z := p.zoneIndices[zi] // Decrement the number of instances that this zone can host. p.testZones[z]-- // Remove this zone from zoneIndices if it can't host any more instances. if p.testZones[z] == 0 { p.zoneIndices = append(p.zoneIndices[:zi], p.zoneIndices[zi+1:]...) } p.Unlock() return z } } // ReleaseZone returns a zone so other tests can use it. func (p *Project) ReleaseZone(z string) { p.Lock() defer p.Unlock() n, ok := p.testZones[z] if !ok { // This shouldn't happen, but if it does just ignore it. return } if n == 0 { p.zoneIndices = append(p.zoneIndices, z) } p.testZones[z]++ } osconfig-20250416.02/e2e_tests/test_suites/000077500000000000000000000000001477773331400202765ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/test_suites/guestpolicies/000077500000000000000000000000001477773331400231555ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/test_suites/guestpolicies/guest_policies.go000066400000000000000000000233271477773331400265310ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package guestpolicies GuestPolicy osconfig agent tests. package guestpolicies import ( "context" "fmt" "log" "path" "regexp" "strings" "sync" "time" osconfigV1beta "cloud.google.com/go/osconfig/apiv1beta" "github.com/GoogleCloudPlatform/compute-image-tools/go/e2e_test_utils/junitxml" "github.com/GoogleCloudPlatform/osconfig/e2e_tests/compute" "github.com/GoogleCloudPlatform/osconfig/e2e_tests/config" gcpclients "github.com/GoogleCloudPlatform/osconfig/e2e_tests/gcp_clients" testconfig "github.com/GoogleCloudPlatform/osconfig/e2e_tests/test_config" "github.com/GoogleCloudPlatform/osconfig/e2e_tests/utils" "github.com/kylelemons/godebug/pretty" computeApi "google.golang.org/api/compute/v1" "cloud.google.com/go/osconfig/apiv1beta/osconfigpb" ) var ( testSuiteName = "GuestPolicies" ) var ( dump = &pretty.Config{IncludeUnexported: true} ) const ( packageInstallFunction = "pkginstall" packageRemovalFunction = "pkgremoval" packageInstallFromNewRepoFunction = "pkgfromnewrepo" packageUpdateFunction = "pkgupdate" packageNoUpdateFunction = "pkgnoupdate" recipeInstallFunction = "recipeinstall" recipeStepsFunction = "recipesteps" metadataPolicyFunction = "metadatapolicy" ) type guestPolicyTestSetup struct { image string imageName string guestPolicyID string instanceName string testName string guestPolicy *osconfigpb.GuestPolicy startup *computeApi.MetadataItems mdPolicy *computeApi.MetadataItems machineType string queryPath string assertTimeout time.Duration } func newGuestPolicyTestSetup(image, imageName, instanceName, testName, queryPath, machineType string, gp *osconfigpb.GuestPolicy, startup *computeApi.MetadataItems, assertTimeout time.Duration) *guestPolicyTestSetup { return &guestPolicyTestSetup{ image: image, imageName: imageName, guestPolicyID: instanceName, instanceName: instanceName, guestPolicy: gp, mdPolicy: nil, testName: testName, machineType: machineType, queryPath: queryPath, assertTimeout: assertTimeout, startup: startup, } } // TestSuite is a OSPackage test suite. func TestSuite(ctx context.Context, tswg *sync.WaitGroup, testSuites chan *junitxml.TestSuite, logger *log.Logger, testSuiteRegex, testCaseRegex *regexp.Regexp) { defer tswg.Done() if testSuiteRegex != nil && !testSuiteRegex.MatchString(testSuiteName) { return } testSuite := junitxml.NewTestSuite(testSuiteName) defer testSuite.Finish(testSuites) logger.Printf("Running TestSuite %q", testSuite.Name) testSetup := generateAllTestSetup() var wg sync.WaitGroup tests := make(chan *junitxml.TestCase) for _, setup := range testSetup { wg.Add(1) go packageManagementTestCase(ctx, setup, tests, &wg, logger, testCaseRegex) } go func() { wg.Wait() close(tests) }() for ret := range tests { testSuite.TestCase = append(testSuite.TestCase, ret) } logger.Printf("Finished TestSuite %q", testSuite.Name) } // We only want to create one GuestPolicy at a time to limit QPS. var gpMx sync.Mutex func createGuestPolicy(ctx context.Context, client *osconfigV1beta.Client, req *osconfigpb.CreateGuestPolicyRequest) (*osconfigpb.GuestPolicy, error) { gpMx.Lock() defer gpMx.Unlock() return client.CreateGuestPolicy(ctx, req) } func runTest(ctx context.Context, testCase *junitxml.TestCase, testSetup *guestPolicyTestSetup, logger *log.Logger) { computeClient, err := gcpclients.GetComputeClient() if err != nil { testCase.WriteFailure("Error getting compute client: %v", err) return } var metadataItems []*computeApi.MetadataItems metadataItems = append(metadataItems, testSetup.startup) metadataItems = append(metadataItems, compute.BuildInstanceMetadataItem("enable-osconfig", "true")) metadataItems = append(metadataItems, compute.BuildInstanceMetadataItem("osconfig-disabled-features", "tasks,osinventory")) testProjectConfig := testconfig.GetProject() zone := testProjectConfig.AcquireZone() defer testProjectConfig.ReleaseZone(zone) testCase.Logf("Creating instance %q with image %q", testSetup.instanceName, testSetup.image) inst, err := utils.CreateComputeInstance(metadataItems, computeClient, testSetup.machineType, testSetup.image, testSetup.instanceName, testProjectConfig.TestProjectID, zone, testProjectConfig.ServiceAccountEmail, testProjectConfig.ServiceAccountScopes) if err != nil { testCase.WriteFailure("Error creating instance: %s", utils.GetStatusFromError(err)) return } defer inst.Cleanup() defer inst.RecordSerialOutput(ctx, path.Join(*config.OutDir, testSuiteName), 1) testCase.Logf("Waiting for agent install to complete") if _, err := inst.WaitForGuestAttributes("osconfig_tests/install_done", 5*time.Second, 20*time.Minute); err != nil { testCase.WriteFailure("Error waiting for osconfig agent install: %v", err) return } // Only create the guest policy after the instance has installed the agent. client, err := gcpclients.GetOsConfigClientV1beta() if err != nil { testCase.WriteFailure("Error getting osconfig client: %v", err) return } if testSetup.guestPolicy != nil { req := &osconfigpb.CreateGuestPolicyRequest{ Parent: fmt.Sprintf("projects/%s", testProjectConfig.TestProjectID), GuestPolicyId: testSetup.guestPolicyID, GuestPolicy: testSetup.guestPolicy, } testCase.Logf("Creating GuestPolicy") res, err := createGuestPolicy(ctx, client, req) if err != nil { testCase.WriteFailure("Error running CreateGuestPolicy: %s", utils.GetStatusFromError(err)) return } defer cleanupGuestPolicy(ctx, testCase, res) } if testSetup.mdPolicy != nil { testCase.Logf("Creating Metadata Policy") if err := inst.AddMetadata(testSetup.mdPolicy); err != nil { testCase.WriteFailure("Error running AddMetadata: %s", utils.GetStatusFromError(err)) return } } testCase.Logf("Restarting agent") if err := inst.AddMetadata(compute.BuildInstanceMetadataItem("restart-agent", "true")); err != nil { testCase.WriteFailure("Error running AddMetadata: %s", utils.GetStatusFromError(err)) return } testCase.Logf("Waiting for signal from GuestAttributes") if _, err := inst.WaitForGuestAttributes(testSetup.queryPath, 10*time.Second, testSetup.assertTimeout); err != nil { testCase.WriteFailure("error while asserting: %v", err) return } } func packageManagementTestCase(ctx context.Context, testSetup *guestPolicyTestSetup, tests chan *junitxml.TestCase, wg *sync.WaitGroup, logger *log.Logger, regex *regexp.Regexp) { defer wg.Done() tc, err := getTestCaseFromTestSetUp(testSetup) if err != nil { logger.Fatalf("invalid testcase: %+v", err) return } if tc.FilterTestCase(regex) { tc.Finish(tests) } else { logger.Printf("Running TestCase %q", tc.Name) runTest(ctx, tc, testSetup, logger) if tc.Failure != nil { rerunTC := junitxml.NewTestCase(testSuiteName, strings.TrimPrefix(tc.Name, fmt.Sprintf("[%s] ", testSuiteName))) wg.Add(1) go func() { defer wg.Done() logger.Printf("Rerunning TestCase %q", rerunTC.Name) runTest(ctx, rerunTC, testSetup, logger) rerunTC.Finish(tests) logger.Printf("TestCase %q finished in %fs", rerunTC.Name, rerunTC.Time) }() } tc.Finish(tests) logger.Printf("TestCase %q finished in %fs", tc.Name, tc.Time) } } // factory method to get testcase from the testsetup func getTestCaseFromTestSetUp(testSetup *guestPolicyTestSetup) (*junitxml.TestCase, error) { var tc *junitxml.TestCase switch testSetup.testName { case packageInstallFunction: tc = junitxml.NewTestCase(testSuiteName, fmt.Sprintf("[Package installation] [%s]", testSetup.imageName)) case packageRemovalFunction: tc = junitxml.NewTestCase(testSuiteName, fmt.Sprintf("[Package removal] [%s]", testSetup.imageName)) case packageInstallFromNewRepoFunction: tc = junitxml.NewTestCase(testSuiteName, fmt.Sprintf("[Add a new package from new repository] [%s]", testSetup.imageName)) case packageUpdateFunction: tc = junitxml.NewTestCase(testSuiteName, fmt.Sprintf("[Package update] [%s]", testSetup.imageName)) case packageNoUpdateFunction: tc = junitxml.NewTestCase(testSuiteName, fmt.Sprintf("[Package install doesn't update] [%s]", testSetup.imageName)) case recipeInstallFunction: tc = junitxml.NewTestCase(testSuiteName, fmt.Sprintf("[Recipe installation] [%s]", testSetup.imageName)) case recipeStepsFunction: tc = junitxml.NewTestCase(testSuiteName, fmt.Sprintf("[Recipe steps] [%s]", testSetup.imageName)) case metadataPolicyFunction: tc = junitxml.NewTestCase(testSuiteName, fmt.Sprintf("[Metadata policy] [%s]", testSetup.imageName)) default: return nil, fmt.Errorf("unknown test function name: %s", testSetup.testName) } return tc, nil } func cleanupGuestPolicy(ctx context.Context, testCase *junitxml.TestCase, gp *osconfigpb.GuestPolicy) { client, err := gcpclients.GetOsConfigClientV1beta() if err != nil { testCase.WriteFailure(fmt.Sprintf("Error while deleting guest policy: %s", utils.GetStatusFromError(err))) } if err := client.DeleteGuestPolicy(ctx, &osconfigpb.DeleteGuestPolicyRequest{Name: gp.GetName()}); err != nil { testCase.WriteFailure(fmt.Sprintf("Error calling DeleteGuestPolicy: %s", utils.GetStatusFromError(err))) } } osconfig-20250416.02/e2e_tests/test_suites/guestpolicies/guest_policies_test_data.go000066400000000000000000000541171477773331400305620ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package guestpolicies import ( "fmt" "path" "strings" "time" "github.com/GoogleCloudPlatform/osconfig/e2e_tests/compute" "github.com/GoogleCloudPlatform/osconfig/e2e_tests/config" osconfigserver "github.com/GoogleCloudPlatform/osconfig/e2e_tests/osconfig_server" "github.com/GoogleCloudPlatform/osconfig/e2e_tests/utils" "github.com/golang/protobuf/jsonpb" "cloud.google.com/go/osconfig/apiv1beta/osconfigpb" ) const ( packageInstalled = "osconfig_tests/pkg_installed" packageNotInstalled = "osconfig_tests/pkg_not_installed" gcsfuseTestRepo = "gcsfuse" testResourceBucket = "osconfig-agent-end2end-test-resources" gcsfuseYumRepoBaseURL = "https://packages.cloud.google.com/yum/repos/gcsfuse-el7-x86_64" aptTestRepoBaseURL = "http://packages.cloud.google.com/apt" gooTestRepoURL = "https://packages.cloud.google.com/yuck/repos/osconfig-agent-test-repository" aptRaptureGpgKey = "https://packages.cloud.google.com/apt/doc/apt-key.gpg" ) var ( yumRaptureGpgKeys = []string{"https://packages.cloud.google.com/yum/doc/yum-key.gpg", "https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg"} ) func buildPkgInstallTestSetup(name, image, pkgManager, key string) *guestPolicyTestSetup { assertTimeout := 120 * time.Second testName := packageInstallFunction packageName := "ed" machineType := "e2-medium" if pkgManager == "googet" { packageName = "google-compute-engine-ssh" machineType = "e2-standard-4" } if strings.Contains(image, "rhel-6") || strings.Contains(image, "centos-6") { packageName = "cowsay" } instanceName := fmt.Sprintf("%s-%s-%s-%s", path.Base(name), testName, key, utils.RandString(3)) gp := &osconfigpb.GuestPolicy{ Packages: osconfigserver.BuildPackagePolicy([]string{packageName}, nil, nil), Assignment: &osconfigpb.Assignment{InstanceNamePrefixes: []string{instanceName}}, } ss := getStartupScript(name, pkgManager, packageName) return newGuestPolicyTestSetup(image, name, instanceName, testName, packageInstalled, machineType, gp, ss, assertTimeout) } func addPackageInstallTest(key string) []*guestPolicyTestSetup { var pkgTestSetup []*guestPolicyTestSetup for name, image := range utils.HeadAptImages { pkgTestSetup = append(pkgTestSetup, buildPkgInstallTestSetup(name, image, "apt", key)) } for name, image := range utils.HeadELImages { pkgTestSetup = append(pkgTestSetup, buildPkgInstallTestSetup(name, image, "yum", key)) } for name, image := range utils.HeadSUSEImages { pkgTestSetup = append(pkgTestSetup, buildPkgInstallTestSetup(name, image, "zypper", key)) } for name, image := range utils.HeadWindowsImages { pkgTestSetup = append(pkgTestSetup, buildPkgInstallTestSetup(name, image, "googet", key)) } return pkgTestSetup } func buildPkgUpdateTestSetup(name, image, pkgManager, key string) *guestPolicyTestSetup { assertTimeout := 240 * time.Second testName := packageUpdateFunction packageName := "gcsfuse" machineType := "e2-medium" if pkgManager == "googet" { packageName = "google-compute-engine-ssh" machineType = "e2-standard-4" } instanceName := fmt.Sprintf("%s-%s-%s-%s", path.Base(name), testName, key, utils.RandString(3)) gp := &osconfigpb.GuestPolicy{ Packages: osconfigserver.BuildPackagePolicy(nil, nil, []string{packageName}), Assignment: &osconfigpb.Assignment{InstanceNamePrefixes: []string{instanceName}}, } ss := getUpdateStartupScript(name, pkgManager) return newGuestPolicyTestSetup(image, name, instanceName, testName, packageNotInstalled, machineType, gp, ss, assertTimeout) } func addPackageUpdateTest(key string) []*guestPolicyTestSetup { var pkgTestSetup []*guestPolicyTestSetup for name, image := range utils.HeadAptImages { pkgTestSetup = append(pkgTestSetup, buildPkgUpdateTestSetup(name, image, "apt", key)) } for name, image := range utils.HeadELImages { pkgTestSetup = append(pkgTestSetup, buildPkgUpdateTestSetup(name, image, "yum", key)) } for name, image := range utils.HeadSUSEImages { pkgTestSetup = append(pkgTestSetup, buildPkgUpdateTestSetup(name, image, "zypper", key)) } for name, image := range utils.HeadWindowsImages { pkgTestSetup = append(pkgTestSetup, buildPkgUpdateTestSetup(name, image, "googet", key)) } return pkgTestSetup } func buildPkgDoesNotUpdateTestSetup(name, image, pkgManager, key string) *guestPolicyTestSetup { assertTimeout := 240 * time.Second testName := packageNoUpdateFunction packageName := "gcsfuse" machineType := "e2-medium" if pkgManager == "googet" { packageName = "google-compute-engine-ssh" machineType = "e2-standard-4" } instanceName := fmt.Sprintf("%s-%s-%s-%s", path.Base(name), testName, key, utils.RandString(3)) gp := &osconfigpb.GuestPolicy{ Packages: osconfigserver.BuildPackagePolicy([]string{packageName}, nil, nil), Assignment: &osconfigpb.Assignment{InstanceNamePrefixes: []string{instanceName}}, } ss := getUpdateStartupScript(name, pkgManager) return newGuestPolicyTestSetup(image, name, instanceName, testName, packageInstalled, machineType, gp, ss, assertTimeout) } func addPackageDoesNotUpdateTest(key string) []*guestPolicyTestSetup { var pkgTestSetup []*guestPolicyTestSetup for name, image := range utils.HeadAptImages { pkgTestSetup = append(pkgTestSetup, buildPkgDoesNotUpdateTestSetup(name, image, "apt", key)) } for name, image := range utils.HeadELImages { pkgTestSetup = append(pkgTestSetup, buildPkgDoesNotUpdateTestSetup(name, image, "yum", key)) } for name, image := range utils.HeadSUSEImages { pkgTestSetup = append(pkgTestSetup, buildPkgDoesNotUpdateTestSetup(name, image, "zypper", key)) } for name, image := range utils.HeadWindowsImages { pkgTestSetup = append(pkgTestSetup, buildPkgDoesNotUpdateTestSetup(name, image, "googet", key)) } return pkgTestSetup } func buildPkgRemoveTestSetup(name, image, pkgManager, key string) *guestPolicyTestSetup { assertTimeout := 180 * time.Second testName := packageRemovalFunction packageName := "vim" machineType := "e2-medium" if pkgManager == "googet" { packageName = "certgen" machineType = "e2-standard-4" } instanceName := fmt.Sprintf("%s-%s-%s-%s", path.Base(name), testName, key, utils.RandString(3)) gp := &osconfigpb.GuestPolicy{ Packages: osconfigserver.BuildPackagePolicy(nil, []string{packageName}, nil), Assignment: &osconfigpb.Assignment{InstanceNamePrefixes: []string{instanceName}}, } ss := getStartupScript(name, pkgManager, packageName) return newGuestPolicyTestSetup(image, name, instanceName, testName, packageNotInstalled, machineType, gp, ss, assertTimeout) } func addPackageRemovalTest(key string) []*guestPolicyTestSetup { var pkgTestSetup []*guestPolicyTestSetup for name, image := range utils.HeadAptImages { pkgTestSetup = append(pkgTestSetup, buildPkgRemoveTestSetup(name, image, "apt", key)) } for name, image := range utils.HeadELImages { pkgTestSetup = append(pkgTestSetup, buildPkgRemoveTestSetup(name, image, "yum", key)) } for name, image := range utils.HeadSUSEImages { pkgTestSetup = append(pkgTestSetup, buildPkgRemoveTestSetup(name, image, "zypper", key)) } for name, image := range utils.HeadWindowsImages { pkgTestSetup = append(pkgTestSetup, buildPkgRemoveTestSetup(name, image, "googet", key)) } return pkgTestSetup } func buildPkgInstallFromNewRepoTestSetup(name, image, pkgManager, key string) *guestPolicyTestSetup { assertTimeout := 120 * time.Second packageName := "gcsfuse" testName := packageInstallFromNewRepoFunction machineType := "e2-medium" if pkgManager == "googet" { machineType = "e2-standard-2" } // TODO: use another test pkg for Windows if strings.Contains(image, "windows") { packageName = "osconfig-agent-test" } gcsfuseAptRepoBane := fmt.Sprintf("gcsfuse-%s", utils.GetDebOsName(image)) instanceName := fmt.Sprintf("%s-%s-%s-%s", path.Base(name), testName, key, utils.RandString(3)) gp := &osconfigpb.GuestPolicy{ // Test that upgrade also installs. Packages: osconfigserver.BuildPackagePolicy(nil, nil, []string{packageName}), Assignment: &osconfigpb.Assignment{InstanceNamePrefixes: []string{instanceName}}, PackageRepositories: []*osconfigpb.PackageRepository{ {Repository: osconfigserver.BuildAptRepository(osconfigpb.AptRepository_DEB, aptTestRepoBaseURL, gcsfuseAptRepoBane, aptRaptureGpgKey, []string{"main"})}, {Repository: osconfigserver.BuildYumRepository(gcsfuseTestRepo, "gcsfuse", gcsfuseYumRepoBaseURL, yumRaptureGpgKeys)}, {Repository: osconfigserver.BuildZypperRepository(gcsfuseTestRepo, "gcsfuse", gcsfuseYumRepoBaseURL, yumRaptureGpgKeys)}, {Repository: osconfigserver.BuildGooRepository("Google OSConfig Agent Test Repository", gooTestRepoURL)}, }, } ss := getStartupScript(name, pkgManager, packageName) return newGuestPolicyTestSetup(image, name, instanceName, testName, packageInstalled, machineType, gp, ss, assertTimeout) } func addPackageInstallFromNewRepoTest(key string) []*guestPolicyTestSetup { var pkgTestSetup []*guestPolicyTestSetup for name, image := range utils.HeadAptImages { pkgTestSetup = append(pkgTestSetup, buildPkgInstallFromNewRepoTestSetup(name, image, "apt", key)) } for name, image := range utils.HeadELImages { pkgTestSetup = append(pkgTestSetup, buildPkgInstallFromNewRepoTestSetup(name, image, "yum", key)) } for name, image := range utils.HeadSUSEImages { pkgTestSetup = append(pkgTestSetup, buildPkgInstallFromNewRepoTestSetup(name, image, "zypper", key)) } for name, image := range utils.HeadWindowsImages { pkgTestSetup = append(pkgTestSetup, buildPkgInstallFromNewRepoTestSetup(name, image, "googet", key)) } return pkgTestSetup } func addRecipeInstallTest(key string) []*guestPolicyTestSetup { var recipeTestSetup []*guestPolicyTestSetup for name, image := range utils.HeadAptImages { recipeTestSetup = append(recipeTestSetup, buildRecipeInstallTestSetup(name, image, "apt", key)) } for name, image := range utils.HeadELImages { recipeTestSetup = append(recipeTestSetup, buildRecipeInstallTestSetup(name, image, "yum", key)) } for name, image := range utils.HeadSUSEImages { recipeTestSetup = append(recipeTestSetup, buildRecipeInstallTestSetup(name, image, "zypper", key)) } for name, image := range utils.HeadWindowsImages { recipeTestSetup = append(recipeTestSetup, buildRecipeInstallTestSetup(name, image, "googet", key)) } // This ensures we only run cos tests on the "head image" tests. if config.AgentRepo() == "" { for name, image := range utils.HeadCOSImages { recipeTestSetup = append(recipeTestSetup, buildRecipeInstallTestSetup(name, image, "cos", key)) } } return recipeTestSetup } func addMetadataPolicyTest(key string) []*guestPolicyTestSetup { var policyTestSetup []*guestPolicyTestSetup for name, image := range utils.HeadAptImages { policyTestSetup = append(policyTestSetup, buildMetadataPolicyTestSetup(name, image, "apt", key)) } for name, image := range utils.HeadELImages { policyTestSetup = append(policyTestSetup, buildMetadataPolicyTestSetup(name, image, "yum", key)) } for name, image := range utils.HeadSUSEImages { policyTestSetup = append(policyTestSetup, buildMetadataPolicyTestSetup(name, image, "zypper", key)) } for name, image := range utils.HeadWindowsImages { policyTestSetup = append(policyTestSetup, buildMetadataPolicyTestSetup(name, image, "googet", key)) } // This ensures we only run cos tests on the "head image" tests. if config.AgentRepo() == "" { for name, image := range utils.HeadCOSImages { policyTestSetup = append(policyTestSetup, buildMetadataPolicyTestSetup(name, image, "cos", key)) } } return policyTestSetup } func buildRecipeInstallTestSetup(name, image, pkgManager, key string) *guestPolicyTestSetup { assertTimeout := 120 * time.Second testName := recipeInstallFunction recipeName := "testrecipe" machineType := "e2-medium" if strings.HasPrefix(image, "windows") { machineType = "e2-standard-4" } instanceName := fmt.Sprintf("%s-%s-%s-%s", path.Base(name), testName, key, utils.RandString(3)) gp := &osconfigpb.GuestPolicy{ Assignment: &osconfigpb.Assignment{InstanceNamePrefixes: []string{instanceName}}, Recipes: []*osconfigpb.SoftwareRecipe{ osconfigserver.BuildSoftwareRecipe(recipeName, "", nil, nil), }, } ss := getRecipeInstallStartupScript(name, recipeName, pkgManager) return newGuestPolicyTestSetup(image, name, instanceName, testName, packageInstalled, machineType, gp, ss, assertTimeout) } func addRecipeStepsTest(key string) []*guestPolicyTestSetup { var recipeTestSetup []*guestPolicyTestSetup for name, image := range utils.HeadAptImages { recipeTestSetup = append(recipeTestSetup, buildRecipeStepsTestSetup(name, image, "apt", key)) } for name, image := range utils.HeadELImages { recipeTestSetup = append(recipeTestSetup, buildRecipeStepsTestSetup(name, image, "yum", key)) } for name, image := range utils.HeadSUSEImages { recipeTestSetup = append(recipeTestSetup, buildRecipeStepsTestSetup(name, image, "zypper", key)) } for name, image := range utils.HeadWindowsImages { recipeTestSetup = append(recipeTestSetup, buildRecipeStepsTestSetup(name, image, "googet", key)) } // This ensures we only run cos tests on the "head image" tests. if config.AgentRepo() == "" { for name, image := range utils.HeadCOSImages { recipeTestSetup = append(recipeTestSetup, buildRecipeStepsTestSetup(name, image, "cos", key)) } } return recipeTestSetup } func buildRecipeStepsTestSetup(name, image, pkgManager, key string) *guestPolicyTestSetup { assertTimeout := 120 * time.Second testName := recipeStepsFunction recipeName := "testrecipe" machineType := "e2-medium" if strings.HasPrefix(image, "windows") { machineType = "e2-standard-2" } instanceName := fmt.Sprintf("%s-%s-%s-%s", path.Base(name), testName, key, utils.RandString(3)) artifacts := []*osconfigpb.SoftwareRecipe_Artifact{ { AllowInsecure: true, Id: "copy-test", Artifact: &osconfigpb.SoftwareRecipe_Artifact_Remote_{ Remote: &osconfigpb.SoftwareRecipe_Artifact_Remote{ Uri: "https://example.com", }, }, }, { AllowInsecure: true, Id: "exec-test-sh", Artifact: &osconfigpb.SoftwareRecipe_Artifact_Gcs_{ Gcs: &osconfigpb.SoftwareRecipe_Artifact_Gcs{ Bucket: testResourceBucket, Object: "software_recipes/exec_test.sh", }, }, }, { AllowInsecure: true, Id: "exec-test-cmd", Artifact: &osconfigpb.SoftwareRecipe_Artifact_Gcs_{ Gcs: &osconfigpb.SoftwareRecipe_Artifact_Gcs{ Bucket: testResourceBucket, Object: "software_recipes/exec_test.cmd", }, }, }, { AllowInsecure: true, Id: "tar-test", Artifact: &osconfigpb.SoftwareRecipe_Artifact_Gcs_{ Gcs: &osconfigpb.SoftwareRecipe_Artifact_Gcs{ Bucket: testResourceBucket, Object: "software_recipes/tar_test.tar.gz", }, }, }, { AllowInsecure: true, Id: "zip-test", Artifact: &osconfigpb.SoftwareRecipe_Artifact_Gcs_{ Gcs: &osconfigpb.SoftwareRecipe_Artifact_Gcs{ Bucket: testResourceBucket, Object: "software_recipes/zip_test.zip", }, }, }, { AllowInsecure: true, Id: "dpkg-test", Artifact: &osconfigpb.SoftwareRecipe_Artifact_Gcs_{ Gcs: &osconfigpb.SoftwareRecipe_Artifact_Gcs{ Bucket: testResourceBucket, Object: "software_recipes/ed_1.15-1_amd64.deb", }, }, }, { AllowInsecure: true, Id: "rpm-test", Artifact: &osconfigpb.SoftwareRecipe_Artifact_Gcs_{ Gcs: &osconfigpb.SoftwareRecipe_Artifact_Gcs{ Bucket: testResourceBucket, Object: "software_recipes/ed-1.1-3.3.el6.x86_64.rpm", }, }, }, } pkgTest := &osconfigpb.SoftwareRecipe_Step{} switch pkgManager { case "apt": pkgTest = &osconfigpb.SoftwareRecipe_Step{Step: &osconfigpb.SoftwareRecipe_Step_DpkgInstallation{ DpkgInstallation: &osconfigpb.SoftwareRecipe_Step_InstallDpkg{ArtifactId: "dpkg-test"}, }} case "yum", "zypper": pkgTest = &osconfigpb.SoftwareRecipe_Step{Step: &osconfigpb.SoftwareRecipe_Step_RpmInstallation{ RpmInstallation: &osconfigpb.SoftwareRecipe_Step_InstallRpm{ArtifactId: "rpm-test"}, }} } gp := &osconfigpb.GuestPolicy{ Assignment: &osconfigpb.Assignment{InstanceNamePrefixes: []string{instanceName}}, Recipes: []*osconfigpb.SoftwareRecipe{ osconfigserver.BuildSoftwareRecipe(recipeName, "", artifacts, []*osconfigpb.SoftwareRecipe_Step{ {Step: &osconfigpb.SoftwareRecipe_Step_ScriptRun{ ScriptRun: &osconfigpb.SoftwareRecipe_Step_RunScript{ Script: "echo 'hello world' > /tmp/osconfig-SoftwareRecipe_Step_RunScript_SHELL", Interpreter: osconfigpb.SoftwareRecipe_Step_RunScript_SHELL, }, }}, {Step: &osconfigpb.SoftwareRecipe_Step_FileCopy{ FileCopy: &osconfigpb.SoftwareRecipe_Step_CopyFile{ArtifactId: "copy-test", Destination: "/tmp/osconfig-copy-test"}, }}, {Step: &osconfigpb.SoftwareRecipe_Step_ArchiveExtraction{ ArchiveExtraction: &osconfigpb.SoftwareRecipe_Step_ExtractArchive{ArtifactId: "tar-test", Destination: "/tmp/tar-test", Type: osconfigpb.SoftwareRecipe_Step_ExtractArchive_TAR_GZIP}, }}, {Step: &osconfigpb.SoftwareRecipe_Step_ArchiveExtraction{ ArchiveExtraction: &osconfigpb.SoftwareRecipe_Step_ExtractArchive{ArtifactId: "zip-test", Destination: "/tmp/zip-test", Type: osconfigpb.SoftwareRecipe_Step_ExtractArchive_ZIP}, }}, }, ), }, } // COS can not create files with the executable bit set on the root partition. if pkgManager != "cos" { gp.Recipes[0].InstallSteps = append(gp.Recipes[0].InstallSteps, &osconfigpb.SoftwareRecipe_Step{Step: &osconfigpb.SoftwareRecipe_Step_ScriptRun{ ScriptRun: &osconfigpb.SoftwareRecipe_Step_RunScript{ Script: "#!/bin/sh\necho 'hello world' > /tmp/osconfig-SoftwareRecipe_Step_RunScript_INTERPRETER_UNSPECIFIED", Interpreter: osconfigpb.SoftwareRecipe_Step_RunScript_INTERPRETER_UNSPECIFIED, }, }}, &osconfigpb.SoftwareRecipe_Step{Step: &osconfigpb.SoftwareRecipe_Step_FileExec{ FileExec: &osconfigpb.SoftwareRecipe_Step_ExecFile{LocationType: &osconfigpb.SoftwareRecipe_Step_ExecFile_ArtifactId{ArtifactId: "exec-test-sh"}}, }}, pkgTest) } if pkgManager == "googet" { gp = &osconfigpb.GuestPolicy{ Assignment: &osconfigpb.Assignment{InstanceNamePrefixes: []string{instanceName}}, Recipes: []*osconfigpb.SoftwareRecipe{ osconfigserver.BuildSoftwareRecipe(recipeName, "", artifacts, []*osconfigpb.SoftwareRecipe_Step{ {Step: &osconfigpb.SoftwareRecipe_Step_ScriptRun{ ScriptRun: &osconfigpb.SoftwareRecipe_Step_RunScript{ Script: "echo 'hello world' > c:\\osconfig-SoftwareRecipe_Step_RunScript_POWERSHELL", Interpreter: osconfigpb.SoftwareRecipe_Step_RunScript_POWERSHELL, }, }}, {Step: &osconfigpb.SoftwareRecipe_Step_ScriptRun{ ScriptRun: &osconfigpb.SoftwareRecipe_Step_RunScript{ Script: "echo 'hello world' > c:\\osconfig-SoftwareRecipe_Step_RunScript_SHELL", Interpreter: osconfigpb.SoftwareRecipe_Step_RunScript_SHELL, }, }}, {Step: &osconfigpb.SoftwareRecipe_Step_FileExec{ FileExec: &osconfigpb.SoftwareRecipe_Step_ExecFile{LocationType: &osconfigpb.SoftwareRecipe_Step_ExecFile_ArtifactId{ArtifactId: "exec-test-cmd"}}, }}, {Step: &osconfigpb.SoftwareRecipe_Step_FileCopy{ FileCopy: &osconfigpb.SoftwareRecipe_Step_CopyFile{ArtifactId: "copy-test", Destination: "c:\\osconfig-copy-test"}, }}, {Step: &osconfigpb.SoftwareRecipe_Step_ArchiveExtraction{ ArchiveExtraction: &osconfigpb.SoftwareRecipe_Step_ExtractArchive{ArtifactId: "tar-test", Destination: "c:\\tar-test", Type: osconfigpb.SoftwareRecipe_Step_ExtractArchive_TAR_GZIP}, }}, {Step: &osconfigpb.SoftwareRecipe_Step_ArchiveExtraction{ ArchiveExtraction: &osconfigpb.SoftwareRecipe_Step_ExtractArchive{ArtifactId: "zip-test", Destination: "c:\\zip-test", Type: osconfigpb.SoftwareRecipe_Step_ExtractArchive_ZIP}, }}, }, ), }, } } ss := getRecipeStepsStartupScript(name, recipeName, pkgManager) return newGuestPolicyTestSetup(image, name, instanceName, testName, packageInstalled, machineType, gp, ss, assertTimeout) } func buildMetadataPolicyTestSetup(name, image, pkgManager, key string) *guestPolicyTestSetup { assertTimeout := 60 * time.Second testName := metadataPolicyFunction recipeName := "testrecipe" machineType := "e2-medium" if strings.HasPrefix(image, "windows") { machineType = "e2-standard-2" } instanceName := fmt.Sprintf("%s-%s-%s-%s", path.Base(name), testName, key, utils.RandString(3)) ss := getRecipeInstallStartupScript(name, recipeName, pkgManager) ts := newGuestPolicyTestSetup(image, name, instanceName, testName, packageInstalled, machineType, nil, ss, assertTimeout) marshaler := jsonpb.Marshaler{} recipeString, err := marshaler.MarshalToString(osconfigserver.BuildSoftwareRecipe(recipeName, "", nil, nil)) if err != nil { // An error in the test setup means something seriously wrong. panic(err) } rec := fmt.Sprintf(`{"softwareRecipes": [%s]}`, recipeString) ts.mdPolicy = compute.BuildInstanceMetadataItem("gce-software-declaration", rec) return ts } func generateAllTestSetup() []*guestPolicyTestSetup { key := utils.RandString(3) pkgTestSetup := []*guestPolicyTestSetup{} pkgTestSetup = append(pkgTestSetup, addPackageInstallTest(key)...) pkgTestSetup = append(pkgTestSetup, addPackageRemovalTest(key)...) pkgTestSetup = append(pkgTestSetup, addPackageInstallFromNewRepoTest(key)...) pkgTestSetup = append(pkgTestSetup, addPackageUpdateTest(key)...) pkgTestSetup = append(pkgTestSetup, addPackageDoesNotUpdateTest(key)...) pkgTestSetup = append(pkgTestSetup, addRecipeInstallTest(key)...) pkgTestSetup = append(pkgTestSetup, addRecipeStepsTest(key)...) pkgTestSetup = append(pkgTestSetup, addMetadataPolicyTest(key)...) return pkgTestSetup } osconfig-20250416.02/e2e_tests/test_suites/guestpolicies/guest_policies_utils.go000066400000000000000000000326231477773331400277500ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package guestpolicies import ( "fmt" "github.com/GoogleCloudPlatform/osconfig/e2e_tests/utils" computeApi "google.golang.org/api/compute/v1" ) var waitForRestartLinux = ` echo 'Waiting for signal to restart agent' while [[ -z $restarted ]]; do sleep 1 restart=$(curl -f "http://metadata.google.internal/computeMetadata/v1/instance/attributes/restart-agent" -H "Metadata-Flavor: Google") if [[ -n $restart ]]; then systemctl restart google-osconfig-agent restarted=true sleep 30 fi done ` var waitForRestartWin = ` echo 'Waiting for signal to restart agent' while (! $restarted) { sleep 1 $restart = Invoke-WebRequest -UseBasicParsing http://metadata.google.internal/computeMetadata/v1/instance/attributes/restart-agent -Headers @{"Metadata-Flavor"="Google"} if ($restart) { Restart-Service google_osconfig_agent $restarted = $true sleep 30 } } ` func getStartupScript(image, pkgManager, packageName string) *computeApi.MetadataItems { var ss, key string switch pkgManager { case "apt": ss = ` apt-get -y remove %[3]s %[1]s %[2]s while true; do isinstalled=$(/usr/bin/dpkg-query -s %s) if [[ $isinstalled =~ "Status: install ok installed" ]]; then uri=http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%s else uri=http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%s fi curl -X PUT --data "1" $uri -H "Metadata-Flavor: Google" sleep 5 done` ss = fmt.Sprintf(ss, utils.InstallOSConfigDeb(image), waitForRestartLinux, packageName, packageInstalled, packageNotInstalled) key = "startup-script" case "yum": ss = ` while ! yum -y remove %[3]s; do if [[ n -gt 5 ]]; then exit 1 fi n=$[$n+1] sleep 10 done %[1]s %[2]s while true; do isinstalled=$(/usr/bin/rpmquery -a %[3]s) if [[ $isinstalled =~ ^%[3]s-* ]]; then uri=http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%s else uri=http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%s fi curl -X PUT --data "1" $uri -H "Metadata-Flavor: Google" sleep 5 done` ss = fmt.Sprintf(ss, utils.InstallOSConfigEL(image), waitForRestartLinux, packageName, packageInstalled, packageNotInstalled) key = "startup-script" case "googet": ss = ` googet addrepo test https://packages.cloud.google.com/yuck/repos/osconfig-agent-test-repository %s %s while(1) { $installed_packages = googet installed if ($installed_packages -like "*%s*") { $uri = 'http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%s' } else { $uri = 'http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%s' } Invoke-RestMethod -Method PUT -Uri $uri -Headers @{"Metadata-Flavor" = "Google"} -Body 1 sleep 5 }` ss = fmt.Sprintf(ss, utils.InstallOSConfigGooGet(), waitForRestartWin, packageName, packageInstalled, packageNotInstalled) key = "windows-startup-script-ps1" case "zypper": ss = ` sleep 10 zypper -n remove %[3]s %[1]s %[2]s while true; do isinstalled=$(/usr/bin/rpmquery -a %[3]s) if [[ $isinstalled =~ ^%[3]s-* ]]; then uri=http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%s else uri=http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%s fi curl -X PUT --data "1" $uri -H "Metadata-Flavor: Google" sleep 5 done` ss = fmt.Sprintf(ss, utils.InstallOSConfigSUSE(), waitForRestartLinux, packageName, packageInstalled, packageNotInstalled) key = "startup-script" default: fmt.Printf("Invalid package manager: %s", pkgManager) } return &computeApi.MetadataItems{ Key: key, Value: &ss, } } func getUpdateStartupScript(image, pkgManager string) *computeApi.MetadataItems { var ss, key string switch pkgManager { case "apt": ss = ` echo 'Adding gcsfuse repo' # install gnupg2 if not exist apt-get update apt-get install -y gnupg2 OSTYPE=$(lsb_release -c -s) GCSFUSE_REPO="gcsfuse-$OSTYPE" echo "deb http://packages.cloud.google.com/apt $GCSFUSE_REPO main" >> /etc/apt/sources.list curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - while fuser /var/lib/dpkg/lock-frontend >/dev/null 2>&1; do sleep 5 done apt-get update apt-get -y remove gcsfuse || exit 1 apt-get -y install gcsfuse=2.3.2 || exit 1 %[1]s %[2]s while true; do isinstalled=$(/usr/bin/dpkg-query -f '${Version}' -W gcsfuse) if [[ $isinstalled == "2.3.2" ]]; then uri=http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%[3]s else uri=http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%[4]s fi curl -X PUT --data "1" $uri -H "Metadata-Flavor: Google" sleep 5; done` ss = fmt.Sprintf(ss, utils.InstallOSConfigDeb(image), waitForRestartLinux, packageInstalled, packageNotInstalled) key = "startup-script" case "yum": ss = ` echo 'Adding gcsfuse repo' cat > /etc/yum.repos.d/gcsfuse.repo < /etc/yum.repos.d/gcsfuse.repo <> /etc/apt/sources.list curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - while fuser /var/lib/dpkg/lock-frontend >/dev/null 2>&1; do sleep 5 done apt-get update apt-get -y install gcsfuse || exit 1 %s` return fmt.Sprintf(ss, gcsfuseAptRepoBane, utils.InstallOSConfigDeb(image)) } func getStartupScriptGoo() string { ss := ` echo 'Adding test repo' googet addrepo test https://packages.cloud.google.com/yuck/repos/osconfig-agent-test-repository %s` return fmt.Sprintf(ss, utils.InstallOSConfigGooGet()) } func getStartupScriptZypper() string { ss := ` echo 'Adding gcsfuse repo' cat > /etc/zypp/repos.d/osconfig-agent-test.repo </dev/null; then\nexit 100\nfi\nexit 101", }, Args: []string{checkPaths[3]}, Interpreter: osconfigpb.OSPolicy_Resource_ExecResource_Exec_SHELL, }, Enforce: &osconfigpb.OSPolicy_Resource_ExecResource_Exec{ Source: &osconfigpb.OSPolicy_Resource_ExecResource_Exec_Script{ Script: "#!/bin/sh\ntouch $1\nexit 100", }, Args: []string{checkPaths[3]}, Interpreter: osconfigpb.OSPolicy_Resource_ExecResource_Exec_NONE, }, }, }, }, { Id: "exec-output", ResourceType: &osconfigpb.OSPolicy_Resource_Exec{ Exec: &osconfigpb.OSPolicy_Resource_ExecResource{ Validate: &osconfigpb.OSPolicy_Resource_ExecResource_Exec{ Source: &osconfigpb.OSPolicy_Resource_ExecResource_Exec_Script{ Script: fmt.Sprintf("if ls %s >/dev/null; then\nexit 100\nfi\nexit 101", checkPaths[4]), }, Interpreter: osconfigpb.OSPolicy_Resource_ExecResource_Exec_SHELL, }, Enforce: &osconfigpb.OSPolicy_Resource_ExecResource_Exec{ Source: &osconfigpb.OSPolicy_Resource_ExecResource_Exec_Script{ Script: fmt.Sprintf("echo -n %q > %s\nexit 100", string(output), checkPaths[4]), }, Interpreter: osconfigpb.OSPolicy_Resource_ExecResource_Exec_SHELL, OutputFilePath: checkPaths[4], }, }, }, }, { Id: "exec-output-too-large", ResourceType: &osconfigpb.OSPolicy_Resource_Exec{ Exec: &osconfigpb.OSPolicy_Resource_ExecResource{ Validate: &osconfigpb.OSPolicy_Resource_ExecResource_Exec{ Source: &osconfigpb.OSPolicy_Resource_ExecResource_Exec_Script{ Script: fmt.Sprintf("if ls %s >/dev/null; then\nexit 100\nfi\nexit 101", checkPaths[5]), }, Interpreter: osconfigpb.OSPolicy_Resource_ExecResource_Exec_SHELL, }, Enforce: &osconfigpb.OSPolicy_Resource_ExecResource_Exec{ Source: &osconfigpb.OSPolicy_Resource_ExecResource_Exec_Script{ Script: fmt.Sprintf("head -c 1000KB /dev/zero > %s\nexit 100", checkPaths[5]), }, Interpreter: osconfigpb.OSPolicy_Resource_ExecResource_Exec_SHELL, OutputFilePath: checkPaths[5], }, }, }, }, }, }, }, }, }, } expectedSteps := []*osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep{ { Type: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_VALIDATION, }, { Type: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_DESIRED_STATE_CHECK, }, { Type: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_DESIRED_STATE_ENFORCEMENT, }, { Type: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_DESIRED_STATE_CHECK_POST_ENFORCEMENT, }, } wantCompliances := []*osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance{ { OsPolicyId: testName, ComplianceState: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_COMPLIANT, OsPolicyResourceCompliances: []*osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance{ { OsPolicyResourceId: "exec-gcs", ConfigSteps: expectedSteps, ComplianceState: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_COMPLIANT, }, { OsPolicyResourceId: "exec-uri", ConfigSteps: expectedSteps, ComplianceState: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_COMPLIANT, }, { OsPolicyResourceId: "exec-local", ConfigSteps: expectedSteps, ComplianceState: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_COMPLIANT, }, { OsPolicyResourceId: "exec-script", ConfigSteps: expectedSteps, ComplianceState: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_COMPLIANT, }, { OsPolicyResourceId: "exec-output", ConfigSteps: expectedSteps, ComplianceState: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_COMPLIANT, Output: &osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput_{ ExecResourceOutput: &osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput{ EnforcementOutput: output, }, }, }, { OsPolicyResourceId: "exec-output-too-large", ConfigSteps: []*osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep{ { Type: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_VALIDATION, }, { Type: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_DESIRED_STATE_CHECK, }, { Type: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_DESIRED_STATE_ENFORCEMENT, ErrorMessage: `Enforce state: resource "exec-output-too-large" error: contents of OutputFilePath greater than 500K`, }, { Type: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_DESIRED_STATE_CHECK_POST_ENFORCEMENT, }, }, ComplianceState: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_COMPLIANT, Output: &osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput_{ ExecResourceOutput: &osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput{ EnforcementOutput: make([]byte, 500*1024), }, }, }, }, }, } ss := getStartupScriptExec(name, pkgManager, checkPaths) return newOsPolicyTestSetup(image, name, instanceName, testName, []string{fileExists}, machineType, ospa, ss, assertTimeout, wantCompliances) } func buildWindowsExecResourceTests(name, image, pkgManager, key string) *osPolicyTestSetup { assertTimeout := 360 * time.Second testName := windowsExecResource machineType := "e2-standard-2" checkPaths := []string{"/path1", "/path2", "/path3", "/path4", "/path5", "/path6", "/path7", "/path8"} output := []byte("some output") instanceName := fmt.Sprintf("%s-%s-%s-%s", path.Base(name), testName, key, utils.RandString(3)) ospa := &osconfigpb.OSPolicyAssignment{ InstanceFilter: &osconfigpb.OSPolicyAssignment_InstanceFilter{ InclusionLabels: []*osconfigpb.OSPolicyAssignment_LabelSet{{ Labels: map[string]string{"name": instanceName}}, }, }, Rollout: &osconfigpb.OSPolicyAssignment_Rollout{ DisruptionBudget: &osconfigpb.FixedOrPercent{Mode: &osconfigpb.FixedOrPercent_Percent{Percent: 100}}, MinWaitDuration: &durationpb.Duration{Seconds: 0}, }, OsPolicies: []*osconfigpb.OSPolicy{ { Id: testName, Mode: osconfigpb.OSPolicy_ENFORCEMENT, // Each of these resources checks for and then creates a file from checkPaths. ResourceGroups: []*osconfigpb.OSPolicy_ResourceGroup{ { Resources: []*osconfigpb.OSPolicy_Resource{ { Id: "exec-gcs-cmd", ResourceType: &osconfigpb.OSPolicy_Resource_Exec{ Exec: &osconfigpb.OSPolicy_Resource_ExecResource{ Validate: &osconfigpb.OSPolicy_Resource_ExecResource_Exec{ Source: &osconfigpb.OSPolicy_Resource_ExecResource_Exec_File{ File: &osconfigpb.OSPolicy_Resource_File{ Type: &osconfigpb.OSPolicy_Resource_File_Gcs_{ Gcs: &osconfigpb.OSPolicy_Resource_File_Gcs{ Bucket: "osconfig-agent-end2end-test-resources", Object: "OSPolicies/validate.cmd", Generation: 1618340275278922, }, }, }, }, Args: []string{checkPaths[0]}, Interpreter: osconfigpb.OSPolicy_Resource_ExecResource_Exec_SHELL, }, Enforce: &osconfigpb.OSPolicy_Resource_ExecResource_Exec{ Source: &osconfigpb.OSPolicy_Resource_ExecResource_Exec_File{ File: &osconfigpb.OSPolicy_Resource_File{ Type: &osconfigpb.OSPolicy_Resource_File_Gcs_{ Gcs: &osconfigpb.OSPolicy_Resource_File_Gcs{ Bucket: "osconfig-agent-end2end-test-resources", Object: "OSPolicies/enforce.cmd", Generation: 1619475023716779, }, }, }, }, Args: []string{checkPaths[0]}, Interpreter: osconfigpb.OSPolicy_Resource_ExecResource_Exec_NONE, }, }, }, }, { Id: "exec-uri-cmd", ResourceType: &osconfigpb.OSPolicy_Resource_Exec{ Exec: &osconfigpb.OSPolicy_Resource_ExecResource{ Validate: &osconfigpb.OSPolicy_Resource_ExecResource_Exec{ Source: &osconfigpb.OSPolicy_Resource_ExecResource_Exec_File{ File: &osconfigpb.OSPolicy_Resource_File{ Type: &osconfigpb.OSPolicy_Resource_File_Remote_{ Remote: &osconfigpb.OSPolicy_Resource_File_Remote{ Uri: "https://storage.googleapis.com/osconfig-agent-end2end-test-resources/OSPolicies/validate.cmd", Sha256Checksum: "1635e97b142fa9dd21bb023093ede409d242f52a535ad779bb80539db95c8f77", }, }, }, }, Args: []string{checkPaths[1]}, Interpreter: osconfigpb.OSPolicy_Resource_ExecResource_Exec_SHELL, }, Enforce: &osconfigpb.OSPolicy_Resource_ExecResource_Exec{ Source: &osconfigpb.OSPolicy_Resource_ExecResource_Exec_File{ File: &osconfigpb.OSPolicy_Resource_File{ Type: &osconfigpb.OSPolicy_Resource_File_Remote_{ Remote: &osconfigpb.OSPolicy_Resource_File_Remote{ Uri: "https://storage.googleapis.com/osconfig-agent-end2end-test-resources/OSPolicies/enforce.cmd", Sha256Checksum: "08307e3de5baf1c7051c6901e798aaaf0c5f06350cc4518fbcd431dc6e6af003", }, }, }, }, Args: []string{checkPaths[1]}, Interpreter: osconfigpb.OSPolicy_Resource_ExecResource_Exec_NONE, }, }, }, }, // These local scripts are created by the startup script. { Id: "exec-local-cmd", ResourceType: &osconfigpb.OSPolicy_Resource_Exec{ Exec: &osconfigpb.OSPolicy_Resource_ExecResource{ Validate: &osconfigpb.OSPolicy_Resource_ExecResource_Exec{ Source: &osconfigpb.OSPolicy_Resource_ExecResource_Exec_File{ File: &osconfigpb.OSPolicy_Resource_File{ Type: &osconfigpb.OSPolicy_Resource_File_LocalPath{ LocalPath: "/validate.cmd", }, }, }, Args: []string{checkPaths[2]}, Interpreter: osconfigpb.OSPolicy_Resource_ExecResource_Exec_SHELL, }, Enforce: &osconfigpb.OSPolicy_Resource_ExecResource_Exec{ Source: &osconfigpb.OSPolicy_Resource_ExecResource_Exec_File{ File: &osconfigpb.OSPolicy_Resource_File{ Type: &osconfigpb.OSPolicy_Resource_File_LocalPath{ LocalPath: "/enforce.cmd", }, }, }, Args: []string{checkPaths[2]}, Interpreter: osconfigpb.OSPolicy_Resource_ExecResource_Exec_NONE, }, }, }, }, // No support for executing a script with no Interpreter via Script on Windows. { Id: "exec-script", ResourceType: &osconfigpb.OSPolicy_Resource_Exec{ Exec: &osconfigpb.OSPolicy_Resource_ExecResource{ Validate: &osconfigpb.OSPolicy_Resource_ExecResource_Exec{ Source: &osconfigpb.OSPolicy_Resource_ExecResource_Exec_Script{ Script: "if exist %1 exit 100\nexit 101", }, Args: []string{checkPaths[3]}, Interpreter: osconfigpb.OSPolicy_Resource_ExecResource_Exec_SHELL, }, Enforce: &osconfigpb.OSPolicy_Resource_ExecResource_Exec{ Source: &osconfigpb.OSPolicy_Resource_ExecResource_Exec_Script{ Script: "New-Item -ItemType File -Path $Args[0]; exit 100", }, Args: []string{checkPaths[3]}, Interpreter: osconfigpb.OSPolicy_Resource_ExecResource_Exec_POWERSHELL, }, }, }, }, // Windows does not support executing a powershell script directly. { Id: "exec-gcs-uri-ps1", ResourceType: &osconfigpb.OSPolicy_Resource_Exec{ Exec: &osconfigpb.OSPolicy_Resource_ExecResource{ Validate: &osconfigpb.OSPolicy_Resource_ExecResource_Exec{ Source: &osconfigpb.OSPolicy_Resource_ExecResource_Exec_File{ File: &osconfigpb.OSPolicy_Resource_File{ Type: &osconfigpb.OSPolicy_Resource_File_Gcs_{ Gcs: &osconfigpb.OSPolicy_Resource_File_Gcs{ Bucket: "osconfig-agent-end2end-test-resources", Object: "OSPolicies/validate.ps1", Generation: 1617995966532645, }, }, }, }, Args: []string{checkPaths[4]}, Interpreter: osconfigpb.OSPolicy_Resource_ExecResource_Exec_POWERSHELL, }, Enforce: &osconfigpb.OSPolicy_Resource_ExecResource_Exec{ Source: &osconfigpb.OSPolicy_Resource_ExecResource_Exec_File{ File: &osconfigpb.OSPolicy_Resource_File{ Type: &osconfigpb.OSPolicy_Resource_File_Remote_{ Remote: &osconfigpb.OSPolicy_Resource_File_Remote{ Uri: "https://storage.googleapis.com/osconfig-agent-end2end-test-resources/OSPolicies/enforce.ps1", Sha256Checksum: "a5737e35f8a3a04785e4e0b9ffa90c5209db320c0ef9692672f5fb0b1dfe99d2", }, }, }, }, Args: []string{checkPaths[4]}, Interpreter: osconfigpb.OSPolicy_Resource_ExecResource_Exec_POWERSHELL, }, }, }, }, { Id: "exec-local-powershell", ResourceType: &osconfigpb.OSPolicy_Resource_Exec{ Exec: &osconfigpb.OSPolicy_Resource_ExecResource{ Validate: &osconfigpb.OSPolicy_Resource_ExecResource_Exec{ Source: &osconfigpb.OSPolicy_Resource_ExecResource_Exec_File{ File: &osconfigpb.OSPolicy_Resource_File{ Type: &osconfigpb.OSPolicy_Resource_File_LocalPath{ LocalPath: "/validate.ps1", }, }, }, Args: []string{checkPaths[5]}, Interpreter: osconfigpb.OSPolicy_Resource_ExecResource_Exec_POWERSHELL, }, Enforce: &osconfigpb.OSPolicy_Resource_ExecResource_Exec{ Source: &osconfigpb.OSPolicy_Resource_ExecResource_Exec_File{ File: &osconfigpb.OSPolicy_Resource_File{ Type: &osconfigpb.OSPolicy_Resource_File_LocalPath{ LocalPath: "/enforce.ps1", }, }, }, Args: []string{checkPaths[5]}, Interpreter: osconfigpb.OSPolicy_Resource_ExecResource_Exec_POWERSHELL, }, }, }, }, { Id: "exec-output", ResourceType: &osconfigpb.OSPolicy_Resource_Exec{ Exec: &osconfigpb.OSPolicy_Resource_ExecResource{ Validate: &osconfigpb.OSPolicy_Resource_ExecResource_Exec{ Source: &osconfigpb.OSPolicy_Resource_ExecResource_Exec_Script{ Script: fmt.Sprintf("if exist %s exit 100\nexit 101", checkPaths[6]), }, Interpreter: osconfigpb.OSPolicy_Resource_ExecResource_Exec_SHELL, }, Enforce: &osconfigpb.OSPolicy_Resource_ExecResource_Exec{ Source: &osconfigpb.OSPolicy_Resource_ExecResource_Exec_Script{ Script: fmt.Sprintf("echo|set /p=%q > %s\nexit 100", string(output), checkPaths[6]), }, Interpreter: osconfigpb.OSPolicy_Resource_ExecResource_Exec_SHELL, OutputFilePath: checkPaths[6], }, }, }, }, { Id: "exec-output-too-large", ResourceType: &osconfigpb.OSPolicy_Resource_Exec{ Exec: &osconfigpb.OSPolicy_Resource_ExecResource{ Validate: &osconfigpb.OSPolicy_Resource_ExecResource_Exec{ Source: &osconfigpb.OSPolicy_Resource_ExecResource_Exec_Script{ Script: fmt.Sprintf("if exist %s exit 100\nexit 101", checkPaths[7]), }, Interpreter: osconfigpb.OSPolicy_Resource_ExecResource_Exec_SHELL, }, Enforce: &osconfigpb.OSPolicy_Resource_ExecResource_Exec{ Source: &osconfigpb.OSPolicy_Resource_ExecResource_Exec_Script{ Script: fmt.Sprintf("fsutil file createnew %s 1000000\nexit 100", checkPaths[7]), }, Interpreter: osconfigpb.OSPolicy_Resource_ExecResource_Exec_SHELL, OutputFilePath: checkPaths[7], }, }, }, }, }, }, }, }, }, } expectedSteps := []*osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep{ { Type: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_VALIDATION, }, { Type: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_DESIRED_STATE_CHECK, }, { Type: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_DESIRED_STATE_ENFORCEMENT, }, { Type: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_DESIRED_STATE_CHECK_POST_ENFORCEMENT, }, } wantCompliances := []*osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance{ { OsPolicyId: testName, ComplianceState: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_COMPLIANT, OsPolicyResourceCompliances: []*osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance{ { OsPolicyResourceId: "exec-gcs-cmd", ConfigSteps: expectedSteps, ComplianceState: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_COMPLIANT, }, { OsPolicyResourceId: "exec-uri-cmd", ConfigSteps: expectedSteps, ComplianceState: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_COMPLIANT, }, { OsPolicyResourceId: "exec-local-cmd", ConfigSteps: expectedSteps, ComplianceState: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_COMPLIANT, }, { OsPolicyResourceId: "exec-script", ConfigSteps: expectedSteps, ComplianceState: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_COMPLIANT, }, { OsPolicyResourceId: "exec-gcs-uri-ps1", ConfigSteps: expectedSteps, ComplianceState: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_COMPLIANT, }, { OsPolicyResourceId: "exec-local-powershell", ConfigSteps: expectedSteps, ComplianceState: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_COMPLIANT, }, { OsPolicyResourceId: "exec-output", ConfigSteps: expectedSteps, ComplianceState: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_COMPLIANT, Output: &osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput_{ ExecResourceOutput: &osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput{ EnforcementOutput: output, }, }, }, { OsPolicyResourceId: "exec-output-too-large", ConfigSteps: []*osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep{ { Type: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_VALIDATION, }, { Type: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_DESIRED_STATE_CHECK, }, { Type: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_DESIRED_STATE_ENFORCEMENT, ErrorMessage: `Enforce state: resource "exec-output-too-large" error: contents of OutputFilePath greater than 500K`, }, { Type: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_DESIRED_STATE_CHECK_POST_ENFORCEMENT, }, }, ComplianceState: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_COMPLIANT, Output: &osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput_{ ExecResourceOutput: &osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_ExecResourceOutput{ EnforcementOutput: make([]byte, 500*1024), }, }, }, }, }, } ss := getStartupScriptExec(name, pkgManager, checkPaths) return newOsPolicyTestSetup(image, name, instanceName, testName, []string{fileExists}, machineType, ospa, ss, assertTimeout, wantCompliances) } func addExecResourceTests(key string) []*osPolicyTestSetup { var pkgTestSetup []*osPolicyTestSetup for name, image := range utils.HeadAptImages { pkgTestSetup = append(pkgTestSetup, buildLinuxExecResourceTests(name, image, "apt", key)) } for name, image := range utils.HeadELImages { pkgTestSetup = append(pkgTestSetup, buildLinuxExecResourceTests(name, image, "yum", key)) } for name, image := range utils.HeadSUSEImages { pkgTestSetup = append(pkgTestSetup, buildLinuxExecResourceTests(name, image, "zypper", key)) } for name, image := range utils.HeadWindowsImages { pkgTestSetup = append(pkgTestSetup, buildWindowsExecResourceTests(name, image, "googet", key)) } return pkgTestSetup } func buildValidationModeTests(name, image, pkgManager, key string) *osPolicyTestSetup { assertTimeout := 360 * time.Second testName := validationMode machineType := "e2-medium" if strings.Contains(image, "windows") { machineType = "e2-standard-2" } instanceName := fmt.Sprintf("%s-%s-%s-%s", path.Base(name), testName, key, utils.RandString(3)) ospa := &osconfigpb.OSPolicyAssignment{ InstanceFilter: &osconfigpb.OSPolicyAssignment_InstanceFilter{ InclusionLabels: []*osconfigpb.OSPolicyAssignment_LabelSet{{ Labels: map[string]string{"name": instanceName}}, }, }, Rollout: &osconfigpb.OSPolicyAssignment_Rollout{ DisruptionBudget: &osconfigpb.FixedOrPercent{Mode: &osconfigpb.FixedOrPercent_Percent{Percent: 100}}, MinWaitDuration: &durationpb.Duration{Seconds: 0}, }, OsPolicies: []*osconfigpb.OSPolicy{ { Id: "file-present", Mode: osconfigpb.OSPolicy_VALIDATION, ResourceGroups: []*osconfigpb.OSPolicy_ResourceGroup{ { Resources: []*osconfigpb.OSPolicy_Resource{ { Id: "file-present", ResourceType: &osconfigpb.OSPolicy_Resource_File_{ File: &osconfigpb.OSPolicy_Resource_FileResource{ State: osconfigpb.OSPolicy_Resource_FileResource_PRESENT, Path: "/file-dne", Source: &osconfigpb.OSPolicy_Resource_FileResource_Content{Content: "something"}, }, }, }, }, }, }, }, }, } wantCompliances := []*osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance{ { OsPolicyId: "file-present", ComplianceState: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_NON_COMPLIANT, OsPolicyResourceCompliances: []*osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance{ { OsPolicyResourceId: "file-present", ConfigSteps: []*osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep{ { Type: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_VALIDATION, }, { Type: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_OSPolicyResourceConfigStep_DESIRED_STATE_CHECK, }, }, ComplianceState: osconfigpb.OSPolicyAssignmentReport_OSPolicyCompliance_OSPolicyResourceCompliance_NON_COMPLIANT, }, }, }, } ss := getStartupScriptFile(name, pkgManager, "", nil) return newOsPolicyTestSetup(image, name, instanceName, testName, nil, machineType, ospa, ss, assertTimeout, wantCompliances) } func addValidationModeTests(key string) []*osPolicyTestSetup { var pkgTestSetup []*osPolicyTestSetup for name, image := range utils.HeadAptImages { pkgTestSetup = append(pkgTestSetup, buildValidationModeTests(name, image, "apt", key)) } for name, image := range utils.HeadELImages { pkgTestSetup = append(pkgTestSetup, buildValidationModeTests(name, image, "yum", key)) } for name, image := range utils.HeadSUSEImages { pkgTestSetup = append(pkgTestSetup, buildValidationModeTests(name, image, "zypper", key)) } for name, image := range utils.HeadWindowsImages { pkgTestSetup = append(pkgTestSetup, buildValidationModeTests(name, image, "googet", key)) } return pkgTestSetup } func generateAllTestSetup() []*osPolicyTestSetup { key := utils.RandString(3) pkgTestSetup := []*osPolicyTestSetup{} pkgTestSetup = append(pkgTestSetup, addPackageResourceTests(key)...) pkgTestSetup = append(pkgTestSetup, addRepositoryResourceTests(key)...) pkgTestSetup = append(pkgTestSetup, addFileResourceTests(key)...) pkgTestSetup = append(pkgTestSetup, addExecResourceTests(key)...) pkgTestSetup = append(pkgTestSetup, addValidationModeTests(key)...) return pkgTestSetup } osconfig-20250416.02/e2e_tests/test_suites/ospolicies/ospolicies_utils.go000066400000000000000000000325511477773331400263750ustar00rootroot00000000000000// Copyright 2021 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package ospolicies import ( "fmt" "strings" "github.com/GoogleCloudPlatform/osconfig/e2e_tests/utils" computeApi "google.golang.org/api/compute/v1" ) func getStartupScriptPackage(image, pkgManager string) *computeApi.MetadataItems { var ss, key string switch pkgManager { case "apt": wantInstall := "ed" wantRemove := "vim" ss = `set -x # install the package we want removed apt-get update apt-get -y install %[2]s # remove the package we want installed apt-get -y remove %[3]s # install agent %[1]s while true; do # make sure the package we want installed is installed isinstalled=$(/usr/bin/dpkg-query -s %[3]s) if [[ $isinstalled =~ "Status: install ok installed" ]]; then uri=http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%[4]s curl -X PUT --data "1" $uri -H "Metadata-Flavor: Google" break fi sleep 10 done while true; do # make sure the package we want removed is removed isinstalled=$(/usr/bin/dpkg-query -s %[2]s) if ! [[ $isinstalled =~ "Status: install ok installed" ]]; then uri=http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%[5]s curl -X PUT --data "1" $uri -H "Metadata-Flavor: Google" break fi sleep 10 done` ss = fmt.Sprintf(ss, utils.InstallOSConfigDeb(image), wantRemove, wantInstall, packageInstalled, packageNotInstalled) key = "startup-script" case "deb": wantInstall := []string{"google-chrome-stable", "osconfig-agent-test"} ss = `set -x # install agent %[1]s while true; do isinstalled=$(/usr/bin/dpkg-query -s %[2]s) if [[ $isinstalled =~ "Status: install ok installed" ]]; then break fi sleep 10 done while true; do isinstalled=$(/usr/bin/dpkg-query -s %[3]s) if [[ $isinstalled =~ "Status: install ok installed" ]]; then uri=http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%[4]s curl -X PUT --data "1" $uri -H "Metadata-Flavor: Google" break fi sleep 10 done` ss = fmt.Sprintf(ss, utils.InstallOSConfigDeb(image), wantInstall[0], wantInstall[1], packageInstalled) key = "startup-script" case "yum": wantInstall := "ed" wantRemove := "nano" ss = `set -x # install the package we want removed yum -y install %[2]s # remove the package we want installed yum -y remove %[3]s %[1]s while true; do # make sure the package we want installed is installed if [[ -n $(/usr/bin/rpmquery -a %[3]s) ]]; then uri=http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%[4]s curl -X PUT --data "1" $uri -H "Metadata-Flavor: Google" break fi sleep 10 done while true; do # make sure the package we want removed is removed if [[ -z $(/usr/bin/rpmquery -a %[2]s) ]]; then uri=http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%[5]s curl -X PUT --data "1" $uri -H "Metadata-Flavor: Google" break fi sleep 10 done` ss = fmt.Sprintf(ss, utils.InstallOSConfigEL(image), wantRemove, wantInstall, packageInstalled, packageNotInstalled) key = "startup-script" case "rpm": wantInstall := []string{"gcsfuse", "osconfig-agent-test"} ss = `set -x # install agent %[1]s rpm --import https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg rpm --import https://dl.google.com/linux/linux_signing_key.pub while true; do if [[ -n $(/usr/bin/rpmquery -a %[2]s) ]]; then break fi sleep 10 done while true; do if [[ -n $(/usr/bin/rpmquery -a %[3]s) ]]; then uri=http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%[4]s curl -X PUT --data "1" $uri -H "Metadata-Flavor: Google" break fi sleep 10 done` install := utils.InstallOSConfigEL(image) if strings.Contains(image, "suse") { install = utils.InstallOSConfigSUSE() } ss = fmt.Sprintf(ss, install, wantInstall[0], wantInstall[1], packageInstalled) key = "startup-script" case "googet": wantInstall := "google-compute-engine-ssh" wantRemove := "certgen" ss = ` googet addrepo test https://packages.cloud.google.com/yuck/repos/osconfig-agent-test-repository %s while(1) { # make sure the package we want installed is installed $installed_packages = googet installed if ($installed_packages -like "*%[3]s*") { $uri = 'http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%[5]s' Invoke-RestMethod -Method PUT -Uri $uri -Headers @{"Metadata-Flavor" = "Google"} -Body 1 break } sleep 10 } while(1) { # make sure the package we want removed is removed $installed_packages = googet installed if ($installed_packages -notlike "*%[2]s*") { $uri = 'http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%[4]s' Invoke-RestMethod -Method PUT -Uri $uri -Headers @{"Metadata-Flavor" = "Google"} -Body 1 break } sleep 10 }` ss = fmt.Sprintf(ss, utils.InstallOSConfigGooGet(), wantRemove, wantInstall, packageInstalled, packageNotInstalled) key = "windows-startup-script-ps1" case "msi": ss = ` %s while(1) { if (Get-WmiObject -Class Win32_Product | Where-Object {$_.Name -like "*Chrome*"}) { $uri = 'http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%s' Invoke-RestMethod -Method PUT -Uri $uri -Headers @{"Metadata-Flavor" = "Google"} -Body 1 break } sleep 10 }` ss = fmt.Sprintf(ss, utils.InstallOSConfigGooGet(), packageInstalled) key = "windows-startup-script-ps1" case "zypper": wantInstall := "ed" wantRemove := "vim" ss = `set -x # install the package we want removed zypper -n install %[2]s # remove the package we want installed zypper -n remove %[3]s %[1]s while true; do # make sure the package we want installed is installed if [[ -n $(/usr/bin/rpmquery -a %[3]s) ]]; then uri=http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%[4]s curl -X PUT --data "1" $uri -H "Metadata-Flavor: Google" break fi sleep 10 done while true; do # make sure the package we want removed is removed if [[ -z $(/usr/bin/rpmquery -a %[2]s) ]]; then uri=http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%[5]s curl -X PUT --data "1" $uri -H "Metadata-Flavor: Google" break fi sleep 10 done` ss = fmt.Sprintf(ss, utils.InstallOSConfigSUSE(), wantRemove, wantInstall, packageInstalled, packageNotInstalled) key = "startup-script" default: fmt.Printf("Invalid package manager: %s", pkgManager) } return &computeApi.MetadataItems{ Key: key, Value: &ss, } } func getStartupScriptRepo(image, pkgManager, packageName string) *computeApi.MetadataItems { var ss, key string switch pkgManager { case "apt": ss = `set -x %s while true; do isinstalled=$(/usr/bin/dpkg-query -s %s) if [[ $isinstalled =~ "Status: install ok installed" ]]; then uri=http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%s curl -X PUT --data "1" $uri -H "Metadata-Flavor: Google" exit 0 fi sleep 10 done` ss = fmt.Sprintf(ss, utils.InstallOSConfigDeb(image), packageName, packageInstalled) key = "startup-script" case "yum": ss = `set -x %s while true; do if [[ -n $(/usr/bin/rpmquery -a %s) ]]; then uri=http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%s curl -X PUT --data "1" $uri -H "Metadata-Flavor: Google" exit 0 fi sleep 10 done` ss = fmt.Sprintf(ss, utils.InstallOSConfigEL(image), packageName, packageInstalled) key = "startup-script" case "googet": ss = `%s while(1) { $installed_packages = googet installed if ($installed_packages -like "*%s*") { $uri = 'http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%s' Invoke-RestMethod -Method PUT -Uri $uri -Headers @{"Metadata-Flavor" = "Google"} -Body 1 exit 0 } sleep 10 }` ss = fmt.Sprintf(ss, utils.InstallOSConfigGooGet(), packageName, packageInstalled) key = "windows-startup-script-ps1" case "zypper": ss = `set -x sleep 10 %s while true; do if [[ -n $(/usr/bin/rpmquery -a %s) ]]; then uri=http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%s curl -X PUT --data "1" $uri -H "Metadata-Flavor: Google" exit 0 fi sleep 10 done` // SLES 12 has an old version of Zypper which has bugs in gpg importing logic. if strings.Contains(image, "sles-12") { ss = "rpm --import https://packages.cloud.google.com/yum/doc/yum-key.gpg\n" + ss } ss = fmt.Sprintf(ss, utils.InstallOSConfigSUSE(), packageName, packageInstalled) key = "startup-script" default: fmt.Printf("Invalid package manager: %s", pkgManager) } return &computeApi.MetadataItems{ Key: key, Value: &ss, } } func getStartupScriptFile(image, pkgManager, dnePath string, wantPaths []string) *computeApi.MetadataItems { var ss, key string linux := `set -x touch %[1]s %[2]s echo "Checking for %[1]s" while [[ -f %[1]s ]]; do echo "%[1]s exists" sleep 5 done echo "%[1]s DNE" uri=http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%[3]s curl -X PUT --data "1" $uri -H "Metadata-Flavor: Google"` linuxCheck := ` echo "Checking for %[1]s" while [[ ! -f %[1]s ]]; do echo "%[1]s DNE" sleep 10 done echo "%[1]s exists"` linuxEnd := fmt.Sprintf(` uri=http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%s curl -X PUT --data "1" $uri -H "Metadata-Flavor: Google"`, fileExists) switch pkgManager { case "apt": ss = fmt.Sprintf(linux, dnePath, utils.InstallOSConfigDeb(image), fileDNE) for _, p := range wantPaths { ss += fmt.Sprintf(linuxCheck, p) } ss += linuxEnd key = "startup-script" case "yum": ss = fmt.Sprintf(linux, dnePath, utils.InstallOSConfigEL(image), fileDNE) for _, p := range wantPaths { ss += fmt.Sprintf(linuxCheck, p) } ss += linuxEnd key = "startup-script" case "zypper": ss = fmt.Sprintf(linux, dnePath, utils.InstallOSConfigSUSE(), fileDNE) for _, p := range wantPaths { ss += fmt.Sprintf(linuxCheck, p) } ss += linuxEnd key = "startup-script" case "googet": ss = ` New-Item -ItemType File -Path %[1]s %[2]s Write-Host "Checking for %[1]s" while (Test-Path %[1]s) { Write-Host "%[1]s exists" sleep 10 } $uri = 'http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%[3]s' Invoke-RestMethod -Method PUT -Uri $uri -Headers @{"Metadata-Flavor" = "Google"} -Body 1` ss = fmt.Sprintf(ss, dnePath, utils.InstallOSConfigGooGet(), fileDNE) windows := ` Write-Host "Checking for %[1]s" while ( ! (Test-Path %[1]s) ) { Write-Host "%[1]s DNE" sleep 10 } Write-Host "%[1]s exists"` for _, p := range wantPaths { ss += fmt.Sprintf(windows, p) } ss += fmt.Sprintf(` $uri = 'http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%s' Invoke-RestMethod -Method PUT -Uri $uri -Headers @{"Metadata-Flavor" = "Google"} -Body 1`, fileExists) key = "windows-startup-script-ps1" default: fmt.Printf("Invalid package manager: %s", pkgManager) } return &computeApi.MetadataItems{ Key: key, Value: &ss, } } func getStartupScriptExec(image, pkgManager string, wantPaths []string) *computeApi.MetadataItems { var ss, key string linux := `set -x echo 'if ls $1 >/dev/null; then exit 100 fi exit 101' > /validate_shell echo '#!/bin/sh touch $1 exit 100' > /enforce_none chmod +x /enforce_none` linuxCheck := ` echo "Checking for %[1]s" while [[ ! -f %[1]s ]]; do echo "%[1]s DNE" sleep 10 done echo "%[1]s exists"` var linuxChecks string for _, p := range wantPaths { linuxChecks += fmt.Sprintf(linuxCheck, p) } linuxEnd := fmt.Sprintf(` uri=http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%s curl -X PUT --data "1" $uri -H "Metadata-Flavor: Google"`, fileExists) switch pkgManager { case "apt": ss = linux + utils.InstallOSConfigDeb(image) + linuxChecks + linuxEnd key = "startup-script" case "yum": ss = linux + utils.InstallOSConfigEL(image) + linuxChecks + linuxEnd key = "startup-script" case "zypper": ss = linux + utils.InstallOSConfigSUSE() + linuxChecks + linuxEnd key = "startup-script" case "googet": ss = ` @' if exist %1 exit 100 exit 101 '@ | Out-File -Encoding ASCII /validate.cmd @' echo "" > %1 exit 100 '@ | Out-File -Encoding ASCII /enforce.cmd 'if (Test-Path $Args[0]) {exit 100}; exit 101' > /validate.ps1 'New-Item -ItemType File -Path $Args[0]; exit 100' > /enforce.ps1` ss += utils.InstallOSConfigGooGet() check := ` Write-Host "Checking for %[1]s" while ( ! (Test-Path %[1]s) ) { Write-Host "%[1]s DNE" sleep 10 } Write-Host "%[1]s exists"` for _, p := range wantPaths { ss += fmt.Sprintf(check, p) } ss += fmt.Sprintf(` $uri = 'http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/%s' Invoke-RestMethod -Method PUT -Uri $uri -Headers @{"Metadata-Flavor" = "Google"} -Body 1`, fileExists) key = "windows-startup-script-ps1" default: fmt.Printf("Invalid package manager: %s", pkgManager) } return &computeApi.MetadataItems{ Key: key, Value: &ss, } } osconfig-20250416.02/e2e_tests/test_suites/patch/000077500000000000000000000000001477773331400213755ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/test_suites/patch/patch.go000066400000000000000000000465441477773331400230400ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package patch contains end to end tests for patch management package patch import ( "context" "errors" "fmt" "log" "path" "regexp" "strconv" "strings" "sync" "time" "github.com/GoogleCloudPlatform/compute-image-tools/go/e2e_test_utils/junitxml" "github.com/GoogleCloudPlatform/osconfig/e2e_tests/compute" "github.com/GoogleCloudPlatform/osconfig/e2e_tests/config" gcpclients "github.com/GoogleCloudPlatform/osconfig/e2e_tests/gcp_clients" testconfig "github.com/GoogleCloudPlatform/osconfig/e2e_tests/test_config" "github.com/GoogleCloudPlatform/osconfig/e2e_tests/utils" "github.com/GoogleCloudPlatform/osconfig/retryutil" "github.com/golang/protobuf/ptypes/duration" "github.com/kylelemons/godebug/pretty" "google.golang.org/api/iterator" "cloud.google.com/go/osconfig/apiv1beta/osconfigpb" ) const ( testSuiteName = "OSPatch" ) var ( dump = &pretty.Config{IncludeUnexported: true} testSuffix = utils.RandString(3) ) // TestSuite is a OSPatch test suite. func TestSuite(ctx context.Context, tswg *sync.WaitGroup, testSuites chan *junitxml.TestSuite, logger *log.Logger, testSuiteRegex, testCaseRegex *regexp.Regexp) { defer tswg.Done() if testSuiteRegex != nil && !testSuiteRegex.MatchString(testSuiteName) { return } testSuite := junitxml.NewTestSuite(testSuiteName) defer testSuite.Finish(testSuites) logger.Printf("Running TestSuite %q", testSuite.Name) var wg sync.WaitGroup tests := make(chan *junitxml.TestCase) // Basic functionality smoke test against all latest images. for _, setup := range headImageTestSetup() { wg.Add(1) s := setup tc := junitxml.NewTestCase(testSuiteName, fmt.Sprintf("[Execute PatchJob] [%s]", s.testName)) f := func(tc *junitxml.TestCase) { runExecutePatchJobTest(ctx, tc, s, nil) } go runTestCase(tc, f, tests, &wg, logger, testCaseRegex) } // TODO: remove this hack and setup specific test suites for each test type. // We can't test 'old' images with the head image test. if config.AgentRepo() != "" { // Test that updates trigger reboot as expected. for _, setup := range oldImageTestSetup() { wg.Add(1) s := setup tc := junitxml.NewTestCase(testSuiteName, fmt.Sprintf("[PatchJob triggers reboot] [%s]", s.testName)) pc := &osconfigpb.PatchConfig{Apt: &osconfigpb.AptSettings{Type: osconfigpb.AptSettings_DIST}} shouldReboot := true f := func(tc *junitxml.TestCase) { runRebootPatchTest(ctx, tc, s, pc, shouldReboot) } go runTestCase(tc, f, tests, &wg, logger, testCaseRegex) } // Test that PatchConfig_NEVER prevents reboot. for _, setup := range oldImageTestSetup() { wg.Add(1) s := setup tc := junitxml.NewTestCase(testSuiteName, fmt.Sprintf("[PatchJob does not reboot] [%s]", s.testName)) pc := &osconfigpb.PatchConfig{RebootConfig: osconfigpb.PatchConfig_NEVER, Apt: &osconfigpb.AptSettings{Type: osconfigpb.AptSettings_DIST}} shouldReboot := false f := func(tc *junitxml.TestCase) { runRebootPatchTest(ctx, tc, s, pc, shouldReboot) } go runTestCase(tc, f, tests, &wg, logger, testCaseRegex) } } // Test that pre- and post-patch steps run as expected. for _, setup := range headImageTestSetup() { wg.Add(1) s := setup tc := junitxml.NewTestCase(testSuiteName, fmt.Sprintf("[PatchJob runs pre-step and post-step] [%s]", s.testName)) pc := patchConfigWithPrePostSteps() f := func(tc *junitxml.TestCase) { runExecutePatchJobTest(ctx, tc, s, pc) } go runTestCase(tc, f, tests, &wg, logger, testCaseRegex) } // Test APT specific functionality, this just tests that using these settings doesn't break anything. for _, setup := range aptHeadImageTestSetup() { wg.Add(1) s := setup tc := junitxml.NewTestCase(testSuiteName, fmt.Sprintf("[APT dist-upgrade, excludes] [%s]", s.testName)) f := func(tc *junitxml.TestCase) { runExecutePatchJobTest(ctx, tc, s, &osconfigpb.PatchConfig{Apt: &osconfigpb.AptSettings{Type: osconfigpb.AptSettings_DIST, Excludes: []string{"pkg1", "/pkg2/"}}}) } go runTestCase(tc, f, tests, &wg, logger, testCaseRegex) } // Test APT specific functionality, this just tests that using these settings doesn't break anything. for _, setup := range aptHeadImageTestSetup() { wg.Add(1) s := setup tc := junitxml.NewTestCase(testSuiteName, fmt.Sprintf("[APT dist-upgrade, exclusive packages] [%s]", s.testName)) f := func(tc *junitxml.TestCase) { runExecutePatchJobTest(ctx, tc, s, &osconfigpb.PatchConfig{Apt: &osconfigpb.AptSettings{Type: osconfigpb.AptSettings_DIST, ExclusivePackages: []string{"pkg1"}}}) } go runTestCase(tc, f, tests, &wg, logger, testCaseRegex) } // Test that apt-get patch works even when a package needs to be downgraded for _, setup := range aptDowngradeImageTestSetup() { wg.Add(1) s := setup tc := junitxml.NewTestCase(testSuiteName, fmt.Sprintf("[PatchJob apt-get doesn't fail on downgrades] [%s]", s.testName)) f := func(tc *junitxml.TestCase) { runExecutePatchJobTest(ctx, tc, s, &osconfigpb.PatchConfig{Apt: &osconfigpb.AptSettings{Type: osconfigpb.AptSettings_DIST}}) } go runTestCase(tc, f, tests, &wg, logger, testCaseRegex) } // Test YUM specific functionality, this just tests that using these settings doesn't break anything. for _, setup := range yumHeadImageTestSetup() { wg.Add(1) s := setup tc := junitxml.NewTestCase(testSuiteName, fmt.Sprintf("[YUM security, minimal and excludes] [%s]", s.testName)) f := func(tc *junitxml.TestCase) { runExecutePatchJobTest(ctx, tc, s, &osconfigpb.PatchConfig{Yum: &osconfigpb.YumSettings{Security: true, Minimal: true, Excludes: []string{"pkg1", "pkg2", "/pkg3/"}}}) } go runTestCase(tc, f, tests, &wg, logger, testCaseRegex) } // Test YUM exclusive_package updates, this just tests that using these settings doesn't break anything. for _, setup := range yumHeadImageTestSetup() { wg.Add(1) s := setup tc := junitxml.NewTestCase(testSuiteName, fmt.Sprintf("[YUM exclusive patches] [%s]", s.testName)) f := func(tc *junitxml.TestCase) { runExecutePatchJobTest(ctx, tc, s, &osconfigpb.PatchConfig{Yum: &osconfigpb.YumSettings{ExclusivePackages: []string{"pkg1", "pk3"}}}) } go runTestCase(tc, f, tests, &wg, logger, testCaseRegex) } // Test Zypper specific functionality, this just tests that using these settings doesn't break anything. for _, setup := range suseHeadImageTestSetup() { wg.Add(1) s := setup tc := junitxml.NewTestCase(testSuiteName, fmt.Sprintf("[Zypper excludes, WithOptional, WithUpdate, Categories and Severities] [%s]", s.testName)) f := func(tc *junitxml.TestCase) { runExecutePatchJobTest(ctx, tc, s, &osconfigpb.PatchConfig{ Zypper: &osconfigpb.ZypperSettings{Excludes: []string{"patch-1", "/patch-2/"}, WithOptional: true, WithUpdate: true, Categories: []string{"security", "recommended", "feature"}, Severities: []string{"critical", "important", "moderate", "low"}}}) } go runTestCase(tc, f, tests, &wg, logger, testCaseRegex) } // Test Zypper exclusive patches. the test just makes sure that it does not break anything // the actual combination tests is a part of unit test for _, setup := range suseHeadImageTestSetup() { wg.Add(1) s := setup tc := junitxml.NewTestCase(testSuiteName, fmt.Sprintf("[Zypper exclusivePatches] [%s]", s.testName)) f := func(tc *junitxml.TestCase) { runExecutePatchJobTest(ctx, tc, s, &osconfigpb.PatchConfig{ Zypper: &osconfigpb.ZypperSettings{ExclusivePatches: []string{"patch-1"}}}) // there should be no patch run } go runTestCase(tc, f, tests, &wg, logger, testCaseRegex) } go func() { wg.Wait() close(tests) }() for ret := range tests { testSuite.TestCase = append(testSuite.TestCase, ret) } logger.Printf("Finished TestSuite %q", testSuite.Name) } func getPatchJobInstanceDetails(ctx context.Context, parent string) ([]string, error) { client, err := gcpclients.GetOsConfigClientV1beta() if err != nil { return nil, err } it := client.ListPatchJobInstanceDetails(ctx, &osconfigpb.ListPatchJobInstanceDetailsRequest{Parent: parent}) var ret []string for { item, err := it.Next() if err == iterator.Done { break } if err != nil { return nil, err } ret = append(ret, item.String()) } return ret, nil } func awaitPatchJob(ctx context.Context, job *osconfigpb.PatchJob, timeout time.Duration) (res *osconfigpb.PatchJob, err error) { client, err := gcpclients.GetOsConfigClientV1beta() if err != nil { return nil, err } tick := time.Tick(10 * time.Second) timedout := time.Tick(timeout) for { select { case <-timedout: return nil, errors.New("timed out while waiting for patch job to complete") case <-tick: if err := retryutil.RetryAPICall(ctx, timeout*time.Second, "GetPatchJobRequest", func() error { res, err = client.GetPatchJob(ctx, &osconfigpb.GetPatchJobRequest{Name: job.GetName()}) return err }); err != nil { return nil, fmt.Errorf("error while fetching patch job: %s", utils.GetStatusFromError(err)) } if isPatchJobFailureState(res.State) { details, err := getPatchJobInstanceDetails(ctx, job.GetName()) if err != nil { details = []string{err.Error()} } return nil, fmt.Errorf("failure status %v with message: %q, InstanceDetails: %q", res.State, job.GetErrorMessage(), details) } if res.State == osconfigpb.PatchJob_SUCCEEDED { if res.GetInstanceDetailsSummary().GetSucceededInstanceCount() < 1 && res.GetInstanceDetailsSummary().GetSucceededRebootRequiredInstanceCount() < 1 { return nil, errors.New("completed with no instances patched") } return res, nil } } } } func runExecutePatchJobTest(ctx context.Context, testCase *junitxml.TestCase, testSetup *patchTestSetup, pc *osconfigpb.PatchConfig) { computeClient, err := gcpclients.GetComputeClient() if err != nil { testCase.WriteFailure("Error getting compute client: %v", err) return } name := fmt.Sprintf("patch-test-%s-%s-%s", path.Base(testSetup.testName), testSuffix, utils.RandString(5)) testProjectConfig := testconfig.GetProject() zone := testProjectConfig.AcquireZone() defer testProjectConfig.ReleaseZone(zone) testCase.Logf("Creating instance %q with image %q", name, testSetup.image) inst, err := utils.CreateComputeInstance(testSetup.metadata, computeClient, testSetup.machineType, testSetup.image, name, testProjectConfig.TestProjectID, zone, testProjectConfig.ServiceAccountEmail, testProjectConfig.ServiceAccountScopes) if err != nil { testCase.WriteFailure("Error creating instance: %v", utils.GetStatusFromError(err)) return } defer inst.Cleanup() defer inst.RecordSerialOutput(ctx, path.Join(*config.OutDir, testSuiteName), 1) testCase.Logf("Waiting for agent install to complete") if _, err := inst.WaitForGuestAttributes("osconfig_tests/install_done", 5*time.Second, 25*time.Minute); err != nil { testCase.WriteFailure("Error waiting for osconfig agent install: %v", err) return } testCase.Logf("Agent installed successfully") if err := inst.AddMetadata(compute.BuildInstanceMetadataItem("windows-startup-script-ps1", windowsRecordBoot), compute.BuildInstanceMetadataItem("startup-script", linuxRecordBoot)); err != nil { testCase.WriteFailure("Error setting metadata: %v", err) return } parent := fmt.Sprintf("projects/%s", testProjectConfig.TestProjectID) osconfigClient, err := gcpclients.GetOsConfigClientV1beta() if err != nil { testCase.WriteFailure("Error getting osconfig client: %v", err) return } req := &osconfigpb.ExecutePatchJobRequest{ Parent: parent, Description: "testing patch job run", InstanceFilter: &osconfigpb.PatchInstanceFilter{InstanceNamePrefixes: []string{name}}, Duration: &duration.Duration{Seconds: int64(testSetup.assertTimeout / time.Second)}, PatchConfig: pc, } testCase.Logf("Running ExecutePatchJob") job, err := osconfigClient.ExecutePatchJob(ctx, req) if err != nil { testCase.WriteFailure("Error running ExecutePatchJob: %s", utils.GetStatusFromError(err)) return } testCase.Logf("Started patch job %q", job.GetName()) pj, err := awaitPatchJob(ctx, job, testSetup.assertTimeout) if err != nil { testCase.WriteFailure("Patch job %q error: %v", job.GetName(), err) return } testCase.Logf("Executed PatchJob: %+v", pj) if pc.GetPreStep() != nil && pc.GetPostStep() != nil { validatePrePostStepSuccess(inst, testCase) } } func runRebootPatchTest(ctx context.Context, testCase *junitxml.TestCase, testSetup *patchTestSetup, pc *osconfigpb.PatchConfig, shouldReboot bool) { computeClient, err := gcpclients.GetComputeClient() if err != nil { testCase.WriteFailure("Error getting compute client: %v", err) return } name := fmt.Sprintf("patch-reboot-%s-%s-%s", path.Base(testSetup.testName), testSuffix, utils.RandString(5)) testProjectConfig := testconfig.GetProject() zone := testProjectConfig.AcquireZone() defer testProjectConfig.ReleaseZone(zone) testCase.Logf("Creating instance %q with image %q", name, testSetup.image) inst, err := utils.CreateComputeInstance(testSetup.metadata, computeClient, testSetup.machineType, testSetup.image, name, testProjectConfig.TestProjectID, zone, testProjectConfig.ServiceAccountEmail, testProjectConfig.ServiceAccountScopes) if err != nil { testCase.WriteFailure("Error creating instance: %v", utils.GetStatusFromError(err)) return } defer inst.Cleanup() defer inst.RecordSerialOutput(ctx, path.Join(*config.OutDir, testSuiteName), 1) testCase.Logf("Waiting for agent install to complete") if _, err := inst.WaitForGuestAttributes("osconfig_tests/install_done", 5*time.Second, 25*time.Minute); err != nil { testCase.WriteFailure("Error waiting for osconfig agent install: %v", err) return } testCase.Logf("Agent installed successfully") if err := inst.AddMetadata(compute.BuildInstanceMetadataItem("windows-startup-script-ps1", windowsRecordBoot), compute.BuildInstanceMetadataItem("startup-script", linuxRecordBoot)); err != nil { testCase.WriteFailure("Error setting metadata: %v", err) return } parent := fmt.Sprintf("projects/%s", testProjectConfig.TestProjectID) osconfigClient, err := gcpclients.GetOsConfigClientV1beta() if err != nil { testCase.WriteFailure("Error getting osconfig client: %v", err) return } req := &osconfigpb.ExecutePatchJobRequest{ Parent: parent, Description: "testing patch job reboot", InstanceFilter: &osconfigpb.PatchInstanceFilter{InstanceNamePrefixes: []string{name}}, Duration: &duration.Duration{Seconds: int64(testSetup.assertTimeout / time.Second)}, PatchConfig: pc, } testCase.Logf("Running ExecutePatchJob") job, err := osconfigClient.ExecutePatchJob(ctx, req) if err != nil { testCase.WriteFailure("Error running ExecutePatchJob: %s", utils.GetStatusFromError(err)) return } testCase.Logf("Started patch job '%s'", job.GetName()) pj, err := awaitPatchJob(ctx, job, testSetup.assertTimeout) if err != nil { testCase.WriteFailure("Patch job '%s' error: %v", job.GetName(), err) return } testCase.Logf("Executed PatchJob: %+v", pj) // If shouldReboot is true that instance should not report a pending reboot. if shouldReboot && pj.GetInstanceDetailsSummary().GetSucceededRebootRequiredInstanceCount() > 0 { testCase.WriteFailure("PatchJob finished with status InstancesSucceededRebootRequired.") return } // If shouldReboot is false that instance should report a pending reboot. if !shouldReboot && pj.GetInstanceDetailsSummary().GetSucceededRebootRequiredInstanceCount() == 0 { testCase.WriteFailure("PatchJob should have finished with status InstancesSucceededRebootRequired.") return } testCase.Logf("Checking reboot count") attr, err := inst.GetGuestAttributes("osconfig_tests/boot_count") if err != nil { testCase.WriteFailure("Error retrieving boot count: %v", err) return } if len(attr) == 0 { testCase.WriteFailure("Error retrieving boot count: osconfig_tests/boot_count attribute empty") return } num, err := strconv.Atoi(attr[0].Value) if err != nil { testCase.WriteFailure("Error parsing boot count: %v", err) return } if shouldReboot && num < 2 { testCase.WriteFailure("Instance should have booted at least 2 times, boot num: %d.", num) return } if !shouldReboot && num > 1 { testCase.WriteFailure("Instance should not have booted more that 1 time, boot num: %d.", num) return } } func isPatchJobFailureState(state osconfigpb.PatchJob_State) bool { return state == osconfigpb.PatchJob_COMPLETED_WITH_ERRORS || state == osconfigpb.PatchJob_TIMED_OUT || state == osconfigpb.PatchJob_CANCELED } func runTestCase(tc *junitxml.TestCase, f func(tc *junitxml.TestCase), tests chan *junitxml.TestCase, wg *sync.WaitGroup, logger *log.Logger, regex *regexp.Regexp) { defer wg.Done() if tc.FilterTestCase(regex) { tc.Finish(tests) } else { logger.Printf("Running TestCase %q", tc.Name) f(tc) if tc.Failure != nil { rerunTC := junitxml.NewTestCase(testSuiteName, strings.TrimPrefix(tc.Name, fmt.Sprintf("[%s] ", testSuiteName))) wg.Add(1) go func() { defer wg.Done() logger.Printf("Rerunning TestCase %q", rerunTC.Name) f(rerunTC) rerunTC.Finish(tests) logger.Printf("TestCase %q finished in %fs", rerunTC.Name, rerunTC.Time) }() } tc.Finish(tests) logger.Printf("TestCase %q finished in %fs", tc.Name, tc.Time) } } func patchConfigWithPrePostSteps() *osconfigpb.PatchConfig { linuxPreStepConfig := &osconfigpb.ExecStepConfig{Executable: &osconfigpb.ExecStepConfig_LocalPath{LocalPath: "./linux_local_pre_patch_script.sh"}, Interpreter: osconfigpb.ExecStepConfig_SHELL} windowsPreStepConfig := &osconfigpb.ExecStepConfig{Executable: &osconfigpb.ExecStepConfig_GcsObject{GcsObject: &osconfigpb.GcsObject{Bucket: "osconfig-agent-end2end-test-resources", Object: "OSPatch/windows_gcs_pre_patch_script.ps1", GenerationNumber: 1571249543230832}}, Interpreter: osconfigpb.ExecStepConfig_POWERSHELL} linuxPostStepConfig := &osconfigpb.ExecStepConfig{Executable: &osconfigpb.ExecStepConfig_GcsObject{GcsObject: &osconfigpb.GcsObject{Bucket: "osconfig-agent-end2end-test-resources", Object: "OSPatch/linux_gcs_post_patch_script", GenerationNumber: 1570567792146617}}} windowsPostStepConfig := &osconfigpb.ExecStepConfig{Executable: &osconfigpb.ExecStepConfig_LocalPath{LocalPath: "C:\\Windows\\System32\\windows_local_post_patch_script.ps1"}, Interpreter: osconfigpb.ExecStepConfig_POWERSHELL} preStep := &osconfigpb.ExecStep{LinuxExecStepConfig: linuxPreStepConfig, WindowsExecStepConfig: windowsPreStepConfig} postStep := &osconfigpb.ExecStep{LinuxExecStepConfig: linuxPostStepConfig, WindowsExecStepConfig: windowsPostStepConfig} return &osconfigpb.PatchConfig{PreStep: preStep, PostStep: postStep} } func validatePrePostStepSuccess(inst *compute.Instance, testCase *junitxml.TestCase) { if _, err := inst.WaitForGuestAttributes("osconfig_tests/pre_step_ran", 5*time.Second, 10*time.Minute); err != nil { testCase.WriteFailure("error while asserting: %v", err) return } if _, err := inst.WaitForGuestAttributes("osconfig_tests/post_step_ran", 5*time.Second, 10*time.Minute); err != nil { testCase.WriteFailure("error while asserting: %v", err) return } } osconfig-20250416.02/e2e_tests/test_suites/patch/test_setup.go000066400000000000000000000201761477773331400241310ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package patch import ( "time" "github.com/GoogleCloudPlatform/osconfig/e2e_tests/compute" "github.com/GoogleCloudPlatform/osconfig/e2e_tests/utils" computeApi "google.golang.org/api/compute/v1" ) type patchTestSetup struct { testName string image string metadata []*computeApi.MetadataItems assertTimeout time.Duration machineType string } var ( windowsRecordBoot = ` while ($true) { $uri = 'http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/osconfig_tests/boot_count' $old = Invoke-RestMethod -Method GET -Uri $uri -Headers @{"Metadata-Flavor" = "Google"} $new = $old+1 try { Invoke-RestMethod -Method PUT -Uri $uri -Headers @{"Metadata-Flavor" = "Google"} -Body $new -ErrorAction Stop } catch { Write-Output $_.Exception.Message Start-Sleep 1 continue } break } ` windowsSetWsus = ` $wu_server = '192.168.0.2' $windows_update_path = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate' $windows_update_au_path = "$windows_update_path\AU" if (Test-Connection $wu_server -Count 1 -ErrorAction SilentlyContinue) { if (-not (Test-Path $windows_update_path -ErrorAction SilentlyContinue)) { New-Item -Path $windows_update_path -Value "" New-Item -Path $windows_update_au_path -Value "" } Set-ItemProperty -Path $windows_update_path -Name WUServer -Value "http://${wu_server}:8530" Set-ItemProperty -Path $windows_update_path -Name WUStatusServer -Value "http://${wu_server}:8530" Set-ItemProperty -Path $windows_update_au_path -Name UseWUServer -Value 1 } ` windowsLocalPostPatchScript = ` $uri = 'http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/osconfig_tests/post_step_ran' New-Item -Path . -Name "windows_local_post_patch_script.ps1" -ItemType "file" -Value "Invoke-RestMethod -Method PUT -Uri $uri -Headers @{'Metadata-Flavor' = 'Google'} -Body 1" ` linuxRecordBoot = ` uri=http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/osconfig_tests/boot_count old=$(curl $uri -H "Metadata-Flavor: Google" -f) new=$(($old + 1)) curl -X PUT --data "${new}" $uri -H "Metadata-Flavor: Google" ` linuxLocalPrePatchScript = ` echo 'curl -X PUT --data "1" http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/osconfig_tests/pre_step_ran -H "Metadata-Flavor: Google"' >> ./linux_local_pre_patch_script.sh chmod +x ./linux_local_pre_patch_script.sh ` setUpDowngradeState = ` echo 'deb [trusted=yes check-valid-until=no] http://snapshot.debian.org/archive/debian/20190801T025637Z/ buster main' >> /etc/apt/sources.list echo 'Package: sudo' >> /etc/apt/preferences echo 'Pin: version 1.8.27-1' >> /etc/apt/preferences echo 'Pin-priority: 9999' >> /etc/apt/preferences ` enableOsconfig = compute.BuildInstanceMetadataItem("enable-osconfig", "true") disableFeatures = compute.BuildInstanceMetadataItem("osconfig-disabled-features", "guestpolicies,osinventory") windowsSetup = &patchTestSetup{ assertTimeout: 60 * time.Minute, metadata: []*computeApi.MetadataItems{ compute.BuildInstanceMetadataItem("sysprep-specialize-script-ps1", windowsSetWsus), compute.BuildInstanceMetadataItem("windows-startup-script-ps1", windowsRecordBoot+utils.InstallOSConfigGooGet()+windowsLocalPostPatchScript), enableOsconfig, disableFeatures, }, machineType: "e2-standard-4", } // apt setup busterAptSetup = createAptPatchTestSetup("debian-10") bullseyeAptSetup = createAptPatchTestSetup("debian-11") bookwormAptSetup = createAptPatchTestSetup("debian-12") // apt Downgrade setup bullseyeAptDowngradeSetup = createAptDowngradeSetup("debian-11") el8Setup = &patchTestSetup{ assertTimeout: 30 * time.Minute, metadata: []*computeApi.MetadataItems{ compute.BuildInstanceMetadataItem("startup-script", linuxRecordBoot+utils.InstallOSConfigEL8()+linuxLocalPrePatchScript), enableOsconfig, disableFeatures, }, machineType: "e2-medium", } el9Setup = &patchTestSetup{ assertTimeout: 30 * time.Minute, metadata: []*computeApi.MetadataItems{ compute.BuildInstanceMetadataItem("startup-script", linuxRecordBoot+utils.InstallOSConfigEL9()+linuxLocalPrePatchScript), enableOsconfig, disableFeatures, }, machineType: "e2-medium", } suseSetup = &patchTestSetup{ assertTimeout: 30 * time.Minute, metadata: []*computeApi.MetadataItems{ compute.BuildInstanceMetadataItem("startup-script", linuxRecordBoot+utils.InstallOSConfigSUSE()+linuxLocalPrePatchScript), enableOsconfig, disableFeatures, }, machineType: "e2-medium", } ) func createAptPatchTestSetup(image string) *patchTestSetup { return &patchTestSetup{ assertTimeout: 30 * time.Minute, metadata: []*computeApi.MetadataItems{ compute.BuildInstanceMetadataItem("startup-script", linuxRecordBoot+utils.InstallOSConfigDeb(image)+linuxLocalPrePatchScript), enableOsconfig, disableFeatures, }, machineType: "e2-medium", } } func createAptDowngradeSetup(image string) *patchTestSetup { return &patchTestSetup{ assertTimeout: 30 * time.Minute, metadata: []*computeApi.MetadataItems{ compute.BuildInstanceMetadataItem("startup-script", linuxRecordBoot+utils.InstallOSConfigDeb(image)+linuxLocalPrePatchScript+setUpDowngradeState), enableOsconfig, disableFeatures, }, machineType: "e2-medium", } } func imageTestSetup(mapping map[*patchTestSetup]map[string]string) (setup []*patchTestSetup) { for s, m := range mapping { for name, image := range m { new := patchTestSetup(*s) new.testName = name new.image = image setup = append(setup, &new) } } return } func headImageTestSetup() []*patchTestSetup { // This maps a specific patchTestSetup to test setup names and associated images. mapping := map[*patchTestSetup]map[string]string{ windowsSetup: utils.HeadWindowsImages, el8Setup: utils.HeadEL8Images, el9Setup: utils.HeadEL9Images, busterAptSetup: utils.HeadBusterAptImages, bullseyeAptSetup: utils.HeadBullseyeAptImages, bookwormAptSetup: utils.HeadBookwormAptImages, suseSetup: utils.HeadSUSEImages, } return imageTestSetup(mapping) } func oldImageTestSetup() []*patchTestSetup { // This maps a specific patchTestSetup to test setup names and associated images. mapping := map[*patchTestSetup]map[string]string{ windowsSetup: utils.OldWindowsImages, el8Setup: utils.OldEL8Images, el9Setup: utils.OldEL9Images, suseSetup: utils.OldSUSEImages, } return imageTestSetup(mapping) } func aptHeadImageTestSetup() []*patchTestSetup { // This maps a specific patchTestSetup to test setup names and associated images. mapping := map[*patchTestSetup]map[string]string{ busterAptSetup: utils.HeadBusterAptImages, bullseyeAptSetup: utils.HeadBullseyeAptImages, busterAptSetup: utils.HeadBookwormAptImages, } return imageTestSetup(mapping) } func aptDowngradeImageTestSetup() []*patchTestSetup { // This maps a specific patchTestSetup to test setup names and associated images. mapping := map[*patchTestSetup]map[string]string{ bullseyeAptDowngradeSetup: utils.DowngradeBullseyeAptImages, } return imageTestSetup(mapping) } func yumHeadImageTestSetup() []*patchTestSetup { // This maps a specific patchTestSetup to test setup names and associated images. mapping := map[*patchTestSetup]map[string]string{ el8Setup: utils.HeadEL8Images, el9Setup: utils.HeadEL9Images, } return imageTestSetup(mapping) } func suseHeadImageTestSetup() []*patchTestSetup { // This maps a specific patchTestSetup to test setup names and associated images. mapping := map[*patchTestSetup]map[string]string{ suseSetup: utils.HeadSUSEImages, } return imageTestSetup(mapping) } osconfig-20250416.02/e2e_tests/utils/000077500000000000000000000000001477773331400170635ustar00rootroot00000000000000osconfig-20250416.02/e2e_tests/utils/utils.go000066400000000000000000000471071477773331400205630ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package utils contains helper utils for osconfig_tests. package utils import ( "fmt" "math/rand" "path" "strings" "time" daisyCompute "github.com/GoogleCloudPlatform/compute-image-tools/daisy/compute" "github.com/GoogleCloudPlatform/osconfig/e2e_tests/compute" "github.com/GoogleCloudPlatform/osconfig/e2e_tests/config" api "google.golang.org/api/compute/v1" "google.golang.org/grpc/status" ) var ( testingPkgsProjectName = "gce-pkg-osconfig-testing" yumInstallAgent = ` sed -i 's/repo_gpgcheck=1/repo_gpgcheck=0/g' /etc/yum.repos.d/google-cloud.repo sleep 10 systemctl stop google-osconfig-agent while ! yum install -y google-osconfig-agent; do if [[ n -gt 3 ]]; then exit 1 fi n=$[$n+1] sleep 5 done systemctl start google-osconfig-agent` + CurlPost zypperInstallAgent = ` sleep 10 systemctl stop google-osconfig-agent zypper -n remove google-osconfig-agent while ! zypper -n -i --no-gpg-checks install google-osconfig-agent; do if [[ n -gt 2 ]]; then # Zypper repos are flaky, we retry 3 times then just continue, the agent may be installed fine. zypper --no-refresh -n -i --no-gpg-checks install google-osconfig-agent break fi n=$[$n+1] sleep 5 done systemctl start google-osconfig-agent` + CurlPost // CosSetup sets up serial logging on COS. CosSetup = ` sleep 10 sed -i 's/^#ForwardToConsole=no/ForwardToConsole=yes/' /etc/systemd/journald.conf sed -i 's/^#MaxLevelConsole=info/MaxLevelConsole=debug/' /etc/systemd/journald.conf MaxLevelConsole=debug systemctl force-reload systemd-journald systemctl restart google-osconfig-agent` + CurlPost // CurlPost indicates agent is installed. CurlPost = ` uri=http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/guestInventory/LastUpdated curl -X DELETE $uri -H "Metadata-Flavor: Google" uri=http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/osconfig_tests/install_done curl -X PUT --data "1" $uri -H "Metadata-Flavor: Google" ` windowsPost = ` $uri = 'http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/guestInventory/LastUpdated' Invoke-RestMethod -Method DELETE -Uri $uri -Headers @{"Metadata-Flavor" = "Google"} Start-Sleep 10 $uri = 'http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/osconfig_tests/install_done' Invoke-RestMethod -Method PUT -Uri $uri -Headers @{"Metadata-Flavor" = "Google"} -Body 1 ` ) // getRegionFromZone extracts the region from a zone name. // Example: If zone is "us-central1-a", this would return "us-central1" func getRegionFromZone(zone string) string { parts := strings.Split(zone, "-") return strings.Join(parts[:len(parts)-1], "-") } // pickTestRegionForArtifactRegistry selects a random zone from the configured zones to pull osconfig-agent package from AR & selected-region func pickTestRegionForArtifactRegistry() string { zones := config.Zones() if len(zones) == 0 { // default region for tests return "us-central1" } zoneKeys := make([]string, 0, len(zones)) for k := range zones { zoneKeys = append(zoneKeys, k) } randomIndex := rand.Intn(len(zoneKeys)) randomZone := zoneKeys[randomIndex] return getRegionFromZone(randomZone) } // getRepoLineForApt returns the repo line that should be added to apt sources.list file func getRepoLineForApt(osName string) string { repo := config.AgentRepo() if repo == "testing" { testRegion := pickTestRegionForArtifactRegistry() return fmt.Sprintf("deb ar+https://%s-apt.pkg.dev/projects/%s google-osconfig-agent-%s-testing main", testRegion, testingPkgsProjectName, osName) } return fmt.Sprintf("deb http://packages.cloud.google.com/apt google-osconfig-agent-%s-%s main", osName, repo) } // InstallOSConfigDeb installs the osconfig agent on deb based systems. func InstallOSConfigDeb(image string) string { if config.AgentRepo() == "" { return CurlPost } osName := GetDebOsName(image) return fmt.Sprintf(` sleep 10 systemctl stop google-osconfig-agent # install gnupg2 if not exist apt-get update apt-get install -y gnupg2 # install apt-transport-artifact-registry apt-get install -y apt-transport-artifact-registry echo '%s' >> /etc/apt/sources.list curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - apt-get update apt-get install -y google-osconfig-agent systemctl start google-osconfig-agent`+CurlPost, getRepoLineForApt(osName)) } // InstallOSConfigGooGet installs the osconfig agent on Windows systems. func InstallOSConfigGooGet() string { if config.AgentRepo() == "" { return windowsPost } removeAgentCmd := `c:\programdata\googet\googet.exe -noconfirm remove google-osconfig-agent` if config.AgentRepo() == "stable" { return fmt.Sprintf(` %s c:\programdata\googet\googet.exe -noconfirm install google-osconfig-agent`, removeAgentCmd) + windowsPost } else if config.AgentRepo() == "testing" { testRegion := pickTestRegionForArtifactRegistry() agentRepo := config.AgentRepo() return fmt.Sprintf(` %s c:\programdata\googet\googet.exe addrepo google-osconfig-agent-googet-testing https://%s-googet.pkg.dev/projects/%s/repos/google-osconfig-agent-googet-%s # set useoauth to true in repo new file $filePath = 'C:\ProgramData\GooGet\repos\google-osconfig-agent-googet-testing.repo' (Get-Content $filePath) -replace 'useoauth: false', 'useoauth: true' | Set-Content $filePath c:\programdata\googet\googet.exe -noconfirm install google-osconfig-agent`+windowsPost, removeAgentCmd, testRegion, testingPkgsProjectName, agentRepo) } return fmt.Sprintf(` %s c:\programdata\googet\googet.exe -noconfirm install -sources https://packages.cloud.google.com/yuck/repos/google-osconfig-agent-%s google-osconfig-agent `+windowsPost, removeAgentCmd, config.AgentRepo()) } // getYumRepoBaseURL returns the repo baseUrl that should be added to repo file google-osconfig-agent.repo func getYumRepoBaseURL(osType string) string { agentRepo := config.AgentRepo() if agentRepo == "testing" { testRegion := pickTestRegionForArtifactRegistry() return fmt.Sprintf("https://%s-yum.pkg.dev/projects/%s/google-osconfig-agent-%s-testing", testRegion, testingPkgsProjectName, osType) } return fmt.Sprintf("https://packages.cloud.google.com/yum/repos/google-osconfig-agent-%s-%s", osType, agentRepo) } func getYumRepoSetup(osType string) string { gpgcheck := 1 // According to doc, pkg name differ according to ELv version // doc: https://cloud.google.com/artifact-registry/docs/os-packages/rpm/configure#prepare-yum format := "dnf" if osType == "el7" { format = "yum" } repoConfig := fmt.Sprintf(` # install yum-plugin-artifact-registry yum makecache yum install -y %s-plugin-artifact-registry cat > /etc/yum.repos.d/google-osconfig-agent.repo < /etc/zypp/repos.d/google-osconfig-agent.repo < bullseye) func GetDebOsName(image string) string { imageName := path.Base(image) switch { case image == "10" || containsAnyOf(imageName, []string{"debian-10", "buster"}): return "buster" case image == "11" || containsAnyOf(imageName, []string{"debian-11", "bullseye"}): return "bullseye" case image == "12" || containsAnyOf(imageName, []string{"debian-12", "bookworm"}): return "bookworm" } return "" } // DowngradeBullseyeAptImages is a single image that are used for testing downgrade case with apt-get var DowngradeBullseyeAptImages = map[string]string{ "debian-cloud/debian-11": "projects/debian-cloud/global/images/debian-11-bullseye-v20231010", } // HeadBusterAptImages empty for now as debian-10 wil reach EOL and some of its repos are not reachable anymore. var HeadBusterAptImages = map[string]string{ // Debian images. } // HeadBullseyeAptImages is a map of names to image paths for public debian-11 images var HeadBullseyeAptImages = map[string]string{ // Debian images. "debian-cloud/debian-11": "projects/debian-cloud/global/images/family/debian-11", } // HeadBookwormAptImages is a map of names to image paths for public debian-12 images var HeadBookwormAptImages = map[string]string{ // Debian images. "debian-cloud/debian-12": "projects/debian-cloud/global/images/family/debian-12", } // HeadSUSEImages is a map of names to image paths for public SUSE images. var HeadSUSEImages = func() map[string]string { imgsMap := make(map[string]string) // TODO: enable SUSE tests to use testing pkgs after Artifact Registry supports zypper installation from private repos if config.AgentRepo() != "testing" { imgsMap = map[string]string{ "suse-cloud/sles-12-sp5": "projects/suse-cloud/global/images/family/sles-12", "suse-cloud/sles-15-sp5": "projects/suse-cloud/global/images/family/sles-15", "suse-sap-cloud/sles-12-sp5-sap": "projects/suse-sap-cloud/global/images/family/sles-12-sp5-sap", "suse-sap-cloud/sles-15-sp5-sap": "projects/suse-sap-cloud/global/images/family/sles-15-sp5-sap", "suse-sap-cloud/sles-15-sp6-sap": "projects/suse-sap-cloud/global/images/family/sles-15-sp6-sap", "suse-sap-cloud/sles-15-sp5-hardened-sap": "projects/suse-sap-cloud/global/images/family/sles-sap-15-sp5-hardened", "opensuse-cloud/opensuse-leap-15": "projects/opensuse-cloud/global/images/family/opensuse-leap", } } return imgsMap }() // OldSUSEImages is a map of names to image paths for public SUSE images. var OldSUSEImages = func() map[string]string { imgsMap := make(map[string]string) // TODO: enable SUSE tests to use testing pkgs after Artifact Registry supports zypper installation from private repos if config.AgentRepo() != "testing" { imgsMap = map[string]string{ "old/sles-15-sp3-sap": "projects/suse-sap-cloud/global/images/sles-15-sp3-sap-v20240808-x86-64", "old/sles-15-sp4-sap": "projects/suse-sap-cloud/global/images/sles-15-sp4-sap-v20240208-x86-64", } } return imgsMap }() // HeadEL8Images is a map of names to image paths for public EL8 image families. (RHEL, CentOS, Rocky) var HeadEL8Images = map[string]string{ "rhel-cloud/rhel-8": "projects/rhel-cloud/global/images/family/rhel-8", "rhel-sap-cloud/rhel-8-4-sap": "projects/rhel-sap-cloud/global/images/family/rhel-8-4-sap-ha", "rhel-sap-cloud/rhel-8-6-sap": "projects/rhel-sap-cloud/global/images/family/rhel-8-6-sap-ha", "rhel-sap-cloud/rhel-8-8-sap": "projects/rhel-sap-cloud/global/images/family/rhel-8-8-sap-ha", "rocky-linux-cloud/rocky-linux-8": "projects/rocky-linux-cloud/global/images/family/rocky-linux-8", "rocky-linux-cloud/rocky-linux-8-optimized-gcp": "projects/rocky-linux-cloud/global/images/family/rocky-linux-8-optimized-gcp", } // OldEL8Images is a map of names to image paths for old EL8 images. (RHEL, CentOS, Rocky) var OldEL8Images = map[string]string{ // Currently empty } // HeadEL9Images is a map of names to image paths for public EL9 image families. (RHEL, CentOS, Rocky) var HeadEL9Images = map[string]string{ "centos-cloud/centos-stream-9": "projects/centos-cloud/global/images/family/centos-stream-9", "rhel-cloud/rhel-9": "projects/rhel-cloud/global/images/family/rhel-9", "rhel-sap-cloud/rhel-9-0-sap": "projects/rhel-sap-cloud/global/images/family/rhel-9-0-sap-ha", "rhel-sap-cloud/rhel-9-2-sap": "projects/rhel-sap-cloud/global/images/family/rhel-9-2-sap-ha", "rocky-linux-cloud/rocky-linux-9": "projects/rocky-linux-cloud/global/images/family/rocky-linux-9", "rocky-linux-cloud/rocky-linux-9-optimized-gcp": "projects/rocky-linux-cloud/global/images/family/rocky-linux-9-optimized-gcp", } // OldEL9Images is a map of names to image paths for old EL9 images. (RHEL, CentOS, Rocky) var OldEL9Images = map[string]string{ // Currently empty } // HeadELImages is a map of names to image paths for public EL image families. (RHEL, CentOS, Rocky) var HeadELImages = func() (newMap map[string]string) { newMap = make(map[string]string) for k, v := range HeadEL8Images { newMap[k] = v } for k, v := range HeadEL9Images { newMap[k] = v } return }() // HeadAptImages is a map of names to image paths for public EL image families. (RHEL, CentOS, Rocky) var HeadAptImages = func() (newMap map[string]string) { newMap = make(map[string]string) for k, v := range HeadBusterAptImages { newMap[k] = v } for k, v := range HeadBullseyeAptImages { newMap[k] = v } for k, v := range HeadBookwormAptImages { newMap[k] = v } return }() // HeadWindowsImages is a map of names to image paths for public Windows image families. var HeadWindowsImages = map[string]string{ "windows-cloud/windows-2016": "projects/windows-cloud/global/images/family/windows-2016", "windows-cloud/windows-2016-core": "projects/windows-cloud/global/images/family/windows-2016-core", "windows-cloud/windows-2019": "projects/windows-cloud/global/images/family/windows-2019", "windows-cloud/windows-2019-core": "projects/windows-cloud/global/images/family/windows-2019-core", // Testing of win-2022-dc disabled because of https://techcommunity.microsoft.com/t5/windows-server-for-it-pro/faulty-patches-on-server-2022/m-p/4028125 /* "windows-cloud/windows-2022": "projects/windows-cloud/global/images/family/windows-2022", "windows-cloud/windows-2022-core": "projects/windows-cloud/global/images/family/windows-2022-core", */ } // OldWindowsImages is a map of names to image paths for old Windows images. var OldWindowsImages = map[string]string{ // Currently empty } // HeadCOSImages is a map of names to image paths for public COS image families. var HeadCOSImages = map[string]string{ "cos-cloud/cos-stable": "projects/cos-cloud/global/images/family/cos-stable", "cos-cloud/cos-beta": "projects/cos-cloud/global/images/family/cos-beta", "cos-cloud/cos-dev": "projects/cos-cloud/global/images/family/cos-dev", } // RandString generates a random string of n length. func RandString(n int) string { gen := rand.New(rand.NewSource(time.Now().UnixNano())) letters := "bdghjlmnpqrstvwxyz0123456789" b := make([]byte, n) for i := range b { b[i] = letters[gen.Int63()%int64(len(letters))] } return string(b) } // GetStatusFromError return a string that contains all information // about the error that is created from a status func GetStatusFromError(err error) string { if s, ok := status.FromError(err); ok { return fmt.Sprintf("code: %q, message: %q, details: %q", s.Code(), s.Message(), s.Details()) } return fmt.Sprintf("%v", err) } // This pool is just used for CreateComputeInstance so that we limit our calls to the API during the heavy create process. var pool = make(chan struct{}, 10) // CreateComputeInstance is an utility function to create gce instance func CreateComputeInstance(metadataitems []*api.MetadataItems, client daisyCompute.Client, machineType, image, name, projectID, zone, serviceAccountEmail string, serviceAccountScopes []string) (*compute.Instance, error) { pool <- struct{}{} defer func() { <-pool }() var items []*api.MetadataItems // enable debug logging and guest-attributes for all test instances items = append(items, compute.BuildInstanceMetadataItem("enable-os-config-debug", "true")) items = append(items, compute.BuildInstanceMetadataItem("enable-guest-attributes", "true")) if config.AgentSvcEndpoint() != "" { items = append(items, compute.BuildInstanceMetadataItem("os-config-endpoint", config.AgentSvcEndpoint())) } for _, item := range metadataitems { items = append(items, item) } i := &api.Instance{ Name: name, MachineType: fmt.Sprintf("projects/%s/zones/%s/machineTypes/%s", projectID, zone, machineType), NetworkInterfaces: []*api.NetworkInterface{ { Subnetwork: fmt.Sprintf("projects/%s/regions/%s/subnetworks/default", projectID, zone[:len(zone)-2]), AccessConfigs: []*api.AccessConfig{ { Type: "ONE_TO_ONE_NAT", }, }, }, }, Metadata: &api.Metadata{ Items: items, }, Disks: []*api.AttachedDisk{ { AutoDelete: true, Boot: true, InitializeParams: &api.AttachedDiskInitializeParams{ SourceImage: image, DiskType: fmt.Sprintf("projects/%s/zones/%s/diskTypes/pd-balanced", projectID, zone), }, }, }, ServiceAccounts: []*api.ServiceAccount{ { Email: serviceAccountEmail, Scopes: serviceAccountScopes, }, }, Labels: map[string]string{"name": name}, } inst, err := compute.CreateInstance(client, projectID, zone, i) if err != nil { return nil, err } return inst, nil } osconfig-20250416.02/examples/000077500000000000000000000000001477773331400156445ustar00rootroot00000000000000osconfig-20250416.02/examples/OSPolicyAssignments/000077500000000000000000000000001477773331400215615ustar00rootroot00000000000000osconfig-20250416.02/examples/OSPolicyAssignments/README.md000066400000000000000000000000001477773331400230260ustar00rootroot00000000000000osconfig-20250416.02/examples/OSPolicyAssignments/console/000077500000000000000000000000001477773331400232235ustar00rootroot00000000000000osconfig-20250416.02/examples/OSPolicyAssignments/console/CIS/000077500000000000000000000000001477773331400236415ustar00rootroot00000000000000osconfig-20250416.02/examples/OSPolicyAssignments/console/CIS/cis-exclude-check-once-a-day.yaml000066400000000000000000000032151477773331400317210ustar00rootroot00000000000000# An OS policy to opt-out of CIS check and check compliance status once a day. id: exclude-cis-check-and-check-compliance-once-a-day-policy mode: ENFORCEMENT resourceGroups: - resources: id: exclude-cis-check-and-check-compliance-once-a-day exec: validate: interpreter: SHELL # If cis-compliance-scanner.service is active, return an exit code # 100 to indicate that the instance is in compliant state. # Otherwise, return an exit code of 101 to run `enforce` step. script: |- is_active=$(systemctl is-active cis-compliance-scanner.timer) result=$(systemctl show -p Result --value cis-compliance-scanner.service) if [ "$is_active" == "active" ] && [ "$result" == "success" ]; then exit 100; else exit 101; fi enforce: interpreter: SHELL # Return an exit code of 100 to indicate that the desired changes # were successfully applied. script: |- # Opt-out of the etc-passwd-permissions check. sed -i 's/^EXTRA.*$/EXTRA_OPTIONS="--benchmark-opt-out-ids=etc-passwd-permissions"/' /etc/cis-scanner/env_vars && # Check the compliance of the instance once a day. systemctl start cis-compliance-scanner.timer # Ensure cis-compliance-scanner completes before exiting PID=$(systemctl show --property MainPID --value cis-compliance-scanner.service) && timeout 5m bash -c -- 'while [ -e /proc/'$PID' ]; do echo "CIS Scanner with PID:'$PID' is still running"; sleep 1; done' && exit 100 osconfig-20250416.02/examples/OSPolicyAssignments/console/CIS/cis-level1-once-a-day-policy.yaml000066400000000000000000000030731477773331400317040ustar00rootroot00000000000000# An OS policy to check CIS level 1 compliance once a day. id: ensure-cis-level1-compliance-once-a-day-policy mode: ENFORCEMENT resourceGroups: - resources: id: ensure-cis-level1-compliance-once-a-day exec: validate: interpreter: SHELL # If cis-compliance-scanner.service is active, return an exit code # 100 to indicate that the instance is in compliant state. # Otherwise, return an exit code of 101 to run `enforce` step. script: |- is_active=$(systemctl is-active cis-compliance-scanner.timer) result=$(systemctl show -p Result --value cis-compliance-scanner.service) if [ "$is_active" == "active" ] && [ "$result" == "success" ]; then exit 100; else exit 101; fi enforce: interpreter: SHELL # COS 97 images are by-default CIS Level 1 compliant and there is no # additional configuration needed. However, if certain changes # cause non-compliance because of the workload on the instance, this # section can be used to automate to make fixes. For example, the # workload might generate a file that does not comply with the # recommended file permissions. # Return an exit code of 100 to indicate that the desired changes # successfully applied. script: |- # optional # Check the compliance of the instance once a day. systemctl start cis-compliance-scanner.timer && exit 100 osconfig-20250416.02/examples/OSPolicyAssignments/console/CIS/cis-level1-once-an-hour-policy.yaml000066400000000000000000000032731477773331400322640ustar00rootroot00000000000000# An OS policy to check CIS level 1 compliance once an hour. id: ensure-cis-level1-compliance-once-an-hour-policy mode: ENFORCEMENT resourceGroups: - resources: id: ensure-cis-level1-compliance-once-an-hour exec: validate: interpreter: SHELL # If cis-compliance-scanner.service is active, return an exit code # 100 to indicate that the instance is in compliant state. # Otherwise, return an exit code of 101 to run `enforce` step. script: |- is_active=$(systemctl is-active cis-compliance-scanner.timer) result=$(systemctl show -p Result --value cis-compliance-scanner.service) if [ "$is_active" == "active" ] && [ "$result" == "success" ]; then exit 100; else exit 101; fi enforce: interpreter: SHELL # Return an exit code of 100 to indicate that the desired changes # were successfully applied. script: |- # Overwrite "OnUnitActiveSec" field of the # cis-compliance-scanner.timer to trigger # cis-compliance-scanner.service once an hour # instead of once a day. mkdir /etc/systemd/system/cis-compliance-scanner.timer.d tee /etc/systemd/system/cis-compliance-scanner.timer.d/override.conf < generation: 123456789 # https://cloud.google.com/storage/docs/generations-preconditions object: test.txt path: C:\ instanceFilter: inclusionLabels: - labels: env: dev rollout: disruptionBudget: fixed: 10 minWaitDuration: 300s osconfig-20250416.02/examples/OSPolicyAssignments/gcloud/exec_script_linux_all.yaml000066400000000000000000000024051477773331400303020ustar00rootroot00000000000000# An OS policy assignment that ensures Apache web server is running on Linux OSes. # The assignment is applied only to those VMs that have the label `type:webserver` assigned to them. osPolicies: - id: apache-always-up-policy mode: ENFORCEMENT resourceGroups: - resources: id: ensure-apache-is-up exec: validate: interpreter: SHELL # If Apache web server is already running, return an exit code 100 to indicate # that exec resource is already in desired state. In this scenario, # the `enforce` step will not be run. # Otherwise return an exit code of 101 to indicate that exec resource is not in # desired state. In this scenario, the `enforce` step will be run. script: if systemctl is-active --quiet httpd; then exit 100; else exit 101; fi enforce: interpreter: SHELL # Start Apache web server and return an exit code of 100 to indicate that the # resource is now in its desired state. script: systemctl start httpd && exit 100 instanceFilter: inclusionLabels: - labels: type: webserver rollout: disruptionBudget: fixed: 10 minWaitDuration: 300s osconfig-20250416.02/examples/OSPolicyAssignments/gcloud/filter_vms_by_labels_windows_all.yaml000066400000000000000000000020661477773331400325160ustar00rootroot00000000000000# An OS policy assignment to install a Windows MSI downloaded from a Google Cloud Storage bucket. # The assignment is applied only to those VMs that have the label `windows-env-target:prod` # assigned to them. # Any VMs with the label `windows-env-target:test` will be excluded from the assignment. # Note that a VM that has both labels `windows-env-target:prod` and `windows-env-target:test` # will be excluded because the exclusion criteria has higher priority than inclusion criteria. osPolicies: - id: install-msi-policy mode: ENFORCEMENT resourceGroups: - resources: - id: install-msi pkg: desiredState: INSTALLED msi: source: gcs: bucket: my-bucket object: my-app.msi generation: 1619136883923956 instanceFilter: inclusionLabels: - labels: windows-env-target: prod exclusionLabels: - labels: windows-env-target: test rollout: disruptionBudget: fixed: 10 minWaitDuration: 300s filter_vms_by_os_family_linux_rhel_centos.yaml000066400000000000000000000007501477773331400343570ustar00rootroot00000000000000osconfig-20250416.02/examples/OSPolicyAssignments/gcloud# An OS policy assignment to remove an unwanted package from Red Hat Enterprise Linux and CentOS OSes. osPolicies: - id: remove-pkg-policy mode: ENFORCEMENT resourceGroups: - resources: - id: remove-pkg pkg: desiredState: REMOVED yum: name: unwanted-package instanceFilter: inventories: - osShortName: rhel - osShortName: centos rollout: disruptionBudget: fixed: 10 minWaitDuration: 300s osconfig-20250416.02/examples/OSPolicyAssignments/gcloud/google_cloud_sap_agent.yaml000066400000000000000000000325471477773331400304200ustar00rootroot00000000000000# # For use with the gcloud OS Policy create / update command # # An OS Policy that will install the Google Cloud SAP Agent and keep it updated # This policy will apply to all RHEL 7.*, 8.*, 9.*, SLES 12.*, 15.*, and Windows with # OS images that have the label "workload=sap". The labels can be modified in the labels section. # # This policy will apply when the VM has enabled the osconfig metadata: "enable-osconfig=TRUE" # osPolicies: - id: google-cloud-sap-agent-policy mode: ENFORCEMENT resourceGroups: # RHEL 7.* - inventoryFilters: - osShortName: rhel osVersion: 7.* resources: - id: sapagent-repo repository: yum: id: google-cloud-sap-agent displayName: Google Cloud Agent for SAP Repository baseUrl: https://packages.cloud.google.com/yum/repos/google-cloud-sap-agent-el7-x86_64 gpgKeys: - https://packages.cloud.google.com/yum/doc/yum-key.gpg - https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg - id: install-sapagent exec: validate: interpreter: SHELL # If the Agent for SAP is already installed, return an exit code 100 to indicate # that exec resource is already in desired state. In this scenario, # the `enforce` step will not be run. # Otherwise return an exit code of 101 to indicate that exec resource is not in # desired state. In this scenario, the `enforce` step will be run. script: if sudo yum list installed | grep google-cloud-sap-agent; then exit 100; else exit 101; fi enforce: interpreter: SHELL # Install the Agent for SAP and return an exit code of 100 to indicate that the # resource is now in its desired state. script: sudo yum install -y google-cloud-sap-agent && exit 100 - id: update-sapagent exec: validate: interpreter: SHELL # If the Agent for SAP is already up-to-date, return an exit code 100 to indicate # that exec resource is already in desired state. In this scenario, # the `enforce` step will not be run. # Otherwise return an exit code of 101 to indicate that exec resource is not in # desired state. In this scenario, the `enforce` step will be run. script: if yum check-update google-cloud-sap-agent | grep google-cloud-sap-agent; then exit 101; else exit 100; fi enforce: interpreter: SHELL # Update the Agent for SAP and return an exit code of 100 to indicate that the # resource is now in its desired state. script: yum update -y google-cloud-sap-agent && exit 100 # RHEL 8.* - inventoryFilters: - osShortName: rhel osVersion: 8.* resources: - id: sapagent-repo repository: yum: id: google-cloud-sap-agent displayName: Google Cloud Agent for SAP Repository baseUrl: https://packages.cloud.google.com/yum/repos/google-cloud-sap-agent-el8-x86_64 gpgKeys: - https://packages.cloud.google.com/yum/doc/yum-key.gpg - https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg - id: install-sapagent exec: validate: interpreter: SHELL # If the Agent for SAP is already installed, return an exit code 100 to indicate # that exec resource is already in desired state. In this scenario, # the `enforce` step will not be run. # Otherwise return an exit code of 101 to indicate that exec resource is not in # desired state. In this scenario, the `enforce` step will be run. script: if sudo yum list installed | grep google-cloud-sap-agent; then exit 100; else exit 101; fi enforce: interpreter: SHELL # Install the Agent for SAP and return an exit code of 100 to indicate that the # resource is now in its desired state. script: sudo yum install -y google-cloud-sap-agent && exit 100 - id: update-sapagent exec: validate: interpreter: SHELL # If the Agent for SAP is already up-to-date, return an exit code 100 to indicate # that exec resource is already in desired state. In this scenario, # the `enforce` step will not be run. # Otherwise return an exit code of 101 to indicate that exec resource is not in # desired state. In this scenario, the `enforce` step will be run. script: if yum check-update google-cloud-sap-agent | grep google-cloud-sap-agent; then exit 101; else exit 100; fi enforce: interpreter: SHELL # Update the Agent for SAP and return an exit code of 100 to indicate that the # resource is now in its desired state. script: yum update -y google-cloud-sap-agent && exit 100 # RHEL 9.* - inventoryFilters: - osShortName: rhel osVersion: 9.* resources: - id: sapagent-repo repository: yum: id: google-cloud-sap-agent displayName: Google Cloud Agent for SAP Repository baseUrl: https://packages.cloud.google.com/yum/repos/google-cloud-sap-agent-el9-x86_64 gpgKeys: - https://packages.cloud.google.com/yum/doc/yum-key.gpg - https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg - id: install-sapagent exec: validate: interpreter: SHELL # If the Agent for SAP is already installed, return an exit code 100 to indicate # that exec resource is already in desired state. In this scenario, # the `enforce` step will not be run. # Otherwise return an exit code of 101 to indicate that exec resource is not in # desired state. In this scenario, the `enforce` step will be run. script: if sudo yum list installed | grep google-cloud-sap-agent; then exit 100; else exit 101; fi enforce: interpreter: SHELL # Install the Agent for SAP and return an exit code of 100 to indicate that the # resource is now in its desired state. script: sudo yum install -y google-cloud-sap-agent && exit 100 - id: update-sapagent exec: validate: interpreter: SHELL # If the Agent for SAP is already up-to-date, return an exit code 100 to indicate # that exec resource is already in desired state. In this scenario, # the `enforce` step will not be run. # Otherwise return an exit code of 101 to indicate that exec resource is not in # desired state. In this scenario, the `enforce` step will be run. script: if yum check-update google-cloud-sap-agent | grep google-cloud-sap-agent; then exit 101; else exit 100; fi enforce: interpreter: SHELL # Update the Agent for SAP and return an exit code of 100 to indicate that the # resource is now in its desired state. script: yum update -y google-cloud-sap-agent && exit 100 # SLES 12.* - inventoryFilters: - osShortName: sles osVersion: 12.* resources: - id: sapagent-repo repository: zypper: id: google-cloud-sap-agent displayName: Google Cloud Agent for SAP Repository baseUrl: https://packages.cloud.google.com/yum/repos/google-cloud-sap-agent-sles12-x86_64 gpgKeys: - https://packages.cloud.google.com/yum/doc/yum-key.gpg - https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg - id: install-sapagent exec: validate: interpreter: SHELL # If the Agent for SAP is already installed, return an exit code 100 to indicate # that exec resource is already in desired state. In this scenario, # the `enforce` step will not be run. # Otherwise return an exit code of 101 to indicate that exec resource is not in # desired state. In this scenario, the `enforce` step will be run. script: if sudo zypper search -i google-cloud-sap-agent; then exit 100; else exit 101; fi enforce: interpreter: SHELL # Install the Agent for SAP and return an exit code of 100 to indicate that the # resource is now in its desired state. script: sudo zypper --gpg-auto-import-keys install -y google-cloud-sap-agent && exit 100 - id: update-sapagent exec: validate: interpreter: SHELL # If the Agent for SAP is already up-to-date, return an exit code 100 to indicate # that exec resource is already in desired state. In this scenario, # the `enforce` step will not be run. # Otherwise return an exit code of 101 to indicate that exec resource is not in # desired state. In this scenario, the `enforce` step will be run. script: if sudo zypper list-updates -r google-cloud-sap-agent | grep google-cloud-sap-agent; then exit 101; else exit 100; fi enforce: interpreter: SHELL # Update the Agent for SAP and return an exit code of 100 to indicate that the # resource is now in its desired state. script: sudo zypper --gpg-auto-import-keys update -y google-cloud-sap-agent && exit 100 # SLES 15.* - inventoryFilters: - osShortName: sles osVersion: 15.* resources: - id: sapagent-repo repository: zypper: id: google-cloud-sap-agent displayName: Google Cloud Agent for SAP Repository baseUrl: https://packages.cloud.google.com/yum/repos/google-cloud-sap-agent-sles15-x86_64 gpgKeys: - https://packages.cloud.google.com/yum/doc/yum-key.gpg - https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg - id: install-sapagent exec: validate: interpreter: SHELL # If the Agent for SAP is already installed, return an exit code 100 to indicate # that exec resource is already in desired state. In this scenario, # the `enforce` step will not be run. # Otherwise return an exit code of 101 to indicate that exec resource is not in # desired state. In this scenario, the `enforce` step will be run. script: if sudo zypper search -i google-cloud-sap-agent; then exit 100; else exit 101; fi enforce: interpreter: SHELL # Install the Agent for SAP and return an exit code of 100 to indicate that the # resource is now in its desired state. script: sudo zypper --gpg-auto-import-keys install -y google-cloud-sap-agent && exit 100 - id: update-sapagent exec: validate: interpreter: SHELL # If the Agent for SAP is already up-to-date, return an exit code 100 to indicate # that exec resource is already in desired state. In this scenario, # the `enforce` step will not be run. # Otherwise return an exit code of 101 to indicate that exec resource is not in # desired state. In this scenario, the `enforce` step will be run. script: if sudo zypper list-updates -r google-cloud-sap-agent | grep google-cloud-sap-agent; then exit 101; else exit 100; fi enforce: interpreter: SHELL # Update the Agent for SAP and return an exit code of 100 to indicate that the # resource is now in its desired state. script: sudo zypper --gpg-auto-import-keys update -y google-cloud-sap-agent && exit 100 # Windows - inventoryFilters: - osShortName: windows resources: - id: sapagent-repo repository: goo: name: google-cloud-sap-agent url: https://packages.cloud.google.com/yuck/repos/google-cloud-sap-agent-windows - id: install-sapagent pkg: desiredState: INSTALLED googet: name: google-cloud-sap-agent instanceFilter: inclusionLabels: # Modify labels for the VMs that you want the policy to apply to - labels: workload: sap inventories: - osShortName: rhel - osShortName: sles - osShortName: windows rollout: disruptionBudget: fixed: 10 minWaitDuration: 60s osconfig-20250416.02/examples/OSPolicyAssignments/gcloud/install_msi_windows_all.yaml000066400000000000000000000011751477773331400306460ustar00rootroot00000000000000# An OS policy assignment to install a Windows MSI downloaded from a Google Cloud Storage bucket # on all VMs running Windows Server OS. osPolicies: - id: install-msi-policy mode: ENFORCEMENT resourceGroups: - resources: - id: install-msi pkg: desiredState: INSTALLED msi: source: gcs: bucket: my-bucket object: my-app.msi generation: 1619136883923956 instanceFilter: inventories: - osShortName: windows rollout: disruptionBudget: fixed: 10 minWaitDuration: 300s setup_repo_and_install_package_linux_apt.yaml000066400000000000000000000030171477773331400341370ustar00rootroot00000000000000osconfig-20250416.02/examples/OSPolicyAssignments/gcloud# An OS policy assignment to set up the Google Cloud Monitoring repository and # install the Stackdriver agent for VMs running Debian and Ubuntu OSes. osPolicies: - id: setup-repo-and-install-package-policy mode: ENFORCEMENT resourceGroups: - inventoryFilters: - osShortName: debian resources: - id: setup-repo repository: apt: archiveType: DEB uri: https://packages.cloud.google.com/apt distribution: google-cloud-monitoring-buster-all components: - main gpgKey: https://packages.cloud.google.com/apt/doc/apt-key.gpg - id: install-pkg pkg: desiredState: INSTALLED apt: name: stackdriver-agent - inventoryFilters: - osShortName: ubuntu resources: - id: setup-repo repository: apt: archiveType: DEB uri: https://packages.cloud.google.com/apt distribution: google-cloud-monitoring-groovy components: - main gpgKey: https://packages.cloud.google.com/apt/doc/apt-key.gpg - id: install-pkg pkg: desiredState: INSTALLED apt: name: stackdriver-agent instanceFilter: inventories: - osShortName: debian - osShortName: ubuntu rollout: disruptionBudget: fixed: 10 minWaitDuration: 300s setup_repo_and_install_package_linux_yum.yaml000066400000000000000000000020421477773331400341620ustar00rootroot00000000000000osconfig-20250416.02/examples/OSPolicyAssignments/gcloud# An OS policy assignment to set up the Google Cloud Monitoring repository and # install the Stackdriver agent for VMs running either Red Hat Enterprise Linux and CentOS OSes. osPolicies: - id: setup-repo-and-install-package-policy mode: ENFORCEMENT resourceGroups: - resources: - id: setup-repo repository: yum: id: google-cloud-monitoring displayName: Google Cloud Monitoring Agent Repository baseUrl: https://packages.cloud.google.com/yum/repos/google-cloud-monitoring-el8-x86_64-all gpgKeys: - https://packages.cloud.google.com/yum/doc/yum-key.gpg - https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg - id: install-pkg pkg: desiredState: INSTALLED yum: name: stackdriver-agent instanceFilter: inventories: - osShortName: rhel - osShortName: centos rollout: disruptionBudget: fixed: 10 minWaitDuration: 300s osconfig-20250416.02/examples/OSPolicyAssignments/gcloud/win-ensure-openssh.yaml000066400000000000000000000017031477773331400274740ustar00rootroot00000000000000# An OS policy to ensure sshd is installed and running on windows # only applies to VMs running windows with the label 'ssh' with value 'installed' osPolicies: - id: win-ensure-openssh-policy mode: ENFORCEMENT resourceGroups: - resources: id: ensure-ssh exec: validate: interpreter: POWERSHELL script: | $service = Get-Service -Name 'sshd' if ($service.Status -eq 'Running') {exit 100} else {exit 101} enforce: interpreter: POWERSHELL script: | Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 Set-Service -Name sshd -StartupType 'Automatic' Start-Service sshd exit 100 instanceFilter: osShortNames: - windows inclusionLabels: - labels: ssh: installed rollout: disruptionBudget: fixed: 10 minWaitDuration: 300sosconfig-20250416.02/examples/OWNERS000066400000000000000000000004721477773331400166070ustar00rootroot00000000000000# This file enables automatic assignment of PR reviewers. # See the OWNERS docs at https://go.k8s.io/owners labels: - examples approvers: - burov - dowgird - Gulio - michaljankowiak - paulinakania - savijatv reviewers: - burov - dowgird - Gulio - michaljankowiak - paulinakania - savijatv osconfig-20250416.02/examples/Terraform/000077500000000000000000000000001477773331400176055ustar00rootroot00000000000000osconfig-20250416.02/examples/Terraform/README.md000066400000000000000000000002041477773331400210600ustar00rootroot00000000000000# Terraform Examples This directory contains examples illustrating the use of Terraform for creating OSConfig related resources. osconfig-20250416.02/examples/Terraform/multi-project-deployments/000077500000000000000000000000001477773331400247445ustar00rootroot00000000000000osconfig-20250416.02/examples/Terraform/multi-project-deployments/README.md000066400000000000000000000037251477773331400262320ustar00rootroot00000000000000# Prototype to deploy OSConfig Guest Policies in Multiple GCP Projects This guide describes how to use [Terraform](https://www.terraform.io/) to deploy an OSConfig Guest Policy in multiple GCP Projects. It proceeds through the following stages: * Determine the list of GCP Projects * For each one of them * Create OSConfig Guest Policies that will execute a basic command (as an illustrative example) # How to use From the [Cloud Shell](https://cloud.google.com/shell) ## Clone the repository Clone the Git repository with the command ``` git clone https://github.com:GoogleCloudPlatform/osconfig.git ``` change directory, into the repository ``` cd osconfig cd examples/Terraform/multi-project-deployments ``` ## Define environment variables The following variables will contain sensitive information. Therefore, it is recommended that you set them dynamically, only for your session. ``` export TF_VAR_organization_id=YOUR_ORG_ID export TF_VAR_billing_account=YOUR_BILLING_ACCOUNT_ID export TF_ADMIN_PROJECT=THE_PROJECT_FROM_WHERE_TF_COMMANDS_WILL_BE_SENT export TF_ADMIN_USER=THE_USER_TYPING_TF_COMMANDS ``` You can find the values for `YOUR_ORG_ID` and `YOUR_BILLING_ACCOUNT_ID` using the following commands: ``` gcloud organizations list gcloud beta billing accounts list ``` ## Configure User Admin and Project Admin ``` cd preparation_scripts ./create_tf_admin_project.sh ``` This script will create a Project that will serve to administer TF commands. It will enable the required services in that project. Finally, it will also grant the necessary permissions to the `TF_ADMIN_USER`. ### Create Resources in order Login as the `TF_ADMIN_USER` and authenticate with the following commands. ``` gcloud auth application-default login gcloud auth application-default set-quota-project $TF_ADMIN_PROJECT ``` You can now proceed to create the cloud resouces by using the following modules in order: ``` create_projects create_guest_policies create_patch_deployments ``` osconfig-20250416.02/examples/Terraform/multi-project-deployments/create_guest_policies/000077500000000000000000000000001477773331400313055ustar00rootroot00000000000000osconfig-20250416.02/examples/Terraform/multi-project-deployments/create_guest_policies/README.md000066400000000000000000000015471477773331400325730ustar00rootroot00000000000000# OSConfig Guest Policies This module is used to create an OSConfig Guest Policy that will trigger an installation in the VM instances belonging to this project. # Usage ## Configure the Variables * Define the folder name in the environment variable: `TF_VAR_folder_name`. * Define the organization ID in the environment variable: `TF_VAR_organization_id`. For example: ``` export TF_VAR_folder_name="production-department-x-folder" export TF_VAR_organization_id="0123456789" ``` ## Launching the Module Use the standard commands ``` terraform init ``` ``` terraform validate ``` ``` terraform plan -out=plan.out ``` Inspect the output, and if you are satisfied, run ``` terraform apply plan.out ``` ## Destroying the Resources Once you no longer have use for the OSConfig Guest Policies, you can destroy them with the command ``` terraform destroy ``` guest_policy_bash_script.txt000066400000000000000000000013101477773331400370510ustar00rootroot00000000000000osconfig-20250416.02/examples/Terraform/multi-project-deployments/create_guest_policiesdate >> /tmp/osconfig-terraform-multi-project-test.txt echo "Execution PASSED!" >> date >> /tmp/osconfig-terraform-multi-project-test.txt INSTANCE_NAME=$(curl http://metadata.google.internal/computeMetadata/v1/instance/name -H Metadata-Flavor:Google) INSTANCE_ZONE=$(curl http://metadata.google.internal/computeMetadata/v1/instance/zone -H Metadata-Flavor:Google | cut -d'/' -f4) echo "INSTANCE_NAME=${INSTANCE_NAME}" >> /tmp/osconfig-terraform-multi-project-test.txt echo "INSTANCE_ZONE=${INSTANCE_ZONE}" >> /tmp/osconfig-terraform-multi-project-test.txt gcloud compute instances add-metadata \ "${INSTANCE_NAME}" \ --zone="${INSTANCE_ZONE}" \ --metadata='osconfig-terraform-multi-project-test=PASSED' osconfig-20250416.02/examples/Terraform/multi-project-deployments/create_guest_policies/main.tf000066400000000000000000000026251477773331400325710ustar00rootroot00000000000000locals { guest_policy_linux = file("${path.module}/guest_policy_bash_script.txt") } data "google_active_folder" "terraform_osconfig" { display_name = var.folder_name parent = "organizations/${var.organization_id}" } locals { folder_id = split("/",data.google_active_folder.terraform_osconfig.id)[1] } data "google_projects" "in_folder" { filter = "parent.id:${local.folder_id}" } data "google_project" "listed_in_folder" { count = length(data.google_projects.in_folder.projects) project_id = data.google_projects.in_folder.projects[count.index].project_id } locals { projects = compact(data.google_project.listed_in_folder.*.number) } resource "google_os_config_guest_policies" "guest_policies" { provider = google-beta count = length(data.google_projects.in_folder.projects) guest_policy_id = "tf-test-guest-policy" description = "Test OSConfig Guest Policy in Linux VM instances." project = data.google_projects.in_folder.projects[count.index].project_id assignment { group_labels { labels = var.labels } os_types { os_short_name = "DEBIAN" os_version = "9*" } os_types { os_short_name = "UBUNTU" } } recipes { name = "tf-test-recipe-linux" desired_state = "INSTALLED" install_steps { script_run { interpreter = "SHELL" script = local.guest_policy_linux } } } } osconfig-20250416.02/examples/Terraform/multi-project-deployments/create_guest_policies/outputs.tf000066400000000000000000000006321477773331400333640ustar00rootroot00000000000000output "folder_id" { description = "ID of the folder containing projects of interest." value = local.folder_id } output "google_projects" { description = "List of projects inside a given folder" value = local.projects } output "guest_policies_self_links" { description = "List of self-links for OSConfig Guest Policies." value = google_os_config_guest_policies.guest_policies } terraform.example.tfvars000066400000000000000000000001131477773331400361030ustar00rootroot00000000000000osconfig-20250416.02/examples/Terraform/multi-project-deployments/create_guest_policiesorganization_id = "id" folder_name = "name" labels = { key = "value" } terraform.tfvars000066400000000000000000000001241477773331400344530ustar00rootroot00000000000000osconfig-20250416.02/examples/Terraform/multi-project-deployments/create_guest_policieslabels = { pizza_topping = "pepperoni" } folder_name = "tf-osconfig-test-folder" osconfig-20250416.02/examples/Terraform/multi-project-deployments/create_guest_policies/variables.tf000066400000000000000000000004751477773331400336160ustar00rootroot00000000000000variable "organization_id" { description = "Cloud Organization where to create Projects." type = string } variable "folder_name" { description = "Folder from where to list projects." type = string } variable "labels" { description = "Labels, provided as a map" type = map(string) } osconfig-20250416.02/examples/Terraform/multi-project-deployments/create_guest_policies/versions.tf000066400000000000000000000004401477773331400335060ustar00rootroot00000000000000terraform { required_version = ">=0.13.0" required_providers { google = ">= 3.43, <4.0" archive = "~> 1.0" random = "~> 2.0" null = "~> 2.1" } provider_meta "google" { module_name = "blueprints/terraform/terraform-google-vm:compute_instance/v6.1.0" } } osconfig-20250416.02/examples/Terraform/multi-project-deployments/create_patch_deployments/000077500000000000000000000000001477773331400320115ustar00rootroot00000000000000osconfig-20250416.02/examples/Terraform/multi-project-deployments/create_patch_deployments/README.md000066400000000000000000000015531477773331400332740ustar00rootroot00000000000000# OSConfig Patch Deployments This module is used to create an OSConfig Patch Deployment that will trigger the application of a patch in VMs on multiple projects. # Usage ## Configure the Variables * Define the folder name in the environment variable: `TF_VAR_folder_name`. * Define the organization ID in the environment variable: `TF_VAR_organization_id`. For example: ``` export TF_VAR_folder_name="production-department-x-folder" export TF_VAR_organization_id="0123456789" ``` ## Launching the Module Use the standard commands ``` terraform init ``` ``` terraform validate ``` ``` terraform plan -out=plan.out ``` Inspect the output, and if you are satisfied, run ``` terraform apply plan.out ``` ## Destroying the Resources Once you no longer have use for the OSConfig Patch Deployments, you can destroy them with the command ``` terraform destroy ``` osconfig-20250416.02/examples/Terraform/multi-project-deployments/create_patch_deployments/main.tf000066400000000000000000000020151477773331400332660ustar00rootroot00000000000000data "google_active_folder" "terraform_osconfig" { display_name = var.folder_name parent = "organizations/${var.organization_id}" } locals { folder_id = split("/",data.google_active_folder.terraform_osconfig.id)[1] } data "google_projects" "in_folder" { filter = "parent.id:${local.folder_id}" } data "google_project" "list_in_folder" { count = length(data.google_projects.in_folder.projects) project_id = data.google_projects.in_folder.projects[count.index].project_id } locals { projects = compact(data.google_project.list_in_folder.*.number) } resource "google_os_config_patch_deployment" "patch_deployments" { patch_deployment_id = "patch-deploy-inst" count = length(data.google_projects.in_folder.projects) project = data.google_projects.in_folder.projects[count.index].project_id instance_filter { group_labels { labels = var.labels } } one_time_schedule { # Execute 2 minutes from now execute_time = timeadd(timestamp(), var.patch_deployment_execute_time) } } outputs.tf000066400000000000000000000006451477773331400340150ustar00rootroot00000000000000osconfig-20250416.02/examples/Terraform/multi-project-deployments/create_patch_deploymentsoutput "folder_id" { description = "ID of the folder containing projects of interest." value = local.folder_id } output "google_projects" { description = "List of projects inside a given folder" value = local.projects } output "patch_deployments_self_links" { description = "List of self-links for OSConfig Patch Deployments." value = google_os_config_patch_deployment.patch_deployments } terraform.example.tfvars000066400000000000000000000001501477773331400366100ustar00rootroot00000000000000osconfig-20250416.02/examples/Terraform/multi-project-deployments/create_patch_deploymentsfolder_name = "name" labels = { key = "value" } patch_deployment_execute_time = "number_of_minutes" terraform.tfvars000066400000000000000000000001721477773331400351620ustar00rootroot00000000000000osconfig-20250416.02/examples/Terraform/multi-project-deployments/create_patch_deploymentsfolder_name = "tf-osconfig-test-folder" labels = { pizza_topping = "pepperoni" } patch_deployment_execute_time = "2m" variables.tf000066400000000000000000000007021477773331400342340ustar00rootroot00000000000000osconfig-20250416.02/examples/Terraform/multi-project-deployments/create_patch_deploymentsvariable "organization_id" { description = "Cloud Organization where to create Projects." type = string } variable "folder_name" { description = "Folder from where to list projects." type = string } variable "labels" { description = "Labels, provided as a map" type = map(string) } variable "patch_deployment_execute_time" { description = "Time to wait before deploying the patch jobs." type = string } versions.tf000066400000000000000000000004401477773331400341330ustar00rootroot00000000000000osconfig-20250416.02/examples/Terraform/multi-project-deployments/create_patch_deploymentsterraform { required_version = ">=0.13.0" required_providers { google = ">= 3.43, <4.0" archive = "~> 1.0" random = "~> 2.0" null = "~> 2.1" } provider_meta "google" { module_name = "blueprints/terraform/terraform-google-vm:compute_instance/v6.1.0" } } osconfig-20250416.02/examples/Terraform/multi-project-deployments/create_projects/000077500000000000000000000000001477773331400301205ustar00rootroot00000000000000osconfig-20250416.02/examples/Terraform/multi-project-deployments/create_projects/README.md000066400000000000000000000013741477773331400314040ustar00rootroot00000000000000# Create GCP Project in a Folder This module is used to create a set of GCP projects in a Folder. # Usage ## Configure the Variables The variables required by this module are defined in the `variables.tf` file. You can provide the specific values desired for your case by defining the environment variables * `TF_VAR_organization_id` * `TF_VAR_folder_name` * `TF_VAR_billing_account` ## Launching the Module Use the standard commands ``` terraform init ``` ``` terraform validate ``` ``` terraform plan -out=plan.out ``` Inspect the output, and if you are satisfied, run ``` terraform apply plan.out ``` ## Destroying the Resources Once you no longer have use for the projects, you can destroy them with the command ``` terraform destroy ``` osconfig-20250416.02/examples/Terraform/multi-project-deployments/create_projects/main.tf000066400000000000000000000131411477773331400313770ustar00rootroot00000000000000# # Create Folder to contain test projects # resource "google_folder" "tf_osconfig_folder" { display_name = var.folder_name parent = "organizations/${var.organization_id}" } locals { number_of_projects = 3 vm_service_account_scopes = [ # # Required by OS Config # "https://www.googleapis.com/auth/cloud-platform", # # Default scopes # https://cloud.google.com/sdk/gcloud/reference/alpha/compute/instances/set-scopes#--scopes "https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/logging.write", "https://www.googleapis.com/auth/monitoring.write", "https://www.googleapis.com/auth/pubsub", "https://www.googleapis.com/auth/service.management.readonly", "https://www.googleapis.com/auth/servicecontrol", "https://www.googleapis.com/auth/trace.append", ] } # # Create test projects # module "project-tf" { source = "terraform-google-modules/project-factory/google" count = local.number_of_projects name = "tf-osconfig-test-${count.index}" random_project_id = "true" org_id = var.organization_id billing_account = var.billing_account folder_id = google_folder.tf_osconfig_folder.id } # # Enable services in test projects # module "project-services" { source = "terraform-google-modules/project-factory/google//modules/project_services" count = local.number_of_projects project_id = module.project-tf[count.index].project_id enable_apis = true activate_apis = [ "iam.googleapis.com", "logging.googleapis.com", "osconfig.googleapis.com", "containeranalysis.googleapis.com", ] } resource "google_project_service" "compute_api" { count = local.number_of_projects project = module.project-tf[count.index].project_id service = "compute.googleapis.com" # Wait for some time after the API has been enabled before continuing, as the # call returns before the API has actually finished initializing. provisioner "local-exec" { command ="sleep 60" } } resource "google_compute_project_metadata_item" "osconfig_enable_meta" { count = local.number_of_projects project = module.project-tf[count.index].project_id key = "enable-osconfig" value = "TRUE" depends_on = [ google_project_service.compute_api ] } resource "google_compute_project_metadata_item" "osconfig_log_level_meta" { count = local.number_of_projects project = module.project-tf[count.index].project_id key = "osconfig-log-level" value = "debug" depends_on = [ google_project_service.compute_api ] } resource "google_compute_project_metadata_item" "enable_guest_attributes_meta" { count = local.number_of_projects project = module.project-tf[count.index].project_id key = "enable-guest-attributes" value = "TRUE" depends_on = [ google_project_service.compute_api ] } # # Create VM instances inside test projects. # resource "google_compute_network" "vpc_network" { name = "vpc-network" count = local.number_of_projects project = module.project-tf[count.index].project_id } resource "google_compute_firewall" "default" { name = "ssh-firewall-rule" count = local.number_of_projects project = module.project-tf[count.index].project_id network = google_compute_network.vpc_network[count.index].name allow { protocol = "tcp" ports = ["22"] } } resource "google_compute_address" "external_ip" { name = "external-ip" region = "us-central1" count = local.number_of_projects project = module.project-tf[count.index].project_id } resource "google_service_account" "default" { account_id = "tf-osconfig-vm" display_name = "TF OSConfig VM Service Account" count = local.number_of_projects project = module.project-tf[count.index].project_id } # # The following roles are needed for the service account to be able to write instance metadata. # resource "google_project_iam_binding" "log_writer" { count = local.number_of_projects project = module.project-tf[count.index].project_id role = "roles/logging.logWriter" members = [ "serviceAccount:${google_service_account.default[count.index].email}" ] } resource "google_project_iam_binding" "compute_viewer" { count = local.number_of_projects project = module.project-tf[count.index].project_id role = "roles/compute.viewer" members = [ "serviceAccount:${google_service_account.default[count.index].email}" ] } resource "google_project_iam_binding" "compute_instance_admin_v1" { count = local.number_of_projects project = module.project-tf[count.index].project_id role = "roles/compute.instanceAdmin.v1" members = [ "serviceAccount:${google_service_account.default[count.index].email}" ] } resource "google_project_iam_binding" "iam_service_account_user" { count = local.number_of_projects project = module.project-tf[count.index].project_id role = "roles/iam.serviceAccountUser" members = [ "serviceAccount:${google_service_account.default[count.index].email}" ] } resource "google_compute_instance" "default" { name = "tf-osconfig-vm" count = local.number_of_projects project = module.project-tf[count.index].project_id machine_type = "n1-standard-1" zone = "us-central1-a" boot_disk { initialize_params { image = "debian-cloud/debian-9" } } network_interface { network = google_compute_network.vpc_network[count.index].name access_config { nat_ip = google_compute_address.external_ip[count.index].address } } service_account { email = google_service_account.default[count.index].email scopes = local.vm_service_account_scopes } labels = var.labels } osconfig-20250416.02/examples/Terraform/multi-project-deployments/create_projects/outputs.tf000066400000000000000000000003721477773331400322000ustar00rootroot00000000000000output "folder" { description = "The ID of the new folder" value = google_folder.tf_osconfig_folder.id } output "projects_self_links" { description = "List of self-links to created projects" value = ["${module.project-tf.*}"] } osconfig-20250416.02/examples/Terraform/multi-project-deployments/create_projects/terraform.tfvars000066400000000000000000000001241477773331400333450ustar00rootroot00000000000000labels = { pizza_topping = "pepperoni" } folder_name = "tf-osconfig-test-folder" osconfig-20250416.02/examples/Terraform/multi-project-deployments/create_projects/variables.tf000066400000000000000000000006641477773331400324310ustar00rootroot00000000000000variable "organization_id" { description = "Cloud Organization where to create Projects." type = string } variable "billing_account" { description = "Billing Account to which charge the Projects." type = string } variable "folder_name" { description = "Folder from where to list projects." type = string } variable "labels" { type = map(string) description = "Labels, provided as a map" } osconfig-20250416.02/examples/Terraform/multi-project-deployments/create_projects/versions.tf000066400000000000000000000004401477773331400323210ustar00rootroot00000000000000terraform { required_version = ">=0.14.0" required_providers { google = ">= 3.43, <4.0" archive = "~> 1.0" random = "~> 2.0" null = "~> 2.1" } provider_meta "google" { module_name = "blueprints/terraform/terraform-google-vm:compute_instance/v6.1.0" } } osconfig-20250416.02/examples/Terraform/multi-project-deployments/preparation_scripts/000077500000000000000000000000001477773331400310375ustar00rootroot00000000000000create_tf_admin_project.sh000077500000000000000000000047631477773331400361630ustar00rootroot00000000000000osconfig-20250416.02/examples/Terraform/multi-project-deployments/preparation_scripts#!/bin/bash if [ -z "$TF_VAR_organization_id" ] then echo "\$TF_VAR_organization_id is empty. You must set it first." exit 1 fi if [ -z "$TF_VAR_billing_account" ] then echo "\$TF_VAR_billing_account is empty. You must set it first." exit 1 fi if [ -z "$TF_ADMIN_PROJECT" ] then echo "\$TF_ADMIN_PROJECT is empty. You must set it first." exit 1 fi if [ -z "$TF_ADMIN_USER" ] then echo "\$TF_ADMIN_USER is empty. You must set it first." exit 1 fi # # Create TF_ADMIN_PROJECT and set it up. # gcloud projects create ${TF_ADMIN_PROJECT} \ --organization ${TF_VAR_organization_id} \ --set-as-default gcloud beta billing projects link ${TF_ADMIN_PROJECT} \ --billing-account ${TF_VAR_billing_account} gcloud config set project "${TF_ADMIN_PROJECT}" export GOOGLE_PROJECT=${TF_ADMIN_PROJECT} # # Enable services required for creating infrastructure # gcloud services enable cloudbilling.googleapis.com gcloud services enable cloudresourcemanager.googleapis.com gcloud services enable compute.googleapis.com gcloud services enable iam.googleapis.com gcloud services enable serviceusage.googleapis.com gcloud services enable osconfig.googleapis.com # # Grant TF_ADMIN_USER the necessary permissions # gcloud projects add-iam-policy-binding ${TF_ADMIN_PROJECT} \ --member user:${TF_ADMIN_USER} \ --role roles/viewer gcloud organizations add-iam-policy-binding ${TF_VAR_organization_id} \ --member user:${TF_ADMIN_USER} \ --role roles/resourcemanager.projectCreator gcloud organizations add-iam-policy-binding ${TF_VAR_organization_id} \ --member user:${TF_ADMIN_USER} \ --role roles/billing.user gcloud organizations add-iam-policy-binding ${TF_VAR_organization_id} \ --member user:${TF_ADMIN_USER} \ --role roles/resourcemanager.folderAdmin gcloud organizations add-iam-policy-binding ${TF_VAR_organization_id} \ --member user:${TF_ADMIN_USER} \ --role roles/compute.admin gcloud organizations add-iam-policy-binding ${TF_VAR_organization_id} \ --member user:${TF_ADMIN_USER} \ --role roles/serviceusage.serviceUsageConsumer gcloud organizations add-iam-policy-binding ${TF_VAR_organization_id} \ --member user:${TF_ADMIN_USER} \ --role roles/osconfig.guestPolicyAdmin gcloud organizations add-iam-policy-binding ${TF_VAR_organization_id} \ --member user:${TF_ADMIN_USER} \ --role roles/osconfig.osPolicyAssignmentAdmin gcloud organizations add-iam-policy-binding ${TF_VAR_organization_id} \ --member user:${TF_ADMIN_USER} \ --role roles/osconfig.patchDeploymentAdmin osconfig-20250416.02/external/000077500000000000000000000000001477773331400156505ustar00rootroot00000000000000osconfig-20250416.02/external/fetcher.go000066400000000000000000000032421477773331400176200ustar00rootroot00000000000000// Copyright 2018 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package external is responsible for all the external interactions package external import ( "context" "fmt" "io" "net/http" "cloud.google.com/go/storage" "github.com/GoogleCloudPlatform/osconfig/clog" ) // FetchGCSObject fetches data from GCS bucket func FetchGCSObject(ctx context.Context, client *storage.Client, bucket, object string, generation int64) (io.ReadCloser, error) { clog.Debugf(ctx, "Fetching GCS object: '%s/%s', generation: '%d", bucket, object, generation) oh := client.Bucket(bucket).Object(object) if generation != 0 { oh = oh.Generation(generation) } return oh.NewReader(ctx) } // FetchRemoteObjectHTTP fetches data from remote location func FetchRemoteObjectHTTP(ctx context.Context, client *http.Client, url string) (io.ReadCloser, error) { clog.Debugf(ctx, "Fetching remote object: '%s'", url) resp, err := client.Get(url) if err != nil { return nil, err } if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("got http status %d when attempting to download artifact", resp.StatusCode) } return resp.Body, nil } osconfig-20250416.02/go.mod000066400000000000000000000066741477773331400151510ustar00rootroot00000000000000module github.com/GoogleCloudPlatform/osconfig go 1.22.7 require ( cloud.google.com/go/compute/metadata v0.6.0 cloud.google.com/go/osconfig v1.14.3 cloud.google.com/go/storage v1.47.0 cos.googlesource.com/cos/tools.git v0.0.0-20210329212435-a349a79f950d github.com/GoogleCloudPlatform/guest-logging-go v0.0.0-20221216194522-f549ad6a1730 github.com/StackExchange/wmi v1.2.1 github.com/go-ole/go-ole v1.3.0 github.com/golang/mock v1.6.0 github.com/google/go-cmp v0.7.0 github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07 github.com/ulikunitz/xz v0.5.12 golang.org/x/crypto v0.32.0 golang.org/x/oauth2 v0.24.0 golang.org/x/sys v0.30.0 google.golang.org/api v0.214.0 google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 google.golang.org/grpc v1.68.0 google.golang.org/protobuf v1.36.3 ) require ( cel.dev/expr v0.22.0 // indirect cloud.google.com/go v0.117.0 // indirect cloud.google.com/go/auth v0.14.0 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.7 // indirect cloud.google.com/go/iam v1.2.2 // indirect cloud.google.com/go/logging v1.13.0 // indirect cloud.google.com/go/longrunning v0.6.3 // indirect cloud.google.com/go/monitoring v1.21.2 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.49.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.49.0 // indirect github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 // indirect github.com/envoyproxy/go-control-plane v0.13.1 // indirect github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/golang/glog v1.2.4 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/s2a-go v0.1.8 // indirect github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect github.com/googleapis/gax-go/v2 v2.14.0 // indirect github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/sirupsen/logrus v1.9.3 // indirect go.chromium.org/luci v0.0.0-20201204084249-3e81ee3e83fe // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/detectors/gcp v1.32.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.57.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.57.0 // indirect go.opentelemetry.io/otel v1.35.0 // indirect go.opentelemetry.io/otel/metric v1.35.0 // indirect go.opentelemetry.io/otel/sdk v1.35.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect go.opentelemetry.io/otel/trace v1.35.0 // indirect golang.org/x/net v0.34.0 // indirect golang.org/x/sync v0.10.0 // indirect golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.9.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697 // indirect google.golang.org/grpc/stats/opentelemetry v0.0.0-20240907200651-3ffb98b2c93a // indirect ) osconfig-20250416.02/go.sum000066400000000000000000001513661477773331400151750ustar00rootroot00000000000000cel.dev/expr v0.22.0 h1:+hFFhLPmquBImfs1BiN2PZmkr5ASse2ZOuaxIs9e4R8= cel.dev/expr v0.22.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.47.0/go.mod h1:5p3Ky/7f3N10VBkhuR5LFtddroTiMyjZV/Kj5qOQFxU= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.117.0 h1:Z5TNFfQxj7WG2FgOGX1ekC5RiXrYgms6QscOm32M/4s= cloud.google.com/go v0.117.0/go.mod h1:ZbwhVTb1DBGt2Iwb3tNO6SEK4q+cplHZmLWH+DelYYc= cloud.google.com/go/auth v0.14.0 h1:A5C4dKV/Spdvxcl0ggWwWEzzP7AZMJSEIgrkngwhGYM= cloud.google.com/go/auth v0.14.0/go.mod h1:CYsoRL1PdiDuqeQpZE0bP2pnPrGqFcOkI0nldEQis+A= cloud.google.com/go/auth/oauth2adapt v0.2.7 h1:/Lc7xODdqcEw8IrZ9SvwnlLX6j9FHQM74z6cBk9Rw6M= cloud.google.com/go/auth/oauth2adapt v0.2.7/go.mod h1:NTbTTzfvPl1Y3V1nPpOgl2w6d/FjO7NNUQaWSox6ZMc= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.1.0/go.mod h1:g4RsfUkOvV3Vi5yRujQETpqwCN0F+faPZ2/ykNYfBJc= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/iam v1.2.2 h1:ozUSofHUGf/F4tCNy/mu9tHLTaxZFLOUiKzjcgWHGIA= cloud.google.com/go/iam v1.2.2/go.mod h1:0Ys8ccaZHdI1dEUilwzqng/6ps2YB6vRsjIe00/+6JY= cloud.google.com/go/logging v1.0.0/go.mod h1:V1cc3ogwobYzQq5f2R7DS/GvRIrI4FKj01Gs5glwAls= cloud.google.com/go/logging v1.13.0 h1:7j0HgAp0B94o1YRDqiqm26w4q1rDMH7XNRU34lJXHYc= cloud.google.com/go/logging v1.13.0/go.mod h1:36CoKh6KA/M0PbhPKMq6/qety2DCAErbhXT62TuXALA= cloud.google.com/go/longrunning v0.6.3 h1:A2q2vuyXysRcwzqDpMMLSI6mb6o39miS52UEG/Rd2ng= cloud.google.com/go/longrunning v0.6.3/go.mod h1:k/vIs83RN4bE3YCswdXC5PFfWVILjm3hpEUlSko4PiI= cloud.google.com/go/monitoring v1.21.2 h1:FChwVtClH19E7pJ+e0xUhJPGksctZNVOk2UhMmblmdU= cloud.google.com/go/monitoring v1.21.2/go.mod h1:hS3pXvaG8KgWTSz+dAdyzPrGUYmi2Q+WFX8g2hqVEZU= cloud.google.com/go/osconfig v1.14.3 h1:cyf1PMK5c2/WOIr5r2lxjH/XBJMA9P4zC8Tm10i0z3M= cloud.google.com/go/osconfig v1.14.3/go.mod h1:9D2MS1Etne18r/mAeW5jtto3toc9H1qu9wLNDG3NvQg= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.1.1/go.mod h1:nbQkUX8zrWh07WKekXr/Phd0q/ERj4IOJnkE+v56Qys= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.47.0 h1:ajqgt30fnOMmLfWfu1PWcb+V9Dxz6n+9WKjdNg5R4HM= cloud.google.com/go/storage v1.47.0/go.mod h1:Ks0vP374w0PW6jOUameJbapbQKXqkjGd/OJRp2fb9IQ= cloud.google.com/go/trace v1.11.2 h1:4ZmaBdL8Ng/ajrgKqY5jfvzqMXbrDcBsUGXOT9aqTtI= cloud.google.com/go/trace v1.11.2/go.mod h1:bn7OwXd4pd5rFuAnTrzBuoZ4ax2XQeG3qNgYmfCy0Io= cos.googlesource.com/cos/tools.git v0.0.0-20210329212435-a349a79f950d h1:qj1jlxRkQblujpwNPW4BOEWmGkrWP+Y5ADIoSKBxO5s= cos.googlesource.com/cos/tools.git v0.0.0-20210329212435-a349a79f950d/go.mod h1:1TJafpZtNmYwNzCwoWQRHfBDl59dxO6l/YW88HezBuk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/GoogleCloudPlatform/guest-logging-go v0.0.0-20221216194522-f549ad6a1730 h1:l4Hin8i/7I1R0cvWBP+z6JdRxU4yJWFbcXvJ8mKKC70= github.com/GoogleCloudPlatform/guest-logging-go v0.0.0-20221216194522-f549ad6a1730/go.mod h1:3F/urXs15KEI7RBGoOsK9/jCCJPBKHxyZH/Nzc7uldo= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 h1:3c8yed4lgqTt+oTQ+JNMDo+F4xprBf+O/il4ZC0nRLw= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0/go.mod h1:obipzmGjfSjam60XLwGfqUkJsfiheAl+TUjG+4yzyPM= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.49.0 h1:o90wcURuxekmXrtxmYWTyNla0+ZEHhud6DI1ZTxd1vI= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.49.0/go.mod h1:6fTWu4m3jocfUZLYF5KsZC1TUfRvEjs7lM4crme/irw= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.49.0 h1:jJKWl98inONJAr/IZrdFQUWcwUO95DLY1XMD1ZIut+g= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.49.0/go.mod h1:l2fIqmwB+FKSfvn3bAD/0i+AXAxhIZjTK2svT/mgUXs= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.49.0 h1:GYUJLfvd++4DMuMhCFLgLXvFwofIxh/qOwoGuS/LTew= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.49.0/go.mod h1:wRbFgBQUVm1YXrvWKofAEmq9HNJTDphbAaJSSX01KUI= github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= github.com/andygrunwald/go-gerrit v0.0.0-20201231163137-46815e48bfe0/go.mod h1:soxaYLbAFToS0OelBriItCts/mtUZOuLBkCk1Xv4ZSo= github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 h1:QVw89YDxXxEe+l8gU8ETbOasdwEV+avkR75ZzsVV9WI= github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.13.1 h1:vPfJZCkob6yTMEgS+0TwfTUfbHjfy/6vOJ8hUWX/uXE= github.com/envoyproxy/go-control-plane v0.13.1/go.mod h1:X45hY0mufo6Fd0KW3rqsGvQMw58jvjymeCzBU3mWyHw= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.2.4 h1:CNNw5U8lSiiBk7druxtSHHTsRWcxKoac6kZKm2peBBc= github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191002201903-404acd9df4cc/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM= github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw= github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.14.0 h1:f+jMrjBPl+DL9nI4IQzLUxMq7XrAqFYB7hBPqMNIe8o= github.com/googleapis/gax-go/v2 v2.14.0/go.mod h1:lhBCnjdLrWRaPvLWhmc8IS24m9mr07qSYnHncrgo+zk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.1.1 h1:T/YLemO5Yp7KPzS+lVtu+WsHn8yoSwTfItdAd1r3cck= github.com/smartystreets/assertions v1.1.1/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07 h1:UyzmZLoiDWMRywV4DUYb9Fbt8uiOSooupjTq10vpvnU= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc= github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.chromium.org/luci v0.0.0-20200722211809-bab0c30be68b/go.mod h1:MIQewVTLvOvc0UioV0JNqTNO/RspKFS0XEeoKrOxsdM= go.chromium.org/luci v0.0.0-20201204084249-3e81ee3e83fe h1:qIWCxSxxiH4294whxeqOxsQ9KaW7CW0gGa3tqluP2NA= go.chromium.org/luci v0.0.0-20201204084249-3e81ee3e83fe/go.mod h1:MIQewVTLvOvc0UioV0JNqTNO/RspKFS0XEeoKrOxsdM= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/contrib/detectors/gcp v1.32.0 h1:P78qWqkLSShicHmAzfECaTgvslqHxblNE9j62Ws1NK8= go.opentelemetry.io/contrib/detectors/gcp v1.32.0/go.mod h1:TVqo0Sda4Cv8gCIixd7LuLwW4EylumVWfhjZJjDD4DU= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.57.0 h1:qtFISDHKolvIxzSs0gIaiPUPR0Cucb0F2coHC7ZLdps= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.57.0/go.mod h1:Y+Pop1Q6hCOnETWTW4NROK/q1hv50hM7yDaUTjG8lp8= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.57.0 h1:DheMAlT6POBP+gh8RUH19EOTnQIor5QE0uSRPtzCpSw= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.57.0/go.mod h1:wZcGmeVO9nzP67aYSLDqXNWK87EZWhi7JWj1v7ZXf94= go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0 h1:WDdP9acbMYjbKIyJUhTvtzj601sVJOqgWdUxSdR/Ysc= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0/go.mod h1:BLbf7zbNIONBLPwvFnwNHGj4zge8uTCM/UPIVW1Mq2I= go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY= go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg= go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o= go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w= go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20190912063710-ac5d2bfcbfe0/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE= golang.org/x/exp v0.0.0-20191014171548-69215a2ee97e/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190917162342-3b4f30a44f3b/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191010171213-8abd42400456/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191017205301-920acffc3e65/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.11.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.214.0 h1:h2Gkq07OYi6kusGOaT/9rnNljuXmqPnaig7WGPmKbwA= google.golang.org/api v0.214.0/go.mod h1:bYPpLG8AyeMWwDU6NXoB00xC0DFkikVvd5MfwoxjLqE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190708153700-3bdd9d9f5532/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191009194640-548a555dbc03/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 h1:ToEetK57OidYuqD4Q5w+vfEnPvPpuTwedCNVohYJfNk= google.golang.org/genproto v0.0.0-20241118233622-e639e219e697/go.mod h1:JJrvXBWRZaFMxBufik1a4RpFw4HhgVtBBWQeQgUj2cc= google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697 h1:pgr/4QbFyktUv9CtQ/Fq4gzEE6/Xs7iCXbktaGzLHbQ= google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697/go.mod h1:+D9ySVjN8nY8YCVjc5O7PZDIdZporIDY3KaGfJunh88= google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 h1:8ZmaLZE4XWrtU3MyClkYqqtl6Oegr3235h7jxsDyqCY= google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0= google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA= google.golang.org/grpc/stats/opentelemetry v0.0.0-20240907200651-3ffb98b2c93a h1:UIpYSuWdWHSzjwcAFRLjKcPXFZVVLXGEM23W+NWqipw= google.golang.org/grpc/stats/opentelemetry v0.0.0-20240907200651-3ffb98b2c93a/go.mod h1:9i1T9n4ZinTUZGgzENMi8MDDgbGC5mqTS75JAv6xN3A= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU= google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= osconfig-20250416.02/google-osconfig-agent.conf000066400000000000000000000001651477773331400210540ustar00rootroot00000000000000description "Google OSConfig Agent" start on stopped rc RUNLEVEL=[2345] respawn exec /usr/bin/google_osconfig_agent osconfig-20250416.02/google-osconfig-agent.service000066400000000000000000000005011477773331400215610ustar00rootroot00000000000000[Unit] Description=Google OSConfig Agent After=local-fs.target network-online.target Wants=local-fs.target network-online.target [Service] ExecStart=/usr/bin/google_osconfig_agent Restart=always RestartSec=1 StartLimitInterval=120 StartLimitBurst=3 KillMode=mixed KillSignal=SIGTERM [Install] WantedBy=multi-user.targetosconfig-20250416.02/inventory/000077500000000000000000000000001477773331400160635ustar00rootroot00000000000000osconfig-20250416.02/inventory/inventory.go000066400000000000000000000046441477773331400204570ustar00rootroot00000000000000// Copyright 2017 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package inventory scans the current inventory (patches and package installed and available) // and writes them to Guest Attributes. package inventory import ( "context" "time" "github.com/GoogleCloudPlatform/osconfig/agentconfig" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/osinfo" "github.com/GoogleCloudPlatform/osconfig/packages" ) // InstanceInventory is an instances inventory data. type InstanceInventory struct { Hostname string LongName string ShortName string Version string Architecture string KernelVersion string KernelRelease string OSConfigAgentVersion string InstalledPackages *packages.Packages PackageUpdates *packages.Packages LastUpdated string } // Get generates inventory data. func Get(ctx context.Context) *InstanceInventory { clog.Debugf(ctx, "Gathering instance inventory.") installedPackages, err := packages.GetInstalledPackages(ctx) if err != nil { clog.Errorf(ctx, "packages.GetInstalledPackages() error: %v", err) } packageUpdates, err := packages.GetPackageUpdates(ctx) if err != nil { clog.Errorf(ctx, "packages.GetPackageUpdates() error: %v", err) } oi, err := osinfo.Get() if err != nil { clog.Errorf(ctx, "osinfo.Get() error: %v", err) } return &InstanceInventory{ Hostname: oi.Hostname, LongName: oi.LongName, ShortName: oi.ShortName, Version: oi.Version, KernelVersion: oi.KernelVersion, KernelRelease: oi.KernelRelease, Architecture: oi.Architecture, OSConfigAgentVersion: agentconfig.Version(), InstalledPackages: installedPackages, PackageUpdates: packageUpdates, LastUpdated: time.Now().UTC().Format(time.RFC3339), } } osconfig-20250416.02/main.go000066400000000000000000000242171477773331400153070ustar00rootroot00000000000000// Copyright 2018 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // osconfig_agent interacts with the osconfig api. package main import ( "context" "flag" "fmt" "io" "io/ioutil" "math/rand" "net/http" "os" "os/signal" "path/filepath" "runtime" "syscall" "time" "github.com/GoogleCloudPlatform/guest-logging-go/logger" "github.com/GoogleCloudPlatform/osconfig/agentconfig" "github.com/GoogleCloudPlatform/osconfig/agentendpoint" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/policies" "github.com/GoogleCloudPlatform/osconfig/tasker" "github.com/GoogleCloudPlatform/osconfig/util" "github.com/tarm/serial" _ "net/http/pprof" _ "google.golang.org/genproto/googleapis/rpc/errdetails" ) var ( version string profile = flag.Bool("profile", false, "serve profiling data at localhost:6060/debug/pprof") ) func init() { if version == "" { version = "manual-" + time.Now().Format(time.RFC3339) } // We do this here so the -X value doesn't need the full path. agentconfig.SetVersion(version) os.MkdirAll(filepath.Dir(agentconfig.RestartFile()), 0755) } type serialPort struct { port string } func (s *serialPort) Write(b []byte) (int, error) { c := &serial.Config{Name: s.port, Baud: 115200} p, err := serial.OpenPort(c) if err != nil { return 0, err } defer p.Close() return p.Write(b) } var deferredFuncs []func() // RegisterAgent is a blocking call, the RPC itself has retry logic baked in // with jitter and backoff up to a total of 10 minutes. // If client creation or register agent (after retries) fail we then wait for // 5 minutes and try again. func registerAgent(ctx context.Context) { for { if client, err := agentendpoint.NewClient(ctx); err != nil { logger.Errorf("%v", err.Error()) } else if err := client.RegisterAgent(ctx); err != nil { logger.Errorf("%v", err.Error()) client.Close() } else { // RegisterAgent completed successfully. client.Close() return } time.Sleep(5 * time.Minute) } } func run(ctx context.Context) { // Setup logging. opts := logger.LogOpts{LoggerName: "OSConfigAgent", UserAgent: agentconfig.UserAgent(), DisableLocalLogging: agentconfig.DisableLocalLogging()} if agentconfig.Stdout() { opts.Writers = []io.Writer{os.Stdout} } if runtime.GOOS == "windows" { opts.Writers = append(opts.Writers, &serialPort{"COM1"}) } // If this call to WatchConfig fails (like a metadata error) we can't continue. if err := agentconfig.WatchConfig(ctx); err != nil { logger.Init(ctx, opts) logger.Fatalf("Error parsing metadata, agent cannot start: %v", err.Error()) } opts.Debug = agentconfig.Debug() clog.DebugEnabled = agentconfig.Debug() opts.ProjectName = agentconfig.ProjectID() if err := logger.Init(ctx, opts); err != nil { fmt.Printf("Error initializing logger: %v", err) os.Exit(1) } ctx = clog.WithLabels(ctx, map[string]string{"instance_name": agentconfig.Name()}) // Remove any existing restart file. if err := os.Remove(agentconfig.RestartFile()); err != nil && !os.IsNotExist(err) { clog.Errorf(ctx, "Error removing restart signal file: %v", err) } // On shutdown if the old restart file exists, and there is nothing else in that old directory, // cleanup that directory ignoring all errors. // This ensures we only cleanup this directory if we were using it with an old version of the agent. deferredFuncs = append(deferredFuncs, func() { if runtime.GOOS == "linux" && util.Exists(agentconfig.OldRestartFile()) { os.Remove(agentconfig.OldRestartFile()) files, err := ioutil.ReadDir(filepath.Dir(agentconfig.OldRestartFile())) if err != nil || len(files) > 0 { return } os.RemoveAll(filepath.Dir(agentconfig.OldRestartFile())) } }) deferredFuncs = append(deferredFuncs, logger.Close, func() { clog.Infof(ctx, "OSConfig Agent (version %s) shutting down.", agentconfig.Version()) }) obtainLock() // obtainLock adds functions to clear the lock at close. logger.DeferredFatalFuncs = append(logger.DeferredFatalFuncs, deferredFuncs...) clog.Infof(ctx, "OSConfig Agent (version %s) started.", agentconfig.Version()) // Call RegisterAgent at least once every day, on start calling // of RegisterAgent is handled in the service loop. go func() { c := time.Tick(24 * time.Hour) for range c { if agentconfig.TaskNotificationEnabled() || agentconfig.GuestPoliciesEnabled() { registerAgent(ctx) } } }() switch action := flag.Arg(0); action { case "", "run", "noservice": runServiceLoop(ctx) case "inventory", "osinventory": client, err := agentendpoint.NewClient(ctx) if err != nil { logger.Fatalf("%v", err.Error()) } tasker.Enqueue(ctx, "Report OSInventory", func() { client.ReportInventory(ctx) }) tasker.Close() return case "gp", "policies", "guestpolicies", "ospackage": policies.Run(ctx) tasker.Close() return case "w", "waitfortasknotification", "ospatch": client, err := agentendpoint.NewClient(ctx) if err != nil { logger.Fatalf("%v", err.Error()) } client.WaitForTaskNotification(ctx) select { case <-ctx.Done(): } default: logger.Fatalf("Unknown arg %q", action) } } func runTaskLoop(ctx context.Context, c chan struct{}) { var taskNotificationClient *agentendpoint.Client var err error for { // Set debug logging settings so that customers don't need to restart the agent. logger.SetDebugLogging(agentconfig.Debug()) clog.DebugEnabled = agentconfig.Debug() if agentconfig.TaskNotificationEnabled() && taskNotificationClient == nil { // Call RegisterAgent now since we just either started running or were just enabled. // This call is blocking until successful as we can't continue unless register agent has completed. registerAgent(ctx) } if agentconfig.TaskNotificationEnabled() && (taskNotificationClient == nil || taskNotificationClient.Closed()) { // Start WaitForTaskNotification if we need to. taskNotificationClient, err = agentendpoint.NewClient(ctx) if err != nil { clog.Errorf(ctx, "%v", err.Error()) } else { taskNotificationClient.WaitForTaskNotification(ctx) } } else if !agentconfig.TaskNotificationEnabled() && taskNotificationClient != nil && !taskNotificationClient.Closed() { // Cancel WaitForTaskNotification if we need to, this will block if there is // an existing current task running. if err := taskNotificationClient.Close(); err != nil { clog.Errorf(ctx, "%v", err.Error()) } } // This is just to signal WaitForTaskNotification has run if needed. select { case c <- struct{}{}: default: } // Wait on any metadata config change. if err := agentconfig.WatchConfig(ctx); err != nil { clog.Errorf(ctx, "%v", err.Error()) } select { case <-ctx.Done(): return default: continue } } } // Runs internal functions that need to run on an interval. func runInternalPeriodics(ctx context.Context) { ticker := time.NewTicker(10 * time.Minute) defer ticker.Stop() for { if _, err := os.Stat(agentconfig.RestartFile()); err == nil { clog.Infof(ctx, "Restart required marker file exists, beginning agent shutdown, waiting for tasks to complete.") tasker.Close() clog.Infof(ctx, "All tasks completed, stopping agent.") for _, f := range deferredFuncs { f() } os.Exit(2) } select { case <-ticker.C: continue case <-ctx.Done(): return } } } func runServiceLoop(ctx context.Context) { go runInternalPeriodics(ctx) // This is just to ensure WaitForTaskNotification runs before any other tasks. c := make(chan struct{}) // Configures WaitForTaskNotification, waits for config changes with WatchConfig. go runTaskLoop(ctx, c) // Don't continue any other tasks until WaitForTaskNotification has run. <-c // Runs functions that need to run on a set interval. ticker := time.NewTicker(agentconfig.SvcPollInterval()) defer ticker.Stop() // First inventory run will be somewhere between 3 and 5 min. firstInventory := time.After(time.Duration(rand.Intn(120)+180) * time.Second) ranFirstInventory := false for { if agentconfig.GuestPoliciesEnabled() { policies.Run(ctx) } if agentconfig.OSInventoryEnabled() { if !ranFirstInventory { // Only run first inventory after the set waiting period or if the main poll ticker ticks. // The default SvcPollInterval is 10min so under normal circumstances firstInventory will // always fire first. select { case <-ticker.C: case <-firstInventory: case <-ctx.Done(): return } ranFirstInventory = true } // This should always run after ospackage.SetConfig. tasker.Enqueue(ctx, "Report OSInventory", func() { client, err := agentendpoint.NewClient(ctx) if err != nil { logger.Errorf("%v", err.Error()) } client.ReportInventory(ctx) client.Close() }) } select { case <-ticker.C: continue case <-ctx.Done(): return } } } func main() { flag.Parse() ctx, cncl := context.WithCancel(context.Background()) ctx = clog.WithLabels(ctx, map[string]string{"agent_version": agentconfig.Version()}) c := make(chan os.Signal, 1) signal.Notify(c, syscall.SIGTERM, syscall.SIGINT) go func() { select { case <-c: cncl() } }() if *profile { go func() { fmt.Println(http.ListenAndServe("localhost:6060", nil)) }() } switch action := flag.Arg(0); action { // wuaupdates just runs the packages.WUAUpdates function and returns it's output // as JSON on stdout. This avoids memory issues with the WUA api since this is // called often for Windows inventory runs. case "wuaupdates": if err := wuaUpdates(ctx, flag.Arg(1)); err != nil { fmt.Fprint(os.Stderr, err) os.Exit(1) } os.Exit(0) case "", "run": runService(ctx) default: run(ctx) } for _, f := range deferredFuncs { f() } } osconfig-20250416.02/main_linux.go000066400000000000000000000033651477773331400165270ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import ( "context" "errors" "os" "path/filepath" "syscall" "time" "github.com/GoogleCloudPlatform/guest-logging-go/logger" ) func runService(ctx context.Context) { run(ctx) } func obtainLock() { lockFile := "/run/lock/osconfig_agent.lock" err := os.Mkdir(filepath.Dir(lockFile), 1777) if err != nil && !os.IsExist(err) { logger.Fatalf("Cannot obtain agent lock: %v", err) } f, err := os.OpenFile(lockFile, os.O_RDWR|os.O_CREATE, 0600) if err != nil && !os.IsExist(err) { logger.Fatalf("Cannot obtain agent lock: %v", err) } c := make(chan error) go func() { c <- syscall.Flock(int(f.Fd()), syscall.LOCK_EX) }() select { case err := <-c: if err != nil { logger.Fatalf("Cannot obtain agent lock, is the agent already running? Error: %v", err) } case <-time.After(time.Second): logger.Fatalf("OSConfig agent lock already held, is the agent already running?") } deferredFuncs = append(deferredFuncs, func() { syscall.Flock(int(f.Fd()), syscall.LOCK_UN); f.Close(); os.Remove(lockFile) }) } func wuaUpdates(ctx context.Context, _ string) error { return errors.New("wuaUpdates not implemented on linux") } osconfig-20250416.02/main_windows.go000066400000000000000000000100421477773331400170500ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import ( "context" "encoding/json" "errors" "fmt" "os" "path/filepath" "syscall" "unsafe" "github.com/GoogleCloudPlatform/guest-logging-go/logger" "github.com/GoogleCloudPlatform/osconfig/agentconfig" "github.com/GoogleCloudPlatform/osconfig/packages" "golang.org/x/sys/windows" "golang.org/x/sys/windows/svc" ) var ( kernel32 = windows.NewLazySystemDLL("kernel32.dll") procLockFileEx = kernel32.NewProc("LockFileEx") procUnlockFileEx = kernel32.NewProc("UnlockFileEx") ) const ( serviceName = "google_osconfig_agent" // https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-lockfileex LOCKFILE_EXCLUSIVE_LOCK = 2 LOCKFILE_FAIL_IMMEDIATELY = 1 ) func lockFileEx(hFile uintptr, dwFlags, nNumberOfBytesToLockLow, nNumberOfBytesToLockHigh uint32, lpOverlapped *syscall.Overlapped) (err error) { ret, _, _ := procLockFileEx.Call( hFile, uintptr(dwFlags), 0, uintptr(nNumberOfBytesToLockLow), uintptr(nNumberOfBytesToLockHigh), uintptr(unsafe.Pointer(lpOverlapped)), ) // If the function succeeds, the return value is nonzero. if ret == 0 { return errors.New("LockFileEx unable to obtain lock") } return nil } func unlockFileEx(hFile uintptr, nNumberOfBytesToLockLow, nNumberOfBytesToLockHigh uint32, lpOverlapped *syscall.Overlapped) (err error) { ret, _, _ := procUnlockFileEx.Call( hFile, 0, uintptr(nNumberOfBytesToLockLow), uintptr(nNumberOfBytesToLockHigh), uintptr(unsafe.Pointer(lpOverlapped)), ) // If the function succeeds, the return value is nonzero. if ret == 0 { return errors.New("UnlockFileEx unable to unlock") } return nil } func obtainLock() { lockFile := filepath.Join(agentconfig.GetCacheDirWindows(), "lock") err := os.MkdirAll(filepath.Dir(lockFile), 0755) if err != nil && !os.IsExist(err) { logger.Fatalf("Cannot obtain agent lock: %v", err) } f, err := os.OpenFile(lockFile, os.O_RDWR|os.O_CREATE, 0600) if err != nil && !os.IsExist(err) { logger.Fatalf("Cannot obtain agent lock: %v", err) } if err := lockFileEx(f.Fd(), LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY, 1, 0, &syscall.Overlapped{}); err != nil { logger.Fatalf("OSConfig agent lock already held, is the agent already running?") } deferredFuncs = append(deferredFuncs, func() { unlockFileEx(f.Fd(), 1, 0, &syscall.Overlapped{}); f.Close(); os.Remove(lockFile) }) } type service struct { ctx context.Context run func(context.Context) } func (s *service) Execute(_ []string, r <-chan svc.ChangeRequest, status chan<- svc.Status) (bool, uint32) { status <- svc.Status{State: svc.StartPending} ctx, cncl := context.WithCancel(s.ctx) defer cncl() done := make(chan struct{}) go func() { s.run(ctx) close(done) }() status <- svc.Status{State: svc.Running, Accepts: svc.AcceptStop | svc.AcceptShutdown} for { select { case <-done: status <- svc.Status{State: svc.StopPending} return false, 0 case c := <-r: switch c.Cmd { case svc.Interrogate: status <- c.CurrentStatus case svc.Stop, svc.Shutdown: cncl() default: } } } } func runService(ctx context.Context) { if err := svc.Run(serviceName, &service{run: run, ctx: ctx}); err != nil { logger.Fatalf("svc.Run error: %v", err) } } func wuaUpdates(ctx context.Context, query string) error { updts, err := packages.WUAUpdates(ctx, query) if err != nil { return err } data, err := json.Marshal(updts) if err != nil { return err } fmt.Fprint(os.Stdout, string(data)) return nil } osconfig-20250416.02/osinfo/000077500000000000000000000000001477773331400153235ustar00rootroot00000000000000osconfig-20250416.02/osinfo/osinfo.go000066400000000000000000000030711477773331400171500ustar00rootroot00000000000000/* Copyright 2017 Google Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // Package osinfo provides basic system info functions for Windows and // Linux. package osinfo import ( "context" ) const ( // DefaultShortNameLinux is the default shortname used for a Linux system. DefaultShortNameLinux = "linux" // DefaultShortNameWindows is the default shortname used for Windows system. DefaultShortNameWindows = "windows" ) // Provider is an interface for OSInfo extraction on different systems. type Provider interface { Get(context.Context) (OSInfo, error) } // OSInfo describes an operating system. type OSInfo struct { Hostname, LongName, ShortName, Version, KernelVersion, KernelRelease, Architecture string } // NormalizeArchitecture attempts to standardize architecture naming. func NormalizeArchitecture(arch string) string { switch arch { case "amd64", "64-bit": arch = "x86_64" case "i386", "i686", "32-bit": arch = "x86_32" case "noarch": arch = "all" } return arch } type osNameAndVersionProvider func() (shortName string, longName string, version string) osconfig-20250416.02/osinfo/osinfo_linux.go000066400000000000000000000125511477773331400203720ustar00rootroot00000000000000/* Copyright 2017 Google Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package osinfo import ( "bufio" "bytes" "context" "fmt" "io/ioutil" "regexp" "strings" "github.com/GoogleCloudPlatform/osconfig/util" "golang.org/x/sys/unix" ) var ( entRelVerRgx = regexp.MustCompile(`\d+(\.\d+)?(\.\d+)?`) ) var _ Provider = &LinuxOsInfoProvider{} var ( defaultReleaseFilepath = "/etc/os-release" oracleReleaseFilepath = "/etc/oracle-release" redHatReleaseFilepath = "/etc/redhat-release" ) // Get reports OSInfo. func Get() (*OSInfo, error) { // Eventually we will get rid of this function and will use providers directly // Providers should support context to be able to handle cancelation and logging // so far we just create empty context to connect the API. ctx := context.TODO() osInfoProvider, err := NewLinuxOsInfoProvider(getOsNameAndVersionProvider(ctx)) if err != nil { return nil, fmt.Errorf("unable to extract osinfo, err: %w", err) } osInfo, err := osInfoProvider.Get(ctx) if err != nil { return &osInfo, err } return &osInfo, nil } // LinuxOsInfoProvider is a provider of OSInfo for the linux based systems. type LinuxOsInfoProvider struct { nameAndVersionProvider osNameAndVersionProvider uts unix.Utsname } // NewLinuxOsInfoProvider is a constructor function for LinuxOsInfoProvider. func NewLinuxOsInfoProvider(nameAndVersionProvider osNameAndVersionProvider) (*LinuxOsInfoProvider, error) { var uts unix.Utsname if err := unix.Uname(&uts); err != nil { return nil, fmt.Errorf("unable to get unix.Uname, err: %w", err) } return &LinuxOsInfoProvider{ nameAndVersionProvider: nameAndVersionProvider, uts: uts, }, nil } // Get gather all required information and returns OSInfo. func (oip *LinuxOsInfoProvider) Get(ctx context.Context) (OSInfo, error) { short, long, version := oip.nameAndVersionProvider() return OSInfo{ ShortName: short, LongName: long, Version: version, Hostname: oip.hostName(), Architecture: oip.architecture(), KernelRelease: oip.kernelRelease(), KernelVersion: oip.kernelVersion(), }, nil } func (oip *LinuxOsInfoProvider) hostName() string { return stringFromUtsField(oip.uts.Nodename) } func (oip *LinuxOsInfoProvider) architecture() string { return NormalizeArchitecture(stringFromUtsField(oip.uts.Machine)) } func (oip *LinuxOsInfoProvider) kernelRelease() string { return stringFromUtsField(oip.uts.Release) } func (oip *LinuxOsInfoProvider) kernelVersion() string { return stringFromUtsField(oip.uts.Version) } func stringFromUtsField(field [65]byte) string { // unix.Utsname Fields are [65]byte so we need to trim any trailing null characters. return string(bytes.TrimRight(field[:], "\x00")) } func getOsNameAndVersionProvider(_ context.Context) osNameAndVersionProvider { return func() (string, string, string) { var ( extractNameAndVersion func(string) (string, string, string) releaseFile string ) defaultShortName, defaultLongName, defaultVersion := DefaultShortNameLinux, "", "" switch { // Check for /etc/os-release first. case util.Exists(defaultReleaseFilepath): releaseFile = defaultReleaseFilepath extractNameAndVersion = parseOsRelease case util.Exists(oracleReleaseFilepath): releaseFile = oracleReleaseFilepath extractNameAndVersion = parseEnterpriseRelease case util.Exists(redHatReleaseFilepath): releaseFile = redHatReleaseFilepath extractNameAndVersion = parseEnterpriseRelease default: return defaultShortName, defaultLongName, defaultVersion } b, err := ioutil.ReadFile(releaseFile) if err != nil { // TODO: log an error return defaultShortName, defaultLongName, defaultVersion } return extractNameAndVersion(string(b)) } } func parseOsRelease(releaseDetails string) (shortName, longName, version string) { scanner := bufio.NewScanner(strings.NewReader(releaseDetails)) for scanner.Scan() { entry := strings.Split(scanner.Text(), "=") switch entry[0] { case "": continue case "PRETTY_NAME": longName = strings.Trim(entry[1], `"`) case "VERSION_ID": version = strings.Trim(entry[1], `"`) case "ID": shortName = strings.Trim(entry[1], `"`) } // TODO: Replace with binary mask if longName != "" && version != "" && shortName != "" { break } } if shortName == "" { shortName = DefaultShortNameLinux } return shortName, longName, version } func parseEnterpriseRelease(releaseDetails string) (shortName string, longName string, version string) { shortName = DefaultShortNameLinux switch { case strings.Contains(releaseDetails, "CentOS"): shortName = "centos" case strings.Contains(releaseDetails, "Red Hat"): shortName = "rhel" case strings.Contains(releaseDetails, "Oracle"): shortName = "ol" } longName = strings.Replace(releaseDetails, " release ", " ", 1) version = entRelVerRgx.FindString(releaseDetails) return shortName, longName, version } osconfig-20250416.02/osinfo/osinfo_linux_test.go000066400000000000000000000244161477773331400214340ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package osinfo import ( "context" "os" "path/filepath" "testing" "github.com/google/go-cmp/cmp" "golang.org/x/sys/unix" ) var debianReleaseFileContent = `PRETTY_NAME="Debian buster" NAME="Debian GNU/Linux" VERSION_ID="10" VERSION="10 (buster)" VERSION_CODENAME=buster ID=debian HOME_URL="https://www.debian.org/" SUPPORT_URL="https://www.debian.org/support" BUG_REPORT_URL="https://bugs.debian.org/" ` func TestLinuxOsInfoProvider(t *testing.T) { mockNameVersionProvidor := func() (string, string, string) { return "testShort", "testLong", "testVersion" } linuxOsinfoProvider := LinuxOsInfoProvider{ nameAndVersionProvider: mockNameVersionProvidor, uts: unix.Utsname{ Nodename: toUtsField("testhost"), Machine: toUtsField("amd64"), Release: toUtsField("6.1.0-29-cloud-amd64"), Version: toUtsField("#1 SMP PREEMPT_DYNAMIC Debian 6.1.123-1 (2025-01-02)"), }, } ctx := context.Background() osInfo, err := linuxOsinfoProvider.Get(ctx) if err != nil { t.Errorf("Unexpected error, err: %v", err) } expectedOsInfo := OSInfo{ Hostname: "testhost", LongName: "testLong", ShortName: "testShort", Version: "testVersion", KernelVersion: "#1 SMP PREEMPT_DYNAMIC Debian 6.1.123-1 (2025-01-02)", KernelRelease: "6.1.0-29-cloud-amd64", Architecture: "x86_64", } if diff := cmp.Diff(expectedOsInfo, osInfo); diff != "" { t.Errorf("Unexpected OsInfo (-want,+got):\n%s", diff) } } func Test_parseOsRelease(t *testing.T) { tests := []struct { name string input string expectedShortName string expectedLongName string expectedVersion string }{ { name: "Empty content", input: ``, expectedShortName: "linux", expectedLongName: "", expectedVersion: "", }, { name: "Empty key", input: `=`, expectedShortName: "linux", expectedLongName: "", expectedVersion: "", }, { name: "Debian 10, normal case", input: debianReleaseFileContent, expectedShortName: "debian", expectedLongName: "Debian buster", expectedVersion: "10", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { shortName, longName, version := parseOsRelease(tt.input) if tt.expectedShortName != shortName { t.Errorf("Unexpected shortName, expected %q, got %q", tt.expectedShortName, shortName) } if tt.expectedLongName != longName { t.Errorf("Unexpected longName, expected %q, got %q", tt.expectedLongName, longName) } if tt.expectedVersion != version { t.Errorf("Unexpected version, expected %q, got %q", tt.expectedVersion, version) } }) } } func Test_parseEnterpriseRelease(t *testing.T) { tests := []struct { name string input string expectedShortName string expectedLongName string expectedVersion string }{ { name: "Empty content", input: ``, expectedShortName: "linux", expectedLongName: "", expectedVersion: "", }, { name: "Red Hat Enterprise, normal case", input: `Red Hat Enterprise Linux release 8.0 (Ootpa)`, expectedShortName: "rhel", expectedLongName: "Red Hat Enterprise Linux 8.0 (Ootpa)", expectedVersion: "8.0", }, { name: "CentOS Linux, normal case", input: `CentOS Linux release 7.6.1810 (Core)`, expectedShortName: "centos", expectedLongName: "CentOS Linux 7.6.1810 (Core)", expectedVersion: "7.6.1810", }, { name: "Oracle Linux Server, normal case", input: `Oracle Linux Server release 9.5`, expectedShortName: "ol", expectedLongName: "Oracle Linux Server 9.5", expectedVersion: "9.5", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { shortName, longName, version := parseEnterpriseRelease(tt.input) if tt.expectedShortName != shortName { t.Errorf("Unexpected shortName, expected %q, got %q", tt.expectedShortName, shortName) } if tt.expectedLongName != longName { t.Errorf("Unexpected longName, expected %q, got %q", tt.expectedLongName, longName) } if tt.expectedVersion != version { t.Errorf("Unexpected version, expected %q, got %q", tt.expectedVersion, version) } }) } } func Test_osNameAndVersionProvider(t *testing.T) { tests := []struct { name string enforceTestingEnvironment func(t *testing.T) expectedShortName string expectedLongName string expectedVersion string }{ { name: "no file exists", enforceTestingEnvironment: func(t *testing.T) { doesNotExists := filepath.Join(os.TempDir(), "does_not_exists") overrideDefaultReleaseFilepath(t, doesNotExists) overrideOracleReleaseFilepath(t, doesNotExists) overrideRedHatReleaseFilepath(t, doesNotExists) }, expectedShortName: "linux", expectedLongName: "", expectedVersion: "", }, { name: "default release file exists, but empty", enforceTestingEnvironment: func(t *testing.T) { doesNotExists := filepath.Join(os.TempDir(), "does_not_exists") defaultReleaseFile := filepath.Join(os.TempDir(), "default_release_file") enforceFileWithContent(t, defaultReleaseFile, []byte("")) overrideDefaultReleaseFilepath(t, defaultReleaseFile) overrideOracleReleaseFilepath(t, doesNotExists) overrideRedHatReleaseFilepath(t, doesNotExists) }, expectedShortName: "linux", expectedLongName: "", expectedVersion: "", }, { name: "default release path exists, but it not a file", enforceTestingEnvironment: func(t *testing.T) { tmpDir := os.TempDir() doesNotExists := filepath.Join(os.TempDir(), "does_not_exists") overrideDefaultReleaseFilepath(t, tmpDir) overrideOracleReleaseFilepath(t, doesNotExists) overrideRedHatReleaseFilepath(t, doesNotExists) }, expectedShortName: "linux", expectedLongName: "", expectedVersion: "", }, { name: "Debian release file exists", enforceTestingEnvironment: func(t *testing.T) { doesNotExists := filepath.Join(os.TempDir(), "does_not_exists") debianReleaseFile := filepath.Join(os.TempDir(), "debian_release_file") enforceFileWithContent(t, debianReleaseFile, []byte(debianReleaseFileContent)) overrideDefaultReleaseFilepath(t, debianReleaseFile) overrideOracleReleaseFilepath(t, doesNotExists) overrideRedHatReleaseFilepath(t, doesNotExists) }, expectedShortName: "debian", expectedLongName: "Debian buster", expectedVersion: "10", }, { name: "Oracle Linux release file exists", enforceTestingEnvironment: func(t *testing.T) { doesNotExists := filepath.Join(os.TempDir(), "does_not_exists") oracleReleaseFile := filepath.Join(os.TempDir(), "oracle_release_file") oracleReleaseFileContent := `Oracle Linux Server release 9.5` enforceFileWithContent(t, oracleReleaseFile, []byte(oracleReleaseFileContent)) overrideDefaultReleaseFilepath(t, doesNotExists) overrideOracleReleaseFilepath(t, oracleReleaseFile) overrideRedHatReleaseFilepath(t, doesNotExists) }, expectedShortName: "ol", expectedLongName: "Oracle Linux Server 9.5", expectedVersion: "9.5", }, { name: "Red Hat release file exists", enforceTestingEnvironment: func(t *testing.T) { doesNotExists := filepath.Join(os.TempDir(), "does_not_exists") redHatReleaseFile := filepath.Join(os.TempDir(), "redhat_release_file") redHatReleaseFileContent := `Red Hat Enterprise Linux release 8.0 (Ootpa)` enforceFileWithContent(t, redHatReleaseFile, []byte(redHatReleaseFileContent)) overrideDefaultReleaseFilepath(t, doesNotExists) overrideOracleReleaseFilepath(t, doesNotExists) overrideRedHatReleaseFilepath(t, redHatReleaseFile) }, expectedShortName: "rhel", expectedLongName: "Red Hat Enterprise Linux 8.0 (Ootpa)", expectedVersion: "8.0", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tt.enforceTestingEnvironment(t) osNameAndVersionProvider := getOsNameAndVersionProvider(context.Background()) shortName, longName, version := osNameAndVersionProvider() if tt.expectedShortName != shortName { t.Errorf("unexpected value of \"shortName\", expected %q, got %q", tt.expectedShortName, shortName) } if tt.expectedLongName != longName { t.Errorf("unexpected value of \"longName\", expected %q, got %q", tt.expectedLongName, longName) } if tt.expectedVersion != version { t.Errorf("unexpected value of \"version\", expected %q, got %q", tt.expectedVersion, version) } }) } } func toUtsField(val string) [65]byte { var result [65]byte for i := 0; i < len(val); i++ { result[i] = val[i] } result[len(val)] = '\x00' return result } func TestNewLinuxOsInfoProvider(t *testing.T) { ctx := context.Background() osInfoProvider, err := NewLinuxOsInfoProvider(getOsNameAndVersionProvider(ctx)) if err != nil { t.Errorf("unable to create osInfoProvider, err: %v", err) return } if osInfoProvider == nil { t.Errorf("expected fully functional os info provider, but get nil") } } func overrideDefaultReleaseFilepath(t *testing.T, filepath string) { prev := defaultReleaseFilepath defaultReleaseFilepath = filepath t.Cleanup(func() { defaultReleaseFilepath = prev }) } func overrideOracleReleaseFilepath(t *testing.T, filepath string) { prev := oracleReleaseFilepath oracleReleaseFilepath = filepath t.Cleanup(func() { oracleReleaseFilepath = prev }) } func overrideRedHatReleaseFilepath(t *testing.T, filepath string) { prev := redHatReleaseFilepath redHatReleaseFilepath = filepath t.Cleanup(func() { redHatReleaseFilepath = prev }) } func enforceFileWithContent(t *testing.T, filepath string, content []byte) { if err := os.WriteFile(filepath, content, 0644); err != nil { t.Errorf("unexpected error while enforcing file content, err: %v", err) } } osconfig-20250416.02/osinfo/osinfo_windows.go000066400000000000000000000121361477773331400207240ustar00rootroot00000000000000/* Copyright 2017 Google Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package osinfo import ( "errors" "fmt" "os" "path/filepath" "runtime" "syscall" "unsafe" "github.com/StackExchange/wmi" "golang.org/x/sys/windows" ) var ( version = windows.NewLazySystemDLL("version.dll") procGetFileVersionInfoSizeW = version.NewProc("GetFileVersionInfoSizeW") procGetFileVersionInfoW = version.NewProc("GetFileVersionInfoW") procVerQueryValueW = version.NewProc("VerQueryValueW") ) // https://msdn.microsoft.com/en-us/library/windows/desktop/ms647464(v=vs.85).aspx func getTranslation(block []byte) (string, error) { var start uint var length uint blockStart := uintptr(unsafe.Pointer(&block[0])) if ret, _, _ := procVerQueryValueW.Call( blockStart, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(`\VarFileInfo\Translation`))), uintptr(unsafe.Pointer(&start)), uintptr(unsafe.Pointer(&length))); ret == 0 { return "", errors.New("zero return code from VerQueryValueW indicates failure") } begin := int(start) - int(blockStart) // For translation data length is bytes. trans := block[begin : begin+int(length)] // Each 'translation' is 4 bytes long (2 16-bit sections), we just want the // first one for simplicity. t := make([]byte, 4) // 16-bit language ID little endian // https://msdn.microsoft.com/en-us/library/windows/desktop/dd318693(v=vs.85).aspx t[0], t[1] = trans[1], trans[0] // 16-bit code page ID little endian // https://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=vs.85).aspx t[2], t[3] = trans[3], trans[2] return fmt.Sprintf("%x", t), nil } // https://msdn.microsoft.com/en-us/library/windows/desktop/ms647464(v=vs.85).aspx func getStringFileInfo(block []byte, langCodePage, name string) (string, error) { var start uint var length uint blockStart := uintptr(unsafe.Pointer(&block[0])) if ret, _, _ := procVerQueryValueW.Call( blockStart, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(fmt.Sprintf(`\StringFileInfo\%s\%s`, langCodePage, name)))), uintptr(unsafe.Pointer(&start)), uintptr(unsafe.Pointer(&length))); ret == 0 { return "", errors.New("zero return code from VerQueryValueW indicates failure") } begin := int(start) - int(blockStart) // For version information length is characters (UTF16). result := block[begin : begin+int(2*length)] // Result is UTF16LE. u16s := make([]uint16, length) for i := range u16s { u16s[i] = uint16(result[i*2+1])<<8 | uint16(result[i*2]) } return syscall.UTF16ToString(u16s), nil } func getVersion(block []byte, langCodePage string) (string, string, error) { ver, err := getStringFileInfo(block, langCodePage, "FileVersion") if err != nil { return "", "", err } rel, err := getStringFileInfo(block, langCodePage, "ProductVersion") return ver, rel, err } func getKernelInfo() (string, string, error) { root := os.Getenv("SystemRoot") if root == "" { root = `C:\Windows` } path := filepath.Join(root, "System32", "ntoskrnl.exe") if _, err := os.Stat(path); err != nil { return "", "", err } pPtr := unsafe.Pointer(syscall.StringToUTF16Ptr(path)) size, _, _ := procGetFileVersionInfoSizeW.Call( uintptr(pPtr)) if size <= 0 { return "", "", errors.New("GetFileVersionInfoSize call failed, data size can not be 0") } info := make([]byte, size) if ret, _, _ := procGetFileVersionInfoW.Call( uintptr(pPtr), 0, uintptr(len(info)), uintptr(unsafe.Pointer(&info[0]))); ret == 0 { return "", "", errors.New("zero return code from GetFileVersionInfoW indicates failure") } // This should be something like 040904b0 for US English UTF16LE. langCodePage, err := getTranslation(info) if err != nil { return "", "", fmt.Errorf("getTranslation() error: %v", err) } return getVersion(info, langCodePage) } type win32OperatingSystem struct { Caption, Version string } // Get reports OSInfo. func Get() (*OSInfo, error) { oi := &OSInfo{ShortName: DefaultShortNameWindows, Architecture: NormalizeArchitecture(runtime.GOARCH)} hn, err := os.Hostname() if err != nil { return oi, fmt.Errorf("os.Hostname() error: %v", err) } oi.Hostname = hn kVersion, kRelease, err := getKernelInfo() if err != nil { return oi, fmt.Errorf("getKernelInfo() error: %v", err) } oi.KernelVersion = kVersion oi.KernelRelease = kRelease var ops []win32OperatingSystem query := "SELECT Caption, Version FROM Win32_OperatingSystem" if err := wmi.Query(query, &ops); err != nil { return oi, fmt.Errorf("wmi.Query(%q) error: %v", query, err) } if len(ops) == 0 { return oi, fmt.Errorf("wmi.Query(%q) nil output", query) } oi.LongName = ops[0].Caption oi.Version = ops[0].Version return oi, nil } osconfig-20250416.02/ospatch/000077500000000000000000000000001477773331400154675ustar00rootroot00000000000000osconfig-20250416.02/ospatch/apt_upgrade.go000066400000000000000000000057171477773331400203230ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package ospatch import ( "context" "fmt" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/packages" ) type aptGetUpgradeOpts struct { exclusivePackages []string excludes []*Exclude upgradeType packages.AptUpgradeType dryrun bool } // AptGetUpgradeOption is an option for apt-get update. type AptGetUpgradeOption func(*aptGetUpgradeOpts) // AptGetUpgradeType returns a AptGetUpgradeOption that specifies upgrade type. func AptGetUpgradeType(upgradeType packages.AptUpgradeType) AptGetUpgradeOption { return func(args *aptGetUpgradeOpts) { args.upgradeType = upgradeType } } // AptGetExcludes excludes these packages from upgrade. func AptGetExcludes(excludes []*Exclude) AptGetUpgradeOption { return func(args *aptGetUpgradeOpts) { args.excludes = excludes } } // AptGetExclusivePackages includes only these packages in the upgrade. func AptGetExclusivePackages(exclusivePackages []string) AptGetUpgradeOption { return func(args *aptGetUpgradeOpts) { args.exclusivePackages = exclusivePackages } } // AptGetDryRun performs a dry run. func AptGetDryRun(dryrun bool) AptGetUpgradeOption { return func(args *aptGetUpgradeOpts) { args.dryrun = dryrun } } // RunAptGetUpgrade runs apt-get upgrade. func RunAptGetUpgrade(ctx context.Context, opts ...AptGetUpgradeOption) error { aptOpts := &aptGetUpgradeOpts{ upgradeType: packages.AptGetUpgrade, excludes: nil, exclusivePackages: nil, dryrun: false, } for _, opt := range opts { opt(aptOpts) } pkgs, err := packages.AptUpdates(ctx, packages.AptGetUpgradeType(aptOpts.upgradeType), packages.AptGetUpgradeShowNew(true)) if err != nil { return err } fPkgs, err := filterPackages(pkgs, aptOpts.exclusivePackages, aptOpts.excludes) if err != nil { return err } if len(fPkgs) == 0 { clog.Infof(ctx, "No packages to update.") return nil } var pkgNames []string for _, pkg := range fPkgs { pkgNames = append(pkgNames, pkg.Name) } msg := fmt.Sprintf("%d packages: %q", len(pkgNames), fPkgs) if aptOpts.dryrun { clog.Infof(ctx, "Running in dryrun mode, not updating %s", msg) return nil } ops := opsToReport{ packages: fPkgs, } logOps(ctx, ops) err = packages.InstallAptPackages(ctx, pkgNames) if err == nil { logSuccess(ctx, ops) } else { logFailure(ctx, ops, err) } return err } osconfig-20250416.02/ospatch/exclude.go000066400000000000000000000033361477773331400174540ustar00rootroot00000000000000// Copyright 2022 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package ospatch import ( "fmt" "regexp" ) // Exclude represents package exclude entry by a user type Exclude struct { isRegexp bool regex *regexp.Regexp strictString *string } func (exclude Exclude) String() string { return fmt.Sprintf("{isRegexp: %t, regex: %+v, strictString: %s}", exclude.isRegexp, exclude.regex, *exclude.strictString) } // CreateRegexExclude returns new Exclude struct that represents exclusion with regex func CreateRegexExclude(regex *regexp.Regexp) *Exclude { return &Exclude{ isRegexp: true, regex: regex, } } // CreateStringExclude returns new Exclude struct that represents exclusion with string func CreateStringExclude(strictString *string) *Exclude { strictStringCopied := *strictString //copy the string for safety reason return &Exclude{ isRegexp: false, strictString: &strictStringCopied, } } // MatchesName returns if a package with a certain name matches Exclude struct and should be excluded func (exclude *Exclude) MatchesName(name *string) bool { if exclude.isRegexp { return exclude.regex.MatchString(*name) } return *exclude.strictString == *name } osconfig-20250416.02/ospatch/googet_update.go000066400000000000000000000047411477773331400206520ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package ospatch import ( "context" "fmt" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/packages" ) type googetUpdateOpts struct { exclusivePackages []string excludes []*Exclude dryrun bool } // GooGetUpdateOption is an option for apt-get update. type GooGetUpdateOption func(*googetUpdateOpts) // GooGetExcludes excludes these packages from upgrade. func GooGetExcludes(excludes []*Exclude) GooGetUpdateOption { return func(args *googetUpdateOpts) { args.excludes = excludes } } // GooGetExclusivePackages includes only these packages in the upgrade. func GooGetExclusivePackages(exclusivePackages []string) GooGetUpdateOption { return func(args *googetUpdateOpts) { args.exclusivePackages = exclusivePackages } } // GooGetDryRun performs a dry run. func GooGetDryRun(dryrun bool) GooGetUpdateOption { return func(args *googetUpdateOpts) { args.dryrun = dryrun } } // RunGooGetUpdate runs googet update. func RunGooGetUpdate(ctx context.Context, opts ...GooGetUpdateOption) error { googetOpts := &googetUpdateOpts{} for _, opt := range opts { opt(googetOpts) } pkgs, err := packages.GooGetUpdates(ctx) if err != nil { return err } fPkgs, err := filterPackages(pkgs, googetOpts.exclusivePackages, googetOpts.excludes) if err != nil { return err } if len(fPkgs) == 0 { clog.Infof(ctx, "No packages to update.") return nil } var pkgNames []string for _, pkg := range fPkgs { pkgNames = append(pkgNames, pkg.Name) } msg := fmt.Sprintf("%d packages: %q", len(pkgNames), fPkgs) if googetOpts.dryrun { clog.Infof(ctx, "Running in dryrun mode, not updating %s", msg) return nil } ops := opsToReport{ packages: fPkgs, } logOps(ctx, ops) err = packages.InstallGooGetPackages(ctx, pkgNames) if err == nil { logSuccess(ctx, ops) } else { logFailure(ctx, ops, err) } return err } osconfig-20250416.02/ospatch/report.go000066400000000000000000000056001477773331400173320ustar00rootroot00000000000000// Copyright 2021 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package ospatch import ( "context" "fmt" "strings" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/packages" ) // repLabels holds the labels by which the log entries for the patch report // are retrieved var repLabels = map[string]string{"package-report": "true"} // opsToReport represents packages and patches that are to be logged // as part of patch reporting type opsToReport struct { packages []*packages.PkgInfo patches []*packages.ZypperPatch } func formatPatches(patches []*packages.ZypperPatch) string { names := []string{} for _, p := range patches { names = append(names, p.Name) } return strings.Join(names, ", ") } // logPackages logs the intent to patch the packages in pkgs // for the purpose of patch report. func logOps(ctx context.Context, ops opsToReport) { msg := "" sep := "" if len(ops.packages) > 0 { msg = fmt.Sprintf("Updating %d packages: %q", len(ops.packages), ops.packages) sep = "; " } if len(ops.patches) > 0 { msg = msg + fmt.Sprintf("%sInstalling %d patches: %s", sep, len(ops.patches), formatPatches(ops.patches)) } clog.Infof(clog.WithLabels(ctx, repLabels), "%v", msg) } // logSuccess logs the success of patching the packages in pkgs // for the purpose of patch report. func logSuccess(ctx context.Context, ops opsToReport) { sep := "" msg := "" pkgs, patches := ops.packages, ops.patches if len(pkgs) > 0 { msg = fmt.Sprintf("Updated %d packages: %q", len(pkgs), pkgs) sep = "; " } if len(patches) > 0 { msg = msg + fmt.Sprintf("%sApplied %d patches: %s", sep, len(patches), formatPatches(patches)) } msg = fmt.Sprintf("Success. %s", msg) clog.Infof(clog.WithLabels(ctx, repLabels), "%v", msg) } // logFailure logs the failure of patching the packages in pkgs caused by err, // for the purpose of patch report. func logFailure(ctx context.Context, ops opsToReport, err error) { sep := "" msg := "" pkgs, patches := ops.packages, ops.patches if len(pkgs) > 0 { msg = fmt.Sprintf("Tried to update %d packages: %q", len(pkgs), pkgs) sep = "; " } if len(patches) > 0 { msg = msg + fmt.Sprintf("%sTried to apply %d patches: %s", sep, len(patches), formatPatches(patches)) } msg = fmt.Sprintf("Failure: %s. Error: %v", msg, err) clog.Infof(clog.WithLabels(ctx, repLabels), "%v", msg) } osconfig-20250416.02/ospatch/system_linux.go000066400000000000000000000071451477773331400205700ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build !test // +build !test package ospatch import ( "bytes" "context" "os" "os/exec" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/packages" ) const ( systemctl = "/bin/systemctl" ) // DisableAutoUpdates disables system auto updates. func DisableAutoUpdates(ctx context.Context) { // yum-cron on el systems if _, err := os.Stat("/usr/lib/systemd/system/yum-cron.service"); err == nil { out, err := exec.Command(systemctl, "is-enabled", "yum-cron.service").CombinedOutput() if err != nil { if eerr, ok := err.(*exec.ExitError); ok { // Error code of 1 indicates disabled. if eerr.ExitCode() == 1 { return } } clog.Errorf(ctx, "Error checking status of yum-cron, error: %v, out: %s", err, out) } clog.Debugf(ctx, "Disabling yum-cron") out, err = exec.Command(systemctl, "stop", "yum-cron.service").CombinedOutput() if err != nil { clog.Errorf(ctx, "Error stopping yum-cron, error: %v, out: %s", err, out) } out, err = exec.Command(systemctl, "disable", "yum-cron.service").CombinedOutput() if err != nil { clog.Errorf(ctx, "Error disabling yum-cron, error: %v, out: %s", err, out) } } else if _, err := os.Stat("/usr/sbin/yum-cron"); err == nil { out, err := exec.Command("/sbin/chkconfig", "yum-cron").CombinedOutput() if err != nil { clog.Errorf(ctx, "Error checking status of yum-cron, error: %v, out: %s", err, out) } if bytes.Contains(out, []byte("disabled")) { return } clog.Debugf(ctx, "Disabling yum-cron") out, err = exec.Command("/sbin/chkconfig", "yum-cron", "off").CombinedOutput() if err != nil { clog.Errorf(ctx, "Error disabling yum-cron, error: %v, out: %s", err, out) } } // dnf-automatic on el8 systems if _, err := os.Stat("/usr/lib/systemd/system/dnf-automatic.timer"); err == nil { out, err := exec.Command(systemctl, "list-timers", "dnf-automatic.timer").CombinedOutput() if err != nil { clog.Errorf(ctx, "Error checking status of dnf-automatic, error: %v, out: %s", err, out) } if bytes.Contains(out, []byte("0 timers listed")) { return } clog.Debugf(ctx, "Disabling dnf-automatic") out, err = exec.Command(systemctl, "stop", "dnf-automatic.timer").CombinedOutput() if err != nil { clog.Errorf(ctx, "Error stopping dnf-automatic, error: %v, out: %s", err, out) } out, err = exec.Command(systemctl, "disable", "dnf-automatic.timer").CombinedOutput() if err != nil { clog.Errorf(ctx, "Error disabling dnf-automatic, error: %v, out: %s", err, out) } } // apt unattended-upgrades // TODO: Removing the package is a bit overkill, look into just managing // the configs, this is probably best done by looking through // /etc/apt/apt.conf.d/ and setting APT::Periodic::Unattended-Upgrade to 0. if _, err := os.Stat("/usr/bin/unattended-upgrades"); err == nil { clog.Debugf(ctx, "Removing unattended-upgrades package") if err := packages.RemoveAptPackages(ctx, []string{"unattended-upgrades"}); err != nil { clog.Errorf(ctx, "%v", err.Error()) } } } osconfig-20250416.02/ospatch/system_test_stub.go000066400000000000000000000013441477773331400214400ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build test // +build test package ospatch func disableAutoUpdates() {} func rebootSystem() error { return nil } osconfig-20250416.02/ospatch/system_windows.go000066400000000000000000000034521477773331400211200ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build !test // +build !test package ospatch import ( "context" "os" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/packages" "golang.org/x/sys/windows/registry" ) // DisableAutoUpdates disables system auto updates. func DisableAutoUpdates(ctx context.Context) { k, openedExisting, err := registry.CreateKey(registry.LOCAL_MACHINE, `SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU`, registry.ALL_ACCESS) if err != nil { clog.Errorf(ctx, "Error disabling Windows auto updates, error: %v", err) } defer k.Close() if openedExisting { val, _, err := k.GetIntegerValue("NoAutoUpdate") if err == nil && val == 1 { return } } clog.Debugf(ctx, "Disabling Windows Auto Updates") if err := k.SetDWordValue("NoAutoUpdate", 1); err != nil { clog.Errorf(ctx, "Error disabling Windows auto updates, error: %v", err) } if _, err := os.Stat(`C:\Program Files\Google\Compute Engine\tools\auto_updater.ps1`); err == nil { clog.Debugf(ctx, "Removing google-compute-engine-auto-updater package") if err := packages.RemoveGooGetPackages(ctx, []string{"google-compute-engine-auto-updater"}); err != nil { clog.Errorf(ctx, err.Error()) } } } osconfig-20250416.02/ospatch/updates.go000066400000000000000000000076511477773331400174740ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package ospatch import ( "bufio" "bytes" "errors" "fmt" "os" "os/exec" "strconv" "github.com/GoogleCloudPlatform/osconfig/packages" ) const ( rpmquery = "/usr/bin/rpmquery" ) func getBtime(stat string) (int64, error) { f, err := os.Open(stat) if err != nil { return 0, fmt.Errorf("error opening %s: %v", stat, err) } defer f.Close() var btime int64 scnr := bufio.NewScanner(f) for scnr.Scan() { if bytes.HasPrefix(scnr.Bytes(), []byte("btime")) { split := bytes.SplitN(scnr.Bytes(), []byte(" "), 2) if len(split) != 2 { return 0, fmt.Errorf("error parsing btime from %s: %q", stat, scnr.Text()) } btime, err = strconv.ParseInt(string(bytes.TrimSpace(split[1])), 10, 64) if err != nil { return 0, fmt.Errorf("error parsing btime: %v", err) } break } } if err := scnr.Err(); err != nil && btime == 0 { return 0, fmt.Errorf("error scanning %s: %v", stat, err) } if btime == 0 { return 0, fmt.Errorf("could not find btime in %s", stat) } return btime, nil } func rpmRebootRequired(pkgs []byte, btime int64) bool { // Scanning this output is best effort, false negatives are much prefered // to false positives, and keeping this as simple as possible is // beneficial. scnr := bufio.NewScanner(bytes.NewReader(pkgs)) for scnr.Scan() { itime, err := strconv.ParseInt(scnr.Text(), 10, 64) if err != nil { continue } if itime > btime { return true } } return false } // rpmReboot returns whether an rpm based system should reboot in order to // finish installing updates. // To get this signal we look at a set of well known packages and whether // install time > system boot time. This list is not meant to be exhastive, // just to provide a signal when core system packages are updated. func rpmReboot() (bool, error) { provides := []string{ // Common packages. "kernel", "glibc", "gnutls", // EL packages. "linux-firmware", "openssl-libs", "dbus", // Suse packages. "kernel-firmware", "libopenssl1_1", "libopenssl1_0_0", "dbus-1", } args := append([]string{"--queryformat", "%{INSTALLTIME}\n", "--whatprovides"}, provides...) out, err := exec.Command(rpmquery, args...).Output() if err != nil { // We don't care about return codes as we know some of these packages won't be installed. if _, ok := err.(*exec.ExitError); !ok { return false, fmt.Errorf("error running %s: %v", rpmquery, err) } } btime, err := getBtime("/proc/stat") if err != nil { return false, err } return rpmRebootRequired(out, btime), nil } func shouldPackageBeExcluded(excludes []*Exclude, packageName *string) bool { for _, exclude := range excludes { if exclude.MatchesName(packageName) { return true } } return false } func containsString(ss []string, c string) bool { for _, s := range ss { if s == c { return true } } return false } func filterPackages(pkgs []*packages.PkgInfo, exclusivePackages []string, excludes []*Exclude) ([]*packages.PkgInfo, error) { if len(exclusivePackages) != 0 && len(excludes) != 0 { return nil, errors.New("exclusivePackages and excludes can not both be non 0") } var fPkgs = []*packages.PkgInfo{} for _, pkg := range pkgs { if shouldPackageBeExcluded(excludes, &pkg.Name) { continue } if exclusivePackages == nil || containsString(exclusivePackages, pkg.Name) { fPkgs = append(fPkgs, pkg) } } return fPkgs, nil } osconfig-20250416.02/ospatch/updates_linux.go000066400000000000000000000035331477773331400207060ustar00rootroot00000000000000// Copyright 2018 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build !test // +build !test package ospatch import ( "context" "errors" "io/ioutil" "os" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/packages" "github.com/GoogleCloudPlatform/osconfig/util" ) // SystemRebootRequired checks whether a system reboot is required. func SystemRebootRequired(ctx context.Context) (bool, error) { if packages.AptExists { clog.Debugf(ctx, "Checking if reboot required by looking at /var/run/reboot-required.") data, err := ioutil.ReadFile("/var/run/reboot-required") if os.IsNotExist(err) { clog.Debugf(ctx, "/var/run/reboot-required does not exist, indicating no reboot is required.") return false, nil } if err != nil { return false, err } clog.Debugf(ctx, "/var/run/reboot-required exists indicating a reboot is required, content:\n%s", string(data)) return true, nil } if ok := util.Exists(rpmquery); ok { clog.Debugf(ctx, "Checking if reboot required by querying rpm database.") return rpmReboot() } return false, errors.New("no recognized package manager installed, can't determine if reboot is required") } // InstallWUAUpdates is the linux stub for InstallWUAUpdates. func InstallWUAUpdates(ctx context.Context) error { return nil } osconfig-20250416.02/ospatch/updates_test.go000066400000000000000000000072251477773331400205300ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package ospatch import ( "io/ioutil" "os" "reflect" "regexp" "testing" "github.com/GoogleCloudPlatform/osconfig/packages" ) func TestGetBtime(t *testing.T) { tests := []struct { name string in string want int64 wantErr bool }{ {"NormalCase", "procs_running 2\nprocs_blocked 0\nctxt 22762852599\nbtime 1561478350\nprocesses 15504510", 1561478350, false}, {"NoBtime", "procs_running 2\nprocs_blocked 0\nctxt 22762852599\nprocesses 15504510", 0, true}, {"CantParseInt", "procs_running 2\nprocs_blocked 0\nctxt 22762852599\nbtime notanint\nprocesses 15504510", 0, true}, {"CantParseLine", "procs_running 2\nprocs_blocked 0\nctxt 22762852599\nbtime1561478350\nprocesses 15504510", 0, true}, } for _, tt := range tests { td, err := ioutil.TempDir(os.TempDir(), "") if err != nil { t.Fatalf("error creating temp dir: %v", err) } defer os.RemoveAll(td) t.Run(tt.name, func(t *testing.T) { f, err := ioutil.TempFile(td, "") if err != nil { t.Fatalf("error creating temp file: %v", err) } if _, err := f.Write([]byte(tt.in)); err != nil { t.Fatalf("error writing temp file: %v", err) } if err := f.Close(); err != nil { t.Fatalf("error writing temp file: %v", err) } got, err := getBtime(f.Name()) if (err != nil) != tt.wantErr { t.Errorf("getBtime() error = %v, wantErr %v", err, tt.wantErr) return } if got != tt.want { t.Errorf("getBtime() = %v, want %v", got, tt.want) } }) } } func TestRpmRebootRequired(t *testing.T) { type args struct { pkgs []byte btime int64 } tests := []struct { name string args args want bool }{ {"RebootRequired", args{[]byte("1\n3\n2\n6"), 5}, true}, {"NoRebootRequired", args{[]byte("1\n3\n2\n5"), 5}, false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := rpmRebootRequired(tt.args.pkgs, tt.args.btime) if got != tt.want { t.Errorf("rpmRebootRequired() = %v, want %v", got, tt.want) } }) } } func TestFilterPackages(t *testing.T) { pkg := packages.PkgInfo{Name: "NameOfThePackage"} strictString := "NameOfThePackage" regex, _ := regexp.Compile("^NameO[e-g]ThePackage$") missingRegex, _ := regexp.Compile("^NameO[e-g]ThePackag$") tests := []struct { name string pkgs []*packages.PkgInfo exludes []*Exclude want []*packages.PkgInfo }{ {name: "StrictStringFiltering", pkgs: []*packages.PkgInfo{&pkg}, exludes: []*Exclude{CreateStringExclude(&strictString)}, want: []*packages.PkgInfo{}}, {name: "RegexpFiltering", pkgs: []*packages.PkgInfo{&pkg}, exludes: []*Exclude{CreateRegexExclude(regex)}, want: []*packages.PkgInfo{}}, {name: "MissedFilter", pkgs: []*packages.PkgInfo{&pkg}, exludes: []*Exclude{CreateRegexExclude(missingRegex)}, want: []*packages.PkgInfo{&pkg}}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := filterPackages(tt.pkgs, nil, tt.exludes) if err != nil { t.Errorf("err = %v, want %v", err, nil) } if !reflect.DeepEqual(got, tt.want) { t.Errorf("filterPackages() = %v, want %v", got, tt.want) } }) } } osconfig-20250416.02/ospatch/updates_test_stub.go000066400000000000000000000015511477773331400215610ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build test // +build test package ospatch import ( "context" ) func systemRebootRequired() (bool, error) { return false, nil } func runUpdates(ctx context.Context, r *patchRun) error { return nil } func rebootSystem() error { return nil } osconfig-20250416.02/ospatch/updates_windows.go000066400000000000000000000153261477773331400212440ustar00rootroot00000000000000// Copyright 2018 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build !test // +build !test package ospatch import ( "context" "fmt" "strings" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/packages" "golang.org/x/sys/windows/registry" ) // SystemRebootRequired checks whether a system reboot is required. func SystemRebootRequired(ctx context.Context) (bool, error) { // https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-movefileexw#remarks clog.Debugf(ctx, "Checking for PendingFileRenameOperations") k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\CurrentControlSet\Control\Session Manager`, registry.QUERY_VALUE) if err == nil { val, _, err := k.GetStringsValue("PendingFileRenameOperations") if err == nil { k.Close() if len(val) > 0 { clog.Infof(ctx, "PendingFileRenameOperations indicate a reboot is required: %q", val) return true, nil } } else if err != registry.ErrNotExist { return false, err } } else if err != registry.ErrNotExist { return false, err } regKeys := []string{ `SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired`, // Skip checking CBS for now until we implement rate limiting on reboots, this key // will not be reset in some instances for a few minutes after a reboot. This should // not prevent updates from running as this mainly indicates a feature install. // `SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending`, } for _, key := range regKeys { clog.Debugf(ctx, "Checking if reboot required by testing the existance of %s", key) k, err := registry.OpenKey(registry.LOCAL_MACHINE, key, registry.QUERY_VALUE) if err == nil { k.Close() clog.Infof(ctx, "%s exists indicating a reboot is required.", key) return true, nil } else if err != registry.ErrNotExist { return false, err } } return false, nil } func checkFilters(ctx context.Context, updt *packages.IUpdate, kbExcludes, classFilter, exclusive_patches []string) (ok bool, err error) { title, err := updt.GetProperty("Title") if err != nil { return false, fmt.Errorf(`updt.GetProperty("Title"): %v`, err) } defer title.Clear() defer func() { if ok == true { clog.Debugf(ctx, "Update %q not excluded by any filters.", title.ToString()) } }() kbArticleIDsRaw, err := updt.GetProperty("KBArticleIDs") if err != nil { return false, fmt.Errorf(`updt.GetProperty("KBArticleIDs"): %v`, err) } defer kbArticleIDsRaw.Clear() kbArticleIDs := kbArticleIDsRaw.ToIDispatch() defer kbArticleIDs.Release() kbArticleIDsCount, err := packages.GetCount(kbArticleIDs) if err != nil { return false, err } if len(exclusive_patches) > 0 { for i := 0; i < int(kbArticleIDsCount); i++ { kbRaw, err := kbArticleIDs.GetProperty("Item", i) if err != nil { return false, err } defer kbRaw.Clear() for _, e := range exclusive_patches { if e == kbRaw.ToString() { // until now we have only seen at most 1 kbarticles // in a patch update. So, if we get a match, we just // install the update return true, nil } } } // since there are exclusive_patches to be installed, // other fields like excludes, classfilter are void return false, nil } if len(kbExcludes) > 0 { for i := 0; i < int(kbArticleIDsCount); i++ { kbRaw, err := kbArticleIDs.GetProperty("Item", i) if err != nil { return false, err } defer kbRaw.Clear() for _, e := range kbExcludes { // kbArticleIDs is just the IDs, but users are used to using the KB prefix. if strings.TrimLeft(e, "KkBb") == kbRaw.ToString() { clog.Debugf(ctx, "Update %q (%s) matched exclude filter", title.ToString(), kbRaw.ToString()) return false, nil } } } } if len(classFilter) == 0 { return true, nil } categoriesRaw, err := updt.GetProperty("Categories") if err != nil { return false, fmt.Errorf(`updt.GetProperty("Categories"): %v`, err) } defer categoriesRaw.Clear() categories := categoriesRaw.ToIDispatch() defer categories.Release() categoriesCount, err := packages.GetCount(categories) if err != nil { return false, err } for i := 0; i < int(categoriesCount); i++ { catRaw, err := categories.GetProperty("Item", i) if err != nil { return false, fmt.Errorf(`categories.GetProperty("Item", i): %v`, err) } defer catRaw.Clear() cat := catRaw.ToIDispatch() defer cat.Release() catIdRaw, err := cat.GetProperty("CategoryID") if err != nil { return false, fmt.Errorf(`cat.GetProperty("CategoryID"): %v`, err) } defer catIdRaw.Clear() for _, c := range classFilter { if c == catIdRaw.ToString() { return true, nil } } } clog.Debugf(ctx, "Update %q not found in classification filter", title.ToString()) return false, nil } // GetWUAUpdates gets WUA updates based on optional classFilter and kbExcludes. func GetWUAUpdates(ctx context.Context, session *packages.IUpdateSession, classFilter, kbExcludes, exclusivePatches []string) (*packages.IUpdateCollection, error) { // Search for all not installed updates but filter out ones that will be installed after a reboot. filter := "IsInstalled=0 AND RebootRequired=0" clog.Debugf(ctx, "Searching for WUA updates with query %q", filter) updts, err := session.GetWUAUpdateCollection(ctx, filter) if err != nil { return nil, fmt.Errorf("GetWUAUpdateCollection error: %v", err) } if len(classFilter) == 0 && len(kbExcludes) == 0 && len(exclusivePatches) == 0 { return updts, nil } defer updts.Release() count, err := updts.Count() if err != nil { return nil, err } clog.Debugf(ctx, "Found %d total updates avaiable (pre filter).", count) newUpdts, err := packages.NewUpdateCollection() if err != nil { return nil, err } clog.Debugf(ctx, "Using filters: Excludes: %q, Classifications: %q, ExclusivePatches: %q", kbExcludes, classFilter, exclusivePatches) for i := 0; i < int(count); i++ { updt, err := updts.Item(i) if err != nil { return nil, err } ok, err := checkFilters(ctx, updt, kbExcludes, classFilter, exclusivePatches) if err != nil { return nil, err } if !ok { continue } if err := newUpdts.Add(updt); err != nil { return nil, err } } return newUpdts, nil } osconfig-20250416.02/ospatch/yum_update.go000066400000000000000000000071121477773331400201730ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package ospatch import ( "context" "fmt" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/packages" ) const yum = "/usr/bin/yum" var ( yumUpdateArgs = []string{"update", "-y"} yumUpdateMinimalArgs = []string{"update-minimal", "-y"} ) type yumUpdateOpts struct { exclusivePackages []string excludes []*Exclude security bool minimal bool dryrun bool } // YumUpdateOption is an option for yum update. type YumUpdateOption func(*yumUpdateOpts) // YumUpdateSecurity returns a YumUpdateOption that specifies the --security flag should // be used. func YumUpdateSecurity(security bool) YumUpdateOption { return func(args *yumUpdateOpts) { args.security = security } } // YumUpdateMinimal returns a YumUpdateOption that specifies the update-minimal // command should be used. func YumUpdateMinimal(minimal bool) YumUpdateOption { return func(args *yumUpdateOpts) { args.minimal = minimal } } // YumUpdateExcludes returns a YumUpdateOption that specifies what packages to add to // the --exclude flag. func YumUpdateExcludes(excludes []*Exclude) YumUpdateOption { return func(args *yumUpdateOpts) { args.excludes = excludes } } // YumExclusivePackages includes only these packages in the upgrade. func YumExclusivePackages(exclusivePackages []string) YumUpdateOption { return func(args *yumUpdateOpts) { args.exclusivePackages = exclusivePackages } } // YumDryRun performs a dry run. func YumDryRun(dryrun bool) YumUpdateOption { return func(args *yumUpdateOpts) { args.dryrun = dryrun } } // fullPackageName returns the package name with architecture if present. func fullPackageName(pkgInfo *packages.PkgInfo) string { pkgName := pkgInfo.Name if len(pkgInfo.RawArch) > 0 { pkgName = pkgName + "." + pkgInfo.RawArch } return pkgName } // RunYumUpdate runs yum update. func RunYumUpdate(ctx context.Context, opts ...YumUpdateOption) error { yumOpts := &yumUpdateOpts{ security: false, minimal: false, dryrun: false, } for _, opt := range opts { opt(yumOpts) } pkgs, err := packages.YumUpdates(ctx, packages.YumUpdateMinimal(yumOpts.minimal), packages.YumUpdateSecurity(yumOpts.security)) if err != nil { return err } // Yum excludes are already excluded while listing yumUpdates, so we send // and empty list. fPkgs, err := filterPackages(pkgs, yumOpts.exclusivePackages, yumOpts.excludes) if err != nil { return err } if len(fPkgs) == 0 { clog.Infof(ctx, "No packages to update.") return nil } var pkgNames []string for _, pkg := range fPkgs { pkgNames = append(pkgNames, fullPackageName(pkg)) } msg := fmt.Sprintf("%d packages: %q", len(pkgNames), fPkgs) if yumOpts.dryrun { clog.Infof(ctx, "Running in dryrun mode, not updating %s", msg) return nil } ops := opsToReport{ packages: fPkgs, } logOps(ctx, ops) err = packages.InstallYumPackages(ctx, pkgNames) if err == nil { logSuccess(ctx, ops) } else { logFailure(ctx, ops, err) } return err } osconfig-20250416.02/ospatch/yum_update_test.go000066400000000000000000000132071477773331400212340ustar00rootroot00000000000000// Copyright 2020 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package ospatch import ( "context" "os" "os/exec" "testing" "github.com/GoogleCloudPlatform/osconfig/packages" utilmocks "github.com/GoogleCloudPlatform/osconfig/util/mocks" "github.com/golang/mock/gomock" ) func TestRunYumUpdateWithSecurity(t *testing.T) { data := []byte(` ================================================================================================================================================================================= Package Arch Version Repository Size ================================================================================================================================================================================= Upgrading: foo noarch 2.0.0-1 BaseOS 361 k blah `) ctx := context.Background() if os.Getenv("EXIT100") == "1" { os.Exit(100) } cmd := exec.CommandContext(context.Background(), os.Args[0], "-test.run=TestRunYumUpdateWithSecurity") cmd.Env = append(os.Environ(), "EXIT100=1") err := cmd.Run() mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) packages.SetCommandRunner(mockCommandRunner) checkUpdateCall := mockCommandRunner.EXPECT().Run(ctx, utilmocks.EqCmd(exec.Command("/usr/bin/yum", []string{"check-update", "--assumeyes"}...))).Return([]byte("stdout"), []byte("stderr"), err).Times(1) // yum install call to install package mockCommandRunner.EXPECT().Run(ctx, utilmocks.EqCmd(exec.Command("/usr/bin/yum", []string{"install", "--assumeyes", "foo.noarch"}...))).After(checkUpdateCall).Return([]byte("stdout"), []byte("stderr"), nil).Times(1) packages.SetPtyCommandRunner(mockCommandRunner) mockCommandRunner.EXPECT().Run(ctx, utilmocks.EqCmd(exec.Command("/usr/bin/yum", []string{"update", "--assumeno", "--cacheonly", "--color=never", "--security"}...))).Return(data, []byte("stderr"), nil).Times(1) err = RunYumUpdate(ctx, YumUpdateMinimal(false), YumUpdateSecurity(true)) if err != nil { t.Errorf("did not expect error: %+v", err) } } func TestRunYumUpdateWithSecurityWithExclusives(t *testing.T) { data := []byte(` ================================================================================================================================================================================= Package Arch Version Repository Size ================================================================================================================================================================================= Installing: kernel x86_64 2.6.32-754.24.3.el6 updates 32 M replacing kernel.x86_64 1.0.0-4 Upgrading: foo noarch 2.0.0-1 BaseOS 361 k bar x86_64 2.0.0-1 repo 10 M Obsoleting: baz noarch 2.0.0-1 repo 10 M `) ctx := context.Background() exclusivePackages := []string{"foo", "bar"} if os.Getenv("EXIT100") == "1" { os.Exit(100) } cmd := exec.CommandContext(context.Background(), os.Args[0], "-test.run=TestRunYumUpdateWithSecurityWithExclusives") cmd.Env = append(os.Environ(), "EXIT100=1") err := cmd.Run() mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) packages.SetCommandRunner(mockCommandRunner) checkUpdateCall := mockCommandRunner.EXPECT().Run(ctx, utilmocks.EqCmd(exec.Command("/usr/bin/yum", []string{"check-update", "--assumeyes"}...))).Return([]byte("stdout"), []byte("stderr"), err).Times(1) // yum install call to install package, make sure only 2 packages are installed. mockCommandRunner.EXPECT().Run(ctx, utilmocks.EqCmd(exec.Command("/usr/bin/yum", []string{"install", "--assumeyes", "foo.noarch", "bar.x86_64"}...))).After(checkUpdateCall).Return([]byte("stdout"), []byte("stderr"), nil).Times(1) packages.SetPtyCommandRunner(mockCommandRunner) mockCommandRunner.EXPECT().Run(ctx, utilmocks.EqCmd(exec.Command("/usr/bin/yum", []string{"update", "--assumeno", "--cacheonly", "--color=never", "--security"}...))).Return(data, []byte("stderr"), nil).Times(1) err = RunYumUpdate(ctx, YumUpdateMinimal(false), YumUpdateSecurity(true), YumExclusivePackages(exclusivePackages)) if err != nil { t.Errorf("did not expect error: %+v", err) } } osconfig-20250416.02/ospatch/zypper_patch.go000066400000000000000000000143201477773331400205260ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package ospatch import ( "context" "fmt" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/packages" ) const zypper = "/usr/bin/zypper" var ( zypperPatchArgs = []string{"patch", "-y"} ) type zypperPatchOpts struct { categories []string severities []string excludes []*Exclude exclusivePatches []string withOptional bool withUpdate bool dryrun bool } // ZypperPatchOption is an option for zypper patch. type ZypperPatchOption func(*zypperPatchOpts) // ZypperPatchCategories returns a ZypperUpdateOption that specifies what // categories to add to the --categories flag. func ZypperPatchCategories(categories []string) ZypperPatchOption { return func(args *zypperPatchOpts) { args.categories = categories } } // ZypperPatchSeverities returns a ZypperUpdateOption that specifies what // categories to add to the --categories flag. func ZypperPatchSeverities(severities []string) ZypperPatchOption { return func(args *zypperPatchOpts) { args.severities = severities } } // ZypperUpdateWithOptional returns a ZypperUpdateOption that specifies the // --with-optional flag should be used. func ZypperUpdateWithOptional(withOptional bool) ZypperPatchOption { return func(args *zypperPatchOpts) { args.withOptional = withOptional } } // ZypperUpdateWithUpdate returns a ZypperUpdateOption that specifies the // --with-update flag should be used. func ZypperUpdateWithUpdate(withUpdate bool) ZypperPatchOption { return func(args *zypperPatchOpts) { args.withUpdate = withUpdate } } // ZypperUpdateWithExcludes returns a ZypperUpdateOption that specifies // list of packages to be excluded from update func ZypperUpdateWithExcludes(excludes []*Exclude) ZypperPatchOption { return func(args *zypperPatchOpts) { args.excludes = excludes } } // ZypperUpdateWithExclusivePatches returns a ZypperUpdateOption that specifies // list of exclusive packages to be updated func ZypperUpdateWithExclusivePatches(exclusivePatches []string) ZypperPatchOption { return func(args *zypperPatchOpts) { args.exclusivePatches = exclusivePatches } } // ZypperUpdateDryrun returns a ZypperUpdateOption that specifies the runner. func ZypperUpdateDryrun(dryrun bool) ZypperPatchOption { return func(args *zypperPatchOpts) { args.dryrun = dryrun } } // RunZypperPatch runs zypper patch. func RunZypperPatch(ctx context.Context, opts ...ZypperPatchOption) error { zOpts := &zypperPatchOpts{ excludes: nil, exclusivePatches: nil, categories: nil, severities: nil, withOptional: false, withUpdate: false, } for _, opt := range opts { opt(zOpts) } zListOpts := []packages.ZypperListOption{ packages.ZypperListPatchCategories(zOpts.categories), packages.ZypperListPatchSeverities(zOpts.severities), packages.ZypperListPatchWithOptional(zOpts.withOptional), // if there is no filter on category and severity, // zypper fetches all available patch updates } patches, err := packages.ZypperPatches(ctx, zListOpts...) if err != nil { return err } // if user specifies, --with-update get the necessary patch/package // information and then runfilter on them var pkgToPatchesMap map[string][]string var pkgUpdates []*packages.PkgInfo if zOpts.withUpdate { pkgUpdates, err = packages.ZypperUpdates(ctx) if err != nil { return err } pkgToPatchesMap, err = packages.ZypperPackagesInPatch(ctx, patches) if err != nil { return err } } fPatches, fpkgs, err := runFilter(patches, zOpts.exclusivePatches, zOpts.excludes, pkgUpdates, pkgToPatchesMap, zOpts.withUpdate) if len(fPatches) == 0 && len(fpkgs) == 0 { clog.Infof(ctx, "No updates required.") return nil } var ops opsToReport if len(fPatches) == 0 { clog.Infof(ctx, "No patches to install.") } else { msg := fmt.Sprintf("%d patches: %s", len(fPatches), formatPatches(fPatches)) if zOpts.dryrun { clog.Infof(ctx, "Running in dryrun mode, not installing %s", msg) } else { ops.patches = fPatches } } if len(fpkgs) == 0 { clog.Infof(ctx, "No non-patch packages to update.") } else { msg := fmt.Sprintf("%d patches: %q", len(fpkgs), fpkgs) if zOpts.dryrun { clog.Infof(ctx, "Running in dryrun mode, not Updating %s", msg) } else { ops.packages = fpkgs } } logOps(ctx, ops) if zOpts.dryrun { return nil } err = packages.ZypperInstall(ctx, fPatches, fpkgs) if err == nil { logSuccess(ctx, ops) } else { logFailure(ctx, ops, err) } return err } func runFilter(patches []*packages.ZypperPatch, exclusivePatches []string, excludes []*Exclude, pkgUpdates []*packages.PkgInfo, pkgToPatchesMap map[string][]string, withUpdate bool) ([]*packages.ZypperPatch, []*packages.PkgInfo, error) { // exclusive patches var fPatches []*packages.ZypperPatch var fPkgs []*packages.PkgInfo if len(exclusivePatches) > 0 { for _, patch := range patches { if containsString(exclusivePatches, patch.Name) { fPatches = append(fPatches, patch) } } return fPatches, fPkgs, nil } // if --with-update is specified, filter out the packages // that will be updated as a part of a patch update if withUpdate { for _, pkg := range pkgUpdates { if _, ok := pkgToPatchesMap[pkg.Name]; !ok { fPkgs = append(fPkgs, pkg) } } } // we have the list of patches which is already filtered // as per the configurations provided by user; // we remove the excluded patches from the list for _, patch := range patches { // in zypper we're filtering patches instead of packages, but the method is still the same if !shouldPackageBeExcluded(excludes, &patch.Name) { fPatches = append(fPatches, patch) } } return fPatches, fPkgs, nil } osconfig-20250416.02/ospatch/zypper_patch_test.go000066400000000000000000000122741477773331400215730ustar00rootroot00000000000000package ospatch import ( "strings" "testing" "github.com/GoogleCloudPlatform/osconfig/packages" ) func TestRunFilter(t *testing.T) { patches, pkgUpdates, pkgToPatchesMap := prepareTestCase() type input struct { patches []*packages.ZypperPatch pkgUpdates []*packages.PkgInfo pkgToPatchesMap map[string][]string exclusiveIncludes []string excludes []*Exclude withUpdate bool } type expect struct { patches []string pkgUpdates []string err error } var patch3String = "patch-3" tests := []struct { name string input input expect expect }{ {name: "runfilterwithexclusivepatches", input: input{patches: patches, pkgUpdates: pkgUpdates, pkgToPatchesMap: pkgToPatchesMap, exclusiveIncludes: []string{"patch-3"}, excludes: []*Exclude{}, withUpdate: false}, expect: expect{patches: []string{"patch-3"}, pkgUpdates: []string{}, err: nil}, }, {name: "runFilterwithUpdatewithexcludes", // withupdate, exclude a patch that has input: input{patches: patches, pkgUpdates: pkgUpdates, pkgToPatchesMap: pkgToPatchesMap, exclusiveIncludes: []string{}, excludes: []*Exclude{CreateStringExclude(&patch3String)}, withUpdate: true}, expect: expect{patches: []string{"patch-1", "patch-2"}, pkgUpdates: []string{"pkg6"}, err: nil}, }, {name: "runFilterwithoutUpdatewithexcludes", input: input{patches: patches, pkgUpdates: pkgUpdates, pkgToPatchesMap: pkgToPatchesMap, exclusiveIncludes: []string{}, excludes: []*Exclude{CreateStringExclude(&patch3String)}, withUpdate: false}, expect: expect{patches: []string{"patch-1", "patch-2"}, pkgUpdates: []string{}, err: nil}, }, {name: "runFilterwithUpdatewithoutexcludes", input: input{patches: patches, pkgUpdates: pkgUpdates, pkgToPatchesMap: pkgToPatchesMap, exclusiveIncludes: []string{}, excludes: []*Exclude{}, withUpdate: true}, expect: expect{patches: []string{"patch-1", "patch-2", "patch-3"}, pkgUpdates: []string{"pkg6"}, err: nil}, }, {name: "runFilterwithoutUpdatewithoutexcludes", input: input{patches: patches, pkgUpdates: pkgUpdates, pkgToPatchesMap: pkgToPatchesMap, exclusiveIncludes: []string{}, excludes: []*Exclude{}, withUpdate: false}, expect: expect{patches: []string{"patch-1", "patch-2", "patch-3"}, pkgUpdates: []string{}, err: nil}, }, } for _, tc := range tests { fPatches, fpkgs, err := runFilter(tc.input.patches, tc.input.exclusiveIncludes, tc.input.excludes, tc.input.pkgUpdates, tc.input.pkgToPatchesMap, tc.input.withUpdate) if err != nil { t.Errorf("[%s] unexpected error: got(%+v)", tc.name, err) continue } if len(fPatches) != len(tc.expect.patches) { t.Errorf("[%s] unexpected number of patches: expected(%d), got(%d)", tc.name, len(tc.expect.patches), len(fPatches)) } for _, p := range fPatches { if !isIn(p.Name, tc.expect.patches) { t.Errorf("[%s] unexpected patch name: (%s)! is not in %+v", tc.name, p.Name, tc.expect.patches) } } if len(fpkgs) != len(tc.expect.pkgUpdates) { t.Errorf("[%s] unexpected number of packages: expected(%d), got(%d)", tc.name, len(tc.expect.pkgUpdates), len(fpkgs)) } for _, p := range fpkgs { if !isIn(p.Name, tc.expect.pkgUpdates) { t.Errorf("[%s] unexpected package name: (%s)! is not in %+v", tc.name, p.Name, tc.expect.pkgUpdates) } } } } func isIn(needle string, haystack []string) bool { for _, hay := range haystack { if strings.Compare(hay, needle) == 0 { return true } } return false } func prepareTestCase() ([]*packages.ZypperPatch, []*packages.PkgInfo, map[string][]string) { var patches []*packages.ZypperPatch var pkgUpdates []*packages.PkgInfo var pkgToPatchesMap map[string][]string patches = append(patches, &packages.ZypperPatch{ Name: "patch-1", Category: "recommended", Severity: "important", Summary: "patch-1", }) patches = append(patches, &packages.ZypperPatch{ Name: "patch-2", Category: "security", Severity: "critical", Summary: "patch-2", }) patches = append(patches, &packages.ZypperPatch{ Name: "patch-3", Category: "optional", Severity: "low", Summary: "patch-3", }) pkgUpdates = append(pkgUpdates, &packages.PkgInfo{ Name: "pkg1", Arch: "noarch", Version: "1.1.1", }) pkgUpdates = append(pkgUpdates, &packages.PkgInfo{ Name: "pkg2", Arch: "noarch", Version: "1.1.1", }) pkgUpdates = append(pkgUpdates, &packages.PkgInfo{ Name: "pkg3", Arch: "noarch", Version: "1.1.1", }) pkgUpdates = append(pkgUpdates, &packages.PkgInfo{ Name: "pkg4", Arch: "noarch", Version: "1.1.1", }) pkgUpdates = append(pkgUpdates, &packages.PkgInfo{ Name: "pkg5", Arch: "noarch", Version: "1.1.1", }) // individual package update that is not a part // of a patch. this package only shows up // if user specifies --with-update pkgUpdates = append(pkgUpdates, &packages.PkgInfo{ Name: "pkg6", Arch: "noarch", Version: "1.1.1", }) pkgToPatchesMap = make(map[string][]string) pkgToPatchesMap["pkg1"] = []string{"patch-1"} pkgToPatchesMap["pkg2"] = []string{"patch-1"} pkgToPatchesMap["pkg3"] = []string{"patch-2"} pkgToPatchesMap["pkg4"] = []string{"patch-2"} pkgToPatchesMap["pkg5"] = []string{"patch-3"} return patches, pkgUpdates, pkgToPatchesMap } osconfig-20250416.02/packagebuild/000077500000000000000000000000001477773331400164415ustar00rootroot00000000000000osconfig-20250416.02/packagebuild/README.md000066400000000000000000000044601477773331400177240ustar00rootroot00000000000000# Package build workflows This directory contains the 'package builder', which is a set of [Daisy] workflows and startup scripts. A package build workflow will accept a git repository set up for package building, build it and produce a system package. We use these packagebuild workflows from our Concourse pipelines and Prow jobs. [Daisy]: https://github.com/GoogleCloudPlatform/compute-daisy ## Repo layout for package building The package builder expects to check out a git repository that contains a `packaging/` directory. This directory may contain one or more of: * 1 or more RPM spec files. * A `debian/` directory, following Debian packaging standards * A `googet/` directory, containing [GooGet] specs and scripts [GooGet]: https://github.com/google/googet ## Workflow invocation Build workflows accept the following parameters: * gcs\_path - where to uploaded the resulting package, e.g. gs://my-bucket/ * repo\_owner - the repo owner, for example 'GoogleCloudPlatform' * repo\_name - the repo name, for example 'guest-agent' * git\_ref - the git ref to check out, for example 'main' * version - the version for the resulting package, for example '20221025.00' * build\_dir - (optional) the subdirectory in the repo to `cd` into before starting the build ## Supported types Each packagebuild workflow corresponds to a single package type. All builds default to the x86\_64 architecture unless otherwise specified. ### Debian Debian workflows launch an instance of the specified Debian release and produce .deb packages. Available workflows: * build\_deb10.wf.json * build\_deb11.wf.json * build\_deb12.wf.json An ARM64 workflow is also included: * build\_deb11\_arm64.wf.json ### Enterprise Linux EL (Enterprise Linux) workflows launch an instance of a predefined EL type and produce .rpm packages. The workflows use the OS that was best suited at the time of development. Available workflows: * build\_el6.wf.json - uses CentOS 6 * build\_el7.wf.json - uses CentOS 7 * build\_el8.wf.json - uses RHEL 8 * build\_el9.wf.json - uses CentOS Stream 9 ARM64 workflows are also included: * build\_el8\_arm64.wf.json - uses the GCP optimized version of Rocky Linux 8 * build\_el9\_arm64.wf.json - uses RHEL 9 ### GooGet The `build_goo.wf.json` (GooGet) workflow launches a Debian 10 instance and produces .goo packages. osconfig-20250416.02/packagebuild/common.sh000066400000000000000000000042161477773331400202700ustar00rootroot00000000000000#!/bin/bash # Copyright 2019 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. function build_success() { echo "Build succeeded: $@" exit 0 } function build_fail() { echo "Build failed: $@" exit 1 } function exit_error() { build_fail "$0:$1 \"$BASH_COMMAND\" returned $?" } trap 'exit_error $LINENO' ERR function install_go() { # Installs a specific version of go for compilation, since availability varies # across linux distributions. Needs curl and tar to be installed. local arch="amd64" if [[ `uname -m` == "aarch64" ]]; then arch="arm64" fi local GOLANG="go1.22.2.linux-${arch}.tar.gz" export GOPATH=/usr/share/gocode export GOCACHE=/tmp/.cache # Golang setup [[ -d /tmp/go ]] && rm -rf /tmp/go mkdir -p /tmp/go/ curl -s "https://dl.google.com/go/${GOLANG}" -o /tmp/go/go.tar.gz tar -C /tmp/go/ --strip-components=1 -xf /tmp/go/go.tar.gz export PATH="/tmp/go/bin:${GOPATH}/bin:${PATH}" # set path for whoever invokes this function. export GO=/tmp/go/bin/go # reference this go explicitly. } function git_checkout() { # Checks out a repo at a specified commit or ref into a specified directory. BASE_REPO="$1" REPO="$2" PULL_REF="$3" # pull the repository from github - start mkdir -p $REPO cd $REPO git init # fetch only the branch that we want to build git_command="git fetch https://github.com/${BASE_REPO}/${REPO}.git ${PULL_REF:-"master"}" echo "Running ${git_command}" $git_command git checkout FETCH_HEAD } function try_command() { n=0 while ! "$@"; do echo "try $n to run $@" if [[ n -gt 3 ]]; then return 1 fi ((n++)) sleep 5 done } osconfig-20250416.02/packagebuild/daisy_startupscript_deb.sh000066400000000000000000000067671477773331400237470ustar00rootroot00000000000000#!/bin/bash # Copyright 2019 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. URL="http://169.254.169.254/computeMetadata/v1/instance/attributes" GCS_PATH=$(curl -f -H Metadata-Flavor:Google ${URL}/daisy-outs-path) SRC_PATH=$(curl -f -H Metadata-Flavor:Google ${URL}/daisy-sources-path) REPO_OWNER=$(curl -f -H Metadata-Flavor:Google ${URL}/repo-owner) REPO_NAME=$(curl -f -H Metadata-Flavor:Google ${URL}/repo-name) GIT_REF=$(curl -f -H Metadata-Flavor:Google ${URL}/git-ref) BUILD_DIR=$(curl -f -H Metadata-Flavor:Google ${URL}/build-dir) VERSION=$(curl -f -H Metadata-Flavor:Google ${URL}/version) VERSION=${VERSION:="1dummy"} DEBIAN_FRONTEND=noninteractive echo "Started build..." gsutil cp "${SRC_PATH}/common.sh" ./ . common.sh # disable the backports repo for debian-10 sed -i 's/^.*debian buster-backports main.*$//g' /etc/apt/sources.list try_command apt-get -y update try_command apt-get install -y --no-install-{suggests,recommends} git-core \ debhelper devscripts build-essential equivs libdistro-info-perl git_checkout "$REPO_OWNER" "$REPO_NAME" "$GIT_REF" if [[ -n "$BUILD_DIR" ]]; then cd "$BUILD_DIR" fi PKGNAME="$(grep "^Package:" ./packaging/debian/control|cut -d' ' -f2-)" # Install build deps mk-build-deps -t "apt-get -o Debug::pkgProblemResolver=yes \ --no-install-recommends --yes" --install packaging/debian/control dpkg-checkbuilddeps packaging/debian/control if grep -q '+deb' packaging/debian/changelog; then DEB=$(/dev/null; then echo "Installing go dependencies" $GO mod download fi echo "Building package(s)" for spec in packaging/googet/*.goospec; do goopack -var:version="$VERSION" "$spec" name=$(basename "${spec}") pref=${name%.*} done gsutil cp -n *.goo "$GCS_PATH/" build_success "Built `ls *.goo|xargs`" osconfig-20250416.02/packagebuild/daisy_startupscript_rpm.sh000066400000000000000000000106061477773331400237760ustar00rootroot00000000000000#!/bin/bash # Copyright 2019 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # This script is expected to be run on an Enterprise Linux system (RHEL, CentOS) # on GCE with various flags set in the instance metadata including the git # repository to clone. The script produces an RPM defined by an RPM spec in the # packaging/ directory from the cloned repo. URL="http://metadata/computeMetadata/v1/instance/attributes" function get_md() { curl -f -H Metadata-Flavor:Google "${URL}/${1}" } GCS_PATH=$(get_md daisy-outs-path) SRC_PATH=$(get_md daisy-sources-path) REPO_OWNER=$(get_md repo-owner) REPO_NAME=$(get_md repo-name) GIT_REF=$(get_md git-ref) BUILD_DIR=$(get_md build-dir) VERSION=$(get_md version) VERSION=${VERSION:-"dummy"} echo "Started build..." # common.sh contains functions common to all builds. gsutil cp "${SRC_PATH}/common.sh" ./ . common.sh # Install git2 as this is not available in centos 6/7 VERSION_ID=6 if [[ -f /etc/os-release ]]; then eval $(grep VERSION_ID /etc/os-release) VERSION_ID=${VERSION_ID:0:1} fi GIT="git" if [[ ${VERSION_ID} =~ 6|7 ]]; then try_command yum install -y "https://repo.ius.io/ius-release-el${VERSION_ID}.rpm" rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-IUS-${VERSION_ID} GIT="git236" fi # Install DevToolSet with gcc 10 for EL7. # Centos 7 has only gcc 4.8.5 available. if (( ${VERSION_ID} == 7 )); then try_command yum install -y centos-release-scl try_command yum install -y devtoolset-10-gcc-c++.x86_64 fi # Enable CRB repo on EL9. if [[ ${VERSION_ID} = 9 ]]; then eval $(grep ID /etc/os-release) # RHEL has a different CRB repo than Rocky/CentOS. if [[ ${ID} == "rhel" ]]; then dnf config-manager --set-enabled rhui-codeready-builder-for-rhel-9-$(uname -m)-rhui-rpms else dnf config-manager --set-enabled crb fi fi try_command yum install -y $GIT rpmdevtools yum-utils python3-devel git_checkout "$REPO_OWNER" "$REPO_NAME" "$GIT_REF" if [[ -n "$BUILD_DIR" ]]; then cd "$BUILD_DIR" fi if grep -q '%{_go}' ./packaging/*.spec; then echo "Installing go" install_go echo "Installing go dependencies" $GO mod download fi # Make build dirs as needed. RPMDIR=/usr/src/redhat for dir in ${RPMDIR}/{SOURCES,SPECS}; do [[ -d "$dir" ]] || mkdir -p "$dir" done # Find the RPM specs to build for this version. TOBUILD="" SPECS=$(ls ./packaging/*.spec | sed -re 's/(\.el.)?.spec//' | sort -ru) echo "all specs $SPECS" for spec in $SPECS; do spec=$(basename "$spec") distspec="${spec}.el${VERSION_ID}.spec" echo checking $spec and $distspec if [[ -f "./packaging/$distspec" ]]; then TOBUILD="${TOBUILD} ${distspec}" else TOBUILD="${TOBUILD} ${spec}.spec" fi done [[ -z "$TOBUILD" ]] && build_fail "No RPM specs found" COMMITURL="https://github.com/$REPO_OWNER/$REPO_NAME/tree/$(git rev-parse HEAD)" echo "Building package(s)" # Enable gcc 10 for EL7 only and before rpmbuild if (( ${VERSION_ID} == 7 )); then source /opt/rh/devtoolset-10/enable fi for spec in $TOBUILD; do PKGNAME="$(grep Name: "./packaging/${spec}"|cut -d' ' -f2-|tr -d ' ')" yum-builddep -y "./packaging/${spec}" cp "./packaging/${spec}" "${RPMDIR}/SPECS/" cp ./packaging/*.tar.gz "${RPMDIR}/SOURCES/" || : cp ./packaging/*.patch "${RPMDIR}/SOURCES/" || : sed -i"" "/^Version/aVcs: ${COMMITURL}" "${RPMDIR}/SPECS/${spec}" tar czvf "${RPMDIR}/SOURCES/${PKGNAME}_${VERSION}.orig.tar.gz" \ --exclude .git --exclude packaging \ --transform "s/^\./${PKGNAME}-${VERSION}/" . rpmbuild --define "_topdir ${RPMDIR}/" --define "_version ${VERSION}" \ --define "_go ${GO:-"UNSET"}" --define "_gopath ${GOPATH:-"UNSET"}" \ -ba "${RPMDIR}/SPECS/${spec}" SRPM_FILE=$(find ${RPMDIR}/SRPMS -iname "${PKGNAME}*.src.rpm") done rpms=$(find ${RPMDIR}/{S,}RPMS -iname "${PKGNAME}*.rpm") for rpm in $rpms; do rpm -qpilR $rpm done echo "copying ${rpms} to $GCS_PATH/" gsutil cp -n ${rpms} "$GCS_PATH/" build_success "Built $(echo ${rpms}|xargs)" osconfig-20250416.02/packagebuild/test_build.sh000077500000000000000000000045141477773331400211420ustar00rootroot00000000000000#!/bin/bash # # Produce a single package build with a custom version. # # - Package TYPEs can be found in the 'workflows/' directory as # a filename pattern build_{{type}}.wf.json # - Package Version should start with a digit # # Example (requires daisy tool somewhere in the PATH): # build rpm package for el9 like distributions and version 0.0.1 for # the last commit in the 'trustca-sync' branch of vorakl/guest-oslogin # fork on Github and save results to gs://vorakl-dev-builds/packages/ bucket. # # env TYPE=el9 \ # PROJECT=vorakl-dev \ # ZONE=us-west1-a \ # OWNER=vorakl \ # REPO=guest-oslogin \ # GIT_REF=trustca-sync \ # GCS_PATH=gs://vorakl-dev-builds/packages \ # VERSION=0.01 \ # BUILD_DIR=. \ # ./test_build.sh DEFAULT_TYPE='deb11' DEFAULT_PROJECT='gcp-guest' DEFAULT_ZONE='us-west1-a' DEFAULT_OWNER='GoogleCloudPlatform' DEFAULT_GIT_REF='master' DEFAULT_GCS_PATH='${SCRATCHPATH}/packages' DEFAULT_BUILD_DIR='.' DEFAULT_VERSION='1dummy' [[ -z "${TYPE}" ]] && read -p "Build type [${DEFAULT_TYPE}]: " TYPE [[ -z "${PROJECT}" ]] && read -p "Build project [${DEFAULT_PROJECT}]: " PROJECT [[ -z "${ZONE}" ]] && read -p "Build zone [${DEFAULT_ZONE}]: " ZONE [[ -z "${OWNER}" ]] && read -p "Repo owner or org [${DEFAULT_OWNER}]: " OWNER [[ -z "${GIT_REF}" ]] && read -p "Ref [${DEFAULT_GIT_REF}]: " GIT_REF [[ -z "${GCS_PATH}" ]] && read -p "GCS Path to upload to [${DEFAULT_GCS_PATH}]: " GCS_PATH [[ -z "${BUILD_DIR}" ]] && read -p "Directory to build from [${DEFAULT_BUILD_DIR}]: " BUILD_DIR [[ -z "${REPO}" ]] && read -p "Repo name: " REPO [[ -z "${TYPE}" ]] && TYPE=${DEFAULT_TYPE} [[ -z "${PROJECT}" ]] && PROJECT=${DEFAULT_PROJECT} [[ -z "${ZONE}" ]] && ZONE=${DEFAULT_ZONE} [[ -z "${OWNER}" ]] && OWNER=${DEFAULT_OWNER} [[ -z "${GIT_REF}" ]] && GIT_REF=${DEFAULT_GIT_REF} [[ -z "${GCS_PATH}" ]] && GCS_PATH=${DEFAULT_GCS_PATH} [[ -z "${BUILD_DIR}" ]] && BUILD_DIR=${DEFAULT_BUILD_DIR} [[ -z "${VERSION}" ]] && VERSION=${DEFAULT_VERSION} WF="workflows/build_${TYPE}.wf.json" if [[ ! -f "${WF}" ]]; then echo "Unknown build type ${TYPE}" exit 1 fi set -x daisy \ -project ${PROJECT} \ -zone ${ZONE} \ -var:gcs_path=${GCS_PATH} \ -var:repo_owner=${OWNER} \ -var:repo_name=${REPO} \ -var:git_ref=${GIT_REF} \ -var:build_dir=${BUILD_DIR} \ -var:version=${VERSION} \ "${WF}" osconfig-20250416.02/packagebuild/workflows/000077500000000000000000000000001477773331400204765ustar00rootroot00000000000000osconfig-20250416.02/packagebuild/workflows/build_deb10.wf.json000066400000000000000000000015241477773331400240600ustar00rootroot00000000000000{ "Name": "deb10", "Timeout": "20m", "Vars": { "gcs_path": { "Required": true }, "repo_owner": { "Required": true }, "repo_name": { "Required": true }, "git_ref": { "Required": true }, "version": { "Required": true }, "build_dir": { "Required": true } }, "Steps": { "build-package": { "Timeout": "20m", "SubWorkflow": { "Path": "./build_package.wf.json", "Vars": { "type": "deb", "sourceImage": "projects/debian-cloud/global/images/family/debian-10", "gcs_path": "${gcs_path}", "repo_owner": "${repo_owner}", "repo_name": "${repo_name}", "git_ref": "${git_ref}", "build_dir": "${build_dir}", "version": "${version}" } } } } } osconfig-20250416.02/packagebuild/workflows/build_deb11.wf.json000066400000000000000000000015241477773331400240610ustar00rootroot00000000000000{ "Name": "deb11", "Timeout": "20m", "Vars": { "gcs_path": { "Required": true }, "repo_owner": { "Required": true }, "repo_name": { "Required": true }, "git_ref": { "Required": true }, "version": { "Required": true }, "build_dir": { "Required": true } }, "Steps": { "build-package": { "Timeout": "20m", "SubWorkflow": { "Path": "./build_package.wf.json", "Vars": { "type": "deb", "sourceImage": "projects/debian-cloud/global/images/family/debian-11", "gcs_path": "${gcs_path}", "repo_owner": "${repo_owner}", "repo_name": "${repo_name}", "git_ref": "${git_ref}", "build_dir": "${build_dir}", "version": "${version}" } } } } } osconfig-20250416.02/packagebuild/workflows/build_deb12.wf.json000066400000000000000000000015241477773331400240620ustar00rootroot00000000000000{ "Name": "deb12", "Timeout": "20m", "Vars": { "gcs_path": { "Required": true }, "repo_owner": { "Required": true }, "repo_name": { "Required": true }, "git_ref": { "Required": true }, "version": { "Required": true }, "build_dir": { "Required": true } }, "Steps": { "build-package": { "Timeout": "20m", "SubWorkflow": { "Path": "./build_package.wf.json", "Vars": { "type": "deb", "sourceImage": "projects/debian-cloud/global/images/family/debian-12", "gcs_path": "${gcs_path}", "repo_owner": "${repo_owner}", "repo_name": "${repo_name}", "git_ref": "${git_ref}", "build_dir": "${build_dir}", "version": "${version}" } } } } } osconfig-20250416.02/packagebuild/workflows/build_deb12_arm64.wf.json000066400000000000000000000016511477773331400250740ustar00rootroot00000000000000{ "Name": "deb12", "Timeout": "20m", "Vars": { "gcs_path": { "Required": true }, "repo_owner": { "Required": true }, "repo_name": { "Required": true }, "git_ref": { "Required": true }, "version": { "Required": true }, "build_dir": { "Required": true } }, "Steps": { "build-package": { "Timeout": "20m", "SubWorkflow": { "Path": "./build_package.wf.json", "Vars": { "type": "deb", "sourceImage": "projects/debian-cloud/global/images/family/debian-12-arm64", "gcs_path": "${gcs_path}", "repo_owner": "${repo_owner}", "repo_name": "${repo_name}", "git_ref": "${git_ref}", "build_dir": "${build_dir}", "machine_type": "t2a-standard-2", "zone": "us-central1-a", "version": "${version}" } } } } } osconfig-20250416.02/packagebuild/workflows/build_el6.wf.json000066400000000000000000000015211477773331400236500ustar00rootroot00000000000000{ "Name": "el6", "Timeout": "20m", "Vars": { "gcs_path": { "Required": true }, "repo_owner": { "Required": true }, "repo_name": { "Required": true }, "git_ref": { "Required": true }, "version": { "Required": true }, "build_dir": { "Required": true } }, "Steps": { "build-package": { "Timeout": "20m", "SubWorkflow": { "Path": "./build_package.wf.json", "Vars": { "type": "rpm", "sourceImage": "projects/centos-cloud/global/images/family/centos-6", "gcs_path": "${gcs_path}", "repo_owner": "${repo_owner}", "repo_name": "${repo_name}", "git_ref": "${git_ref}", "build_dir": "${build_dir}", "version": "${version}" } } } } } osconfig-20250416.02/packagebuild/workflows/build_el7.wf.json000066400000000000000000000015211477773331400236510ustar00rootroot00000000000000{ "Name": "el7", "Timeout": "20m", "Vars": { "gcs_path": { "Required": true }, "repo_owner": { "Required": true }, "repo_name": { "Required": true }, "git_ref": { "Required": true }, "version": { "Required": true }, "build_dir": { "Required": true } }, "Steps": { "build-package": { "Timeout": "20m", "SubWorkflow": { "Path": "./build_package.wf.json", "Vars": { "type": "rpm", "sourceImage": "projects/centos-cloud/global/images/family/centos-7", "gcs_path": "${gcs_path}", "repo_owner": "${repo_owner}", "repo_name": "${repo_name}", "git_ref": "${git_ref}", "build_dir": "${build_dir}", "version": "${version}" } } } } } osconfig-20250416.02/packagebuild/workflows/build_el8.wf.json000066400000000000000000000015151477773331400236550ustar00rootroot00000000000000{ "Name": "el8", "Timeout": "20m", "Vars": { "gcs_path": { "Required": true }, "repo_owner": { "Required": true }, "repo_name": { "Required": true }, "git_ref": { "Required": true }, "version": { "Required": true }, "build_dir": { "Required": true } }, "Steps": { "build-package": { "Timeout": "20m", "SubWorkflow": { "Path": "./build_package.wf.json", "Vars": { "type": "rpm", "sourceImage": "projects/rhel-cloud/global/images/family/rhel-8", "gcs_path": "${gcs_path}", "repo_owner": "${repo_owner}", "repo_name": "${repo_name}", "git_ref": "${git_ref}", "build_dir": "${build_dir}", "version": "${version}" } } } } } osconfig-20250416.02/packagebuild/workflows/build_el8_arm64.wf.json000066400000000000000000000016761477773331400246760ustar00rootroot00000000000000{ "Name": "el8", "Timeout": "20m", "Vars": { "gcs_path": { "Required": true }, "repo_owner": { "Required": true }, "repo_name": { "Required": true }, "git_ref": { "Required": true }, "version": { "Required": true }, "build_dir": { "Required": true } }, "Steps": { "build-package": { "Timeout": "20m", "SubWorkflow": { "Path": "./build_package.wf.json", "Vars": { "type": "rpm", "sourceImage": "projects/rocky-linux-cloud/global/images/family/rocky-linux-8-optimized-gcp-arm64", "gcs_path": "${gcs_path}", "repo_owner": "${repo_owner}", "repo_name": "${repo_name}", "git_ref": "${git_ref}", "build_dir": "${build_dir}", "machine_type": "t2a-standard-2", "zone": "us-central1-a", "version": "${version}" } } } } } osconfig-20250416.02/packagebuild/workflows/build_el9.wf.json000066400000000000000000000015151477773331400236560ustar00rootroot00000000000000{ "Name": "el9", "Timeout": "40m", "Vars": { "gcs_path": { "Required": true }, "repo_owner": { "Required": true }, "repo_name": { "Required": true }, "git_ref": { "Required": true }, "version": { "Required": true }, "build_dir": { "Required": true } }, "Steps": { "build-package": { "Timeout": "40m", "SubWorkflow": { "Path": "./build_package.wf.json", "Vars": { "type": "rpm", "sourceImage": "projects/rhel-cloud/global/images/family/rhel-9", "gcs_path": "${gcs_path}", "repo_owner": "${repo_owner}", "repo_name": "${repo_name}", "git_ref": "${git_ref}", "build_dir": "${build_dir}", "version": "${version}" } } } } } osconfig-20250416.02/packagebuild/workflows/build_el9_arm64.wf.json000066400000000000000000000016421477773331400246700ustar00rootroot00000000000000{ "Name": "el9", "Timeout": "20m", "Vars": { "gcs_path": { "Required": true }, "repo_owner": { "Required": true }, "repo_name": { "Required": true }, "git_ref": { "Required": true }, "version": { "Required": true }, "build_dir": { "Required": true } }, "Steps": { "build-package": { "Timeout": "20m", "SubWorkflow": { "Path": "./build_package.wf.json", "Vars": { "type": "rpm", "sourceImage": "projects/rhel-cloud/global/images/family/rhel-9-arm64", "gcs_path": "${gcs_path}", "repo_owner": "${repo_owner}", "repo_name": "${repo_name}", "git_ref": "${git_ref}", "build_dir": "${build_dir}", "machine_type": "t2a-standard-2", "zone": "us-central1-a", "version": "${version}" } } } } } osconfig-20250416.02/packagebuild/workflows/build_goo.wf.json000066400000000000000000000014461477773331400237540ustar00rootroot00000000000000{ "Name": "goo", "Vars": { "gcs_path": { "Required": true }, "repo_owner": { "Required": true }, "repo_name": { "Required": true }, "git_ref": { "Required": true }, "version": { "Required": true }, "build_dir": { "Required": true } }, "Steps": { "build-package": { "SubWorkflow": { "Path": "./build_package.wf.json", "Vars": { "type": "goo", "sourceImage": "projects/debian-cloud/global/images/family/debian-11", "gcs_path": "${gcs_path}", "repo_owner": "${repo_owner}", "repo_name": "${repo_name}", "git_ref": "${git_ref}", "build_dir": "${build_dir}", "version": "${version}" } } } } } osconfig-20250416.02/packagebuild/workflows/build_package.wf.json000066400000000000000000000042551477773331400245640ustar00rootroot00000000000000{ "Name": "build-package", "DefaultTimeout": "30m", "Sources": { "startup.sh": "../daisy_startupscript_${type}.sh", "common.sh": "../common.sh" }, "Vars": { "type": { "Description": "Type of workflow: rpm,deb, or goo", "Required": true }, "sourceImage": { "Description": "Source image to use for instance", "Required": true }, "gcs_path": { "Required": true }, "repo_owner": { "Required": true }, "repo_name": { "Required": true }, "git_ref": { "Required": true }, "version": { "Required": true }, "build_dir": { "Required": true }, "machine_type": { "Value": "e2-standard-2", "Description": "machine type" }, "zone": { "Value": "us-central1-a", "Description": "zone" } }, "Steps": { "build-packages": { "CreateInstances": [ { "disks": [ { "initializeParams": { "diskType": "pd-ssd", "sourceImage": "${sourceImage}" } } ], "Metadata": { "repo-owner": "${repo_owner}", "repo-name": "${repo_name}", "git-ref": "${git_ref}", "build-dir": "${build_dir}", "version": "${version}" }, "machineType": "${machine_type}", "zone": "${zone}", "name": "inst-build-pkg", "StartupScript": "startup.sh", "Scopes": ["https://www.googleapis.com/auth/devstorage.read_write"] } ] }, "wait-for-build": { "Timeout": "30m", "WaitForInstancesSignal": [ { "Name": "inst-build-pkg", "SerialOutput": { "Port": 1, "SuccessMatch": "Build succeeded", "FailureMatch": "Build failed" } } ] }, "copy-packages": { "CopyGCSObjects": [ { "Source": "${OUTSPATH}/", "Destination": "${gcs_path}/" } ] } }, "Dependencies": { "wait-for-build": [ "build-packages" ], "copy-packages": [ "wait-for-build" ] } } osconfig-20250416.02/packages/000077500000000000000000000000001477773331400156045ustar00rootroot00000000000000osconfig-20250416.02/packages/apt_deb.go000066400000000000000000000315211477773331400175330ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package packages import ( "bytes" "context" "encoding/json" "fmt" "os" "os/exec" "runtime" "strings" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/osinfo" "github.com/GoogleCloudPlatform/osconfig/util" ) var ( dpkg string dpkgQuery string dpkgDeb string aptGet string dpkgInstallArgs = []string{"--install"} dpkgPackageFieldsMapping = map[string]string{ "package": "${Package}", "architecture": "${Architecture}", "version": "${Version}", "status": "${db:Status-Status}", "source_name": "${source:Package}", "source_version": "${source:Version}", } dpkgQueryArgs = []string{"-W", "-f", formatFieldsMappingToFormattingString(dpkgPackageFieldsMapping)} dpkgRepairArgs = []string{"--configure", "-a"} aptGetInstallArgs = []string{"install", "-y"} aptGetRemoveArgs = []string{"remove", "-y"} aptGetUpdateArgs = []string{"update"} aptGetUpgradeCmd = "upgrade" aptGetFullUpgradeCmd = "full-upgrade" aptGetDistUpgradeCmd = "dist-upgrade" aptGetUpgradableArgs = []string{"--just-print", "-qq"} allowDowngradesArg = "--allow-downgrades" dpkgErr = []byte("dpkg --configure -a") ) func init() { if runtime.GOOS != "windows" { dpkg = "/usr/bin/dpkg" dpkgQuery = "/usr/bin/dpkg-query" dpkgDeb = "/usr/bin/dpkg-deb" aptGet = "/usr/bin/apt-get" } AptExists = util.Exists(aptGet) DpkgExists = util.Exists(dpkg) DpkgQueryExists = util.Exists(dpkgQuery) } // AptUpgradeType is the apt upgrade type. type AptUpgradeType int const ( // AptGetUpgrade specifies apt-get upgrade should be run. AptGetUpgrade AptUpgradeType = iota // AptGetDistUpgrade specifies apt-get dist-upgrade should be run. AptGetDistUpgrade // AptGetFullUpgrade specifies apt-get full-upgrade should be run. AptGetFullUpgrade ) type aptGetUpgradeOpts struct { upgradeType AptUpgradeType showNew bool allowDowngrades bool } // AptGetUpgradeOption is an option for apt-get upgrade. type AptGetUpgradeOption func(*aptGetUpgradeOpts) // AptGetUpgradeType returns a AptGetUpgradeOption that specifies upgrade type. func AptGetUpgradeType(upgradeType AptUpgradeType) AptGetUpgradeOption { return func(args *aptGetUpgradeOpts) { args.upgradeType = upgradeType } } // AptGetUpgradeShowNew returns a AptGetUpgradeOption that indicates whether 'new' packages should be returned. func AptGetUpgradeShowNew(showNew bool) AptGetUpgradeOption { return func(args *aptGetUpgradeOpts) { args.showNew = showNew } } // AptGetUpgradeAllowDowngrades returns a AptGetUpgradeOption that specifies AllowDowngrades. func AptGetUpgradeAllowDowngrades(allowDowngrades bool) AptGetUpgradeOption { return func(args *aptGetUpgradeOpts) { args.allowDowngrades = allowDowngrades } } func dpkgRepair(ctx context.Context, out []byte) bool { // Error code 100 may occur for non repairable errors, just check the output. if !bytes.Contains(out, dpkgErr) { return false } clog.Debugf(ctx, "apt-get error, attempting dpkg repair.") // Ignore error here, just log and rerun apt-get. run(ctx, dpkg, dpkgRepairArgs) return true } type cmdModifier func(*exec.Cmd) func runAptGet(ctx context.Context, args []string, cmdModifiers []cmdModifier) ([]byte, []byte, error) { cmd := exec.CommandContext(ctx, aptGet, args...) for _, modifier := range cmdModifiers { modifier(cmd) } return runner.Run(ctx, cmd) } func runAptGetWithDowngradeRetrial(ctx context.Context, args []string, cmdModifiers []cmdModifier) ([]byte, []byte, error) { stdout, stderr, err := runAptGet(ctx, args, cmdModifiers) if err != nil { if strings.Contains(string(stderr), "E: Packages were downgraded and -y was used without --allow-downgrades.") { cmdModifiers = append(cmdModifiers, func(cmd *exec.Cmd) { cmd.Args = append(cmd.Args, allowDowngradesArg) }) stdout, stderr, err = runAptGet(ctx, args, cmdModifiers) } } return stdout, stderr, err } func parseDpkgDeb(data []byte) (*PkgInfo, error) { /* new Debian package, version 2.0. size 6731954 bytes: control archive=2138 bytes. 498 bytes, 12 lines control 3465 bytes, 31 lines md5sums 2793 bytes, 65 lines * postinst #!/bin/sh 938 bytes, 28 lines * postrm #!/bin/sh 216 bytes, 7 lines * prerm #!/bin/sh Package: google-guest-agent Version: 1:1dummy-g1 Architecture: amd64 Maintainer: Google Cloud Team Installed-Size: 23279 Depends: init-system-helpers (>= 1.18~) Conflicts: python-google-compute-engine, python3-google-compute-engine Section: misc Priority: optional Description: Google Compute Engine Guest Agent Contains the guest agent and metadata script runner binaries. Git: https://github.com/GoogleCloudPlatform/guest-agent/tree/c3d526e650c4e45ae3258c07836fd72f85fd9fc8 */ lines := bytes.Split(bytes.TrimSpace(data), []byte("\n")) info := &PkgInfo{} for _, ln := range lines { if info.Name != "" && info.Version != "" && info.Arch != "" { break } fields := bytes.Fields(ln) if len(fields) != 2 { continue } if bytes.Contains(fields[0], []byte("Package:")) { // Some packages do not adhere to the Debian Policy and might have mix-cased names // And dpkg will register the package with lower case anyway so use lower-case package name // This is necessary because the compliance check is done between the .deb file descriptor value // and the internal dpkg db which register a lower-cased package name info.Name = strings.ToLower(string(fields[1])) continue } if bytes.Contains(fields[0], []byte("Version:")) { info.Version = string(fields[1]) continue } if bytes.Contains(fields[0], []byte("Architecture:")) { info.Arch = osinfo.NormalizeArchitecture(string(fields[1])) continue } } if info.Name == "" || info.Version == "" || info.Arch == "" { return nil, fmt.Errorf("could not parse dpkg-deb output: %q", data) } return info, nil } // DebPkgInfo gets PkgInfo from a deb package. func DebPkgInfo(ctx context.Context, path string) (*PkgInfo, error) { out, err := run(ctx, dpkgDeb, []string{"-I", path}) if err != nil { return nil, err } return parseDpkgDeb(out) } // InstallAptPackages installs apt packages. func InstallAptPackages(ctx context.Context, pkgs []string) error { args := append(aptGetInstallArgs, pkgs...) cmdModifiers := []cmdModifier{ func(cmd *exec.Cmd) { cmd.Env = append(os.Environ(), "DEBIAN_FRONTEND=noninteractive") }, } stdout, stderr, err := runAptGetWithDowngradeRetrial(ctx, args, cmdModifiers) if err != nil { if dpkgRepair(ctx, stderr) { stdout, stderr, err = runAptGetWithDowngradeRetrial(ctx, args, cmdModifiers) } } if err != nil { err = fmt.Errorf("error running %s with args %q: %v, stdout: %q, stderr: %q", aptGet, args, err, stdout, stderr) } return err } // RemoveAptPackages removes apt packages. func RemoveAptPackages(ctx context.Context, pkgs []string) error { args := append(aptGetRemoveArgs, pkgs...) cmdModifiers := []cmdModifier{ func(cmd *exec.Cmd) { cmd.Env = append(os.Environ(), "DEBIAN_FRONTEND=noninteractive") }, } stdout, stderr, err := runAptGet(ctx, args, cmdModifiers) if err != nil { if dpkgRepair(ctx, stderr) { stdout, stderr, err = runAptGet(ctx, args, cmdModifiers) } } if err != nil { err = fmt.Errorf("error running %s with args %q: %v, stdout: %q, stderr: %q", aptGet, args, err, stdout, stderr) } return err } func parseAptUpdates(ctx context.Context, data []byte, showNew bool) []*PkgInfo { /* Inst libldap-common [2.4.45+dfsg-1ubuntu1.2] (2.4.45+dfsg-1ubuntu1.3 Ubuntu:18.04/bionic-updates, Ubuntu:18.04/bionic-security [all]) Inst firmware-linux-free (3.4 Debian:9.9/stable [all]) [] Inst google-cloud-sdk [245.0.0-0] (246.0.0-0 cloud-sdk-stretch:cloud-sdk-stretch [all]) Inst linux-image-4.9.0-9-amd64 (4.9.168-1+deb9u2 Debian-Security:9/stable [amd64]) Inst linux-image-amd64 [4.9+80+deb9u6] (4.9+80+deb9u7 Debian:9.9/stable [amd64]) Conf firmware-linux-free (3.4 Debian:9.9/stable [all]) Conf google-cloud-sdk (246.0.0-0 cloud-sdk-stretch:cloud-sdk-stretch [all]) Conf linux-image-4.9.0-9-amd64 (4.9.168-1+deb9u2 Debian-Security:9/stable [amd64]) Conf linux-image-amd64 (4.9+80+deb9u7 Debian:9.9/stable [amd64]) */ lines := bytes.Split(bytes.TrimSpace(data), []byte("\n")) var pkgs []*PkgInfo for _, ln := range lines { pkg := bytes.Fields(ln) if len(pkg) < 5 || string(pkg[0]) != "Inst" { continue } // Inst google-cloud-sdk [245.0.0-0] (246.0.0-0 cloud-sdk-stretch:cloud-sdk-stretch [all]) pkg = pkg[1:] // ==> google-cloud-sdk [245.0.0-0] (246.0.0-0 cloud-sdk-stretch:cloud-sdk-stretch [all]) if bytes.HasPrefix(pkg[1], []byte("[")) { pkg = append(pkg[:1], pkg[2:]...) // ==> google-cloud-sdk (246.0.0-0 cloud-sdk-stretch:cloud-sdk-stretch [all]) } else if !showNew { // This is a newly installed package and not an upgrade, ignore if showNew is false. continue } // Drop trailing "[]" if they exist. if bytes.Contains(pkg[len(pkg)-1], []byte("[]")) { pkg = pkg[:len(pkg)-1] } if !bytes.HasPrefix(pkg[1], []byte("(")) || !bytes.HasSuffix(pkg[len(pkg)-1], []byte(")")) { continue } ver := bytes.Trim(pkg[1], "(") // (246.0.0-0 => 246.0.0-0 arch := bytes.Trim(pkg[len(pkg)-1], "[])") // [all]) => all pkgs = append(pkgs, &PkgInfo{Name: string(pkg[0]), Arch: osinfo.NormalizeArchitecture(string(arch)), Version: string(ver)}) } return pkgs } // AptUpdates returns all the packages that will be installed when running // apt-get [dist-|full-]upgrade. func AptUpdates(ctx context.Context, opts ...AptGetUpgradeOption) ([]*PkgInfo, error) { aptOpts := &aptGetUpgradeOpts{ upgradeType: AptGetUpgrade, showNew: false, allowDowngrades: false, } for _, opt := range opts { opt(aptOpts) } args := aptGetUpgradableArgs switch aptOpts.upgradeType { case AptGetUpgrade: args = append(aptGetUpgradableArgs, aptGetUpgradeCmd) case AptGetDistUpgrade: args = append(aptGetUpgradableArgs, aptGetDistUpgradeCmd) case AptGetFullUpgrade: args = append(aptGetUpgradableArgs, aptGetFullUpgradeCmd) default: return nil, fmt.Errorf("unknown upgrade type: %q", aptOpts.upgradeType) } if _, err := AptUpdate(ctx); err != nil { return nil, err } out, _, err := runAptGetWithDowngradeRetrial(ctx, args, []cmdModifier{ func(cmd *exec.Cmd) { cmd.Env = append(os.Environ(), "DEBIAN_FRONTEND=noninteractive") }, }) if err != nil { return nil, err } return parseAptUpdates(ctx, out, aptOpts.showNew), nil } // AptUpdate runs apt-get update. func AptUpdate(ctx context.Context) ([]byte, error) { stdout, _, err := runAptGet(ctx, aptGetUpdateArgs, []cmdModifier{ func(cmd *exec.Cmd) { cmd.Env = append(os.Environ(), "DEBIAN_FRONTEND=noninteractive") }, }) return stdout, err } // InstalledDebPackages queries for all installed deb packages. func InstalledDebPackages(ctx context.Context) ([]*PkgInfo, error) { out, err := run(ctx, dpkgQuery, dpkgQueryArgs) if err != nil { return nil, err } return parseInstalledDebPackages(ctx, out), nil } func parseInstalledDebPackages(ctx context.Context, data []byte) []*PkgInfo { /* Each line contains an entry in a json format, keep in mind that whole output is not valid json. {"package":"adduser","architecture":"all","version":"3.118ubuntu2","status":"installed","source_name":"adduser","source_version":"3.118ubuntu2"} {"package":"apt-utils","architecture":"amd64","version":"2.0.10","status":"installed","source_name":"apt","source_version":"2.0.10"} {"package":"git","architecture":"amd64","version":"1:2.25.1-1ubuntu3.12","status":"installed","source_name":"git","source_version":"1:2.25.1-1ubuntu3.12"} ... */ entries := bytes.Split(bytes.TrimSpace(data), []byte("\n")) var result []*PkgInfo for _, entry := range entries { var dpkg packageMetadata if err := json.Unmarshal(entry, &dpkg); err != nil { clog.Debugf(ctx, "unable to parse dpkg package info, err %s, raw - %s", err, string(entry)) continue } pkg := pkgInfoFromPackageMetadata(dpkg) if dpkg.Status != "installed" { continue } result = append(result, pkg) } return result } // DpkgInstall installs a deb package. func DpkgInstall(ctx context.Context, path string) error { _, err := run(ctx, dpkg, append(dpkgInstallArgs, path)) return err } osconfig-20250416.02/packages/apt_deb_test.go000066400000000000000000000615071477773331400206010ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package packages import ( "errors" "fmt" "os/exec" "reflect" "slices" "testing" utilmocks "github.com/GoogleCloudPlatform/osconfig/util/mocks" "github.com/golang/mock/gomock" ) func TestInstallAptPackages(t *testing.T) { tests := []struct { name string pkgs []string expectedCommandsChain []expectedCommand expectedError error }{ { name: "basic installation", pkgs: []string{"pkg1", "pkg2"}, expectedCommandsChain: []expectedCommand{ { cmd: exec.Command(aptGet, append(aptGetInstallArgs, pkgs...)...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("stdout"), stderr: []byte("stderr"), err: nil, }, }, expectedError: nil, }, { name: "allow downgrade added if specific error", pkgs: []string{"pkg1", "pkg2"}, expectedCommandsChain: []expectedCommand{ { cmd: exec.Command(aptGet, append(aptGetInstallArgs, pkgs...)...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("stdout"), stderr: []byte("E: Packages were downgraded and -y was used without --allow-downgrades."), err: errors.New("unexpected error"), }, { cmd: exec.Command(aptGet, append(append(aptGetInstallArgs, pkgs...), allowDowngradesArg)...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("stdout"), stderr: []byte("stderr"), err: nil, }, }, expectedError: nil, }, { name: "run dpkg repair on dpkg error", pkgs: []string{"pkg1", "pkg2"}, expectedCommandsChain: []expectedCommand{ { cmd: exec.Command(aptGet, append(aptGetInstallArgs, pkgs...)...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("stdout"), stderr: dpkgErr, err: errors.New("unexpected error"), }, { cmd: exec.CommandContext(testCtx, dpkg, dpkgRepairArgs...), envs: nil, stdout: []byte("stdout"), stderr: []byte("stderr"), err: nil, }, { cmd: exec.Command(aptGet, append(aptGetInstallArgs, pkgs...)...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("stdout"), stderr: []byte("stderr"), err: nil, }, }, expectedError: nil, }, { name: "throw an error if non dpkgErr", pkgs: []string{"pkg1", "pkg2"}, expectedCommandsChain: []expectedCommand{ { cmd: exec.Command(aptGet, append(slices.Clone(aptGetInstallArgs), pkgs...)...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("stdout"), stderr: []byte("stderr"), err: errors.New("unexpected error"), }, }, expectedError: errors.New("error running /usr/bin/apt-get with args" + " [\"install\" \"-y\" \"pkg1\" \"pkg2\"]:" + " unexpected error, stdout: \"stdout\", stderr: \"stderr\""), }, { name: "throw an error if any at the end", pkgs: []string{"pkg1", "pkg2"}, expectedCommandsChain: []expectedCommand{ { cmd: exec.Command(aptGet, append(aptGetInstallArgs, pkgs...)...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("stdout"), stderr: dpkgErr, err: errors.New("unexpected error"), }, { cmd: exec.CommandContext(testCtx, dpkg, dpkgRepairArgs...), envs: nil, stdout: []byte("stdout"), stderr: []byte("stderr"), err: nil, }, { cmd: exec.Command(aptGet, append(aptGetInstallArgs, pkgs...)...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("stdout"), stderr: []byte("stderr"), err: errors.New("unexpected error"), }, }, expectedError: errors.New("error running /usr/bin/apt-get with args" + " [\"install\" \"-y\" \"pkg1\" \"pkg2\"]:" + " unexpected error, stdout: \"stdout\", stderr: \"stderr\""), }, } for _, tt := range tests { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) runner = mockCommandRunner t.Run(tt.name, func(t *testing.T) { setExpectations(mockCommandRunner, tt.expectedCommandsChain) err := InstallAptPackages(testCtx, tt.pkgs) if !reflect.DeepEqual(err, tt.expectedError) { t.Errorf("InstallAptPackages: unexpected error, expect %q, got %q", formatError(tt.expectedError), formatError(err)) } }) } } func TestAptUpdates(t *testing.T) { tests := []struct { name string args []AptGetUpgradeOption expectedCommandsChain []expectedCommand expectedResults []*PkgInfo expectedError error }{ { name: "UnexpectedUpgradeType", args: []AptGetUpgradeOption{AptGetUpgradeType(10)}, expectedCommandsChain: nil, expectedResults: nil, expectedError: fmt.Errorf("unknown upgrade type: %q", 10), }, { name: "apt-get update", args: nil, expectedCommandsChain: []expectedCommand{ { cmd: exec.Command(aptGet, aptGetUpdateArgs...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("stdout"), stderr: []byte("stderr"), err: errors.New("unexpected error"), }, }, expectedResults: nil, expectedError: errors.New("unexpected error"), }, { name: "apt-get upgrade fail", args: nil, expectedCommandsChain: []expectedCommand{ { cmd: exec.Command(aptGet, aptGetUpdateArgs...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("stdout"), stderr: []byte(""), err: nil, }, { cmd: exec.Command(aptGet, append(slices.Clone(aptGetUpgradableArgs), aptGetUpgradeCmd)...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("stdout"), stderr: []byte("stderr"), err: errors.New("unexpected error"), }, }, expectedResults: nil, expectedError: errors.New("unexpected error"), }, { name: "Default upgrade type", args: nil, expectedCommandsChain: []expectedCommand{ { cmd: exec.Command(aptGet, aptGetUpdateArgs...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("stdout"), stderr: []byte(""), err: nil, }, { cmd: exec.Command(aptGet, append(slices.Clone(aptGetUpgradableArgs), aptGetUpgradeCmd)...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("Inst google-cloud-sdk [245.0.0-0] (246.0.0-0 cloud-sdk-stretch:cloud-sdk-stretch [amd64])"), stderr: []byte(""), err: nil, }, }, expectedResults: []*PkgInfo{{Name: "google-cloud-sdk", Arch: "x86_64", Version: "246.0.0-0"}}, expectedError: nil, }, { name: "Dist upgrade type", args: []AptGetUpgradeOption{AptGetUpgradeType(AptGetDistUpgrade)}, expectedCommandsChain: []expectedCommand{ { cmd: exec.Command(aptGet, aptGetUpdateArgs...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("stdout"), stderr: []byte(""), err: nil, }, { cmd: exec.Command(aptGet, append(slices.Clone(aptGetUpgradableArgs), aptGetDistUpgradeCmd)...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("Inst google-cloud-sdk [245.0.0-0] (246.0.0-0 cloud-sdk-stretch:cloud-sdk-stretch [amd64])"), stderr: []byte(""), err: nil, }, }, expectedResults: []*PkgInfo{{Name: "google-cloud-sdk", Arch: "x86_64", Version: "246.0.0-0"}}, expectedError: nil, }, { name: "Full upgrade type", args: []AptGetUpgradeOption{AptGetUpgradeType(AptGetFullUpgrade)}, expectedCommandsChain: []expectedCommand{ { cmd: exec.Command(aptGet, aptGetUpdateArgs...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("stdout"), stderr: []byte(""), err: nil, }, { cmd: exec.Command(aptGet, append(slices.Clone(aptGetUpgradableArgs), aptGetFullUpgradeCmd)...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("Inst google-cloud-sdk [245.0.0-0] (246.0.0-0 cloud-sdk-stretch:cloud-sdk-stretch [amd64])"), stderr: []byte(""), err: nil, }, }, expectedResults: []*PkgInfo{{Name: "google-cloud-sdk", Arch: "x86_64", Version: "246.0.0-0"}}, expectedError: nil, }, { name: "Default upgrade type with showNew equals true", args: []AptGetUpgradeOption{AptGetUpgradeShowNew(true)}, expectedCommandsChain: []expectedCommand{ { cmd: exec.Command(aptGet, aptGetUpdateArgs...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("stdout"), stderr: []byte(""), err: nil, }, { cmd: exec.Command(aptGet, append(slices.Clone(aptGetUpgradableArgs), aptGetUpgradeCmd)...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte( "Inst google-cloud-sdk [245.0.0-0] (246.0.0-0 cloud-sdk-stretch:cloud-sdk-stretch [amd64])\n" + "Inst firmware-linux-free (3.4 Debian:9.9/stable [all]) []"), stderr: []byte(""), err: nil, }, }, expectedResults: []*PkgInfo{ {Name: "google-cloud-sdk", Arch: "x86_64", Version: "246.0.0-0"}, {Name: "firmware-linux-free", Arch: "all", Version: "3.4"}, }, expectedError: nil, }, { name: "Default upgrade type with showNew equals false", args: []AptGetUpgradeOption{AptGetUpgradeShowNew(false)}, expectedCommandsChain: []expectedCommand{ { cmd: exec.Command(aptGet, aptGetUpdateArgs...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("stdout"), stderr: []byte(""), err: nil, }, { cmd: exec.Command(aptGet, append(slices.Clone(aptGetUpgradableArgs), aptGetUpgradeCmd)...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte( "Inst google-cloud-sdk [245.0.0-0] (246.0.0-0 cloud-sdk-stretch:cloud-sdk-stretch [amd64])\n" + "Inst firmware-linux-free (3.4 Debian:9.9/stable [all]) []"), stderr: []byte(""), err: nil, }, }, expectedResults: []*PkgInfo{ {Name: "google-cloud-sdk", Arch: "x86_64", Version: "246.0.0-0"}, }, expectedError: nil, }, { name: "Add --allow-downgrades when specific error provided.", args: nil, expectedCommandsChain: []expectedCommand{ { cmd: exec.Command(aptGet, aptGetUpdateArgs...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("stdout"), stderr: []byte(""), err: nil, }, { cmd: exec.Command(aptGet, append(slices.Clone(aptGetUpgradableArgs), aptGetUpgradeCmd)...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("stdout"), stderr: []byte("E: Packages were downgraded and -y was used without --allow-downgrades."), err: errors.New("failure"), }, { cmd: exec.Command(aptGet, append(slices.Clone(aptGetUpgradableArgs), aptGetUpgradeCmd, allowDowngradesArg)...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("Inst google-cloud-sdk [245.0.0-0] (246.0.0-0 cloud-sdk-stretch:cloud-sdk-stretch [amd64])"), stderr: []byte("stderr"), err: nil, }, }, expectedResults: []*PkgInfo{ {Name: "google-cloud-sdk", Arch: "x86_64", Version: "246.0.0-0"}, }, expectedError: nil, }, } for _, tt := range tests { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) runner = mockCommandRunner t.Run(tt.name, func(t *testing.T) { setExpectations(mockCommandRunner, tt.expectedCommandsChain) pkgs, err := AptUpdates(testCtx, tt.args...) if !reflect.DeepEqual(err, tt.expectedError) { t.Errorf("AptUpdates: unexpected error, expect %q, got %q", formatError(tt.expectedError), formatError(err)) } if !reflect.DeepEqual(pkgs, tt.expectedResults) { t.Errorf("AptUpdates: unexpected result, expect %v, got %v", pkgs, tt.expectedResults) } }) } } func TestRemoveAptPackages(t *testing.T) { tests := []struct { name string pkgs []string expectedCommandsChain []expectedCommand expectedError error }{ { name: "Successful path", pkgs: []string{"pkg1", "pkg2"}, expectedCommandsChain: []expectedCommand{ { cmd: exec.Command(aptGet, append(slices.Clone(aptGetRemoveArgs), pkgs...)...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("stdout"), stderr: []byte("stderr"), err: nil, }, }, expectedError: nil, }, { name: "Run dpkg repair on dpkg error", pkgs: []string{"pkg1", "pkg2"}, expectedCommandsChain: []expectedCommand{ { cmd: exec.Command(aptGet, append(slices.Clone(aptGetRemoveArgs), pkgs...)...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("stdout"), stderr: dpkgErr, err: errors.New("error"), }, { cmd: exec.CommandContext(testCtx, dpkg, dpkgRepairArgs...), envs: nil, stdout: []byte("stdout"), stderr: []byte("stderr"), err: nil, }, { cmd: exec.Command(aptGet, append(slices.Clone(aptGetRemoveArgs), pkgs...)...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("stdout"), stderr: []byte("stderr"), err: nil, }, }, expectedError: nil, }, { name: "throw an error if non dpkgErr", pkgs: []string{"pkg1", "pkg2"}, expectedCommandsChain: []expectedCommand{ { cmd: exec.Command(aptGet, append(slices.Clone(aptGetRemoveArgs), pkgs...)...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("stdout"), stderr: []byte("stderr"), err: errors.New("unexpected error"), }, }, expectedError: errors.New("error running /usr/bin/apt-get with args" + " [\"remove\" \"-y\" \"pkg1\" \"pkg2\"]:" + " unexpected error, stdout: \"stdout\", stderr: \"stderr\""), }, { name: "throw an error if any at the end", pkgs: []string{"pkg1", "pkg2"}, expectedCommandsChain: []expectedCommand{ { cmd: exec.Command(aptGet, append(aptGetRemoveArgs, pkgs...)...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("stdout"), stderr: dpkgErr, err: errors.New("unexpected error"), }, { cmd: exec.CommandContext(testCtx, dpkg, dpkgRepairArgs...), envs: nil, stdout: []byte("stdout"), stderr: []byte("stderr"), err: nil, }, { cmd: exec.Command(aptGet, append(aptGetRemoveArgs, pkgs...)...), envs: []string{"DEBIAN_FRONTEND=noninteractive"}, stdout: []byte("stdout"), stderr: []byte("stderr"), err: errors.New("unexpected error"), }, }, expectedError: errors.New("error running /usr/bin/apt-get with args" + " [\"remove\" \"-y\" \"pkg1\" \"pkg2\"]:" + " unexpected error, stdout: \"stdout\", stderr: \"stderr\""), }, } for _, tt := range tests { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) runner = mockCommandRunner t.Run(tt.name, func(t *testing.T) { setExpectations(mockCommandRunner, tt.expectedCommandsChain) err := RemoveAptPackages(testCtx, tt.pkgs) if !reflect.DeepEqual(err, tt.expectedError) { t.Errorf("RemoveAptPackages: unexpected error, expect %q, got %q", formatError(tt.expectedError), formatError(err)) } }) } } func TestInstalledDebPackages(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) runner = mockCommandRunner //Successfully returns result dpkgQueryCmd := utilmocks.EqCmd(exec.Command(dpkgQuery, dpkgQueryArgs...)) stdout := []byte(`{"package":"git","architecture":"amd64","version":"1:2.25.1-1ubuntu3.12","status":"installed","source_name":"git","source_version":"1:2.25.1-1ubuntu3.12"}`) stderr := []byte("stderr") mockCommandRunner.EXPECT().Run(testCtx, dpkgQueryCmd).Return(stdout, stderr, nil).Times(1) result, err := InstalledDebPackages(testCtx) if err != nil { t.Errorf("InstalledDebPackages(): got unexpected error: %v", err) } want := []*PkgInfo{{Name: "git", Arch: "x86_64", Version: "1:2.25.1-1ubuntu3.12", Source: Source{Name: "git", Version: "1:2.25.1-1ubuntu3.12"}}} if !reflect.DeepEqual(result, want) { t.Errorf("InstalledDebPackages() = %v, want %v", result, want) } //Returns error if any mockCommandRunner.EXPECT().Run(testCtx, dpkgQueryCmd).Return(stdout, stderr, errors.New("error")).Times(1) if _, err := InstalledDebPackages(testCtx); err == nil { t.Errorf("did not get expected error") } } func TestParseInstalledDebpackages(t *testing.T) { tests := []struct { name string input []byte want []*PkgInfo }{ { name: "two valid packages in input", input: []byte("" + `{"package":"python3-gi","architecture":"amd64","version":"3.36.0-1","status":"installed","source_name":"pygobject","source_version":"3.36.0-1"}` + "\n" + `{"package":"man-db","architecture":"amd64","version":"2.9.1-1","status":"installed","source_name":"man-db","source_version":"2.9.1-1"}`), want: []*PkgInfo{ {Name: "python3-gi", Arch: "x86_64", Version: "3.36.0-1", Source: Source{Name: "pygobject", Version: "3.36.0-1"}}, {Name: "man-db", Arch: "x86_64", Version: "2.9.1-1", Source: Source{Name: "man-db", Version: "2.9.1-1"}}}, }, { name: "No lines formatted as a package info", input: []byte("nothing here"), want: nil, }, { name: "Nil as input does not panic", input: nil, want: nil, }, { name: "Skip wrongly formatted lines", input: []byte("something we dont understand\n" + `{"package":"python3-gi","architecture":"amd64","version":"3.36.0-1","status":"installed","source_name":"pygobject","source_version":"3.36.0-1"}`), want: []*PkgInfo{{Name: "python3-gi", Arch: "x86_64", Version: "3.36.0-1", Source: Source{Name: "pygobject", Version: "3.36.0-1"}}}, }, { name: "Skip entries that have status other than 'installed'", input: []byte("" + `{"package":"python3-gi","architecture":"amd64","version":"3.36.0-1","status":"installed","source_name":"pygobject","source_version":"3.36.0-1"}` + "\n" + `{"package":"man-db","architecture":"amd64","version":"2.9.1-1","status":"config-files","source_name":"man-db","source_version":"2.9.1-1"}`), want: []*PkgInfo{{Name: "python3-gi", Arch: "x86_64", Version: "3.36.0-1", Source: Source{Name: "pygobject", Version: "3.36.0-1"}}}, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := parseInstalledDebPackages(testCtx, tt.input); !reflect.DeepEqual(got, tt.want) { t.Errorf("parseInstalledDebPackages() = %v, want %v", got, tt.want) } }) } } func TestParseAptUpdates(t *testing.T) { normalCase := ` Inst libldap-common [2.4.45+dfsg-1ubuntu1.2] (2.4.45+dfsg-1ubuntu1.3 Ubuntu:18.04/bionic-updates, Ubuntu:18.04/bionic-security [all]) Inst google-cloud-sdk [245.0.0-0] (246.0.0-0 cloud-sdk-stretch:cloud-sdk-stretch [amd64]) [] Inst firmware-linux-free (3.4 Debian:9.9/stable [all]) Conf firmware-linux-free (3.4 Debian:9.9/stable [all]) ` tests := []struct { name string input []byte showNew bool want []*PkgInfo }{ { name: "Set of packages with new, show new - false", input: []byte(normalCase), showNew: false, want: []*PkgInfo{ {Name: "libldap-common", Arch: "all", Version: "2.4.45+dfsg-1ubuntu1.3"}, {Name: "google-cloud-sdk", Arch: "x86_64", Version: "246.0.0-0"}, }, }, { name: "Set of packages with new, show new - true", input: []byte(normalCase), showNew: true, want: []*PkgInfo{ {Name: "libldap-common", Arch: "all", Version: "2.4.45+dfsg-1ubuntu1.3"}, {Name: "google-cloud-sdk", Arch: "x86_64", Version: "246.0.0-0"}, {Name: "firmware-linux-free", Arch: "all", Version: "3.4"}, }, }, { name: "No lines formatted as a package info", input: []byte("nothing here"), showNew: false, want: nil, }, { name: "Nil as input does not panic", input: nil, showNew: false, want: nil, }, { name: "Skip wrongly formatted lines", input: []byte("Inst something [we dont understand\n Inst google-cloud-sdk [245.0.0-0] (246.0.0-0 cloud-sdk-stretch:cloud-sdk-stretch [amd64])"), showNew: false, want: []*PkgInfo{ {Name: "google-cloud-sdk", Arch: "x86_64", Version: "246.0.0-0"}, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := parseAptUpdates(testCtx, tt.input, tt.showNew); !reflect.DeepEqual(got, tt.want) { t.Errorf("parseAptUpdates() = %v, want %v", got, tt.want) } }) } } func TestDebPkgInfo(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) runner = mockCommandRunner testPkg := "test.deb" expectedCmd := utilmocks.EqCmd(exec.Command(dpkgDeb, "-I", testPkg)) out := []byte(`new Debian package, version 2.0. size 6731954 bytes: control archive=2138 bytes. 498 bytes, 12 lines control 3465 bytes, 31 lines md5sums 2793 bytes, 65 lines * postinst #!/bin/sh 938 bytes, 28 lines * postrm #!/bin/sh 216 bytes, 7 lines * prerm #!/bin/sh Package: google-guest-agent Version: 1:1dummy-g1 Architecture: amd64 Maintainer: Google Cloud Team Installed-Size: 23279 Depends: init-system-helpers (>= 1.18~) Conflicts: python-google-compute-engine, python3-google-compute-engine Section: misc Priority: optional Description: Google Compute Engine Guest Agent Contains the guest agent and metadata script runner binaries. Git: https://github.com/GoogleCloudPlatform/guest-agent/tree/c3d526e650c4e45ae3258c07836fd72f85fd9fc8`) mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).Return(out, []byte("stderr"), nil).Times(1) ret, err := DebPkgInfo(testCtx, testPkg) if err != nil { t.Errorf("unexpected error: %v", err) } want := &PkgInfo{Name: "google-guest-agent", Arch: "x86_64", Version: "1:1dummy-g1"} if !reflect.DeepEqual(ret, want) { t.Errorf("DebPkgInfo() = %+v, want %+v", ret, want) } // Error output. mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).Return([]byte("stdout"), []byte("stderr"), errors.New("bad error")).Times(1) if _, err := DebPkgInfo(testCtx, testPkg); err == nil { t.Errorf("did not get expected error") } // No package mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).Return([]byte(""), []byte("stderr"), nil).Times(1) if _, err := DebPkgInfo(testCtx, testPkg); err == nil { t.Errorf("did not get expected error") } } func Test_dpkgRepair(t *testing.T) { tests := []struct { name string input []byte expected bool expectedCmd *exec.Cmd }{ { name: "NonDpkgError", input: []byte("some random error"), expected: false, expectedCmd: nil, }, { name: "DpkgError", input: dpkgErr, expected: true, expectedCmd: exec.CommandContext(testCtx, dpkg, dpkgRepairArgs...), }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) runner = mockCommandRunner if tt.expectedCmd != nil { mockCommandRunner.EXPECT().Run(testCtx, utilmocks.EqCmd(tt.expectedCmd)).Return([]byte("output"), []byte(""), nil).Times(1) } if result := dpkgRepair(testCtx, tt.input); result != tt.expected { t.Errorf("unexpected result of dpkgRepair, expected %t, got %t", tt.expected, result) } }) } } func TestDpkgInstall(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) runner = mockCommandRunner path := "/tmp/test.dpkg" dpkgInstallCmd := exec.CommandContext(testCtx, dpkg, append(dpkgInstallArgs, path)...) //Dpkg install fail wantErr := errors.New("unexpected error") mockCommandRunner.EXPECT().Run(testCtx, utilmocks.EqCmd(dpkgInstallCmd)).Return([]byte("stdout"), []byte("stderr"), wantErr).Times(1) if err := DpkgInstall(testCtx, path); err == nil { t.Errorf("DpkgInstall: expected error %q, but got ", formatError(wantErr)) } //Dpkg install succeeded mockCommandRunner.EXPECT().Run(testCtx, utilmocks.EqCmd(dpkgInstallCmd)).Return([]byte("stdout"), []byte("stderr"), nil).Times(1) if err := DpkgInstall(testCtx, path); err != nil { t.Errorf("DpkgInstall: got unexpected error %q", err) } } osconfig-20250416.02/packages/cos.go000066400000000000000000000040741477773331400167240ustar00rootroot00000000000000// Copyright 2020 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Only build for linux but not on unsupported architectures. //go:build linux && (386 || amd64 || arm64) // +build linux // +build 386 amd64 arm64 package packages import ( "fmt" "cos.googlesource.com/cos/tools.git/src/pkg/cos" "github.com/GoogleCloudPlatform/osconfig/osinfo" ) func init() { COSPkgInfoExists = cos.PackageInfoExists() } var readMachineArch = func() (string, error) { oi, err := osinfo.Get() if err != nil { return "", fmt.Errorf("error getting osinfo: %v", err) } return oi.Architecture, nil } func parseInstalledCOSPackages(cosPkgInfo *cos.PackageInfo) ([]*PkgInfo, error) { arch, err := readMachineArch() if err != nil { return nil, fmt.Errorf("error from readMachineArch: %v", err) } var pkgs = make([]*PkgInfo, len(cosPkgInfo.InstalledPackages)) for i, pkg := range cosPkgInfo.InstalledPackages { name := pkg.Category + "/" + pkg.Name version := pkg.Version pkgs[i] = &PkgInfo{Name: name, Arch: arch, Version: version} } return pkgs, nil } var readCOSPackageInfo = func() (*cos.PackageInfo, error) { pkgInfo, err := cos.GetPackageInfo() if err != nil { return nil, err } return &pkgInfo, nil } // InstalledCOSPackages queries for all installed COS packages. func InstalledCOSPackages() ([]*PkgInfo, error) { packageInfo, err := readCOSPackageInfo() if err != nil { return nil, fmt.Errorf("error reading COS package list with args: %v, contents: %v", err, packageInfo) } return parseInstalledCOSPackages(packageInfo) } osconfig-20250416.02/packages/cos_stub.go000066400000000000000000000015601477773331400177560ustar00rootroot00000000000000// Copyright 2021 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Stub for linux builds. //go:build linux && !386 && !amd64 && !arm64 // +build linux,!386,!amd64,!arm64 package packages // InstalledCOSPackages is a stub for unsupported architectures. func InstalledCOSPackages() ([]*PkgInfo, error) { return nil, nil } osconfig-20250416.02/packages/cos_test.go000066400000000000000000000152211477773331400177570ustar00rootroot00000000000000// Copyright 2020 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build linux && (386 || amd64) // +build linux // +build 386 amd64 package packages import ( "errors" "io/ioutil" "os" "reflect" "testing" "cos.googlesource.com/cos/tools.git/src/pkg/cos" ) func TestParseInstalledCOSPackages(t *testing.T) { readMachineArch = func() (string, error) { return "", errors.New("failed to obtain machine architecture") } if _, err := parseInstalledCOSPackages(&cos.PackageInfo{}); err == nil { t.Errorf("did not get expected error") } readMachineArch = func() (string, error) { return "x86_64", nil } pkg0 := cos.Package{Category: "dev-util", Name: "foo-x", Version: "1.2.3", EbuildVersion: "someversion"} expect0 := &PkgInfo{Name: "dev-util/foo-x", Arch: "x86_64", Version: "1.2.3"} pkg1 := cos.Package{Category: "app-admin", Name: "bar", Version: "0.1"} expect1 := &PkgInfo{Name: "app-admin/bar", Arch: "x86_64", Version: "0.1"} pkgInfo := &cos.PackageInfo{InstalledPackages: []cos.Package{pkg0, pkg1}} parsed, err := parseInstalledCOSPackages(pkgInfo) if err != nil { t.Errorf("unexpected error: %v", err) } if !reflect.DeepEqual(parsed[0], expect0) { t.Errorf("parseInstalledCOSPackages pkg0: %v, want: %v", parsed[0], expect0) } if !reflect.DeepEqual(parsed[1], expect1) { t.Errorf("parseInstalledCOSPackages pkg1: %v, want: %v", parsed[1], expect1) } } func TestInstalledCOSPackages(t *testing.T) { testDataJSON := `{ "installedPackages": [ { "category": "app-arch", "name": "gzip", "version": "1.9", "ebuildverison": "someotherversion" }, { "category": "dev-libs", "name": "popt", "version": "1.16" }, { "category": "app-emulation", "name": "docker-credential-helpers", "version": "0.6.3" }, { "category": "_not.real-category1+", "name": "_not-real_package1", "version": "12.34.56.78" }, { "category": "_not.real-category1+", "name": "_not-real_package2", "version": "12.34.56.78" }, { "category": "_not.real-category1+", "name": "_not-real_package3", "version": "12.34.56.78_rc3" }, { "category": "_not.real-category1+", "name": "_not-real_package4", "version": "12.34.56.78_rc3" }, { "category": "_not.real-category1+", "name": "_not-real_package5", "version": "12.34.56.78_pre2_rc3" }, { "category": "_not.real-category2+", "name": "_not-real_package1", "version": "12.34.56.78q" }, { "category": "_not.real-category2+", "name": "_not-real_package2", "version": "12.34.56.78q" }, { "category": "_not.real-category2+", "name": "_not-real_package3", "version": "12.34.56.78q_rc3" }, { "category": "_not.real-category2+", "name": "_not-real_package4", "version": "12.34.56.78q_rc3" }, { "category": "_not.real-category2+", "name": "_not-real_package5", "version": "12.34.56.78q_pre2_rc3" } ] }` testFile, err := ioutil.TempFile("", "cos_pkg_info_test") if err != nil { t.Fatalf("Failed to create tempfile: %v", err) } defer os.Remove(testFile.Name()) _, err = testFile.WriteString(testDataJSON) if err != nil { t.Fatalf("Failed to write test data: %v", err) } err = testFile.Close() if err != nil { t.Fatalf("Failed to close test file: %v", err) } expected := []*PkgInfo{ {Name: "app-arch/gzip", Arch: "x86_64", Version: "1.9"}, {Name: "dev-libs/popt", Arch: "x86_64", Version: "1.16"}, {Name: "app-emulation/docker-credential-helpers", Arch: "x86_64", Version: "0.6.3"}, {Name: "_not.real-category1+/_not-real_package1", Arch: "x86_64", Version: "12.34.56.78"}, {Name: "_not.real-category1+/_not-real_package2", Arch: "x86_64", Version: "12.34.56.78"}, {Name: "_not.real-category1+/_not-real_package3", Arch: "x86_64", Version: "12.34.56.78_rc3"}, {Name: "_not.real-category1+/_not-real_package4", Arch: "x86_64", Version: "12.34.56.78_rc3"}, {Name: "_not.real-category1+/_not-real_package5", Arch: "x86_64", Version: "12.34.56.78_pre2_rc3"}, {Name: "_not.real-category2+/_not-real_package1", Arch: "x86_64", Version: "12.34.56.78q"}, {Name: "_not.real-category2+/_not-real_package2", Arch: "x86_64", Version: "12.34.56.78q"}, {Name: "_not.real-category2+/_not-real_package3", Arch: "x86_64", Version: "12.34.56.78q_rc3"}, {Name: "_not.real-category2+/_not-real_package4", Arch: "x86_64", Version: "12.34.56.78q_rc3"}, {Name: "_not.real-category2+/_not-real_package5", Arch: "x86_64", Version: "12.34.56.78q_pre2_rc3"}, } readMachineArch = func() (string, error) { return "", errors.New("failed to obtain machine architecture") } readCOSPackageInfo = func() (*cos.PackageInfo, error) { info, err := cos.GetPackageInfoFromFile(testFile.Name()) return &info, err } if _, err := InstalledCOSPackages(); err == nil { t.Errorf("did not get expected error from readMachineArch") } readMachineArch = func() (string, error) { return "x86_64", nil } readCOSPackageInfo = func() (*cos.PackageInfo, error) { info, err := cos.GetPackageInfoFromFile("_" + testFile.Name()) return &info, err } if _, err := InstalledCOSPackages(); err == nil { t.Errorf("did not get expected error fro readCOSPackageInfo") } readMachineArch = func() (string, error) { return "x86_64", nil } readCOSPackageInfo = func() (*cos.PackageInfo, error) { info, err := cos.GetPackageInfoFromFile(testFile.Name()) return &info, err } ret, err := InstalledCOSPackages() if err != nil { t.Errorf("unexpected error: %v", err) } if len(ret) != len(expected) { t.Errorf("Length is wrong. want: %d, got: %d", len(expected), len(ret)) } if !reflect.DeepEqual(ret, expected) { t.Errorf("InstalledCOSPackages() returned: %v, want: %v", ret, expected) } } osconfig-20250416.02/packages/gem.go000066400000000000000000000051111477773331400167010ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package packages import ( "context" "runtime" "strings" "time" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/util" ) var ( gem string gemListArgs = []string{"list", "--local"} gemOutdatedArgs = []string{"outdated", "--local"} gemListTimeout = 15 * time.Second gemOutdatedTimeout = 15 * time.Second ) func init() { if runtime.GOOS != "windows" { gem = "/usr/bin/gem" } GemExists = util.Exists(gem) } // GemUpdates queries for all available gem updates. func GemUpdates(ctx context.Context) ([]*PkgInfo, error) { stdout, err := runWithDeadline(ctx, gemOutdatedTimeout, gem, gemOutdatedArgs) if err != nil { return nil, err } /* foo (1.2.8 < 1.3.2) bar (1.0.0 < 1.1.2) ... */ lines := strings.Split(strings.TrimSpace(string(stdout)), "\n") if len(lines) == 0 { return nil, nil } var pkgs []*PkgInfo for _, ln := range lines { pkg := strings.Fields(ln) if len(pkg) != 4 { clog.Debugf(ctx, "%q does not represent a gem update\n", ln) continue } ver := strings.Trim(pkg[3], ")") pkgs = append(pkgs, &PkgInfo{Name: pkg[0], Arch: noarch, Version: ver}) } return pkgs, nil } // InstalledGemPackages queries for all installed gem packages. func InstalledGemPackages(ctx context.Context) ([]*PkgInfo, error) { stdout, err := runWithDeadline(ctx, gemListTimeout, gem, gemListArgs) if err != nil { return nil, err } /* *** LOCAL GEMS *** foo (1.2.3, 1.2.4) bar (1.2.3) ... */ lines := strings.Split(strings.TrimSpace(string(stdout)), "\n") if len(lines) == 0 { clog.Debugf(ctx, "No gems installed.") return nil, nil } var pkgs []*PkgInfo for _, ln := range lines[2:] { pkg := strings.Fields(ln) if len(pkg) < 2 { clog.Debugf(ctx, "'%s' does not represent a gem", ln) continue } for _, ver := range strings.Split(strings.Trim(pkg[1], "()"), ", ") { pkgs = append(pkgs, &PkgInfo{Name: pkg[0], Arch: noarch, Version: ver}) } } return pkgs, nil } osconfig-20250416.02/packages/googet.go000066400000000000000000000060331477773331400174210ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package packages import ( "bytes" "context" "os" "path/filepath" "strings" "github.com/GoogleCloudPlatform/osconfig/util" ) var ( googet string googetUpdateQueryArgs = []string{"update"} googetInstalledQueryArgs = []string{"installed"} googetInstallArgs = []string{"-noconfirm", "install"} googetRemoveArgs = []string{"-noconfirm", "remove"} ) func init() { googet = filepath.Join(os.Getenv("GooGetRoot"), "googet.exe") GooGetExists = util.Exists(googet) } func parseGooGetUpdates(data []byte) []*PkgInfo { /* Searching for available updates... foo.noarch, 3.5.4@1 --> 3.6.7@1 from repo ... Perform update? (y/N): */ lines := strings.Split(strings.TrimSpace(string(data)), "\n") var pkgs []*PkgInfo for _, ln := range lines { pkg := strings.Fields(ln) if len(pkg) < 4 { continue } p := strings.Split(pkg[0], ".") if len(p) != 2 { continue } pkgs = append(pkgs, &PkgInfo{Name: p[0], Arch: strings.Trim(p[1], ","), Version: pkg[3]}) } return pkgs } // GooGetUpdates queries for all available googet updates. func GooGetUpdates(ctx context.Context) ([]*PkgInfo, error) { out, err := run(ctx, googet, googetUpdateQueryArgs) if err != nil { return nil, err } return parseGooGetUpdates(out), nil } // InstallGooGetPackages installs GooGet packages. func InstallGooGetPackages(ctx context.Context, pkgs []string) error { _, err := run(ctx, googet, append(googetInstallArgs, pkgs...)) return err } // RemoveGooGetPackages installs GooGet packages. func RemoveGooGetPackages(ctx context.Context, pkgs []string) error { _, err := run(ctx, googet, append(googetRemoveArgs, pkgs...)) return err } func parseInstalledGooGetPackages(data []byte) []*PkgInfo { /* Installed Packages: foo.x86_64 1.2.3@4 bar.noarch 1.2.3@4 ... */ lines := bytes.Split(bytes.TrimSpace(data), []byte("\n")) var pkgs []*PkgInfo for _, ln := range lines { pkg := bytes.Fields(ln) if len(pkg) != 2 { continue } p := bytes.Split(pkg[0], []byte(".")) if len(p) != 2 { continue } pkgs = append(pkgs, &PkgInfo{Name: string(p[0]), Arch: string(p[1]), Version: string(pkg[1])}) } return pkgs } // InstalledGooGetPackages queries for all installed googet packages. func InstalledGooGetPackages(ctx context.Context) ([]*PkgInfo, error) { out, err := run(ctx, googet, googetInstalledQueryArgs) if err != nil { return nil, err } return parseInstalledGooGetPackages(out), nil } osconfig-20250416.02/packages/googet_test.go000066400000000000000000000132601477773331400204600ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package packages import ( "errors" "os/exec" "reflect" "testing" utilmocks "github.com/GoogleCloudPlatform/osconfig/util/mocks" "github.com/golang/mock/gomock" ) func TestInstallGooGetPackages(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) runner = mockCommandRunner expectedCmd := utilmocks.EqCmd(exec.Command(googet, append(googetInstallArgs, pkgs...)...)) mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).Return([]byte("stdout"), []byte("stderr"), nil).Times(1) if err := InstallGooGetPackages(testCtx, pkgs); err != nil { t.Errorf("unexpected error: %v", err) } mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).Return([]byte("stdout"), []byte("stderr"), errors.New("Could not install package")).Times(1) if err := InstallGooGetPackages(testCtx, pkgs); err == nil { t.Errorf("did not get expected error") } } func TestRemoveGooGet(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) runner = mockCommandRunner expectedCmd := utilmocks.EqCmd(exec.Command(googet, append(googetRemoveArgs, pkgs...)...)) mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).Return([]byte("stdout"), []byte("stderr"), nil).Times(1) if err := RemoveGooGetPackages(testCtx, pkgs); err != nil { t.Errorf("unexpected error: %v", err) } mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).Return([]byte("stdout"), []byte("stderr"), errors.New("Could not remove package")).Times(1) if err := RemoveGooGetPackages(testCtx, pkgs); err == nil { t.Errorf("did not get expected error") } } func TestParseInstalledGooGetPackages(t *testing.T) { tests := []struct { name string data []byte want []*PkgInfo }{ {"NormalCase", []byte(" Installed Packages:\nfoo.x86_64 1.2.3@4\nbar.noarch 1.2.3@4"), []*PkgInfo{{Name: "foo", Arch: "x86_64", Version: "1.2.3@4"}, {Name: "bar", Arch: "noarch", Version: "1.2.3@4"}}}, {"NoPackages", []byte("nothing here"), nil}, {"nil", nil, nil}, {"UnrecognizedPackage", []byte("Inst something we dont understand\n foo.x86_64 1.2.3@4"), []*PkgInfo{{Name: "foo", Arch: "x86_64", Version: "1.2.3@4"}}}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := parseInstalledGooGetPackages(tt.data); !reflect.DeepEqual(got, tt.want) { t.Errorf("parseInstalledGooGetPackages() = %v, want %v", got, tt.want) } }) } } func TestInstalledGooGetPackages(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) runner = mockCommandRunner expectedCmd := utilmocks.EqCmd(exec.Command(googet, googetInstalledQueryArgs...)) mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).Return([]byte("foo.x86_64 1.2.3@4"), []byte("stderr"), nil).Times(1) ret, err := InstalledGooGetPackages(testCtx) if err != nil { t.Errorf("unexpected error: %v", err) } want := []*PkgInfo{{Name: "foo", Arch: "x86_64", Version: "1.2.3@4"}} if !reflect.DeepEqual(ret, want) { t.Errorf("InstalledGooGetPackages() = %v, want %v", ret, want) } mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).Return(nil, nil, errors.New("bad error")).Times(1) if _, err := InstalledGooGetPackages(testCtx); err == nil { t.Errorf("did not get expected error") } } func TestParseGooGetUpdates(t *testing.T) { tests := []struct { name string data []byte want []*PkgInfo }{ {"NormalCase", []byte("Searching for available updates...\nfoo.noarch, 3.5.4@1 --> 3.6.7@1 from repo\nbar.x86_64, 1.0.0@1 --> 2.0.0@1 from repo\nPerform update? (y/N):"), []*PkgInfo{{Name: "foo", Arch: "noarch", Version: "3.6.7@1"}, {Name: "bar", Arch: "x86_64", Version: "2.0.0@1"}}}, {"NoPackages", []byte("nothing here"), nil}, {"nil", nil, nil}, {"UnrecognizedPackage", []byte("Inst something we dont understand\n foo.noarch, 3.5.4@1 --> 3.6.7@1 from repo"), []*PkgInfo{{Name: "foo", Arch: "noarch", Version: "3.6.7@1"}}}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := parseGooGetUpdates(tt.data); !reflect.DeepEqual(got, tt.want) { t.Errorf("parseGooGetUpdates() = %v, want %v", got, tt.want) } }) } } func TestGooGetUpdates(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) runner = mockCommandRunner expectedCmd := utilmocks.EqCmd(exec.Command(googet, googetUpdateQueryArgs...)) mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).Return([]byte("foo.noarch, 3.5.4@1 --> 3.6.7@1 from repo"), []byte("stderr"), nil).Times(1) ret, err := GooGetUpdates(testCtx) if err != nil { t.Errorf("unexpected error: %v", err) } want := []*PkgInfo{{Name: "foo", Arch: "noarch", Version: "3.6.7@1"}} if !reflect.DeepEqual(ret, want) { t.Errorf("GooGetUpdates() = %v, want %v", ret, want) } mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).Return([]byte("stdout"), []byte("stderr"), errors.New("bad error")).Times(1) if _, err := GooGetUpdates(testCtx); err == nil { t.Errorf("did not get expected error") } } osconfig-20250416.02/packages/msi_windows.go000066400000000000000000000147741477773331400205120ustar00rootroot00000000000000// Copyright 2020 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package packages import ( "context" "fmt" "strings" "sync" "syscall" "unsafe" "github.com/GoogleCloudPlatform/osconfig/clog" ole "github.com/go-ole/go-ole" "golang.org/x/sys/windows" ) var ( msiInstallArgs = []string{"ACTION=INSTALL", "REBOOT=ReallySuppress"} msi = windows.NewLazySystemDLL("msi.dll") procMsiOpenPackageExW = msi.NewProc("MsiOpenPackageExW") procMsiGetProductPropertyW = msi.NewProc("MsiGetProductPropertyW") procMsiQueryProductStateW = msi.NewProc("MsiQueryProductStateW") procMsiCloseHandle = msi.NewProc("MsiCloseHandle") procMsiInstallProductW = msi.NewProc("MsiInstallProductW") procMsiSetInternalUI = msi.NewProc("MsiSetInternalUI") once sync.Once ) func init() { MSIExists = true } func setUIMode() { /* INSTALLUILEVEL MsiSetInternalUI( INSTALLUILEVEL dwUILevel, HWND *phWnd ); */ const INSTALLUILEVEL_NONE = 2 once.Do(func() { procMsiSetInternalUI.Call( uintptr(INSTALLUILEVEL_NONE), 0, ) }) } // https://docs.microsoft.com/en-us/windows/win32/api/msi/nf-msi-msiopenpackageexw func msiOpenPackageExW(szPackagePath string, dwOptions uint32) (uintptr, error) { /* UINT MsiOpenPackageExW( LPCWSTR szPackagePath, DWORD dwOptions, MSIHANDLE *hProduct ); */ var handle int32 pHandle := uintptr(unsafe.Pointer(&handle)) szPackagePathPtr, err := syscall.UTF16PtrFromString(szPackagePath) if err != nil { return 0, fmt.Errorf("error encoding szPackagePath to UTF16: %v", err) } ret, _, _ := procMsiOpenPackageExW.Call( uintptr(unsafe.Pointer(szPackagePathPtr)), uintptr(dwOptions), pHandle, ) if ret != 0 { return 0, fmt.Errorf("MsiOpenPackageExW error: %s", syscall.Errno(ret)) } return uintptr(handle), nil } // https://docs.microsoft.com/en-us/windows/win32/api/msi/nf-msi-msiclosehandle func msiCloseHandle(handle uintptr) { /* UINT MsiCloseHandle( MSIHANDLE hAny ); */ procMsiCloseHandle.Call(handle) } // https://docs.microsoft.com/en-us/windows/win32/api/msi/nf-msi-msigetproductpropertyw func msiGetProductPropertyW(handle uintptr, szProperty string) (string, error) { /* UINT MsiGetProductPropertyW( MSIHANDLE hProduct, LPCSTR szProperty, LPSTR lpValueBuf, LPDWORD pcchValueBuf ); */ szPropertyPtr, err := syscall.UTF16PtrFromString(szProperty) if err != nil { return "", fmt.Errorf("error encoding szProperty to UTF16: %v", err) } size := uint32(128) lpValueBuf := make([]uint16, size) ret, _, _ := procMsiGetProductPropertyW.Call( handle, uintptr(unsafe.Pointer(szPropertyPtr)), uintptr(unsafe.Pointer(&lpValueBuf[0])), uintptr(unsafe.Pointer(&size)), ) if ret != 0 { return "", fmt.Errorf("MsiGetProductPropertyW error: %s", syscall.Errno(ret)) } return syscall.UTF16ToString(lpValueBuf), nil } type msiInstallState int32 const ( INSTALLSTATE_UNKNOWN = msiInstallState(-1) INSTALLSTATE_ADVERTISED = msiInstallState(1) INSTALLSTATE_ABSENT = msiInstallState(2) INSTALLSTATE_DEFAULT = msiInstallState(5) ) // https://docs.microsoft.com/en-us/windows/win32/api/msi/nf-msi-msiqueryproductstatew func msiMsiQueryProductStateW(szProduct string) (msiInstallState, error) { /* INSTALLSTATE MsiQueryProductStateW( LPCWSTR szProduct ); */ szProductPtr, err := syscall.UTF16PtrFromString(szProduct) if err != nil { return -1, fmt.Errorf("error encoding szProduct to UTF16: %v", err) } ret, _, _ := procMsiQueryProductStateW.Call(uintptr(unsafe.Pointer(szProductPtr))) return msiInstallState(ret), nil } // https://docs.microsoft.com/en-us/windows/win32/api/msi/nf-msi-msiinstallproductw func msiInstallProductW(szPackagePath string, szCommandLine []string) error { /* UINT MsiInstallProductW( LPCWSTR szPackagePath, LPCWSTR szCommandLine ); */ szPackagePathPtr, err := syscall.UTF16PtrFromString(szPackagePath) if err != nil { return fmt.Errorf("error encoding szPackagePath to UTF16: %v", err) } szCommandLinePtr, err := syscall.UTF16PtrFromString(strings.Join(szCommandLine, " ")) if err != nil { return fmt.Errorf("error encoding szCommandLine to UTF16: %v", err) } ret, _, _ := procMsiInstallProductW.Call( uintptr(unsafe.Pointer(szPackagePathPtr)), uintptr(unsafe.Pointer(szCommandLinePtr)), ) if ret != 0 { return fmt.Errorf("MsiInstallProductW error: %s", syscall.Errno(ret)) } return nil } // MSIInfo returns the ProductName and ProductCode for an MSI. func MSIInfo(path string) (string, string, error) { setUIMode() if err := coInitializeEx(); err != nil { return "", "", err } defer ole.CoUninitialize() const MSIOPENPACKAGEFLAGS_IGNOREMACHINESTATE = 1 handle, err := msiOpenPackageExW(path, MSIOPENPACKAGEFLAGS_IGNOREMACHINESTATE) if err != nil { return "", "", fmt.Errorf("error opening MSI package %q: %v", path, err) } defer msiCloseHandle(handle) productCode, err := msiGetProductPropertyW(handle, "ProductCode") if err != nil { return "", "", fmt.Errorf("error getting ProductCode property: %v", err) } productName, err := msiGetProductPropertyW(handle, "ProductName") if err != nil { return "", "", fmt.Errorf("error getting ProductName property: %v", err) } return productName, productCode, nil } // MSIInstalled returns if the msi ProductCode is installed. func MSIInstalled(productCode string) (bool, error) { setUIMode() if err := coInitializeEx(); err != nil { return false, err } defer ole.CoUninitialize() state, err := msiMsiQueryProductStateW(productCode) if err != nil { return false, err } return state == INSTALLSTATE_DEFAULT, nil } // InstallMSIPackage installs an msi package. func InstallMSIPackage(ctx context.Context, path string, args []string) error { setUIMode() args = append(msiInstallArgs, args...) clog.Infof(ctx, "Installing msi package %q with command line %q.", path, args) if err := msiInstallProductW(path, args); err != nil { return fmt.Errorf("error installing MSI package %q: %v", path, err) } return nil } osconfig-20250416.02/packages/packages.go000066400000000000000000000153721477773331400177210ustar00rootroot00000000000000// Copyright 2017 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package packages provides package management functions for Windows and Linux // systems. package packages import ( "context" "fmt" "os/exec" "sort" "strings" "time" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/osinfo" "github.com/GoogleCloudPlatform/osconfig/util" ) var ( // AptExists indicates whether apt is installed. AptExists bool // DpkgExists indicates whether dpkg is installed. DpkgExists bool // DpkgQueryExists indicates whether dpkg-query is installed. DpkgQueryExists bool // YumExists indicates whether yum is installed. YumExists bool // ZypperExists indicates whether zypper is installed. ZypperExists bool // RPMExists indicates whether rpm is installed. RPMExists bool // RPMQueryExists indicates whether rpmquery is installed. RPMQueryExists bool // COSPkgInfoExists indicates whether COS package information is available. COSPkgInfoExists bool // GemExists indicates whether gem is installed. GemExists bool // PipExists indicates whether pip is installed. PipExists bool // GooGetExists indicates whether googet is installed. GooGetExists bool // MSIExists indicates whether MSIs can be installed. MSIExists bool noarch = osinfo.NormalizeArchitecture("noarch") runner = util.CommandRunner(&util.DefaultRunner{}) ptyrunner = util.CommandRunner(&ptyRunner{}) ) // Packages is a selection of packages based on their manager. type Packages struct { Yum []*PkgInfo `json:"yum,omitempty"` Rpm []*PkgInfo `json:"rpm,omitempty"` Apt []*PkgInfo `json:"apt,omitempty"` Deb []*PkgInfo `json:"deb,omitempty"` Zypper []*PkgInfo `json:"zypper,omitempty"` ZypperPatches []*ZypperPatch `json:"zypperPatches,omitempty"` COS []*PkgInfo `json:"cos,omitempty"` Gem []*PkgInfo `json:"gem,omitempty"` Pip []*PkgInfo `json:"pip,omitempty"` GooGet []*PkgInfo `json:"googet,omitempty"` WUA []*WUAPackage `json:"wua,omitempty"` QFE []*QFEPackage `json:"qfe,omitempty"` WindowsApplication []*WindowsApplication `json:"-"` } // PkgInfo describes a package. type PkgInfo struct { Name, Arch, RawArch, Version string Source Source } // Source represents source package from which binary package was built. type Source struct { Name, Version string } func (i *PkgInfo) String() string { return fmt.Sprintf("%s %s %s", i.Name, i.Arch, i.Version) } // ZypperPatch describes a Zypper patch. type ZypperPatch struct { Name, Category, Severity, Summary string } // WUAPackage describes a Windows Update Agent package. type WUAPackage struct { LastDeploymentChangeTime time.Time Title string Description string SupportURL string UpdateID string Categories []string KBArticleIDs []string MoreInfoURLs []string CategoryIDs []string RevisionNumber int32 } // QFEPackage describes a Windows Quick Fix Engineering package. type QFEPackage struct { Caption, Description, HotFixID, InstalledOn string } // WindowsApplication describes a Windows Application. type WindowsApplication struct { DisplayName string DisplayVersion string InstallDate time.Time Publisher string HelpLink string } func run(ctx context.Context, cmd string, args []string) ([]byte, error) { stdout, stderr, err := runner.Run(ctx, exec.CommandContext(ctx, cmd, args...)) if err != nil { return nil, fmt.Errorf("error running %s with args %q: %v, stdout: %q, stderr: %q", cmd, args, err, stdout, stderr) } return stdout, nil } func runWithDeadline(ctx context.Context, timeout time.Duration, cmd string, args []string) ([]byte, error) { ctxWithTimeout, cancel := context.WithTimeout(ctx, timeout) defer cancel() return run(ctxWithTimeout, cmd, args) } func formatFieldsMappingToFormattingString(fieldsMapping map[string]string) string { fieldsDescriptors := make([]string, 0, len(fieldsMapping)) for name, selector := range fieldsMapping { // Format field name and its selector to one single entry separated by ":" and each of them wrapped in quotes // Examples: // name:source_name, selector:${source:Package -> ""source_name":"${source:Package}"". // name:source_name, selector:%{NAME} -> ""source_name":"%{NAME}"". fieldsDescriptors = append(fieldsDescriptors, fmt.Sprintf("\"%s\":\"%s\"", name, selector)) } // Sort descriptors to get predictable result. sort.Strings(fieldsDescriptors) // Returns string to format all information in json // Example: {"package":"${Package}","architecture":"${Architecture}","version":"${Version}","status":"${db:Status-Status}"...}\n // See dpkgInfoFieldsMapping for full set of fields. return "\\{" + strings.Join(fieldsDescriptors, ",") + "\\}\n" } type packageMetadata struct { Package string `json:"package"` Architecture string `json:"architecture"` Version string `json:"version"` Status string `json:"status"` SourceName string `json:"source_name"` SourceVersion string `json:"source_version"` } func pkgInfoFromPackageMetadata(pm packageMetadata) *PkgInfo { return &PkgInfo{ Name: pm.Package, Arch: osinfo.NormalizeArchitecture(pm.Architecture), Version: pm.Version, Source: Source{ Name: pm.SourceName, Version: pm.SourceVersion, }, } } type ptyRunner struct{} func (p *ptyRunner) Run(ctx context.Context, cmd *exec.Cmd) ([]byte, []byte, error) { clog.Debugf(ctx, "Running %q with args %q\n", cmd.Path, cmd.Args[1:]) stdout, stderr, err := runWithPty(cmd) clog.Debugf(ctx, "%s %q output:\n%s", cmd.Path, cmd.Args[1:], strings.ReplaceAll(string(stdout), "\n", "\n ")) return stdout, stderr, err } // SetCommandRunner allows external clients to set a custom commandRunner. func SetCommandRunner(commandRunner util.CommandRunner) { runner = commandRunner } // SetPtyCommandRunner allows external clients to set a custom // custom commandRunner. func SetPtyCommandRunner(commandRunner util.CommandRunner) { ptyrunner = commandRunner } osconfig-20250416.02/packages/packages_linux.go000066400000000000000000000101571477773331400211340ustar00rootroot00000000000000/* Copyright 2017 Google Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package packages import ( "context" "errors" "fmt" "strings" "github.com/GoogleCloudPlatform/osconfig/clog" ) // GetPackageUpdates gets all available package updates from any known // installed package manager. func GetPackageUpdates(ctx context.Context) (*Packages, error) { pkgs := Packages{} var errs []string if AptExists { apt, err := AptUpdates(ctx, AptGetUpgradeType(AptGetFullUpgrade), AptGetUpgradeShowNew(false)) if err != nil { msg := fmt.Sprintf("error getting apt updates: %v", err) clog.Debugf(ctx, "Error: %s", msg) errs = append(errs, msg) } else { pkgs.Apt = apt } } if YumExists { yum, err := YumUpdates(ctx) if err != nil { msg := fmt.Sprintf("error getting yum updates: %v", err) clog.Debugf(ctx, "Error: %s", msg) errs = append(errs, msg) } else { pkgs.Yum = yum } } if ZypperExists { zypper, err := ZypperUpdates(ctx) if err != nil { msg := fmt.Sprintf("error getting zypper updates: %v", err) clog.Debugf(ctx, "Error: %s", msg) errs = append(errs, msg) } else { pkgs.Zypper = zypper } zypperPatches, err := ZypperPatches(ctx) if err != nil { msg := fmt.Sprintf("error getting zypper available patches: %v", err) clog.Debugf(ctx, "Error: %s", msg) errs = append(errs, msg) } else { pkgs.ZypperPatches = zypperPatches } } if GemExists { gem, err := GemUpdates(ctx) if err != nil { msg := fmt.Sprintf("error getting gem updates: %v", err) clog.Debugf(ctx, "Error: %s", msg) } else { pkgs.Gem = gem } } if PipExists { pip, err := PipUpdates(ctx) if err != nil { msg := fmt.Sprintf("error getting pip updates: %v", err) clog.Debugf(ctx, "Error: %s", msg) } else { pkgs.Pip = pip } } var err error if len(errs) != 0 { err = errors.New(strings.Join(errs, "\n")) } return &pkgs, err } // GetInstalledPackages gets all installed packages from any known installed // package manager. func GetInstalledPackages(ctx context.Context) (*Packages, error) { pkgs := &Packages{} var errs []string if RPMQueryExists { rpm, err := InstalledRPMPackages(ctx) if err != nil { msg := fmt.Sprintf("error listing installed rpm packages: %v", err) clog.Debugf(ctx, "Error: %s", msg) errs = append(errs, msg) } else { pkgs.Rpm = rpm } } if ZypperExists { zypperPatches, err := ZypperInstalledPatches(ctx) if err != nil { msg := fmt.Sprintf("error getting zypper installed patches: %v", err) clog.Debugf(ctx, "Error: %s", msg) errs = append(errs, msg) } else { pkgs.ZypperPatches = zypperPatches } } if DpkgQueryExists { deb, err := InstalledDebPackages(ctx) if err != nil { msg := fmt.Sprintf("error listing installed deb packages: %v", err) clog.Debugf(ctx, "Error: %s", msg) errs = append(errs, msg) } else { pkgs.Deb = deb } } if COSPkgInfoExists { cos, err := InstalledCOSPackages() if err != nil { msg := fmt.Sprintf("error listing installed COS packages: %v", err) clog.Debugf(ctx, "Error: %s", msg) errs = append(errs, msg) } else { pkgs.COS = cos } } if GemExists { gem, err := InstalledGemPackages(ctx) if err != nil { msg := fmt.Sprintf("error listing installed gem packages: %v", err) clog.Debugf(ctx, "Error: %s", msg) } else { pkgs.Gem = gem } } if PipExists { pip, err := InstalledPipPackages(ctx) if err != nil { msg := fmt.Sprintf("error listing installed pip packages: %v", err) clog.Debugf(ctx, "Error: %s", msg) } else { pkgs.Pip = pip } } var err error if len(errs) != 0 { err = errors.New(strings.Join(errs, "\n")) } return pkgs, err } osconfig-20250416.02/packages/packages_test.go000066400000000000000000000043211477773331400207500ustar00rootroot00000000000000// Copyright 2017 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package packages import ( "context" "io/ioutil" "os" "os/exec" "path/filepath" utilmocks "github.com/GoogleCloudPlatform/osconfig/util/mocks" "github.com/golang/mock/gomock" ) var pkgs = []string{"pkg1", "pkg2"} var testCtx = context.Background() type expectedCommand struct { cmd *exec.Cmd envs []string stdout []byte stderr []byte err error } func setExpectations(mockCommandRunner *utilmocks.MockCommandRunner, expectedCommandsChain []expectedCommand) { if len(expectedCommandsChain) == 0 { return } var prev *gomock.Call for _, expectedCmd := range expectedCommandsChain { cmd := expectedCmd.cmd if len(expectedCmd.envs) > 0 { cmd.Env = append(os.Environ(), expectedCmd.envs...) } if prev == nil { prev = mockCommandRunner.EXPECT(). Run(testCtx, utilmocks.EqCmd(cmd)). Return(expectedCmd.stdout, expectedCmd.stderr, expectedCmd.err).Times(1) } else { prev = mockCommandRunner.EXPECT(). Run(testCtx, utilmocks.EqCmd(cmd)). After(prev). Return(expectedCmd.stdout, expectedCmd.stderr, expectedCmd.err).Times(1) } } } func formatError(err error) string { if err == nil { return "" } return err.Error() } func getMockRun(content []byte, err error) func(_ context.Context, cmd *exec.Cmd) ([]byte, error) { return func(_ context.Context, cmd *exec.Cmd) ([]byte, error) { return content, err } } // TODO: move this to a common helper package func helperLoadBytes(name string) ([]byte, error) { path := filepath.Join("testdata", name) // relative path bytes, err := ioutil.ReadFile(path) if err != nil { return nil, err } return bytes, nil } osconfig-20250416.02/packages/packages_windows.go000066400000000000000000000101421477773331400214610ustar00rootroot00000000000000/* Copyright 2017 Google Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package packages import ( "context" "encoding/json" "errors" "fmt" "os" "os/exec" "strings" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/util" ole "github.com/go-ole/go-ole" ) func coInitializeEx() error { if err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED); err != nil { e, ok := err.(*ole.OleError) // S_OK and S_FALSE are both are Success codes. // https://docs.microsoft.com/en-us/windows/win32/learnwin32/error-handling-in-com if !ok || (e.Code() != S_OK && e.Code() != S_FALSE) { return fmt.Errorf(`ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED): %v`, err) } } return nil } // In order to work around memory issues with the WUA library we spawn a // new process for these inventory queries. func wuaUpdates(ctx context.Context, query string) ([]*WUAPackage, error) { exe, err := os.Executable() if err != nil { return nil, err } var wua []*WUAPackage stdout, stderr, err := runner.Run(ctx, exec.Command(exe, "wuaupdates", query)) if err != nil { return nil, fmt.Errorf("error running agent to query for WUA updates, err: %v, stderr: %q ", err, stderr) } if err := json.Unmarshal(stdout, &wua); err != nil { return nil, err } return wua, nil } // GetPackageUpdates gets available package updates GooGet as well as any // available updates from Windows Update Agent. func GetPackageUpdates(ctx context.Context) (*Packages, error) { var pkgs Packages var errs []string if GooGetExists { if googet, err := GooGetUpdates(ctx); err != nil { msg := fmt.Sprintf("error listing googet updates: %v", err) clog.Debugf(ctx, "Error: %s", msg) errs = append(errs, msg) } else { pkgs.GooGet = googet } } clog.Debugf(ctx, "Searching for available WUA updates.") if wua, err := wuaUpdates(ctx, "IsInstalled=0"); err != nil { msg := fmt.Sprintf("error listing installed Windows updates: %v", err) clog.Debugf(ctx, "Error: %s", msg) errs = append(errs, msg) } else { pkgs.WUA = wua } var err error if len(errs) != 0 { err = errors.New(strings.Join(errs, "\n")) } return &pkgs, err } // GetInstalledPackages gets all installed GooGet packages and Windows updates. // Windows updates are read from Windows Update Agent and Win32_QuickFixEngineering. func GetInstalledPackages(ctx context.Context) (*Packages, error) { var pkgs Packages var errs []string if util.Exists(googet) { if googet, err := InstalledGooGetPackages(ctx); err != nil { msg := fmt.Sprintf("error listing installed googet packages: %v", err) clog.Debugf(ctx, "Error: %s", msg) errs = append(errs, msg) } else { pkgs.GooGet = googet } } clog.Debugf(ctx, "Searching for installed WUA updates.") if wua, err := wuaUpdates(ctx, "IsInstalled=1"); err != nil { msg := fmt.Sprintf("error listing installed Windows updates: %v", err) clog.Debugf(ctx, "Error: %s", msg) errs = append(errs, msg) } else { pkgs.WUA = wua } if qfe, err := QuickFixEngineering(ctx); err != nil { msg := fmt.Sprintf("error listing installed QuickFixEngineering updates: %v", err) clog.Debugf(ctx, "Error: %s", msg) errs = append(errs, msg) } else { pkgs.QFE = qfe } clog.Debugf(ctx, "Listing Windows Applications.") if windowsApplications, err := GetWindowsApplications(ctx); err != nil { msg := fmt.Sprintf("error listing installed Windows Applications: %v", err) clog.Debugf(ctx, "Error: %s", msg) errs = append(errs, msg) } else { pkgs.WindowsApplication = windowsApplications } var err error if len(errs) != 0 { err = errors.New(strings.Join(errs, "\n")) } return &pkgs, err } osconfig-20250416.02/packages/pip.go000066400000000000000000000043721477773331400167310ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package packages import ( "context" "encoding/json" "runtime" "time" "github.com/GoogleCloudPlatform/osconfig/util" ) var ( pip string pipListArgs = []string{"list", "--format=json"} pipOutdatedArgs = append(pipListArgs, "--outdated") pipListTimeout = 15 * time.Second pipOutdatedTimeout = 15 * time.Second ) func init() { if runtime.GOOS != "windows" { pip = "/usr/bin/pip" } PipExists = util.Exists(pip) } type pipUpdatesPkg struct { Name string `json:"name"` LatestVersion string `json:"latest_version"` } type pipInstalledPkg struct { Name string `json:"name"` Version string `json:"version"` } // PipUpdates queries for all available pip updates. func PipUpdates(ctx context.Context) ([]*PkgInfo, error) { out, err := runWithDeadline(ctx, pipOutdatedTimeout, pip, pipOutdatedArgs) if err != nil { return nil, err } var pipUpdates []pipUpdatesPkg if err := json.Unmarshal(out, &pipUpdates); err != nil { return nil, err } var pkgs []*PkgInfo for _, pkg := range pipUpdates { pkgs = append(pkgs, &PkgInfo{Name: pkg.Name, Arch: noarch, Version: pkg.LatestVersion}) } return pkgs, nil } // InstalledPipPackages queries for all installed pip packages. func InstalledPipPackages(ctx context.Context) ([]*PkgInfo, error) { out, err := runWithDeadline(ctx, pipListTimeout, pip, pipListArgs) if err != nil { return nil, err } var pipUpdates []pipInstalledPkg if err := json.Unmarshal(out, &pipUpdates); err != nil { return nil, err } var pkgs []*PkgInfo for _, pkg := range pipUpdates { pkgs = append(pkgs, &PkgInfo{Name: pkg.Name, Arch: noarch, Version: pkg.Version}) } return pkgs, nil } osconfig-20250416.02/packages/pty_linux.go000066400000000000000000000066131477773331400201740ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package packages import ( "bufio" "bytes" "fmt" "io" "os" "os/exec" "path/filepath" "strconv" "sync" "syscall" "unsafe" "golang.org/x/sys/unix" ) func ioctl(fd, req, arg uintptr) (err error) { _, _, e1 := unix.Syscall(unix.SYS_IOCTL, fd, req, arg) if e1 != 0 { err = syscall.Errno(e1) } return } // This is used for anytime we need to parse YUM output. // See https://bugzilla.redhat.com/show_bug.cgi?id=584525#c21 // TODO: We should probably look into a thin python shim we can // interact with that the utilizes the yum libraries. func runWithPty(cmd *exec.Cmd) ([]byte, []byte, error) { // Much of this logic was taken from, without the CGO stuff: // https://golang.org/src/os/signal/signal_cgo_test.go pty, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0) if err != nil { return nil, nil, err } defer pty.Close() // grantpt doesn't appear to be required anymore. // unlockpt var i int if err := ioctl(pty.Fd(), unix.TIOCSPTLCK, uintptr(unsafe.Pointer(&i))); err != nil { return nil, nil, fmt.Errorf("error from ioctl TIOCSPTLCK: %v", err) } // ptsname var u uint32 if err := ioctl(pty.Fd(), unix.TIOCGPTN, uintptr(unsafe.Pointer(&u))); err != nil { return nil, nil, fmt.Errorf("error from ioctl TIOCGPTN: %v", err) } path := filepath.Join("/dev/pts", strconv.Itoa(int(u))) tty, err := os.OpenFile(path, os.O_RDWR|syscall.O_NOCTTY, 0) if err != nil { return nil, nil, err } defer tty.Close() if err := unix.IoctlSetWinsize(int(pty.Fd()), syscall.TIOCSWINSZ, &unix.Winsize{Row: 1, Col: 500}); err != nil { return nil, nil, fmt.Errorf("error from IoctlSetWinsize: %v", err) } var stderr bytes.Buffer cmd.Stdin = tty cmd.Stdout = tty cmd.Stderr = &stderr cmd.SysProcAttr = &syscall.SysProcAttr{ Setctty: true, Setsid: true, Ctty: 0, // Stdin of the child process } var stdout bytes.Buffer var retErr error var wg sync.WaitGroup wg.Add(1) go func() { defer wg.Done() input := bufio.NewReader(pty) for { b, err := input.ReadBytes('\n') if err != nil { if perr, ok := err.(*os.PathError); ok { err = perr.Err } if err != io.EOF && err != syscall.EIO { retErr = err } return } if _, err := stdout.Write(b); err != nil { retErr = err return } } }() cmdErr := cmd.Run() if err := tty.Close(); err != nil { return stdout.Bytes(), stderr.Bytes(), err } wg.Wait() if cmdErr != nil { // Yum returns non-zero exit values on non-error conditions. // Errors which are *not* in this category indicate failure. if _, ok := cmdErr.(*exec.ExitError); !ok { return stdout.Bytes(), stderr.Bytes(), cmdErr } } // Exit code 0 means no updates, 1 probably means there are but we just didn't install them. if cmdErr == nil { return nil, nil, nil } return stdout.Bytes(), stderr.Bytes(), retErr } osconfig-20250416.02/packages/qfe_windows.go000066400000000000000000000030521477773331400204600ustar00rootroot00000000000000/* Copyright 2019 Google Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package packages import ( "context" "fmt" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/StackExchange/wmi" ) type win32QuickFixEngineering struct { Caption, Description, HotFixID, InstalledOn string } // QuickFixEngineering queries the wmi object win32_QuickFixEngineering for a list of installed updates. func QuickFixEngineering(ctx context.Context) ([]*QFEPackage, error) { var updts []win32QuickFixEngineering query := "SELECT Caption, Description, HotFixID, InstalledOn FROM Win32_QuickFixEngineering" clog.Debugf(ctx, "Querying WMI for installed QuickFixEngineering updates, query=%q.", query) if err := wmi.Query(query, &updts); err != nil { return nil, fmt.Errorf("wmi.Query(%q) error: %v", query, err) } qfe := make([]*QFEPackage, len(updts)) for i, update := range updts { qfe[i] = &QFEPackage{ Caption: update.Caption, Description: update.Description, HotFixID: update.HotFixID, InstalledOn: update.InstalledOn, } } return qfe, nil } osconfig-20250416.02/packages/rpm.go000066400000000000000000000062331477773331400167350ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package packages import ( "bytes" "context" "encoding/json" "fmt" "runtime" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/util" ) var ( rpmquery string rpm string rpmqueryFields = map[string]string{ "package": "%{NAME}", "architecture": "%{ARCH}", // %|EPOCH?{%{EPOCH}:}:{}| == if EPOCH then prepend "%{EPOCH}:" to version. "version": "%|EPOCH?{%{EPOCH}:}:{}|%{VERSION}-%{RELEASE}", "source_name": "%{SOURCERPM}", } rpmInstallArgs = []string{"--upgrade", "--replacepkgs", "-v"} rpmqueryArgs = []string{"--queryformat", formatFieldsMappingToFormattingString(rpmqueryFields)} rpmqueryInstalledArgs = append(rpmqueryArgs, "-a") rpmqueryRPMArgs = append(rpmqueryArgs, "-p") ) func init() { if runtime.GOOS != "windows" { rpmquery = "/usr/bin/rpmquery" rpm = "/bin/rpm" } RPMQueryExists = util.Exists(rpmquery) RPMExists = util.Exists(rpm) } func parseInstalledRPMPackages(ctx context.Context, data []byte) []*PkgInfo { /* Each line contains an entry in a json format, keep in mind that whole output is not valid json. {"architecture":"x86_64","package":"gcc","source_name":"gcc-11.4.1-3.el9.src.rpm","version":"11.4.1-3.el9"} {"architecture":"noarch","package":"golang-src","source_name":"golang-1.22.3-1.el9.src.rpm","version":"1.22.3-1.el9"} */ lines := bytes.Split(bytes.TrimSpace(data), []byte("\n")) var result []*PkgInfo for _, entry := range lines { var rpm packageMetadata if err := json.Unmarshal(entry, &rpm); err != nil { clog.Debugf(ctx, "unable to parse rpm package info, err %s, raw - %s", err, string(entry)) continue } pkg := pkgInfoFromPackageMetadata(rpm) result = append(result, pkg) } return result } // InstalledRPMPackages queries for all installed rpm packages. func InstalledRPMPackages(ctx context.Context) ([]*PkgInfo, error) { out, err := run(ctx, rpmquery, rpmqueryInstalledArgs) if err != nil { return nil, err } return parseInstalledRPMPackages(ctx, out), nil } // RPMInstall installs an rpm packages. func RPMInstall(ctx context.Context, path string) error { _, err := run(ctx, rpm, append(rpmInstallArgs, path)) return err } // RPMPkgInfo gets PkgInfo from a rpm package. func RPMPkgInfo(ctx context.Context, path string) (*PkgInfo, error) { out, err := run(ctx, rpmquery, append(rpmqueryRPMArgs, path)) if err != nil { return nil, err } pkgs := parseInstalledRPMPackages(ctx, out) if len(pkgs) != 1 { return nil, fmt.Errorf("unexpected number of parsed rpm packages %d: %q", len(pkgs), out) } return pkgs[0], nil } osconfig-20250416.02/packages/rpm_test.go000066400000000000000000000215501477773331400177730ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package packages import ( "errors" "os/exec" "reflect" "testing" utilmocks "github.com/GoogleCloudPlatform/osconfig/util/mocks" "github.com/golang/mock/gomock" ) func TestParseInstalledRPMPackages(t *testing.T) { tests := []struct { name string data []byte want []*PkgInfo }{ { name: "Two packages in input", data: []byte("" + `{"architecture":"x86_64","package":"gcc","source_name":"gcc-11.4.1-3.el9.src.rpm","version":"11.4.1-3.el9"}` + "\n" + `{"architecture":"noarch","package":"golang-src","source_name":"golang-1.22.3-1.el9.src.rpm","version":"1.22.3-1.el9"}`), want: []*PkgInfo{ {Name: "gcc", Arch: "x86_64", Version: "11.4.1-3.el9", Source: Source{Name: "gcc-11.4.1-3.el9.src.rpm"}}, {Name: "golang-src", Arch: "all", Version: "1.22.3-1.el9", Source: Source{Name: "golang-1.22.3-1.el9.src.rpm"}}, }, }, { name: "No valid pacakges", data: []byte("nothing here"), want: nil, }, { name: "Function doesn't panic on nil input", data: nil, want: nil, }, { name: "Skip invalid packages", data: []byte("" + `{"architecture":"x86_64","package":"gcc","source_name":"gcc-11.4.1-3.el9.src.rpm","version":"11.4.1-3.el9"}` + "\n" + "something we dont understand\n bar noarch 1.2.3-4 "), want: []*PkgInfo{{Name: "gcc", Arch: "x86_64", Version: "11.4.1-3.el9", Source: Source{Name: "gcc-11.4.1-3.el9.src.rpm"}}}, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := parseInstalledRPMPackages(testCtx, tt.data) if !reflect.DeepEqual(got, tt.want) { t.Errorf("installedRPMPackages() = %v, want %v", got, tt.want) } }) } } func TestInstalledRPMPackages(t *testing.T) { tests := []struct { name string expectedCommandsChain []expectedCommand expectedResults []*PkgInfo expectedError error }{ { name: "success path", expectedCommandsChain: []expectedCommand{ { cmd: exec.Command(rpmquery, rpmqueryInstalledArgs...), stdout: []byte("" + `{"architecture":"x86_64","package":"gcc","source_name":"gcc-11.4.1-3.el9.src.rpm","version":"11.4.1-3.el9"}` + "\n" + `{"architecture":"noarch","package":"golang-src","source_name":"golang-1.22.3-1.el9.src.rpm","version":"1.22.3-1.el9"}`), stderr: []byte("stderr"), err: nil, }, }, expectedResults: []*PkgInfo{ {Name: "gcc", Arch: "x86_64", Version: "11.4.1-3.el9", Source: Source{Name: "gcc-11.4.1-3.el9.src.rpm"}}, {Name: "golang-src", Arch: "all", Version: "1.22.3-1.el9", Source: Source{Name: "golang-1.22.3-1.el9.src.rpm"}}, }, expectedError: nil, }, { name: "rpmquery command failed", expectedCommandsChain: []expectedCommand{{ cmd: exec.Command(rpmquery, rpmqueryInstalledArgs...), stdout: []byte("stdout"), stderr: []byte("stderr"), err: errors.New("unexpected error"), }, }, expectedResults: nil, expectedError: errors.New("error running /usr/bin/rpmquery with args [\"--queryformat\" \"\\\\{\\\"architecture\\\":\\\"%{ARCH}\\\",\\\"package\\\":\\\"%{NAME}\\\",\\\"source_name\\\":\\\"%{SOURCERPM}\\\",\\\"version\\\":\\\"%|EPOCH?{%{EPOCH}:}:{}|%{VERSION}-%{RELEASE}\\\"\\\\}\\n\" \"-a\"]: unexpected error, stdout: \"stdout\", stderr: \"stderr\""), }, } for _, tt := range tests { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) runner = mockCommandRunner t.Run(tt.name, func(t *testing.T) { setExpectations(mockCommandRunner, tt.expectedCommandsChain) results, err := InstalledRPMPackages(testCtx) if !reflect.DeepEqual(err, tt.expectedError) { t.Errorf("InstalledRPMPackages: unexpected error, expect %q, got %q", formatError(tt.expectedError), formatError(err)) } if !reflect.DeepEqual(results, tt.expectedResults) { t.Errorf("InstalledRPMPackages: unexpected result, expect %v, got %v", pkgs, tt.expectedResults) } }) } } func TestRPMPkgInfo(t *testing.T) { tests := []struct { name string path string expectedCommandsChain []expectedCommand expectedResult *PkgInfo expectedError error }{ { name: "single package", path: "/tmp/gcc.rpm", expectedCommandsChain: []expectedCommand{ { cmd: exec.Command(rpmquery, append(rpmqueryRPMArgs, "/tmp/gcc.rpm")...), stdout: []byte(`{"architecture":"x86_64","package":"gcc","source_name":"gcc-11.4.1-3.el9.src.rpm","version":"11.4.1-3.el9"}`), stderr: []byte("stderr"), err: nil, }, }, expectedResult: &PkgInfo{ Name: "gcc", Arch: "x86_64", Version: "11.4.1-3.el9", Source: Source{Name: "gcc-11.4.1-3.el9.src.rpm"}, }, expectedError: nil, }, { name: "multiple packages", path: "/tmp/gcc.rpm", expectedCommandsChain: []expectedCommand{ { cmd: exec.Command(rpmquery, append(rpmqueryRPMArgs, "/tmp/gcc.rpm")...), stdout: []byte("" + `{"architecture":"x86_64","package":"gcc","source_name":"gcc-11.4.1-3.el9.src.rpm","version":"11.4.1-3.el9"}` + "\n" + `{"architecture":"noarch","package":"golang-src","source_name":"golang-1.22.3-1.el9.src.rpm","version":"1.22.3-1.el9"}`), stderr: []byte("stderr"), err: nil, }, }, expectedResult: nil, expectedError: errors.New("unexpected number of parsed rpm packages 2: \"{\\\"architecture\\\":\\\"x86_64\\\",\\\"package\\\":\\\"gcc\\\",\\\"source_name\\\":\\\"gcc-11.4.1-3.el9.src.rpm\\\",\\\"version\\\":\\\"11.4.1-3.el9\\\"}\\n{\\\"architecture\\\":\\\"noarch\\\",\\\"package\\\":\\\"golang-src\\\",\\\"source_name\\\":\\\"golang-1.22.3-1.el9.src.rpm\\\",\\\"version\\\":\\\"1.22.3-1.el9\\\"}\""), }, { name: "rpmquery returns no package", path: "/tmp/gcc.rpm", expectedCommandsChain: []expectedCommand{ { cmd: exec.Command(rpmquery, append(rpmqueryRPMArgs, "/tmp/gcc.rpm")...), stdout: []byte("no packages"), stderr: []byte("stderr"), err: nil, }, }, expectedResult: nil, expectedError: errors.New("unexpected number of parsed rpm packages 0: \"no packages\""), }, { name: "rpmquery failed with error", path: "/tmp/gcc.rpm", expectedCommandsChain: []expectedCommand{ { cmd: exec.Command(rpmquery, append(rpmqueryRPMArgs, "/tmp/gcc.rpm")...), stdout: []byte("stdout"), stderr: []byte("stderr"), err: errors.New("unexpected error"), }, }, expectedResult: nil, expectedError: errors.New("error running /usr/bin/rpmquery with args [\"--queryformat\" \"\\\\{\\\"architecture\\\":\\\"%{ARCH}\\\",\\\"package\\\":\\\"%{NAME}\\\",\\\"source_name\\\":\\\"%{SOURCERPM}\\\",\\\"version\\\":\\\"%|EPOCH?{%{EPOCH}:}:{}|%{VERSION}-%{RELEASE}\\\"\\\\}\\n\" \"-p\" \"/tmp/gcc.rpm\"]: unexpected error, stdout: \"stdout\", stderr: \"stderr\""), }, } for _, tt := range tests { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) runner = mockCommandRunner t.Run(tt.name, func(t *testing.T) { setExpectations(mockCommandRunner, tt.expectedCommandsChain) result, err := RPMPkgInfo(testCtx, tt.path) if !reflect.DeepEqual(err, tt.expectedError) { t.Errorf("RPMPkgInfo: unexpected error, expect %q, got %q", formatError(tt.expectedError), formatError(err)) } if !reflect.DeepEqual(result, tt.expectedResult) { t.Errorf("RPMPkgInfo: unexpected result, expect %v, got %v", result, tt.expectedResult) } }) } } func TestRPMInstall(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) runner = mockCommandRunner path := "/tmp/test.dpkg" rpmInstallCmd := exec.CommandContext(testCtx, rpm, append(rpmInstallArgs, path)...) //rpm install fail wantErr := errors.New("unexpected error") mockCommandRunner.EXPECT().Run(testCtx, utilmocks.EqCmd(rpmInstallCmd)).Return([]byte("stdout"), []byte("stderr"), wantErr).Times(1) if err := RPMInstall(testCtx, path); reflect.DeepEqual(err, wantErr) { t.Errorf("RPMInstall: expected error %q, but got %q", formatError(wantErr), formatError(err)) } //rpm install succeeded mockCommandRunner.EXPECT().Run(testCtx, utilmocks.EqCmd(rpmInstallCmd)).Return([]byte("stdout"), []byte("stderr"), nil).Times(1) if err := RPMInstall(testCtx, path); err != nil { t.Errorf("RPMInstall: got unexpected error %q", err) } } osconfig-20250416.02/packages/stub_linux.go000066400000000000000000000020261477773331400203270ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build !windows // +build !windows package packages import "context" // InstallMSIPackage is a linux stub function. func InstallMSIPackage(_ context.Context, _ string, _ []string) error { return nil } // MSIInfo is a linux stub function. func MSIInfo(_ string) (string, string, error) { return "", "", nil } // MSIInstalled is a linux stub function. func MSIInstalled(_ string) (bool, error) { return false, nil } osconfig-20250416.02/packages/stub_windows.go000066400000000000000000000014121477773331400206600ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build !linux // +build !linux package packages import ( "os/exec" ) func runWithPty(cmd *exec.Cmd) ([]byte, []byte, error) { return nil, nil, nil } osconfig-20250416.02/packages/testdata/000077500000000000000000000000001477773331400174155ustar00rootroot00000000000000osconfig-20250416.02/packages/testdata/sles_12_zypper_patches000066400000000000000000002352101477773331400237330ustar00rootroot00000000000000 Repository | Name | Category | Severity | Interactive | Status | Summary --------------------------------------------+-----------------------------------------------------+-------------+-----------+----------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- SLE-Module-Adv-Systems-Management12-Updates | SUSE-SLE-Module-Adv-Systems-Management-12-2014-69 | recommended | moderate | --- | not needed | Recommended update for machinery SLE-Module-Adv-Systems-Management12-Updates | SUSE-SLE-Module-Adv-Systems-Management-12-2015-196 | recommended | low | --- | not needed | Recommended update for facter SLE-Module-Adv-Systems-Management12-Updates | SUSE-SLE-Module-Adv-Systems-Management-12-2015-427 | recommended | low | --- | applied | Recommended update for SUSE Linux Enterprise Modules SLE-Module-Adv-Systems-Management12-Updates | SUSE-SLE-Module-Adv-Systems-Management-12-2016-782 | optional | low | --- | not needed | Optional update for lmdb SLE-Module-Adv-Systems-Management12-Updates | SUSE-SLE-Module-Adv-Systems-Management-12-2017-1310 | security | important | --- | not needed | Security update for puppet SLE-Module-Adv-Systems-Management12-Updates | SUSE-SLE-Module-Adv-Systems-Management-12-2017-1384 | recommended | moderate | restart | not needed | Recommended update for Salt SLE-Module-Adv-Systems-Management12-Updates | SUSE-SLE-Module-Adv-Systems-Management-12-2017-1660 | security | moderate | restart | not needed | Security update for Salt SLE-Module-Adv-Systems-Management12-Updates | SUSE-SLE-Module-Adv-Systems-Management-12-2017-170 | optional | low | --- | not needed | Initial release of Salt SLE-Module-Adv-Systems-Management12-Updates | SUSE-SLE-Module-Adv-Systems-Management-12-2017-1892 | recommended | moderate | --- | applied | Recommended update for sle-module-adv-systems-management-release SLE-Module-Adv-Systems-Management12-Updates | SUSE-SLE-Module-Adv-Systems-Management-12-2018-379 | security | moderate | --- | not needed | Security update for puppet SLE-Module-Adv-Systems-Management12-Updates | SUSE-SLE-Module-Adv-Systems-Management-12-2018-925 | optional | low | --- | applied | Initial release of python3-requests SLE-Module-Adv-Systems-Management12-Updates | SUSE-SLE-Module-Adv-Systems-Management-12-2020-1147 | security | critical | --- | not needed | Security update for salt SLE-Module-Adv-Systems-Management12-Updates | SUSE-SLE-Module-Adv-Systems-Management-12-2020-3245 | security | critical | restart | not needed | Security update for Salt SLE-Module-Adv-Systems-Management12-Updates | SUSE-SLE-Module-Adv-Systems-Management-12-2020-775 | recommended | important | --- | not needed | Recommended update for python-botocore SLE-Module-Adv-Systems-Management12-Updates | SUSE-SLE-Module-Adv-Systems-Management-12-2021-2102 | security | important | restart | not needed | Security update for Salt SLE-Module-Adv-Systems-Management12-Updates | SUSE-SLE-Module-Adv-Systems-Management-12-2022-1819 | security | moderate | --- | applied | Security update for python-requests SLE-Module-Containers12-Updates | SUSE-SLE-Module-Containers-12-2015-287 | recommended | low | --- | applied | Initial update for the Containers-Module SLE-Module-Containers12-Updates | SUSE-SLE-Module-Containers-12-2015-691 | security | important | --- | applied | Security update for docker SLE-Module-Containers12-Updates | SUSE-SLE-Module-Containers-12-2017-1143 | recommended | moderate | message | applied | Recommended update for Docker, RunC, Containerd SLE-Module-Containers12-Updates | SUSE-SLE-Module-Containers-12-2017-201 | security | moderate | message | applied | Security update for containerd, docker, runc SLE-Module-Containers12-Updates | SUSE-SLE-Module-Containers-12-2017-249 | recommended | important | --- | applied | Recommended update for docker SLE-Module-Containers12-Updates | SUSE-SLE-Module-Containers-12-2018-1124 | recommended | moderate | message | applied | Version update for docker, catatonit SLE-Module-Containers12-Updates | SUSE-SLE-Module-Containers-12-2018-273 | security | important | --- | applied | Version update for docker, docker-runc, containerd, golang-github-docker-libnetwork SLE-Module-Containers12-Updates | SUSE-SLE-Module-Containers-12-2018-2817 | recommended | moderate | message | applied | Security update for containerd, docker, docker-runc, go, go1.10, golang-github-docker-libnetwork, golang-packaging SLE-Module-Containers12-Updates | SUSE-SLE-Module-Containers-12-2019-1264 | security | important | message | applied | Security update for containerd, docker, docker-runc, go, go1.11, go1.12, golang-github-docker-libnetwork SLE-Module-Containers12-Updates | SUSE-SLE-Module-Containers-12-2019-1368 | security | important | --- | not needed | Recommended update for sles12sp3-docker-image, sles12sp4-image, system-user-root SLE-Module-Containers12-Updates | SUSE-SLE-Module-Containers-12-2020-1664 | security | moderate | reboot,message | applied | Security update for containerd, docker, docker-runc, golang-github-docker-libnetwork SLE-Module-Containers12-Updates | SUSE-SLE-Module-Containers-12-2021-3204 | recommended | important | message | applied | Recommended update for docker SLE-Module-Containers12-Updates | SUSE-SLE-Module-Containers-12-2023-4625 | security | important | message | needed | Security update for containerd, docker, runc SLE-Module-HPC12-Updates | SUSE-SLE-Module-HPC-12-2017-1845 | recommended | moderate | --- | not needed | Initial release of mvapich2 for HPC (v2.2, gcc) SLE-Module-HPC12-Updates | SUSE-SLE-Module-HPC-12-2023-3860 | feature | moderate | --- | not needed | Feature update for slurm and pdsh SLE-Module-Legacy12-Updates | SUSE-SLE-Module-Legacy-12-2021-3019 | security | low | --- | not needed | Security update for compat-openssl098 SLE-Module-Public-Cloud12-Updates | SUSE-SLE-Module-Public-Cloud-12-2015-130 | security | important | reboot | not needed | Security update for the Linux Kernel SLE-Module-Public-Cloud12-Updates | SUSE-SLE-Module-Public-Cloud-12-2015-142 | optional | low | --- | not needed | Recommended update for Azure and HP service settings SLE-Module-Public-Cloud12-Updates | SUSE-SLE-Module-Public-Cloud-12-2015-287 | recommended | low | --- | not needed | Initial update for the Containers-Module SLE-Module-Public-Cloud12-Updates | SUSE-SLE-Module-Public-Cloud-12-2015-588 | security | moderate | reboot | not needed | Security update for kernel-source SLE-Module-Public-Cloud12-Updates | SUSE-SLE-Module-Public-Cloud-12-2017-1397 | recommended | important | reboot | not needed | Recommended update for the Linux Kernel SLE-Module-Public-Cloud12-Updates | SUSE-SLE-Module-Public-Cloud-12-2017-995 | security | critical | reboot | not needed | Security update for the Linux Kernel SLE-Module-Public-Cloud12-Updates | SUSE-SLE-Module-Public-Cloud-12-2020-1257 | recommended | critical | --- | not needed | Recommended update for regionServiceClientConfigAzure SLE-Module-Public-Cloud12-Updates | SUSE-SLE-Module-Public-Cloud-12-2020-2135 | optional | low | --- | applied | Optional update for python-setuptools SLE-Module-Public-Cloud12-Updates | SUSE-SLE-Module-Public-Cloud-12-2021-2194 | recommended | important | --- | needed | Recommended update for the Azure and AWS SDKs SLE-Module-Public-Cloud12-Updates | SUSE-SLE-Module-Public-Cloud-12-2022-1063 | recommended | critical | --- | applied | Recommended update for cloud-regionsrv-client SLE-Module-Public-Cloud12-Updates | SUSE-SLE-Module-Public-Cloud-12-2022-1165 | recommended | important | --- | applied | Recommended update for cloud-regionsrv-client SLE-Module-Public-Cloud12-Updates | SUSE-SLE-Module-Public-Cloud-12-2022-2579 | feature | important | --- | not needed | Feature update for regionServiceClientConfigEC2 SLE-Module-Public-Cloud12-Updates | SUSE-SLE-Module-Public-Cloud-12-2023-2931 | feature | critical | --- | not needed | Recommended update for python-instance-billing-flavor-check SLE-Module-Public-Cloud12-Updates | SUSE-SLE-Module-Public-Cloud-12-2023-4468 | security | moderate | --- | needed | Security update for python-urllib3 SLE-Module-Toolchain12-Updates | SUSE-SLE-Module-Toolchain-12-2017-1917 | recommended | low | --- | not needed | Optional update for gcc7 SLE-Module-Toolchain12-Updates | SUSE-SLE-Module-Toolchain-12-2022-949 | feature | moderate | --- | applied | Feature update for lifecycle-data-sle-module-toolchain SLE-Module-Web-Scripting12-Updates | SUSE-SLE-Module-Web-Scripting-12-2018-2849 | security | moderate | --- | not needed | Recommended update for php7 SLE-Module-Web-Scripting12-Updates | SUSE-SLE-Module-Web-Scripting-12-2019-823 | recommended | moderate | --- | not needed | Optional update for php72 SLE-SDK12-SP5-Updates | SUSE-SLE-SDK-12-SP5-2019-2818 | recommended | important | restart | applied | Recommended update for zypper and libzypp SLE-SDK12-SP5-Updates | SUSE-SLE-SDK-12-SP5-2020-3794 | recommended | moderate | restart | applied | Recommended update for libzypp, zypper SLE-SDK12-SP5-Updates | SUSE-SLE-SDK-12-SP5-2020-3909 | security | low | restart | not needed | Security update for PackageKit SLE-SDK12-SP5-Updates | SUSE-SLE-SDK-12-SP5-2020-79 | security | moderate | restart | applied | Security update for libzypp SLE-SDK12-SP5-Updates | SUSE-SLE-SDK-12-SP5-2020-807 | recommended | moderate | --- | not needed | - add 0001-Fix-makefile-consistency-check.patch SLE-SDK12-SP5-Updates | SUSE-SLE-SDK-12-SP5-2021-2180 | security | important | restart | applied | Security update for libsolv SLE-SDK12-SP5-Updates | SUSE-SLE-SDK-12-SP5-2021-2405 | security | moderate | reboot | applied | Security update for systemd SLE-SDK12-SP5-Updates | SUSE-SLE-SDK-12-SP5-2021-2424 | security | important | reboot | applied | Security update for dbus-1 SLE-SDK12-SP5-Updates | SUSE-SLE-SDK-12-SP5-2021-2995 | security | low | --- | applied | Security update for openssl-1_0_0 SLE-SDK12-SP5-Updates | SUSE-SLE-SDK-12-SP5-2021-3016 | recommended | important | --- | not needed | Create update the package in the update channels SLE-SDK12-SP5-Updates | SUSE-SLE-SDK-12-SP5-2022-1169 | recommended | moderate | reboot | applied | Recommended update for systemd SLE-SDK12-SP5-Updates | SUSE-SLE-SDK-12-SP5-2022-323 | security | critical | --- | applied | Security update for samba SLE-SDK12-SP5-Updates | SUSE-SLE-SDK-12-SP5-2022-484 | feature | important | --- | applied | Feature update for tcl and tk SLES12-SP5-Updates | SUSE-SLE-SERVER-12-SP5-2020-1519 | optional | moderate | --- | not needed | Optional update for psqlODBC SLES12-SP5-Updates | SUSE-SLE-SERVER-12-SP5-2020-2164 | recommended | important | reboot | applied | Recommended update for Linux Kernel SLES12-SP5-Updates | SUSE-SLE-SERVER-12-SP5-2020-2981 | security | critical | reboot | applied | Security update for the Linux Kernel SLES12-SP5-Updates | SUSE-SLE-SERVER-12-SP5-2021-2936 | recommended | low | restart | applied | Recommended update for zypper SLES12-SP5-Updates | SUSE-SLE-SERVER-12-SP5-2022-2704 | recommended | moderate | --- | not needed | Re-release for SLE Base System SLES12-SP5-Updates | SUSE-SLE-SERVER-12-SP5-2023-4480 | security | important | --- | needed | Security update for gcc13 SLES12-SP5-Updates | SUSE-SLE-SERVER-12-SP5-2023-4541 | recommended | moderate | --- | needed | Recommended update for autofs SLE-Module-Public-Cloud12-Updates | SUSE-SLE-Module-Public-Cloud-12-2020-1988 | recommended | moderate | --- | not needed | Recommended update for azure-cli, azure-cli-acr, azure-cli-acs, azure-cli-advisor, azure-cli-ams, azure-cli-appservice, azure-cli-backup, azure-cli-batch, azure-cli-batchai, azure-cli-billing, azure-cli-cdn, azure-cli-cloud, azure-cli-cognitiveservices, azure-cli-command-modules-nspkg, azure-cli-component, azure-cli-configure, azure-cli-consumption, azure-cli-container, azure-cli-core, azure-cli-cosmosdb, azure-cli-dla, azure-cli-dls, azure-cli-dms, azure-cli-eventgrid, azure-cli-eventhubs, azure-cli-extension, azure-cli-feedback, azure-cli-find, azure-cli-interactive, azure-cli-iot, azure-cli-keyvault, azure-cli-lab, azure-cli-monitor, azure-cli-network, azure-cli-nspkg, azure-cli-profile, azure-cli-rdbms, azure-cli-redis, azure-cli-reservations, azure-cli-resource, azure-cli-role, azure-cli-search, azure-cli-servicebus, azure-cli-servicefabric, azure-cli-sql, azure-cli-storage, azure-cli-taskhelp, azure-cli-telemetry, azure-cli-vm osconfig-20250416.02/packages/testdata/sles_15_zypper_patches000066400000000000000000000240471477773331400237420ustar00rootroot00000000000000 Repository | Name | Category | Severity | Interactive | Status | Summary ----------------------------------------------+-------------------------------------------------------+-------------+-----------+-------------+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-335 | recommended | moderate | --- | not needed | Recommended update for hyper-v SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-2233 | security | important | --- | not needed | Security update for cups-filters SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-2236 | recommended | critical | --- | not needed | Security update for python-looseversion SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-2239 | recommended | low | --- | not needed | Recommended update for zram-generator SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-2240 | recommended | moderate | --- | applied | Recommended update for systemd SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-2243 | security | important | reboot | not needed | Security update for ucode-intel SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-2245 | recommended | moderate | restart | applied | Recommended update for libzypp, zypper SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-2269 | feature | moderate | --- | not needed | Feature update for javapackages-tools SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-2307 | recommended | low | --- | applied | Recommended update for kbd SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-2313 | security | important | --- | applied | Security update for c-ares SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-2320 | security | moderate | --- | not needed | Security update for wireshark SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-2484 | security | moderate | --- | applied | Security update for openldap2 SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-2495 | recommended | important | restart | applied | Recommended update for libzypp SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-2535 | security | important | reboot | applied | Security update for xen SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-2554 | recommended | critical | --- | not needed | Recommended update for nvme-stas SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-2571 | security | moderate | restart | applied | Security update for Salt SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-2582 | recommended | moderate | restart | not needed | Recommended update for salt SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-2585 | security | moderate | restart | not needed | Security update for salt and python-pyzmq SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-2615 | recommended | important | --- | not needed | Recommended update for mdadm SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-2901 | recommended | important | --- | applied | Recommended update for lvm2 SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-3019 | security | moderate | reboot | not needed | Security update for kernel-firmware SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-3146 | optional | low | --- | not needed | Optional update for mono-core, ghc, ghc-xml-conduit, gstreamer, poppler and python-mccabe SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-3190 | security | low | --- | not needed | Security update for xtrans SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-3413 | feature | important | --- | not needed | Feature update for LibreOffice and xmlsec1 SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-3440 | security | low | --- | applied | Security update for gawk SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-3451 | recommended | moderate | reboot | applied | Recommended update for systemd SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-3634 | security | critical | --- | not needed | Security update for libwebp SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-3704 | security | important | reboot | retracted | Security update for the Linux Kernel SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-3716 | recommended | moderate | --- | needed | Recommended update for libnvme, nvme-cli SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-3821 | security | important | --- | needed | Security update for bind SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-3822 | security | moderate | --- | needed | Security update for supportutils SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-3831 | security | important | reboot | needed | Security update for xen SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-3835 | security | important | --- | not needed | Securitys update for open-vm-tools SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-3843 | recommended | important | --- | needed | Recommended update for suse-build-key SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-3973 | recommended | moderate | restart | needed | Recommended update for zypper SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-4024 | security | low | --- | needed | Security update for shadow SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-4073 | recommended | low | --- | needed | Recommended update for rpm SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-4194 | feature | low | --- | optional | Feature update for python3 SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-4386 | security | important | restart | not needed | Security update for salt SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-4502 | feature | low | --- | not needed | Feature update for python3 SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-4583 | feature | moderate | --- | optional | Feature update for python-psutil SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-4678 | feature | important | --- | optional | Feature update for lvm2 SLE-Module-Desktop-Applications15-SP5-Updates | SUSE-SLE-Module-Desktop-Applications-15-SP5-2023-3550 | optional | moderate | --- | not needed | Optional update for ibus SLE-Module-Public-Cloud15-SP5-Updates | SUSE-SLE-Module-Public-Cloud-15-SP5-2023-2430 | recommended | critical | --- | applied | Recommended update for supportutils-plugin-suse-public-cloud SLE-Module-Public-Cloud15-SP5-Updates | SUSE-SLE-Module-Public-Cloud-15-SP5-2023-2898 | feature | critical | --- | applied | Recommended update for python-instance-billing-flavor-check SLE-Module-Public-Cloud15-SP5-Updates | SUSE-SLE-Module-Public-Cloud-15-SP5-2023-4670 | recommended | critical | --- | needed | Recommended update for regionServiceClientConfigGCE SLE-Module-Basesystem15-SP5-Updates | SUSE-SLE-Module-Basesystem-15-SP5-2023-2783 | security | important | --- | not needed | Security update for grpc, protobuf, python-Deprecated, python-PyGithub, python-aiocontextvars, python-avro, python-bcrypt, python-cryptography, python-cryptography-vectors, python-google-api-core, python-googleapis-common-protos, python-grpcio-gcp, python-humanfriendly, python-jsondiff, python-knack, python-opencensus, python-opencensus-context, python-opencensus-ext-threading, python-opentelemetry-api, python-psutil, python-pytest-asyncio, python-requests, python-websocket-client, python-websockets osconfig-20250416.02/packages/testdata/ubuntu_20_apt_get_full_upgrade000066400000000000000000000040321477773331400254160ustar00rootroot00000000000000Inst open-iscsi [2.0.874-7.1ubuntu6.4] (2.0.874-7.1ubuntu6.5 Ubuntu:20.04/focal-updates [amd64]) Inst distro-info-data [0.43ubuntu1.16] (0.43ubuntu1.17 Ubuntu:20.04/focal-updates [all]) Inst apt-transport-artifact-registry [1:20240607.00-g1] (1:20241017.00-g1 apt-transport-artifact-registry-stable:apt-transport-artifact-registry-stable [amd64]) Inst google-guest-agent [20240716.00-0ubuntu1~20.04.0] (20241011.01-0ubuntu1~20.04.1 Ubuntu:20.04/focal-updates [amd64]) Inst landscape-common [23.02-0ubuntu1~20.04.3] (23.02-0ubuntu1~20.04.4 Ubuntu:20.04/focal-updates [amd64]) Inst pollinate [4.33-3ubuntu1.20.04.1] (4.33-3ubuntu1.20.04.2 Ubuntu:20.04/focal-updates [all]) Inst python3-pyparsing (2.4.6-1 Ubuntu:20.04/focal [all]) Inst python3-packaging (20.3-1 Ubuntu:20.04/focal [all]) Inst snapd [2.65.3+20.04] (2.67.1+20.04 Ubuntu:20.04/focal-updates [amd64]) Inst sosreport [4.5.6-0ubuntu1~20.04.2] (4.8.2-0ubuntu0~20.04.1 Ubuntu:20.04/focal-updates [amd64]) Inst xfsprogs [5.3.0-1ubuntu2] (5.3.0-1ubuntu2.1 Ubuntu:20.04/focal-updates [amd64]) Inst cloud-init [24.3.1-0ubuntu0~20.04.1] (24.4.1-0ubuntu0~20.04.2 Ubuntu:20.04/focal-updates [all]) Conf open-iscsi (2.0.874-7.1ubuntu6.5 Ubuntu:20.04/focal-updates [amd64]) Conf distro-info-data (0.43ubuntu1.17 Ubuntu:20.04/focal-updates [all]) Conf apt-transport-artifact-registry (1:20241017.00-g1 apt-transport-artifact-registry-stable:apt-transport-artifact-registry-stable [amd64]) Conf google-guest-agent (20241011.01-0ubuntu1~20.04.1 Ubuntu:20.04/focal-updates [amd64]) Conf landscape-common (23.02-0ubuntu1~20.04.4 Ubuntu:20.04/focal-updates [amd64]) Conf pollinate (4.33-3ubuntu1.20.04.2 Ubuntu:20.04/focal-updates [all]) Conf python3-pyparsing (2.4.6-1 Ubuntu:20.04/focal [all]) Conf python3-packaging (20.3-1 Ubuntu:20.04/focal [all]) Conf snapd (2.67.1+20.04 Ubuntu:20.04/focal-updates [amd64]) Conf sosreport (4.8.2-0ubuntu0~20.04.1 Ubuntu:20.04/focal-updates [amd64]) Conf xfsprogs (5.3.0-1ubuntu2.1 Ubuntu:20.04/focal-updates [amd64]) Conf cloud-init (24.4.1-0ubuntu0~20.04.2 Ubuntu:20.04/focal-updates [all]) osconfig-20250416.02/packages/testdata/ubuntu_22_apt_get_full_upgrade000066400000000000000000000163601477773331400254270ustar00rootroot00000000000000Inst libpam0g [1.4.0-11ubuntu2.4] (1.4.0-11ubuntu2.5 Ubuntu:22.04/jammy-updates [amd64]) Conf libpam0g (1.4.0-11ubuntu2.5 Ubuntu:22.04/jammy-updates [amd64]) Inst libpam-modules-bin [1.4.0-11ubuntu2.4] (1.4.0-11ubuntu2.5 Ubuntu:22.04/jammy-updates [amd64]) [libpam-modules:amd64 on libpam-modules-bin:amd64] [libpam-modules:amd64 ] Conf libpam-modules-bin (1.4.0-11ubuntu2.5 Ubuntu:22.04/jammy-updates [amd64]) [libpam-modules:amd64 ] Inst libpam-modules [1.4.0-11ubuntu2.4] (1.4.0-11ubuntu2.5 Ubuntu:22.04/jammy-updates [amd64]) Conf libpam-modules (1.4.0-11ubuntu2.5 Ubuntu:22.04/jammy-updates [amd64]) Inst libnss-systemd [249.11-0ubuntu3.12] (249.11-0ubuntu3.15 Ubuntu:22.04/jammy-updates [amd64]) [] Inst libsystemd0 [249.11-0ubuntu3.12] (249.11-0ubuntu3.15 Ubuntu:22.04/jammy-updates [amd64]) [systemd:amd64 ] Conf libsystemd0 (249.11-0ubuntu3.15 Ubuntu:22.04/jammy-updates [amd64]) [systemd:amd64 ] Inst systemd-sysv [249.11-0ubuntu3.12] (249.11-0ubuntu3.15 Ubuntu:22.04/jammy-updates [amd64]) [systemd:amd64 ] Inst libpam-systemd [249.11-0ubuntu3.12] (249.11-0ubuntu3.15 Ubuntu:22.04/jammy-updates [amd64]) [systemd:amd64 ] Inst systemd [249.11-0ubuntu3.12] (249.11-0ubuntu3.15 Ubuntu:22.04/jammy-updates [amd64]) Inst udev [249.11-0ubuntu3.12] (249.11-0ubuntu3.15 Ubuntu:22.04/jammy-updates [amd64]) [] Inst libudev1 [249.11-0ubuntu3.12] (249.11-0ubuntu3.15 Ubuntu:22.04/jammy-updates [amd64]) Conf libudev1 (249.11-0ubuntu3.15 Ubuntu:22.04/jammy-updates [amd64]) Inst libpam-runtime [1.4.0-11ubuntu2.4] (1.4.0-11ubuntu2.5 Ubuntu:22.04/jammy-updates [all]) Conf libpam-runtime (1.4.0-11ubuntu2.5 Ubuntu:22.04/jammy-updates [all]) Inst libdevmapper1.02.1 [2:1.02.175-2.1ubuntu4] (2:1.02.175-2.1ubuntu5 Ubuntu:22.04/jammy-updates [amd64]) Inst libcryptsetup12 [2:2.4.3-1ubuntu1.2] (2:2.4.3-1ubuntu1.3 Ubuntu:22.04/jammy-updates [amd64]) Inst libseccomp2 [2.5.3-2ubuntu2] (2.5.3-2ubuntu3~22.04.1 Ubuntu:22.04/jammy-updates [amd64]) Conf libseccomp2 (2.5.3-2ubuntu3~22.04.1 Ubuntu:22.04/jammy-updates [amd64]) Inst libdevmapper-event1.02.1 [2:1.02.175-2.1ubuntu4] (2:1.02.175-2.1ubuntu5 Ubuntu:22.04/jammy-updates [amd64]) Inst dmsetup [2:1.02.175-2.1ubuntu4] (2:1.02.175-2.1ubuntu5 Ubuntu:22.04/jammy-updates [amd64]) Inst liblvm2cmd2.03 [2.03.11-2.1ubuntu4] (2.03.11-2.1ubuntu5 Ubuntu:22.04/jammy-updates [amd64]) Inst dmeventd [2:1.02.175-2.1ubuntu4] (2:1.02.175-2.1ubuntu5 Ubuntu:22.04/jammy-updates [amd64]) Inst lvm2 [2.03.11-2.1ubuntu4] (2.03.11-2.1ubuntu5 Ubuntu:22.04/jammy-updates [amd64]) Inst libopeniscsiusr [2.1.5-1ubuntu1] (2.1.5-1ubuntu1.1 Ubuntu:22.04/jammy-updates [amd64]) Inst open-iscsi [2.1.5-1ubuntu1] (2.1.5-1ubuntu1.1 Ubuntu:22.04/jammy-updates [amd64]) Inst distro-info-data [0.52ubuntu0.7] (0.52ubuntu0.8 Ubuntu:22.04/jammy-updates [all]) Inst dmidecode [3.3-3ubuntu0.1] (3.3-3ubuntu0.2 Ubuntu:22.04/jammy-updates [amd64]) Inst apt-transport-artifact-registry [1:20240607.00-g1] (1:20241017.00-g1 apt-transport-artifact-registry-stable:apt-transport-artifact-registry-stable [amd64]) Inst cryptsetup-initramfs [2:2.4.3-1ubuntu1.2] (2:2.4.3-1ubuntu1.3 Ubuntu:22.04/jammy-updates [all]) [] Inst cryptsetup-bin [2:2.4.3-1ubuntu1.2] (2:2.4.3-1ubuntu1.3 Ubuntu:22.04/jammy-updates [amd64]) [] Inst cryptsetup [2:2.4.3-1ubuntu1.2] (2:2.4.3-1ubuntu1.3 Ubuntu:22.04/jammy-updates [amd64]) Inst libpackagekit-glib2-18 [1.2.5-2ubuntu2] (1.2.5-2ubuntu3 Ubuntu:22.04/jammy-updates [amd64]) Inst gir1.2-packagekitglib-1.0 [1.2.5-2ubuntu2] (1.2.5-2ubuntu3 Ubuntu:22.04/jammy-updates [amd64]) Inst landscape-common [23.02-0ubuntu1~22.04.3] (23.02-0ubuntu1~22.04.4 Ubuntu:22.04/jammy-updates [amd64]) Inst libldap-2.5-0 [2.5.18+dfsg-0ubuntu0.22.04.2] (2.5.18+dfsg-0ubuntu0.22.04.3 Ubuntu:22.04/jammy-updates [amd64]) Inst libldap-common [2.5.18+dfsg-0ubuntu0.22.04.2] (2.5.18+dfsg-0ubuntu0.22.04.3 Ubuntu:22.04/jammy-updates [all]) Inst libmbim-proxy [1.28.0-1~ubuntu20.04.1] (1.28.0-1~ubuntu20.04.2 Ubuntu:22.04/jammy-updates [amd64]) [] Inst libmbim-glib4 [1.28.0-1~ubuntu20.04.1] (1.28.0-1~ubuntu20.04.2 Ubuntu:22.04/jammy-updates [amd64]) Inst packagekit-tools [1.2.5-2ubuntu2] (1.2.5-2ubuntu3 Ubuntu:22.04/jammy-updates [amd64]) [] Inst packagekit [1.2.5-2ubuntu2] (1.2.5-2ubuntu3 Ubuntu:22.04/jammy-updates [amd64]) Inst pollinate [4.33-3ubuntu2] (4.33-3ubuntu2.1 Ubuntu:22.04/jammy-updates [all]) Inst python3-packaging (21.3-1 Ubuntu:22.04/jammy [all]) Inst snapd [2.65.3+22.04] (2.67.1+22.04 Ubuntu:22.04/jammy-updates [amd64]) Inst sosreport [4.5.6-0ubuntu1~22.04.2] (4.8.2-0ubuntu0~22.04.1 Ubuntu:22.04/jammy-updates [amd64]) Inst xfsprogs [5.13.0-1ubuntu2] (5.13.0-1ubuntu2.1 Ubuntu:22.04/jammy-updates [amd64]) Inst cloud-init [24.3.1-0ubuntu0~22.04.1] (24.4.1-0ubuntu0~22.04.2 Ubuntu:22.04/jammy-updates [all]) Conf libnss-systemd (249.11-0ubuntu3.15 Ubuntu:22.04/jammy-updates [amd64]) Conf systemd-sysv (249.11-0ubuntu3.15 Ubuntu:22.04/jammy-updates [amd64]) Conf libpam-systemd (249.11-0ubuntu3.15 Ubuntu:22.04/jammy-updates [amd64]) Conf systemd (249.11-0ubuntu3.15 Ubuntu:22.04/jammy-updates [amd64]) Conf udev (249.11-0ubuntu3.15 Ubuntu:22.04/jammy-updates [amd64]) Conf libdevmapper1.02.1 (2:1.02.175-2.1ubuntu5 Ubuntu:22.04/jammy-updates [amd64]) Conf libcryptsetup12 (2:2.4.3-1ubuntu1.3 Ubuntu:22.04/jammy-updates [amd64]) Conf libdevmapper-event1.02.1 (2:1.02.175-2.1ubuntu5 Ubuntu:22.04/jammy-updates [amd64]) Conf dmsetup (2:1.02.175-2.1ubuntu5 Ubuntu:22.04/jammy-updates [amd64]) Conf liblvm2cmd2.03 (2.03.11-2.1ubuntu5 Ubuntu:22.04/jammy-updates [amd64]) Conf dmeventd (2:1.02.175-2.1ubuntu5 Ubuntu:22.04/jammy-updates [amd64]) Conf lvm2 (2.03.11-2.1ubuntu5 Ubuntu:22.04/jammy-updates [amd64]) Conf libopeniscsiusr (2.1.5-1ubuntu1.1 Ubuntu:22.04/jammy-updates [amd64]) Conf open-iscsi (2.1.5-1ubuntu1.1 Ubuntu:22.04/jammy-updates [amd64]) Conf distro-info-data (0.52ubuntu0.8 Ubuntu:22.04/jammy-updates [all]) Conf dmidecode (3.3-3ubuntu0.2 Ubuntu:22.04/jammy-updates [amd64]) Conf apt-transport-artifact-registry (1:20241017.00-g1 apt-transport-artifact-registry-stable:apt-transport-artifact-registry-stable [amd64]) Conf cryptsetup-initramfs (2:2.4.3-1ubuntu1.3 Ubuntu:22.04/jammy-updates [all]) Conf cryptsetup-bin (2:2.4.3-1ubuntu1.3 Ubuntu:22.04/jammy-updates [amd64]) Conf cryptsetup (2:2.4.3-1ubuntu1.3 Ubuntu:22.04/jammy-updates [amd64]) Conf libpackagekit-glib2-18 (1.2.5-2ubuntu3 Ubuntu:22.04/jammy-updates [amd64]) Conf gir1.2-packagekitglib-1.0 (1.2.5-2ubuntu3 Ubuntu:22.04/jammy-updates [amd64]) Conf landscape-common (23.02-0ubuntu1~22.04.4 Ubuntu:22.04/jammy-updates [amd64]) Conf libldap-2.5-0 (2.5.18+dfsg-0ubuntu0.22.04.3 Ubuntu:22.04/jammy-updates [amd64]) Conf libldap-common (2.5.18+dfsg-0ubuntu0.22.04.3 Ubuntu:22.04/jammy-updates [all]) Conf libmbim-proxy (1.28.0-1~ubuntu20.04.2 Ubuntu:22.04/jammy-updates [amd64]) Conf libmbim-glib4 (1.28.0-1~ubuntu20.04.2 Ubuntu:22.04/jammy-updates [amd64]) Conf packagekit-tools (1.2.5-2ubuntu3 Ubuntu:22.04/jammy-updates [amd64]) Conf packagekit (1.2.5-2ubuntu3 Ubuntu:22.04/jammy-updates [amd64]) Conf pollinate (4.33-3ubuntu2.1 Ubuntu:22.04/jammy-updates [all]) Conf python3-packaging (21.3-1 Ubuntu:22.04/jammy [all]) Conf snapd (2.67.1+22.04 Ubuntu:22.04/jammy-updates [amd64]) Conf sosreport (4.8.2-0ubuntu0~22.04.1 Ubuntu:22.04/jammy-updates [amd64]) Conf xfsprogs (5.13.0-1ubuntu2.1 Ubuntu:22.04/jammy-updates [amd64]) Conf cloud-init (24.4.1-0ubuntu0~22.04.2 Ubuntu:22.04/jammy-updates [all]) osconfig-20250416.02/packages/testdata/ubuntu_24_apt_get_full_upgrade000066400000000000000000000156131477773331400254310ustar00rootroot00000000000000Inst motd-news-config [13ubuntu10.1] (13ubuntu10.2 Ubuntu:24.04/noble-updates [all]) Conf base-files (13ubuntu10.2 Ubuntu:24.04/noble-updates [amd64]) Conf bsdutils (1:2.39.3-9ubuntu6.2 Ubuntu:24.04/noble-updates [amd64]) Inst perl [5.38.2-3.2build2] (5.38.2-3.2build2.1 Ubuntu:24.04/noble-updates [amd64]) [] Conf perl-base (5.38.2-3.2build2.1 Ubuntu:24.04/noble-updates [amd64]) [] Inst util-linux [2.39.3-9ubuntu6.1] (2.39.3-9ubuntu6.2 Ubuntu:24.04/noble-updates [amd64]) Inst mount [2.39.3-9ubuntu6.1] (2.39.3-9ubuntu6.2 Ubuntu:24.04/noble-updates [amd64]) Inst systemd-dev [255.4-1ubuntu8.4] (255.4-1ubuntu8.6 Ubuntu:24.04/noble-updates [all]) [] Conf libacl1 (2.3.2-1build1.1 Ubuntu:24.04/noble-updates [amd64]) [] Conf libblkid1 (2.39.3-9ubuntu6.2 Ubuntu:24.04/noble-updates [amd64]) [] Inst libkmod2 [31+20240202-2ubuntu7] (31+20240202-2ubuntu7.1 Ubuntu:24.04/noble-updates [amd64]) [] Conf libpcre2-8-0 (10.42-4ubuntu2.1 Ubuntu:24.04/noble-updates [amd64]) [] Conf libselinux1 (3.5-2ubuntu2.1 Ubuntu:24.04/noble-updates [amd64]) [] Inst libsystemd-shared [255.4-1ubuntu8.4] (255.4-1ubuntu8.6 Ubuntu:24.04/noble-updates [amd64]) [systemd:amd64 ] Conf libsystemd0 (255.4-1ubuntu8.6 Ubuntu:24.04/noble-updates [amd64]) [systemd:amd64 ] Inst libpam-systemd [255.4-1ubuntu8.4] (255.4-1ubuntu8.6 Ubuntu:24.04/noble-updates [amd64]) [systemd:amd64 ] Inst udev [255.4-1ubuntu8.4] (255.4-1ubuntu8.6 Ubuntu:24.04/noble-updates [amd64]) [] Conf libudev1 (255.4-1ubuntu8.6 Ubuntu:24.04/noble-updates [amd64]) Conf libaudit-common (1:3.1.2-2.1build1.1 Ubuntu:24.04/noble-updates [all]) Conf libaudit1 (1:3.1.2-2.1build1.1 Ubuntu:24.04/noble-updates [amd64]) Conf libmount1 (2.39.3-9ubuntu6.2 Ubuntu:24.04/noble-updates [amd64]) Inst libuuid1 [2.39.3-9ubuntu6.1] (2.39.3-9ubuntu6.2 Ubuntu:24.04/noble-updates [amd64]) Inst libcryptsetup12 [2:2.7.0-1ubuntu4.1] (2:2.7.0-1ubuntu4.2 Ubuntu:24.04/noble-updates [amd64]) Inst libsmartcols1 [2.39.3-9ubuntu6.1] (2.39.3-9ubuntu6.2 Ubuntu:24.04/noble-updates [amd64]) Inst uuid-runtime [2.39.3-9ubuntu6.1] (2.39.3-9ubuntu6.2 Ubuntu:24.04/noble-updates [amd64]) Inst distro-info-data [0.60ubuntu0.1] (0.60ubuntu0.2 Ubuntu:24.04/noble-updates [all]) Inst python3-problem-report [2.28.1-0ubuntu3.1] (2.28.1-0ubuntu3.5 Ubuntu:24.04/noble-updates [all]) Inst grub2-common [2.12-1ubuntu7] (2.12-1ubuntu7.1 Ubuntu:24.04/noble-updates [amd64]) [grub-pc:amd64 ] Inst grub-pc-bin [2.12-1ubuntu7] (2.12-1ubuntu7.1 Ubuntu:24.04/noble-updates [amd64]) [] Inst apport-core-dump-handler [2.28.1-0ubuntu3.1] (2.28.1-0ubuntu3.5 Ubuntu:24.04/noble-updates [all]) Inst libopeniscsiusr [2.1.9-3ubuntu5.1] (2.1.9-3ubuntu5.3 Ubuntu:24.04/noble-updates [amd64]) Inst openssh-sftp-server [1:9.6p1-3ubuntu13.8] (1:9.6p1-3ubuntu13.9 Ubuntu:24.04/noble-updates [amd64]) [] Inst openssh-client [1:9.6p1-3ubuntu13.8] (1:9.6p1-3ubuntu13.9 Ubuntu:24.04/noble-updates [amd64]) Inst libattr1 [1:2.5.2-1build1] (1:2.5.2-1build1.1 Ubuntu:24.04/noble-updates [amd64]) Inst libgmp10 [2:6.3.0+dfsg-2ubuntu6] (2:6.3.0+dfsg-2ubuntu6.1 Ubuntu:24.04/noble-updates [amd64]) Inst libgpg-error-l10n [1.47-3build2] (1.47-3build2.1 Ubuntu:24.04/noble-updates [all]) Conf libgpg-error0 (1.47-3build2.1 Ubuntu:24.04/noble-updates [amd64]) Conf libmd0 (1.1.0-2build1.1 Ubuntu:24.04/noble-updates [amd64]) Conf libunistring5 (1.1-2build1.1 Ubuntu:24.04/noble-updates [amd64]) Conf libidn2-0 (2.3.7-2build1.1 Ubuntu:24.04/noble-updates [amd64]) Inst eject [2.39.3-9ubuntu6.1] (2.39.3-9ubuntu6.2 Ubuntu:24.04/noble-updates [amd64]) Inst netplan-generator [1.0.1-1ubuntu2~24.04.1] (1.1.1-1~ubuntu24.04.1 Ubuntu:24.04/noble-updates [amd64]) [] Inst ubuntu-minimal [1.539.1] (1.539.2 Ubuntu:24.04/noble-updates [amd64]) [] Inst initramfs-tools [0.142ubuntu25.2] (0.142ubuntu25.5 Ubuntu:24.04/noble-updates [all]) [] Inst initramfs-tools-bin [0.142ubuntu25.2] (0.142ubuntu25.5 Ubuntu:24.04/noble-updates [amd64]) [] Inst libnetplan1 [1.0.1-1ubuntu2~24.04.1] (1.1.1-1~ubuntu24.04.1 Ubuntu:24.04/noble-updates [amd64]) Inst bsdextrautils [2.39.3-9ubuntu6.1] (2.39.3-9ubuntu6.2 Ubuntu:24.04/noble-updates [amd64]) Inst libdrm-common [2.4.120-2build1] (2.4.122-1~ubuntu0.24.04.1 Ubuntu:24.04/noble-updates [all]) Inst libnghttp2-14 [1.59.0-1ubuntu0.1] (1.59.0-1ubuntu0.2 Ubuntu:24.04/noble-updates [amd64]) Inst libnl-genl-3-200 [3.7.0-0.3build1] (3.7.0-0.3build1.1 Ubuntu:24.04/noble-updates [amd64]) [] Inst libplymouth5 [24.004.60-1ubuntu7] (24.004.60-1ubuntu7.1 Ubuntu:24.04/noble-updates [amd64]) Inst libpackagekit-glib2-18 [1.2.8-2build3] (1.2.8-2ubuntu1.2 Ubuntu:24.04/noble-updates [amd64]) Inst polkitd [124-2ubuntu1] (124-2ubuntu1.24.04.2 Ubuntu:24.04/noble-updates [amd64]) [] Inst libpolkit-gobject-1-0 [124-2ubuntu1] (124-2ubuntu1.24.04.2 Ubuntu:24.04/noble-updates [amd64]) [] Inst plymouth-theme-ubuntu-text [24.004.60-1ubuntu7] (24.004.60-1ubuntu7.1 Ubuntu:24.04/noble-updates [amd64]) [] Inst ubuntu-release-upgrader-core [1:24.04.23] (1:24.04.26 Ubuntu:24.04/noble-updates [all]) [] Inst ubuntu-standard [1.539.1] (1.539.2 Ubuntu:24.04/noble-updates [amd64]) Inst bpftrace [0.20.2-1ubuntu4] (0.20.2-1ubuntu4.3 Ubuntu:24.04/noble-updates [amd64]) Inst cryptsetup-bin [2:2.7.0-1ubuntu4.1] (2:2.7.0-1ubuntu4.2 Ubuntu:24.04/noble-updates [amd64]) [] Inst libdevmapper-event1.02.1 [2:1.02.185-3ubuntu3.1] (2:1.02.185-3ubuntu3.2 Ubuntu:24.04/noble-updates [amd64]) Inst liblvm2cmd2.03 [2.03.16-3ubuntu3.1] (2.03.16-3ubuntu3.2 Ubuntu:24.04/noble-updates [amd64]) Inst fdisk [2.39.3-9ubuntu6.1] (2.39.3-9ubuntu6.2 Ubuntu:24.04/noble-updates [amd64]) Inst grub-efi-amd64-signed [1.202+2.12-1ubuntu7] (1.202.2+2.12-1ubuntu7.1 Ubuntu:24.04/noble-updates [amd64]) [] Inst landscape-common [24.02-0ubuntu5.1] (24.02-0ubuntu5.3 Ubuntu:24.04/noble-updates [amd64]) Inst libldap2 [2.6.7+dfsg-1~exp1ubuntu8] (2.6.7+dfsg-1~exp1ubuntu8.2 Ubuntu:24.04/noble-updates [amd64]) Inst libnvme1t64 [1.8-3build1] (1.8-3ubuntu1 Ubuntu:24.04/noble-updates [amd64]) Inst lvm2 [2.03.16-3ubuntu3.1] (2.03.16-3ubuntu3.2 Ubuntu:24.04/noble-updates [amd64]) Inst python3-dateutil (2.8.2-3ubuntu1 Ubuntu:24.04/noble [all]) Inst python3-botocore (1.34.46+repack-1ubuntu1 Ubuntu:24.04/noble [all]) Conf distro-info-data (0.60ubuntu0.2 Ubuntu:24.04/noble-updates [all]) Conf python3-problem-report (2.28.1-0ubuntu3.5 Ubuntu:24.04/noble-updates [all]) Conf grub2-common (2.12-1ubuntu7.1 Ubuntu:24.04/noble-updates [amd64]) Conf grub-pc-bin (2.12-1ubuntu7.1 Ubuntu:24.04/noble-updates [amd64]) Conf apport-core-dump-handler (2.28.1-0ubuntu3.5 Ubuntu:24.04/noble-updates [all]) Conf libopeniscsiusr (2.1.9-3ubuntu5.3 Ubuntu:24.04/noble-updates [amd64]) Conf openssh-sftp-server (1:9.6p1-3ubuntu13.9 Ubuntu:24.04/noble-updates [amd64]) Conf openssh-client (1:9.6p1-3ubuntu13.9 Ubuntu:24.04/noble-updates [amd64]) Conf libgpg-error-l10n (1.47-3build2.1 Ubuntu:24.04/noble-updates [all]) Conf eject (2.39.3-9ubuntu6.2 Ubuntu:24.04/noble-updates [amd64]) Conf netplan-generator (1.1.1-1~ubuntu24.04.1 Ubuntu:24.04/noble-updates [amd64]) Conf ubuntu-minimal (1.539.2 Ubuntu:24.04/noble-updates [amd64]) osconfig-20250416.02/packages/windows_application_windows.go000066400000000000000000000062731477773331400237720ustar00rootroot00000000000000// Copyright 2021 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package packages import ( "context" "strconv" "time" "github.com/GoogleCloudPlatform/osconfig/clog" "golang.org/x/sys/windows/registry" ) func parseDate(dateString string) time.Time { if len(dateString) != 8 { return time.Time{} } year, err := strconv.ParseInt(dateString[0:4], 10, 32) if err != nil { return time.Time{} } month, err := strconv.ParseInt(dateString[4:6], 10, 32) if err != nil { return time.Time{} } day, err := strconv.ParseInt(dateString[6:8], 10, 32) if err != nil { return time.Time{} } return time.Date(int(year), time.Month(month), int(day), 0, 0, 0, 0, time.Now().Location()) } func getWindowsApplication(ctx context.Context, k *registry.Key) *WindowsApplication { displayName, _, errName := k.GetStringValue("DisplayName") _, _, errUninstall := k.GetStringValue("UninstallString") if errName == nil && errUninstall == nil { displayVersion, _, _ := k.GetStringValue("DisplayVersion") publisher, _, _ := k.GetStringValue("Publisher") installDate, _, _ := k.GetStringValue("InstallDate") helpLink, _, _ := k.GetStringValue("HelpLink") return &WindowsApplication{ DisplayName: displayName, DisplayVersion: displayVersion, Publisher: publisher, InstallDate: parseDate(installDate), HelpLink: helpLink, } } return nil } func GetWindowsApplications(ctx context.Context) ([]*WindowsApplication, error) { directories := []string{ `SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall`, `SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall`, } var allApps []*WindowsApplication for _, dir := range directories { clog.Debugf(ctx, "Loading windows applications from: %v", dir) apps, err := getWindowsApplications(ctx, dir) if err != nil { clog.Errorf(ctx, "error loading windows applications from registry: %v, error: %v", dir, err) continue } allApps = append(allApps, apps...) } return allApps, nil } func getWindowsApplications(ctx context.Context, directory string) ([]*WindowsApplication, error) { dirKey, err := registry.OpenKey(registry.LOCAL_MACHINE, directory, registry.ENUMERATE_SUB_KEYS) if err != nil { return nil, err } defer dirKey.Close() var result []*WindowsApplication subkeys, err := dirKey.ReadSubKeyNames(0) if err != nil { return nil, err } for _, subkey := range subkeys { k, err := registry.OpenKey(dirKey, subkey, registry.QUERY_VALUE) if err != nil { clog.Debugf(ctx, "error when opening registry key: %v", err) continue } app := getWindowsApplication(ctx, &k) if app != nil { result = append(result, app) } k.Close() } return result, nil } osconfig-20250416.02/packages/wua_windows.go000066400000000000000000000331571477773331400205120ustar00rootroot00000000000000/* Copyright 2019 Google Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package packages import ( "context" "fmt" "sync" "github.com/GoogleCloudPlatform/osconfig/clog" ole "github.com/go-ole/go-ole" "github.com/go-ole/go-ole/oleutil" ) const ( S_OK = 0 S_FALSE = 1 ) var wuaSession sync.Mutex // IUpdateSession is a an IUpdateSession. type IUpdateSession struct { *ole.IDispatch } func NewUpdateSession() (*IUpdateSession, error) { wuaSession.Lock() if err := coInitializeEx(); err != nil { wuaSession.Unlock() return nil, err } s := &IUpdateSession{} unknown, err := oleutil.CreateObject("Microsoft.Update.Session") if err != nil { s.Close() return nil, fmt.Errorf(`oleutil.CreateObject("Microsoft.Update.Session"): %v`, err) } disp, err := unknown.QueryInterface(ole.IID_IDispatch) if err != nil { unknown.Release() s.Close() return nil, fmt.Errorf(`error creating Dispatch object from Microsoft.Update.Session connection: %v`, err) } s.IDispatch = disp return s, nil } func (s *IUpdateSession) Close() { if s.IDispatch != nil { s.IDispatch.Release() } ole.CoUninitialize() wuaSession.Unlock() } // InstallWUAUpdate install a WIndows update. func (s *IUpdateSession) InstallWUAUpdate(ctx context.Context, updt *IUpdate) error { title, err := updt.GetProperty("Title") if err != nil { return fmt.Errorf(`updt.GetProperty("Title"): %v`, err) } updts, err := NewUpdateCollection() if err != nil { return err } defer updts.Release() eula, err := updt.GetProperty("EulaAccepted") if err != nil { return fmt.Errorf(`updt.GetProperty("EulaAccepted"): %v`, err) } // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-oaut/7b39eb24-9d39-498a-bcd8-75c38e5823d0 if eula.Val == 0 { clog.Debugf(ctx, "%s - Accepting EULA", title.Value()) if _, err := updt.CallMethod("AcceptEula"); err != nil { return fmt.Errorf(`updt.CallMethod("AcceptEula"): %v`, err) } } else { clog.Debugf(ctx, "%s - EulaAccepted: %v", title.Value(), eula.Value()) } if err := updts.Add(updt); err != nil { return err } clog.Debugf(ctx, "Downloading update %s", title.Value()) if err := s.DownloadWUAUpdateCollection(ctx, updts); err != nil { return fmt.Errorf("DownloadWUAUpdateCollection error: %v", err) } clog.Debugf(ctx, "Installing update %s", title.Value()) if err := s.InstallWUAUpdateCollection(ctx, updts); err != nil { return fmt.Errorf("InstallWUAUpdateCollection error: %v", err) } return nil } func NewUpdateCollection() (*IUpdateCollection, error) { updateCollObj, err := oleutil.CreateObject("Microsoft.Update.UpdateColl") if err != nil { return nil, fmt.Errorf(`oleutil.CreateObject("Microsoft.Update.UpdateColl"): %v`, err) } defer updateCollObj.Release() updateColl, err := updateCollObj.IDispatch(ole.IID_IDispatch) if err != nil { return nil, err } return &IUpdateCollection{IDispatch: updateColl}, nil } type IUpdateCollection struct { *ole.IDispatch } type IUpdate struct { *ole.IDispatch } func (c *IUpdateCollection) Add(updt *IUpdate) error { if _, err := c.CallMethod("Add", updt.IDispatch); err != nil { return fmt.Errorf(`IUpdateCollection.CallMethod("Add", updt): %v`, err) } return nil } func (c *IUpdateCollection) RemoveAt(i int) error { if _, err := c.CallMethod("RemoveAt", i); err != nil { return fmt.Errorf(`IUpdateCollection.CallMethod("RemoveAt", %d): %v`, i, err) } return nil } func (c *IUpdateCollection) Count() (int32, error) { return GetCount(c.IDispatch) } func (c *IUpdateCollection) Item(i int) (*IUpdate, error) { updtRaw, err := c.GetProperty("Item", i) if err != nil { return nil, fmt.Errorf(`IUpdateCollection.GetProperty("Item", %d): %v`, i, err) } return &IUpdate{IDispatch: updtRaw.ToIDispatch()}, nil } // GetCount returns the Count property. func GetCount(dis *ole.IDispatch) (int32, error) { countRaw, err := dis.GetProperty("Count") if err != nil { return 0, fmt.Errorf(`IDispatch.GetProperty("Count"): %v`, err) } count, _ := countRaw.Value().(int32) return count, nil } func (u *IUpdate) kbaIDs() ([]string, error) { kbArticleIDsRaw, err := u.GetProperty("KBArticleIDs") if err != nil { return nil, fmt.Errorf(`IUpdate.GetProperty("KBArticleIDs"): %v`, err) } kbArticleIDs := kbArticleIDsRaw.ToIDispatch() defer kbArticleIDs.Release() count, err := GetCount(kbArticleIDs) if err != nil { return nil, err } if count == 0 { return nil, nil } var ss []string for i := 0; i < int(count); i++ { item, err := kbArticleIDs.GetProperty("Item", i) if err != nil { return nil, fmt.Errorf(`kbArticleIDs.GetProperty("Item", %d): %v`, i, err) } ss = append(ss, item.ToString()) } return ss, nil } func (u *IUpdate) categories() ([]string, []string, error) { catRaw, err := u.GetProperty("Categories") if err != nil { return nil, nil, fmt.Errorf(`IUpdate.GetProperty("Categories"): %v`, err) } cat := catRaw.ToIDispatch() defer cat.Release() count, err := GetCount(cat) if err != nil { return nil, nil, err } if count == 0 { return nil, nil, nil } var cns, cids []string for i := 0; i < int(count); i++ { itemRaw, err := cat.GetProperty("Item", i) if err != nil { return nil, nil, fmt.Errorf(`cat.GetProperty("Item", %d): %v`, i, err) } item := itemRaw.ToIDispatch() defer item.Release() name, err := item.GetProperty("Name") if err != nil { return nil, nil, fmt.Errorf(`item.GetProperty("Name"): %v`, err) } categoryID, err := item.GetProperty("CategoryID") if err != nil { return nil, nil, fmt.Errorf(`item.GetProperty("CategoryID"): %v`, err) } cns = append(cns, name.ToString()) cids = append(cids, categoryID.ToString()) } return cns, cids, nil } func (u *IUpdate) moreInfoURLs() ([]string, error) { moreInfoURLsRaw, err := u.GetProperty("MoreInfoURLs") if err != nil { return nil, fmt.Errorf(`IUpdate.GetProperty("MoreInfoURLs"): %v`, err) } moreInfoURLs := moreInfoURLsRaw.ToIDispatch() defer moreInfoURLs.Release() count, err := GetCount(moreInfoURLs) if err != nil { return nil, err } if count == 0 { return nil, nil } var ss []string for i := 0; i < int(count); i++ { item, err := moreInfoURLs.GetProperty("Item", i) if err != nil { return nil, fmt.Errorf(`moreInfoURLs.GetProperty("Item", %d): %v`, i, err) } ss = append(ss, item.ToString()) } return ss, nil } func (c *IUpdateCollection) extractPkg(item int) (*WUAPackage, error) { updt, err := c.Item(item) if err != nil { return nil, err } defer updt.Release() title, err := updt.GetProperty("Title") if err != nil { return nil, fmt.Errorf(`updt.GetProperty("Title"): %v`, err) } description, err := updt.GetProperty("Description") if err != nil { return nil, fmt.Errorf(`updt.GetProperty("Description"): %v`, err) } kbArticleIDs, err := updt.kbaIDs() if err != nil { return nil, err } categories, categoryIDs, err := updt.categories() if err != nil { return nil, err } moreInfoURLs, err := updt.moreInfoURLs() if err != nil { return nil, err } supportURL, err := updt.GetProperty("SupportURL") if err != nil { return nil, fmt.Errorf(`updt.GetProperty("SupportURL"): %v`, err) } lastDeploymentChangeTimeRaw, err := updt.GetProperty("LastDeploymentChangeTime") if err != nil { return nil, fmt.Errorf(`updt.GetProperty("LastDeploymentChangeTime"): %v`, err) } lastDeploymentChangeTime, err := ole.GetVariantDate(uint64(lastDeploymentChangeTimeRaw.Val)) if err != nil { return nil, fmt.Errorf(`ole.GetVariantDate(uint64(lastDeploymentChangeTimeRaw.Val)): %v`, err) } identityRaw, err := updt.GetProperty("Identity") if err != nil { return nil, fmt.Errorf(`updt.GetProperty("Identity"): %v`, err) } identity := identityRaw.ToIDispatch() defer identity.Release() revisionNumber, err := identity.GetProperty("RevisionNumber") if err != nil { return nil, fmt.Errorf(`identity.GetProperty("RevisionNumber"): %v`, err) } updateID, err := identity.GetProperty("UpdateID") if err != nil { return nil, fmt.Errorf(`identity.GetProperty("UpdateID"): %v`, err) } return &WUAPackage{ Title: title.ToString(), Description: description.ToString(), SupportURL: supportURL.ToString(), KBArticleIDs: kbArticleIDs, UpdateID: updateID.ToString(), Categories: categories, CategoryIDs: categoryIDs, MoreInfoURLs: moreInfoURLs, RevisionNumber: int32(revisionNumber.Val), LastDeploymentChangeTime: lastDeploymentChangeTime, }, nil } // WUAUpdates queries the Windows Update Agent API searcher with the provided query. func WUAUpdates(ctx context.Context, query string) ([]WUAPackage, error) { session, err := NewUpdateSession() if err != nil { return nil, fmt.Errorf("error creating NewUpdateSession: %v", err) } defer session.Close() updts, err := session.GetWUAUpdateCollection(ctx, query) if err != nil { return nil, fmt.Errorf("error calling GetWUAUpdateCollection with query %q: %v", query, err) } defer updts.Release() updtCnt, err := updts.Count() if err != nil { return nil, err } if updtCnt == 0 { return nil, nil } var packages []WUAPackage for i := 0; i < int(updtCnt); i++ { pkg, err := updts.extractPkg(i) if err != nil { return nil, err } packages = append(packages, *pkg) } return packages, nil } // DownloadWUAUpdateCollection downloads all updates in a IUpdateCollection func (s *IUpdateSession) DownloadWUAUpdateCollection(ctx context.Context, updates *IUpdateCollection) error { // returns IUpdateDownloader // https://docs.microsoft.com/en-us/windows/desktop/api/wuapi/nn-wuapi-iupdatedownloader downloaderRaw, err := s.CallMethod("CreateUpdateDownloader") if err != nil { return fmt.Errorf("error calling method CreateUpdateDownloader on IUpdateSession: %v"+GetScodeString(ctx, err), err) } downloader := downloaderRaw.ToIDispatch() defer downloader.Release() if _, err := downloader.PutProperty("Updates", updates.IDispatch); err != nil { return fmt.Errorf("error calling PutProperty Updates on IUpdateDownloader: %v"+GetScodeString(ctx, err), err) } if _, err := downloader.CallMethod("Download"); err != nil { return fmt.Errorf("error calling method Download on IUpdateDownloader: %v"+GetScodeString(ctx, err), err) } return nil } // InstallWUAUpdateCollection installs all updates in a IUpdateCollection func (s *IUpdateSession) InstallWUAUpdateCollection(ctx context.Context, updates *IUpdateCollection) error { // returns IUpdateInstallersession *ole.IDispatch, // https://docs.microsoft.com/en-us/windows/desktop/api/wuapi/nf-wuapi-iupdatesession-createupdateinstaller installerRaw, err := s.CallMethod("CreateUpdateInstaller") if err != nil { return fmt.Errorf("error calling method CreateUpdateInstaller on IUpdateSession: %v"+GetScodeString(ctx, err), err) } installer := installerRaw.ToIDispatch() defer installer.Release() if _, err := installer.PutProperty("Updates", updates.IDispatch); err != nil { return fmt.Errorf("error calling PutProperty Updates on IUpdateInstaller: %v"+GetScodeString(ctx, err), err) } // TODO: Look into using the async methods and attempt to track/log progress. if _, err := installer.CallMethod("Install"); err != nil { return fmt.Errorf("error calling method Install on IUpdateInstaller: %v"+GetScodeString(ctx, err), err) } return nil } // GetWUAUpdateCollection queries the Windows Update Agent API searcher with the provided query // and returns a IUpdateCollection. func (s *IUpdateSession) GetWUAUpdateCollection(ctx context.Context, query string) (*IUpdateCollection, error) { // returns IUpdateSearcher // https://msdn.microsoft.com/en-us/library/windows/desktop/aa386515(v=vs.85).aspx searcherRaw, err := s.CallMethod("CreateUpdateSearcher") if err != nil { return nil, fmt.Errorf("error calling CreateUpdateSearcher: %v"+GetScodeString(ctx, err), err) } searcher := searcherRaw.ToIDispatch() defer searcher.Release() // returns ISearchResult // https://msdn.microsoft.com/en-us/library/windows/desktop/aa386077(v=vs.85).aspx resultRaw, err := searcher.CallMethod("Search", query) if err != nil { return nil, fmt.Errorf("error calling method Search on IUpdateSearcher: %v"+GetScodeString(ctx, err), err) } result := resultRaw.ToIDispatch() defer result.Release() // returns IUpdateCollection // https://msdn.microsoft.com/en-us/library/windows/desktop/aa386107(v=vs.85).aspx updtsRaw, err := result.GetProperty("Updates") if err != nil { return nil, fmt.Errorf("error calling GetProperty Updates on ISearchResult: %v"+GetScodeString(ctx, err), err) } return &IUpdateCollection{IDispatch: updtsRaw.ToIDispatch()}, nil } // GetScodeString return empty string if empty string if SCODE wasn't found else string containgin SCODE the // following format " SCODE : 0x12345678". Where SCODE is a 32-bit status value that is used to describe an error or warning. func GetScodeString(ctx context.Context, err error) string { var scodeStr = "" var oleError *ole.OleError oleError, ok := err.(*ole.OleError) if ok { var excepinfo ole.EXCEPINFO excepinfo, ok = oleError.SubError().(ole.EXCEPINFO) if ok { clog.Errorf(ctx, "Error with SCODE was founded. SCODE : 0x%x", excepinfo.SCODE()) scodeStr = fmt.Sprintf(" SCODE: 0x%x", excepinfo.SCODE()) } } return scodeStr } osconfig-20250416.02/packages/yum.go000066400000000000000000000177601477773331400167600ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package packages import ( "bytes" "context" "fmt" "os" "os/exec" "runtime" "slices" "strings" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/osinfo" "github.com/GoogleCloudPlatform/osconfig/util" ) var ( yum string yumInstallArgs = []string{"install", "--assumeyes"} yumRemoveArgs = []string{"remove", "--assumeyes"} yumCheckUpdateArgs = []string{"check-update", "--assumeyes"} yumListUpdatesArgs = []string{"update", "--assumeno", "--cacheonly", "--color=never"} yumListUpdateMinimalArgs = []string{"update-minimal", "--assumeno", "--cacheonly", "--color=never"} ) func init() { if runtime.GOOS != "windows" { yum = "/usr/bin/yum" } YumExists = util.Exists(yum) } type yumUpdateOpts struct { security bool minimal bool } // YumUpdateOption is an option for yum update. type YumUpdateOption func(*yumUpdateOpts) // YumUpdateSecurity returns a YumUpdateOption that specifies the --security flag should // be used. func YumUpdateSecurity(security bool) YumUpdateOption { return func(args *yumUpdateOpts) { args.security = security } } // YumUpdateMinimal returns a YumUpdateOption that specifies the update-minimal // command should be used. func YumUpdateMinimal(minimal bool) YumUpdateOption { return func(args *yumUpdateOpts) { args.minimal = minimal } } // InstallYumPackages installs yum packages. func InstallYumPackages(ctx context.Context, pkgs []string) error { _, err := run(ctx, yum, append(yumInstallArgs, pkgs...)) return err } // RemoveYumPackages removes yum packages. func RemoveYumPackages(ctx context.Context, pkgs []string) error { _, err := run(ctx, yum, append(yumRemoveArgs, pkgs...)) return err } func parseYumUpdates(data []byte) []*PkgInfo { /* Last metadata expiration check: 0:11:22 ago on Tue 12 Nov 2019 12:13:38 AM UTC. Dependencies resolved. ================================================================================================================================================================================= Package Arch Version Repository Size ================================================================================================================================================================================= Installing: kernel x86_64 2.6.32-754.24.3.el6 updates 32 M Updating: google-compute-engine noarch 1:20190916.00-g2.el6 google-compute-engine 18 k kernel-firmware noarch 2.6.32-754.24.3.el6 updates 29 M libudev x86_64 147-2.74.el6_10 updates 78 k nspr x86_64 4.21.0-1.el6_10 updates 114 k google-cloud-sdk noarch 270.0.0-1 google-cloud-sdk 36 M Transaction Summary ================================================================================================================================================================================= Upgrade 5 Packages Total download size: 36 M Operation aborted. */ lines := bytes.Split(bytes.TrimSpace(data), []byte("\n")) var pkgs []*PkgInfo var upgrading bool packagesInstallOrUpdateKeywords := []string{"Upgrading:", "Updating:", "Installing:", "Installing dependencies:", "Installing weak dependencies:"} for _, ln := range lines { pkg := bytes.Fields(ln) if len(pkg) == 0 { continue } // Continue until we see one of the installing/upgrading keywords section. // Yum has this as Updating, dnf is Upgrading. if slices.Contains(packagesInstallOrUpdateKeywords, string(bytes.Join(pkg, []byte(" ")))) { upgrading = true continue } else if !upgrading { continue } // A package line should have 6 fields, break unless this is a 'replacing' entry. if len(pkg) < 6 { if string(pkg[0]) == "replacing" { continue } break } pkgs = append(pkgs, &PkgInfo{Name: string(pkg[0]), Arch: osinfo.NormalizeArchitecture(string(pkg[1])), RawArch: string(pkg[1]), Version: string(pkg[2])}) } return pkgs } func getYumTXFile(data []byte) string { /* The last lines of a non-complete yum update where the transaction is saved look like: Exiting on user command Your transaction was saved, rerun it with: yum load-transaction /tmp/yum_save_tx.2022-10-12.20-26.j3auah.yumtx */ lines := bytes.Split(bytes.TrimSpace(data), []byte("\n")) for _, ln := range lines { flds := bytes.Fields(ln) if len(flds) == 3 && string(flds[1]) == "load-transaction" && strings.HasPrefix(string(flds[2]), "/tmp/yum_save_tx.") { return string(flds[2]) } } return "" } // YumUpdates queries for all available yum updates. func YumUpdates(ctx context.Context, opts ...YumUpdateOption) ([]*PkgInfo, error) { // We just use check-update to ensure all repo keys are synced as we run // update with --assumeno. stdout, stderr, err := runner.Run(ctx, exec.CommandContext(ctx, yum, yumCheckUpdateArgs...)) // Exit code 0 means no updates, 100 means there are updates. if err == nil { return nil, nil } if exitErr, ok := err.(*exec.ExitError); ok { if exitErr.ExitCode() == 100 { err = nil } } // Since we don't get good error codes from 'yum update' exit now if there is an issue. if err != nil { return nil, fmt.Errorf("error running %s with args %q: %v, stdout: %q, stderr: %q", yum, yumCheckUpdateArgs, err, stdout, stderr) } return listAndParseYumPackages(ctx, opts...) } func listAndParseYumPackages(ctx context.Context, opts ...YumUpdateOption) ([]*PkgInfo, error) { yumOpts := &yumUpdateOpts{ security: false, minimal: false, } for _, opt := range opts { opt(yumOpts) } args := yumListUpdatesArgs if yumOpts.minimal { args = yumListUpdateMinimalArgs } if yumOpts.security { args = append(args, "--security") } stdout, stderr, err := ptyrunner.Run(ctx, exec.CommandContext(ctx, yum, args...)) if err != nil { return nil, fmt.Errorf("error running %s with args %q: %v, stdout: %q, stderr: %q", yum, args, err, stdout, stderr) } if stdout == nil { return nil, nil } // Some versions of yum will leave a transaction file in /tmp when update // is run with --assumeno. This will attempt to delete that file. yumTXFile := getYumTXFile(stdout) if yumTXFile != "" { clog.Debugf(ctx, "Removing yum tx file: %s", yumTXFile) if err := os.Remove(yumTXFile); err != nil { clog.Debugf(ctx, "Error deleting yum tx file %s: %v", yumTXFile, err) } } pkgs := parseYumUpdates(stdout) if len(pkgs) == 0 { // This means we could not parse any packages and instead got an error from yum. return nil, fmt.Errorf("error checking for yum updates, non-zero error code from 'yum update' but no packages parsed, stdout: %q", stdout) } return pkgs, nil } osconfig-20250416.02/packages/yum_test.go000066400000000000000000000354651477773331400200210ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package packages import ( "context" "errors" "os" "os/exec" "reflect" "testing" utilmocks "github.com/GoogleCloudPlatform/osconfig/util/mocks" "github.com/golang/mock/gomock" ) func TestInstallYumPackages(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) runner = mockCommandRunner expectedCmd := utilmocks.EqCmd(exec.Command(yum, append(yumInstallArgs, pkgs...)...)) mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).Return([]byte("stdout"), []byte("stderr"), nil).Times(1) if err := InstallYumPackages(testCtx, pkgs); err != nil { t.Errorf("unexpected error: %v", err) } mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).Return([]byte("stdout"), []byte("stderr"), errors.New("could not update")).Times(1) if err := InstallYumPackages(testCtx, pkgs); err == nil { t.Errorf("did not get expected error") } } func TestRemoveYum(t *testing.T) { ctx := context.Background() mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) runner = mockCommandRunner expectedCmd := utilmocks.EqCmd(exec.Command(yum, append(yumRemoveArgs, pkgs...)...)) mockCommandRunner.EXPECT().Run(ctx, expectedCmd).Return([]byte("stdout"), []byte("stderr"), nil).Times(1) if err := RemoveYumPackages(ctx, pkgs); err != nil { t.Errorf("unexpected error: %v", err) } mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).Return([]byte("stdout"), []byte("stderr"), errors.New("removal error")).Times(1) if err := RemoveYumPackages(testCtx, pkgs); err == nil { t.Errorf("did not get expected error") } } func TestYumUpdates(t *testing.T) { data := []byte(` ================================================================================================================================================================================= Package Arch Version Repository Size ================================================================================================================================================================================= Installing: kernel x86_64 2.6.32-754.24.3.el6 updates 32 M replacing kernel.x86_64 1.0.0-4 Upgrading: foo noarch 2.0.0-1 BaseOS 361 k bar x86_64 2.0.0-1 repo 10 M Obsoleting: baz noarch 2.0.0-1 repo 10 M `) if os.Getenv("EXIT100") == "1" { os.Exit(100) } cmd := exec.CommandContext(context.Background(), os.Args[0], "-test.run=TestYumUpdates") cmd.Env = append(os.Environ(), "EXIT100=1") errExit100 := cmd.Run() mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) runner = mockCommandRunner ptyrunner = mockCommandRunner expectedCheckUpdate := utilmocks.EqCmd(exec.Command(yum, yumCheckUpdateArgs...)) // Test Error t.Run("Error", func(t *testing.T) { mockCommandRunner.EXPECT().Run(testCtx, expectedCheckUpdate).Return(data, []byte("stderr"), errors.New("Bad error")).Times(1) if _, err := YumUpdates(testCtx); err == nil { t.Errorf("did not get expected error") } }) // yum check-updates exit code 0 t.Run("ExitCode0", func(t *testing.T) { mockCommandRunner.EXPECT().Run(testCtx, expectedCheckUpdate).Return([]byte("stdout"), []byte("stderr"), nil).Times(1) ret, err := YumUpdates(testCtx) if err != nil { t.Errorf("unexpected error: %v", err) } if ret != nil { t.Errorf("unexpected return: %v", ret) } }) // Test no options t.Run("NoOptions", func(t *testing.T) { expectedCmd := utilmocks.EqCmd(exec.Command(yum, yumListUpdatesArgs...)) first := mockCommandRunner.EXPECT().Run(testCtx, expectedCheckUpdate).Return(data, []byte("stderr"), errExit100).Times(1) mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).After(first).Return(data, []byte("stderr"), nil).Times(1) ret, err := YumUpdates(testCtx) if err != nil { t.Errorf("did not expect error: %v", err) } allPackageNames := []string{"kernel", "foo", "bar"} for _, pkg := range ret { if !contains(allPackageNames, pkg.Name) { t.Errorf("package %s expected to be present.", pkg.Name) } } }) // Test MinimalWithSecurity t.Run("MinimalWithSecurity", func(t *testing.T) { expectedCmd := utilmocks.EqCmd(exec.Command(yum, append(yumListUpdateMinimalArgs, "--security")...)) first := mockCommandRunner.EXPECT().Run(testCtx, expectedCheckUpdate).Return(data, []byte("stderr"), errExit100).Times(1) mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).After(first).Return(data, []byte("stderr"), nil).Times(1) ret, err := YumUpdates(testCtx, YumUpdateMinimal(true), YumUpdateSecurity(true)) if err != nil { t.Errorf("did not expect error: %v", err) } allPackageNames := []string{"kernel", "foo", "bar"} for _, pkg := range ret { if !contains(allPackageNames, pkg.Name) { t.Errorf("package %s expected to be present.", pkg.Name) } } }) /* // Test WithSecurityWithExcludes t.Run("WithSecurityWithExcludes", func(t *testing.T) { // the mock data returned by mockcommandrunner will not include this // package anyways. The purpose of this test is to make sure that // when customer specifies excluded packages, we set the --exclude flag // in the yum command. expectedCmd := exec.CommandContext(context.Background(), yum, append(yumListUpdatesArgs, "--security")...) first := mockCommandRunner.EXPECT().Run(testCtx, expectedCheckUpdate).Return(data, []byte("stderr"), errExit100).Times(1) mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).After(first).Return(data, []byte("stderr"), nil).Times(1) ret, err := YumUpdates(testCtx, YumUpdateMinimal(false), YumUpdateSecurity(true)) if err != nil { t.Errorf("did not expect error: %v", err) } allPackageNames := []string{"kernel", "foo", "bar"} for _, pkg := range ret { if !contains(allPackageNames, pkg.Name) { t.Errorf("package %s expected to be present.", pkg.Name) } } })*/ } func contains(names []string, name string) bool { for _, n := range names { if n == name { return true } } return false } func TestParseYumUpdates(t *testing.T) { data := []byte(` ================================================================================================================================================================================= Package Arch Version Repository Size ================================================================================================================================================================================= Installing: kernel x86_64 2.6.32-754.24.3.el6 updates 32 M replacing kernel.x86_64 1.0.0-4 Upgrading: foo noarch 2.0.0-1 BaseOS 361 k bar x86_64 2.0.0-1 repo 10 M Obsoleting: baz noarch 2.0.0-1 repo 10 M `) tests := []struct { name string data []byte want []*PkgInfo }{ {"NormalCase", data, []*PkgInfo{{Name: "kernel", Arch: "x86_64", RawArch: "x86_64", Version: "2.6.32-754.24.3.el6"}, {Name: "foo", Arch: "all", RawArch: "noarch", Version: "2.0.0-1"}, {Name: "bar", Arch: "x86_64", RawArch: "x86_64", Version: "2.0.0-1"}}}, {"NoPackages", []byte("nothing here"), nil}, {"nil", nil, nil}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := parseYumUpdates(tt.data); !reflect.DeepEqual(got, tt.want) { t.Errorf("parseYumUpdates() = %v, want %v", got, tt.want) } }) } } func TestParseYumUpdatesWithInstallingDependenciesKeywords(t *testing.T) { data := []byte(` ================================================================================================================================================================================= Package Arch Version Repository Size ================================================================================================================================================================================= Installing dependencies: kernel x86_64 2.6.32-754.24.3.el6 updates 32 M Installing weak dependencies: foo noarch 2.0.0-1 BaseOS 361 k bar x86_64 2.0.0-1 repo 10 M `) tests := []struct { name string data []byte want []*PkgInfo }{ {"NormalCase", data, []*PkgInfo{{Name: "kernel", Arch: "x86_64", RawArch: "x86_64", Version: "2.6.32-754.24.3.el6"}, {Name: "foo", Arch: "all", RawArch: "noarch", Version: "2.0.0-1"}, {Name: "bar", Arch: "x86_64", RawArch: "x86_64", Version: "2.0.0-1"}}}, {"NoPackages", []byte("nothing here"), nil}, {"nil", nil, nil}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := parseYumUpdates(tt.data); !reflect.DeepEqual(got, tt.want) { t.Errorf("parseYumUpdates() = %v, want %v", got, tt.want) } }) } } func TestGetYumTX(t *testing.T) { dataWithTX := []byte(` ================================================================================================================================================================================= Package Arch Version Repository Size ================================================================================================================================================================================= Installing: kernel x86_64 2.6.32-754.24.3.el6 updates 32 M replacing kernel.x86_64 1.0.0-4 Upgrading: foo noarch 2.0.0-1 BaseOS 361 k bar x86_64 2.0.0-1 repo 10 M Obsoleting: baz noarch 2.0.0-1 repo 10 M Transaction Summary ================================================================================================================================================================================= Upgrade 11 Packages Total download size: 106 M Exiting on user command Your transaction was saved, rerun it with: yum load-transaction /tmp/yum_save_tx.abcdef.yumtx `) dataNoTX := []byte(` ================================================================================================================================================================================= Package Arch Version Repository Size ================================================================================================================================================================================= Installing: kernel x86_64 2.6.32-754.24.3.el6 updates 32 M replacing kernel.x86_64 1.0.0-4 Upgrading: foo noarch 2.0.0-1 BaseOS 361 k bar x86_64 2.0.0-1 repo 10 M Obsoleting: baz noarch 2.0.0-1 repo 10 M Transaction Summary ================================================================================================================================================================================= Upgrade 11 Packages `) dataUnexpected := []byte(` Exiting on user command Your transaction was saved, rerun it with: yum load-transaction /tmp/otherfilename `) tests := []struct { name string data []byte want string }{ {"Transaction created", dataWithTX, "/tmp/yum_save_tx.abcdef.yumtx"}, {"Transaction not created", dataNoTX, ""}, {"Unexpected Filename", dataUnexpected, ""}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := getYumTXFile(tt.data); got != tt.want { t.Errorf("%s: getYumTXFile() = %v, want %v", tt.name, got, tt.want) } }) } } osconfig-20250416.02/packages/zypper.go000066400000000000000000000334001477773331400174640ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package packages import ( "bytes" "context" "fmt" "os/exec" "regexp" "runtime" "strconv" "strings" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/osinfo" "github.com/GoogleCloudPlatform/osconfig/util" ) var ( zypper string // zypperInstallArgs is zypper command to install patches, packages zypperInstallArgs = []string{"--gpg-auto-import-keys", "--non-interactive", "install", "--auto-agree-with-licenses"} zypperRemoveArgs = []string{"--non-interactive", "remove"} zypperListUpdatesArgs = []string{"--gpg-auto-import-keys", "-q", "list-updates"} zypperListPatchesArgs = []string{"--gpg-auto-import-keys", "-q", "list-patches"} zypperPatchInfoArgs = []string{"info", "-t", "patch"} ) func init() { if runtime.GOOS != "windows" { zypper = "/usr/bin/zypper" } ZypperExists = util.Exists(zypper) } type zypperListPatchOpts struct { categories []string severities []string withOptional bool all bool } // ZypperListOption is patch list options type ZypperListOption func(opts *zypperListPatchOpts) // ZypperListPatchCategories is zypper list option to provide category filter func ZypperListPatchCategories(categories []string) ZypperListOption { return func(args *zypperListPatchOpts) { args.categories = categories } } // ZypperListPatchSeverities is zypper list option to provide severity filter func ZypperListPatchSeverities(severities []string) ZypperListOption { return func(args *zypperListPatchOpts) { args.severities = severities } } // ZypperListPatchWithOptional is zypper list option to also list optional patches func ZypperListPatchWithOptional(withOptional bool) ZypperListOption { return func(args *zypperListPatchOpts) { args.withOptional = withOptional } } // ZypperListPatchAll is zypper list option to all all patches func ZypperListPatchAll(all bool) ZypperListOption { return func(args *zypperListPatchOpts) { args.all = all } } // InstallZypperPackages Installs zypper packages func InstallZypperPackages(ctx context.Context, pkgs []string) error { // TODO: Add retries when the it fails with exit code: 7 - which means zypper is locked by another process id. _, err := run(ctx, zypper, append(zypperInstallArgs, pkgs...)) return err } // ZypperInstall installs zypper patches and packages func ZypperInstall(ctx context.Context, patches []*ZypperPatch, pkgs []*PkgInfo) error { args := zypperInstallArgs // https://www.mankier.com/8/zypper#Concepts-Package_Types use patch install // for single patch and package installs for _, patch := range patches { args = append(args, "patch:"+patch.Name) } for _, pkg := range pkgs { args = append(args, "package:"+pkg.Name) } stdout, stderr, err := runner.Run(ctx, exec.CommandContext(ctx, zypper, args...)) // https://en.opensuse.org/SDB:Zypper_manual#EXIT_CODES if err != nil { if exitErr, ok := err.(*exec.ExitError); ok { // ZYPPER_EXIT_INF_REBOOT_NEEDED if exitErr.ExitCode() == 102 { err = nil } } else { err = fmt.Errorf("error running %s with args %q: %v, stdout: %q, stderr: %q", zypper, args, err, stdout, stderr) } } return err } // RemoveZypperPackages installed Zypper packages. func RemoveZypperPackages(ctx context.Context, pkgs []string) error { _, err := run(ctx, zypper, append(zypperRemoveArgs, pkgs...)) return err } func parseZypperUpdates(data []byte) []*PkgInfo { /* S | Repository | Name | Current Version | Available Version | Arch --+---------------------+------------------------+-----------------+-------------------+------- v | SLES12-SP3-Updates | at | 3.1.14-7.3 | 3.1.14-8.3.1 | x86_64 v | SLES12-SP3-Updates | autoyast2-installation | 3.2.17-1.3 | 3.2.22-2.9.2 | noarch ... */ lines := bytes.Split(bytes.TrimSpace(data), []byte("\n")) var pkgs []*PkgInfo for _, ln := range lines { pkg := bytes.Split(ln, []byte("|")) if len(pkg) != 6 || string(bytes.TrimSpace(pkg[0])) != "v" { continue } name := string(bytes.TrimSpace(pkg[2])) arch := string(bytes.TrimSpace(pkg[5])) ver := string(bytes.TrimSpace(pkg[4])) pkgs = append(pkgs, &PkgInfo{Name: name, Arch: osinfo.NormalizeArchitecture(arch), Version: ver}) } return pkgs } // ZypperUpdates queries for all available zypper updates. func ZypperUpdates(ctx context.Context) ([]*PkgInfo, error) { out, err := run(ctx, zypper, zypperListUpdatesArgs) if err != nil { return nil, err } return parseZypperUpdates(out), nil } func parseZypperPatches(ctx context.Context, data []byte) ([]*ZypperPatch, []*ZypperPatch) { /* Repository | Name | Category | Severity | Interactive | Status | Summary ------------------------------------+---------------------------------------------+-------------+-----------+-------------+------------+------------------------------------------------------------ SLE-Module-Basesystem15-SP1-Updates | SUSE-SLE-Module-Basesystem-15-SP1-2019-1206 | security | low | --- | applied | Security update for bzip2 SLE-Module-Basesystem15-SP1-Updates | SUSE-SLE-Module-Basesystem-15-SP1-2019-1221 | security | moderate | --- | applied | Security update for libxslt SLE-Module-Basesystem15-SP1-Updates | SUSE-SLE-Module-Basesystem-15-SP1-2019-1229 | recommended | moderate | --- | not needed | Recommended update for sensors SLE-Module-Basesystem15-SP1-Updates | SUSE-SLE-Module-Basesystem-15-SP1-2019-1258 | recommended | moderate | --- | needed | Recommended update for postfix */ lines := bytes.Split(bytes.TrimSpace(data), []byte("\n")) var installed []*ZypperPatch var available []*ZypperPatch for _, ln := range lines { patch, status, err := parseZypperPatch(ln) if err != nil { clog.Debugf(ctx, "skipping a line from zypper patch output: %s", err) continue } switch status { case "needed": available = append(available, patch) case "applied": installed = append(installed, patch) default: continue } } return installed, available } func parseZypperPatch(tableLine []byte) (*ZypperPatch, string, error) { patch := bytes.Split(tableLine, []byte("|")) if len(patch) < 7 || len(patch) > 8 { return nil, "", fmt.Errorf("not parsable zypper patch line; expected 7 or 8 segments, got - %d; this usually isn't an error; line: %s", len(patch), string(tableLine)) } name := string(bytes.TrimSpace(patch[1])) category := string(bytes.TrimSpace(patch[2])) severity := string(bytes.TrimSpace(patch[3])) status := string(bytes.TrimSpace(patch[5])) summary := string(bytes.TrimSpace(patch[6])) if len(patch) == 8 { summary = string(bytes.TrimSpace(patch[7])) } return &ZypperPatch{Name: name, Category: category, Severity: severity, Summary: summary}, status, nil } func zypperPatches(ctx context.Context, opts ...ZypperListOption) ([]byte, error) { zOpts := &zypperListPatchOpts{ categories: nil, severities: nil, withOptional: false, all: false, } for _, opt := range opts { opt(zOpts) } args := zypperListPatchesArgs for _, c := range zOpts.categories { args = append(args, "--category="+c) } for _, s := range zOpts.severities { args = append(args, "--severity="+s) } if zOpts.withOptional { args = append(args, "--with-optional") } // As per zypper's current implementation, // --all is ignored if we have any filters on any other // field. if zOpts.all || (len(zOpts.severities)+len(zOpts.categories)) <= 0 { args = append(args, "--all") } return run(ctx, zypper, args) } // ZypperPatches queries for all available zypper patches. func ZypperPatches(ctx context.Context, opts ...ZypperListOption) ([]*ZypperPatch, error) { out, err := zypperPatches(ctx, opts...) if err != nil { return nil, err } _, patches := parseZypperPatches(ctx, out) return patches, nil } // ZypperInstalledPatches queries for all installed zypper patches. func ZypperInstalledPatches(ctx context.Context, opts ...ZypperListOption) ([]*ZypperPatch, error) { out, err := zypperPatches(ctx, opts...) if err != nil { return nil, err } patches, _ := parseZypperPatches(ctx, out) return patches, nil } func zypperPatchInfo(ctx context.Context, patches []string) ([]byte, error) { args := zypperPatchInfoArgs for _, name := range patches { args = append(args, name) } return run(ctx, zypper, args) } func parseZypperPatchInfo(out []byte) (map[string][]string, error) { /* Loading repository data... Reading installed packages... Information for patch SUSE-SLE-SERVER-12-SP4-2019-2974: ------------------------------------------------------- Repository : SLES12-SP4-Updates Name : SUSE-SLE-SERVER-12-SP4-2019-2974 Version : 1 Arch : noarch Vendor : maint-coord@suse.de Status : needed Category : recommended Severity : important Created On : Thu Nov 14 13:17:48 2019 Interactive : --- Summary : Recommended update for irqbalance Description : This update for irqbalance fixes the following issues: - Irqbalanced spreads the IRQs between the available virtual machines. (bsc#1119465, bsc#1154905) Provides : patch:SUSE-SLE-SERVER-12-SP4-2019-2974 = 1 Conflicts : [2] irqbalance.src < 1.1.0-9.3.1 irqbalance.x86_64 < 1.1.0-9.3.1 */ patchInfo := make(map[string][]string) var validConflictLine = regexp.MustCompile(`\s*Conflicts\s*:\s*\[\d*\]\s*`) var conflictLineExtract = regexp.MustCompile(`\[[0-9]+\]`) var nameLine = regexp.MustCompile(`\s*Name\s*:\s*`) lines := bytes.Split(bytes.TrimSpace(out), []byte("\n")) i := 0 for { // find the name line for ; i < len(lines); i++ { b := nameLine.Find([]byte(lines[i])) if b != nil { break } } if i >= len(lines) { // we do not have any more patch info blobs break } parts := strings.Split(string(lines[i]), ":") i++ if len(parts) != 2 { return nil, fmt.Errorf("invalid name output") } patchName := strings.Trim(parts[1], " ") for ; i < len(lines); i++ { b := validConflictLine.Find([]byte(lines[i])) if b != nil { // Conflicts : [2] break } } if i >= len(lines) { // did not find conflicting packages // this should not happen return nil, nil } matches := conflictLineExtract.FindAllString(string(lines[i]), -1) if len(matches) != 1 { return nil, fmt.Errorf("invalid patch info") } // get the number of package lines to parse conflicts := strings.Trim(matches[0], "[") conflicts = strings.Trim(conflicts, "]") conflictLines, err := strconv.Atoi(conflicts) if err != nil { return nil, fmt.Errorf("invalid patch info: invalid conflict info") } ctr := i + 1 ctrEnd := ctr + conflictLines for ; ctr < ctrEnd; ctr++ { //libsolv.src < 0.6.36-2.27.19.8 //libsolv-tools.x86_64 < 0.6.36-2.27.19.8 //libzypp.src < 16.20.2-27.60.4 //libzypp.x86_64 < 16.20.2-27.60.4 //perl-solv.x86_64 < 0.6.36-2.27.19.8 //python-solv.x86_64 < 0.6.36-2.27.19.8 //zypper.src < 1.13.54-18.40.2 //zypper.x86_64 < 1.13.54-18.40.2 //zypper-log < 1.13.54-18.40.2 //srcpackage:ruby2.5 < 2.5.9-150000.4.29.1 //ruby2.5.noarch < 2.5.9-150000.4.29.1 //ruby2.5.x86_64 < 2.5.9-150000.4.29.1 //srcpackage:zypper //zypper-log < 1.14.64-150400.3.32.1 //zypper-needs-restarting < 1.14.64-150400.3.32.1 parts := strings.Split(string(lines[ctr]), "<") if len(parts) != 2 { return nil, fmt.Errorf("invalid package info, can't parse line: %v", string(lines[ctr])) } nameArch := parts[0] pkgName := "" if strings.Contains(nameArch, "srcpackage:") { colonIdx := strings.Index(nameArch, ":") pkgName = strings.Trim(nameArch[colonIdx+1:], " ") if len(pkgName) == 0 { return nil, fmt.Errorf("invalid package info, can't parse line: %v", string(lines[ctr])) } } else { // Get the last index to handle the case if pkg has float version // (e.g. `ruby2.5.noarch < 2.5.9-150000.4.29.1`) lastDotIdx := strings.LastIndex(nameArch, ".") // In case if there's NO dot exist, then the package name doen't contain // the architecture details (`e.g. zypper-log < 1.14.64-150400.3.32.1`) if lastDotIdx == -1 { pkgName = strings.Trim(nameArch, " ") } else { pkgName = strings.Trim(nameArch[:lastDotIdx], " ") } } patches, ok := patchInfo[pkgName] if !ok { patches = make([]string, 0) } patches = append(patches, patchName) patchInfo[pkgName] = patches } // set i for next patch information blob i = ctrEnd } // TODO: instead of returning a map of // make it more concrete type returns with more information // about the package and patch if len(patchInfo) == 0 { return nil, fmt.Errorf("invalid patch information, did not find patch blobs") } return patchInfo, nil } // ZypperPackagesInPatch returns the list of patches, a package upgrade belongs to func ZypperPackagesInPatch(ctx context.Context, patches []*ZypperPatch) (map[string][]string, error) { if len(patches) == 0 { return make(map[string][]string), nil } var patchNames []string for _, patch := range patches { patchNames = append(patchNames, patch.Name) } out, err := zypperPatchInfo(ctx, patchNames) if err != nil { return nil, err } return parseZypperPatchInfo(out) } osconfig-20250416.02/packages/zypper_test.go000066400000000000000000000463471477773331400205410ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package packages import ( "context" "errors" "os/exec" "reflect" "strings" "testing" utilmocks "github.com/GoogleCloudPlatform/osconfig/util/mocks" "github.com/golang/mock/gomock" ) func TestZypperInstalls(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) runner = mockCommandRunner expectedCmd := utilmocks.EqCmd(exec.Command(zypper, append(zypperInstallArgs, pkgs...)...)) mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).Return([]byte("stdout"), []byte("stderr"), nil).Times(1) if err := InstallZypperPackages(testCtx, pkgs); err != nil { t.Errorf("unexpected error: %v", err) } mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).Return([]byte("stdout"), []byte("stderr"), errors.New("error")).Times(1) if err := InstallZypperPackages(testCtx, pkgs); err == nil { t.Errorf("did not get expected error") } } func TestRemoveZypper(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) runner = mockCommandRunner expectedCmd := utilmocks.EqCmd(exec.Command(zypper, append(zypperRemoveArgs, pkgs...)...)) mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).Return([]byte("stdout"), []byte("stderr"), nil).Times(1) if err := RemoveZypperPackages(testCtx, pkgs); err != nil { t.Errorf("unexpected error: %v", err) } mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).Return([]byte("stdout"), []byte("stderr"), errors.New("error")).Times(1) if err := RemoveZypperPackages(testCtx, pkgs); err == nil { t.Errorf("unexpected error: %v", err) } } func TestParseZypperUpdates(t *testing.T) { normalCase := `S | Repository | Name | Current Version | Available Version | Arch --+---------------------+------------------------+-----------------+-------------------+------- v | SLES12-SP3-Updates | at | 3.1.14-7.3 | 3.1.14-8.3.1 | x86_64 v | SLES12-SP3-Updates | autoyast2-installation | 3.2.17-1.3 | 3.2.22-2.9.2 | noarch this is junk data` tests := []struct { name string data []byte want []*PkgInfo }{ {"NormalCase", []byte(normalCase), []*PkgInfo{{Name: "at", Arch: "x86_64", Version: "3.1.14-8.3.1"}, {Name: "autoyast2-installation", Arch: "all", Version: "3.2.22-2.9.2"}}}, {"NoPackages", []byte("nothing here"), nil}, {"nil", nil, nil}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := parseZypperUpdates(tt.data); !reflect.DeepEqual(got, tt.want) { t.Errorf("parseZypperUpdates() = %v, want %v", got, tt.want) } }) } } func TestZypperUpdates(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) runner = mockCommandRunner expectedCmd := utilmocks.EqCmd(exec.Command(zypper, zypperListUpdatesArgs...)) data := []byte("v | SLES12-SP3-Updates | at | 3.1.14-7.3 | 3.1.14-8.3.1 | x86_64") mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).Return(data, []byte("stderr"), nil).Times(1) ret, err := ZypperUpdates(testCtx) if err != nil { t.Errorf("unexpected error: %v", err) } want := []*PkgInfo{{Name: "at", Arch: "x86_64", Version: "3.1.14-8.3.1"}} if !reflect.DeepEqual(ret, want) { t.Errorf("ZypperUpdates() = %v, want %v", ret, want) } mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).Return([]byte("stdout"), []byte("stderr"), errors.New("error")).Times(1) if _, err := ZypperUpdates(testCtx); err == nil { t.Errorf("did not get expected error") } } func TestParseZypperPatches(t *testing.T) { normalCase := `Repository | Name | Category | Severity | Interactive | Status | Summary ------------------------------------+---------------------------------------------+-------------+-----------+-------------+------------+------------------------------------------------------------ SLE-Module-Basesystem15-SP1-Updates | SUSE-SLE-Module-Basesystem-15-SP1-2019-1206 | security | low | --- | applied | Security update for bzip2 SLE-Module-Basesystem15-SP1-Updates | SUSE-SLE-Module-Basesystem-15-SP1-2019-1221 | security | moderate | --- | needed | Security update for libxslt SLE-Module-Basesystem15-SP1-Updates | SUSE-SLE-Module-Basesystem-15-SP1-2019-1229 | recommended | moderate | --- | not needed | Recommended update for sensors SLE-Module-Basesystem15-SP1-Updates | SUSE-SLE-Module-Basesystem-15-SP1-2019-1258 | recommended | moderate | --- | needed | Recommended update for postfix some junk data` //Recently new format of response was observed, the difference is additional "Since" field in the table. withSinceField := `Repository | Name | Category | Severity | Interactive | Status | Since | Summary ----------------------------------------------+-------------------------------------------------------+-------------+-----------+----------------+------------+------------------------------------------------------------ SLE-Module-Basesystem15-SP1-Updates | SUSE-SLE-Module-Basesystem-15-SP1-2019-1206 | security | low | --- | applied | - | Security update for bzip2 SLE-Module-Basesystem15-SP1-Updates | SUSE-SLE-Module-Basesystem-15-SP1-2019-1221 | security | moderate | --- | needed | - | Security update for libxslt SLE-Module-Basesystem15-SP1-Updates | SUSE-SLE-Module-Basesystem-15-SP1-2019-1229 | recommended | moderate | --- | not needed | - | Recommended update for sensors SLE-Module-Basesystem15-SP1-Updates | SUSE-SLE-Module-Basesystem-15-SP1-2019-1258 | recommended | moderate | --- | needed | - | Recommended update for postfix some junk data` tests := []struct { name string data []byte wantIns []*ZypperPatch wantAvail []*ZypperPatch }{ { "NormalCase", []byte(normalCase), []*ZypperPatch{{"SUSE-SLE-Module-Basesystem-15-SP1-2019-1206", "security", "low", "Security update for bzip2"}}, []*ZypperPatch{{"SUSE-SLE-Module-Basesystem-15-SP1-2019-1221", "security", "moderate", "Security update for libxslt"}, {"SUSE-SLE-Module-Basesystem-15-SP1-2019-1258", "recommended", "moderate", "Recommended update for postfix"}}, }, { "WithSinceField", []byte(withSinceField), []*ZypperPatch{{"SUSE-SLE-Module-Basesystem-15-SP1-2019-1206", "security", "low", "Security update for bzip2"}}, []*ZypperPatch{{"SUSE-SLE-Module-Basesystem-15-SP1-2019-1221", "security", "moderate", "Security update for libxslt"}, {"SUSE-SLE-Module-Basesystem-15-SP1-2019-1258", "recommended", "moderate", "Recommended update for postfix"}}, }, {"NoPackages", []byte("nothing here"), nil, nil}, {"nil", nil, nil, nil}, } ctx := context.Background() for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { gotIns, gotAvail := parseZypperPatches(ctx, tt.data) if !reflect.DeepEqual(gotIns, tt.wantIns) { t.Errorf("parseZypperPatches() = %v, want %v", gotIns, tt.wantIns) } if !reflect.DeepEqual(gotAvail, tt.wantAvail) { t.Errorf("parseZypperPatches() = %v, want %v", gotAvail, tt.wantAvail) } }) } } func TestZypperPatches(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) runner = mockCommandRunner expectedCmd := utilmocks.EqCmd(exec.Command(zypper, append(zypperListPatchesArgs, "--all")...)) data := []byte("SLE-Module-Basesystem15-SP1-Updates | SUSE-SLE-Module-Basesystem-15-SP1-2019-1258 | recommended | moderate | --- | needed | Recommended update for postfix") mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).Return(data, []byte("stderr"), nil).Times(1) ret, err := ZypperPatches(testCtx) if err != nil { t.Errorf("unexpected error: %v", err) } want := []*ZypperPatch{{"SUSE-SLE-Module-Basesystem-15-SP1-2019-1258", "recommended", "moderate", "Recommended update for postfix"}} if !reflect.DeepEqual(ret, want) { t.Errorf("ZypperPatches() = %v, want %v", ret, want) } mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).Return([]byte("stdout"), []byte("stderr"), errors.New("error")).Times(1) if _, err := ZypperPatches(testCtx); err == nil { t.Errorf("did not get expected error") } } func TestZypperInstalledPatches(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockCommandRunner := utilmocks.NewMockCommandRunner(mockCtrl) runner = mockCommandRunner expectedCmd := utilmocks.EqCmd(exec.Command(zypper, append(zypperListPatchesArgs, "--all")...)) data := []byte("SLE-Module-Basesystem15-SP1-Updates | SUSE-SLE-Module-Basesystem-15-SP1-2019-1258 | recommended | moderate | --- | applied | Recommended update for postfix") mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).Return(data, []byte("stderr"), nil).Times(1) ret, err := ZypperInstalledPatches(testCtx) if err != nil { t.Errorf("unexpected error: %v", err) } want := []*ZypperPatch{{"SUSE-SLE-Module-Basesystem-15-SP1-2019-1258", "recommended", "moderate", "Recommended update for postfix"}} if !reflect.DeepEqual(ret, want) { t.Errorf("ZypperInstalledPatches() = %v, want %v", ret, want) } mockCommandRunner.EXPECT().Run(testCtx, expectedCmd).Return([]byte("stdout"), []byte("stderr"), errors.New("error")).Times(1) if _, err := ZypperInstalledPatches(testCtx); err == nil { t.Errorf("did not get expected error") } } func TestParsePatchInfo(t *testing.T) { patchInfo := ` Loading repository data... Reading installed packages... Information for patch SUSE-SLE-SERVER-12-SP4-2019-2974: ------------------------------------------------------- Repository : SLES12-SP4-Updates Name : SUSE-SLE-SERVER-12-SP4-2019-2974 Version : 1 Arch : noarch Vendor : maint-coord@suse.de Status : needed Category : recommended Severity : important Created On : Thu Nov 14 13:17:48 2019 Interactive : --- Summary : Recommended update for irqbalance Description : This update for irqbalance fixes the following issues: - Irqbalanced spreads the IRQs between the available virtual machines. (bsc#1119465, bsc#1154905) Provides : patch:SUSE-SLE-SERVER-12-SP4-2019-2974 = 1 Conflicts : [4] irqbalance.src < 1.1.0-9.3.1 irqbalance.x86_64 < 1.1.0-9.3.1 common-package.src < 1.1.0-9.3.1 common-package.x86_64 < 1.1.0-9.3.1 Information for patch SUSE-SLE-Module-Public-Cloud-12-2019-2026: ---------------------------------------------------------------- Repository : SLE-Module-Public-Cloud12-Updates Name : SUSE-SLE-Module-Public-Cloud-12-2019-2026 Version : 1 Arch : noarch Vendor : maint-coord@suse.de Status : needed Category : recommended Severity : moderate Created On : Tue Jul 30 17:20:02 2019 Interactive : --- Summary : Recommended update for Azure Python SDK Description : This update brings the following python modules for the Azure Python SDK: - python-Flask - python-Werkzeug - python-click - python-decorator - python-httpbin - python-idna - python-itsdangerous - python-py - python-pytest-httpbin - python-pytest-mock - python-requests Provides : patch:SUSE-SLE-Module-Public-Cloud-12-2019-2026 = 1 Conflicts : [32] python-Flask.noarch < 0.12.1-7.4.2 python-Flask.src < 0.12.1-7.4.2 python-Werkzeug.noarch < 0.12.2-10.4.2 python-Werkzeug.src < 0.12.2-10.4.2 python-click.noarch < 6.7-2.4.2 python-click.src < 6.7-2.4.2 python-decorator.noarch < 4.1.2-4.4.2 python-decorator.src < 4.1.2-4.4.2 python-httpbin.noarch < 0.5.0-2.4.2 python-httpbin.src < 0.5.0-2.4.2 python-idna.noarch < 2.5-3.10.2 python-idna.src < 2.5-3.10.2 python-itsdangerous.noarch < 0.24-7.4.2 python-itsdangerous.src < 0.24-7.4.2 python-py.noarch < 1.5.2-8.8.2 python-py.src < 1.5.2-8.8.2 python-requests.noarch < 2.18.2-8.4.2 python-requests.src < 2.18.2-8.4.2 python-six.noarch < 1.11.0-9.21.2 python-six.src < 1.11.0-9.21.2 python3-Flask.noarch < 0.12.1-7.4.2 python3-Werkzeug.noarch < 0.12.2-10.4.2 python3-click.noarch < 6.7-2.4.2 python3-decorator.noarch < 4.1.2-4.4.2 python3-httpbin.noarch < 0.5.0-2.4.2 python3-idna.noarch < 2.5-3.10.2 python3-itsdangerous.noarch < 0.24-7.4.2 python3-py.noarch < 1.5.2-8.8.2 python3-requests.noarch < 2.18.2-8.4.2 python3-six.noarch < 1.11.0-9.21.2 common-package.src < 1.1.0-9.3.1 common-package.x86_64 < 1.1.0-9.3.1 zypper.src < 1.14.46-13.1 zypper.noarch < 1.14.46-13.1 zypper.x86_64 < 1.14.46-13.1 zypper-log < 1.14.46-13.1 zypper-needs-restarting < 1.14.46-13.1 ` ppMap, err := parseZypperPatchInfo([]byte(patchInfo)) if err != nil { t.Errorf("unexpected error: %+v", err) } if _, ok := ppMap["python3-requests"]; !ok { t.Errorf("Unexpected result: expected a patch for python3-requests") } if _, ok := ppMap["random-package"]; ok { t.Errorf("Unexpected result: did not expect patch for random-package") } if _, ok := ppMap["random-package"]; ok { t.Errorf("Unexpected result: did not expect patch for random-package") } if patches, ok := ppMap["common-package"]; !ok { t.Errorf("Unexpected result: did not expect patch for common-package") for _, patch := range patches { if (strings.Compare(patch, "SUSE-SLE-Module-Public-Cloud-12-2019-2026") != 0) || (strings.Compare(patch, "SUSE-SLE-SERVER-12-SP4-2019-2974") != 0) { t.Errorf("Unexptected result: patch name should be one of SUSE-SLE-SERVER-12-SP4-2019-2974 or SUSE-SLE-Module-Public-Cloud-12-2019-2026") } } } } func TestParsePatchInfo_differentFormatsOfConflictPkgsVersions(t *testing.T) { patchInfo := ` Information for patch SUSE-SLE-Module-Basesystem-15-SP5-2023-4176: ------------------------------------------------------------------ Repository : SLE-Module-Basesystem15-SP5-Updates Name : SUSE-SLE-Module-Basesystem-15-SP5-2023-4176 Version : 1 Arch : noarch Vendor : maint-coord@suse.de Status : needed Category : security Severity : important Created On : Tue Oct 24 13:35:58 2023 Interactive : --- Summary : Security update for ruby2.5 Description : This update for ruby2.5 fixes the following issues: - CVE-2023-28755: Fixed a ReDoS vulnerability in URI. (bsc#1209891) - CVE-2023-28756: Fixed an expensive regexp in the RFC2822 time parser. (bsc#1209967) - CVE-2021-41817: Fixed a Regular Expression Denial of Service Vulnerability of Date Parsing Methods. (bsc#1193035) - CVE-2021-33621: Fixed a HTTP response splitting vulnerability in CGI gem. (bsc#1205726) Provides : patch:SUSE-SLE-Module-Basesystem-15-SP5-2023-4176 = 1 Conflicts : [11] libruby2_5-2_5.x86_64 < 2.5.9-150000.4.29.1 libruby2_5-2_5.noarch < 2.5.9-150000.4.29.1 srcpackage:ruby2.5 < 2.5.9-150000.4.29.1 ruby2.5.noarch < 2.5.9-150000.4.29.1 ruby2.5.x86_64 < 2.5.9-150000.4.29.1 ruby2.5-devel.x86_64 < 2.5.9-150000.4.29.1 ruby2.5-devel.noarch < 2.5.9-150000.4.29.1 ruby2.5-devel-extra.x86_64 < 2.5.9-150000.4.29.1 ruby2.5-devel-extra.noarch < 2.5.9-150000.4.29.1 ruby2.5-stdlib.x86_64 < 2.5.9-150000.4.29.1 ruby2.5-stdlib.noarch < 2.5.9-150000.4.29.1 Information for patch SUSE-SLE-Module-Basesystem-15-SP5-2023-4843: ------------------------------------------------------------------ Repository : SLE-Module-Basesystem15-SP5-Updates Name : SUSE-SLE-Module-Basesystem-15-SP5-2023-4843 Version : 1 Arch : noarch Vendor : maint-coord@suse.de Status : needed Category : security Severity : moderate Created On : Thu Dec 14 11:23:04 2023 Interactive : --- Summary : Security update for python3-cryptography Description : This update for python3-cryptography fixes the following issues: - CVE-2023-49083: Fixed a NULL pointer dereference when loading certificates from a PKCS#7 bundle (bsc#1217592). Provides : patch:SUSE-SLE-Module-Basesystem-15-SP5-2023-4843 = 1 Conflicts : [3] srcpackage:python3-cryptography < 3.3.2-150400.23.1 python3-cryptography.noarch < 3.3.2-150400.23.1 python3-cryptography.x86_64 < 3.3.2-150400.23.1 Information for patch SUSE-SLE-Module-Basesystem-15-SP5-2023-3973: ------------------------------------------------------------------ Repository : SLE-Module-Basesystem15-SP5-Updates Name : SUSE-SLE-Module-Basesystem-15-SP5-2023-3973 Version : 1 Arch : noarch Vendor : maint-coord@suse.de Status : needed Category : recommended Severity : moderate Created On : Thu Oct 5 08:17:12 2023 Interactive : restart Summary : Recommended update for zypper Description : This update for zypper fixes the following issues: - Fix name of the bash completion script (bsc#1215007) - Update notes about failing signature checks (bsc#1214395) - Improve the SIGINT handler to be signal safe (bsc#1214292) - Update to version 1.14.64 - Changed location of bash completion script (bsc#1213854). Provides : patch:SUSE-SLE-Module-Basesystem-15-SP5-2023-3973 = 1 Conflicts : [5] srcpackage:zypper < 1.14.64-150400.3.32.1 zypper.noarch < 1.14.64-150400.3.32.1 zypper.x86_64 < 1.14.64-150400.3.32.1 zypper-log < 1.14.64-150400.3.32.1 zypper-needs-restarting < 1.14.64-150400.3.32.1 ` ppMap, err := parseZypperPatchInfo([]byte(patchInfo)) if err != nil { t.Errorf("unexpected error: %+v", err) } if _, ok := ppMap["libruby2_5-2_5"]; !ok { t.Errorf("Unexpected result: expected a patch for libruby2_5-2_5") } if _, ok := ppMap["ruby2.5"]; !ok { t.Errorf("Unexpected result: expected a patch for ruby2.5") } if _, ok := ppMap["python3-cryptography"]; !ok { t.Errorf("Unexpected result: expected a patch for python3-cryptography") } if _, ok := ppMap["zypper-log"]; !ok { t.Errorf("Unexpected result: expected a patch for zypper-log") } if _, ok := ppMap["zypper-needs-restarting"]; !ok { t.Errorf("Unexpected result: expected a patch for zypper-needs-restarting") } patches, ok := ppMap["python3-cryptography"] if !ok { t.Errorf("Unexpected result: expected a patch for python3-cryptography") } else { for _, patch := range patches { if strings.Compare(patch, "SUSE-SLE-Module-Basesystem-15-SP5-2023-4843") != 0 { t.Errorf("Unexptected result: patch name should be SUSE-SLE-Module-Basesystem-15-SP5-2023-4843") } } } } func TestZypperPackagesInPatch(t *testing.T) { ppMap, err := ZypperPackagesInPatch(testCtx, nil) if err != nil { t.Errorf("Unexpected error: %v", err) } if len(ppMap) > 0 { t.Errorf("Unexpected result: expected no mappings, got = [%+v]", ppMap) } } osconfig-20250416.02/packaging/000077500000000000000000000000001477773331400157525ustar00rootroot00000000000000osconfig-20250416.02/packaging/debian/000077500000000000000000000000001477773331400171745ustar00rootroot00000000000000osconfig-20250416.02/packaging/debian/changelog000066400000000000000000000002441477773331400210460ustar00rootroot00000000000000google-osconfig-agent (1:20191216.00-g1) stable; urgency=medium * Move to Beta API. -- Google Cloud Team Tue, 16 Dec 2019 12:00:00 +0000 osconfig-20250416.02/packaging/debian/compat000066400000000000000000000000031477773331400203730ustar00rootroot0000000000000010 osconfig-20250416.02/packaging/debian/control000066400000000000000000000007461477773331400206060ustar00rootroot00000000000000Source: google-osconfig-agent Maintainer: Google Cloud Team Section: misc Priority: optional Standards-Version: 3.9.8 Build-Depends: debhelper (>= 10), dh-golang (>= 1.1), golang-go Package: google-osconfig-agent Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: Google Compute Engine OSConfig Agent Contains the OSConfig agent service binary as well as systemd startup scripts XS-Go-Import-Path: github.com/GoogleCloudPlatform/osconfig osconfig-20250416.02/packaging/debian/copyright000066400000000000000000000017261477773331400211350ustar00rootroot00000000000000Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: google-compute-engine Upstream-Contact: gc-team@google.com Files: * Copyright: Copyright 2017 Google Inc. License: Apache-2.0 Files: debian/* Copyright: Copyright 2017 Google Inc. License: Apache-2.0 License: Apache-2.0 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at . http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. . On Debian systems, the complete text of the Apache version 2.0 license can be found in "/usr/share/common-licenses/Apache-2.0". osconfig-20250416.02/packaging/debian/google-osconfig-agent.docs000066400000000000000000000000261477773331400242210ustar00rootroot00000000000000THIRD_PARTY_LICENSES/ osconfig-20250416.02/packaging/debian/postrm000066400000000000000000000004221477773331400204410ustar00rootroot00000000000000#!/bin/sh set -e if [ $1 = upgrade ]; then # If the old directory exists make sure we set the file there. [ -e /etc/osconfig ] && touch /etc/osconfig/osconfig_agent_restart_required touch /var/lib/google_osconfig_agent/osconfig_agent_restart_required fi exit 0 osconfig-20250416.02/packaging/debian/rules000077500000000000000000000040441477773331400202560ustar00rootroot00000000000000#!/usr/bin/make -f export PATH := /tmp/go/bin:$(PATH) export SHELL := env PATH=$(PATH) /bin/bash export DH_OPTIONS export DH_GOPKG := github.com/GoogleCloudPlatform/osconfig export DH_GOLANG_EXCLUDES := e2e_tests/ export CGO_ENABLED := 0 export GO111MODULE := on export GOPATH := /usr/share/gocode export DH_GOLANG_BUILDPKG := github.com/GoogleCloudPlatform/osconfig github.com/GoogleCloudPlatform/osconfig/agentconfig github.com/GoogleCloudPlatform/osconfig/agentendpoint github.com/GoogleCloudPlatform/osconfig/attributes github.com/GoogleCloudPlatform/osconfig/clog github.com/GoogleCloudPlatform/osconfig/external github.com/GoogleCloudPlatform/osconfig/inventory github.com/GoogleCloudPlatform/osconfig/osinfo github.com/GoogleCloudPlatform/osconfig/ospatch github.com/GoogleCloudPlatform/osconfig/packages github.com/GoogleCloudPlatform/osconfig/policies github.com/GoogleCloudPlatform/osconfig/policies/recipes github.com/GoogleCloudPlatform/osconfig/retryutil github.com/GoogleCloudPlatform/osconfig/tasker github.com/GoogleCloudPlatform/osconfig/util github.com/GoogleCloudPlatform/osconfig/util/mocks export GOPROXY := https://proxy.golang.org export GOCACHE := /tmp/.cache %: dh $@ --buildsystem=golang --with=golang,systemd override_dh_auto_install: # Binary-only package. dh_auto_install -- --no-source mv debian/google-osconfig-agent/usr/bin/osconfig debian/google-osconfig-agent/usr/bin/google_osconfig_agent install -d debian/google-osconfig-agent/var/lib/google_osconfig_agent install -d debian/google-osconfig-agent/lib/systemd/system install -p -m 0644 *.service debian/google-osconfig-agent/lib/systemd/system/ override_dh_golang: # We don't use any packaged dependencies, so skip dh_golang step. override_dh_auto_test: # Skip tests as they are already setup as part of the commit process. override_dh_auto_build: dh_auto_build -O--buildsystem=golang -- -ldflags="-s -w -X main.version=$(VERSION)-$(RELEASE)" -mod=readonly override_dh_installinit: override_dh_systemd_start: dh_systemd_start --no-restart-after-upgrade --no-restart-on-upgrade osconfig-20250416.02/packaging/debian/source/000077500000000000000000000000001477773331400204745ustar00rootroot00000000000000osconfig-20250416.02/packaging/debian/source/format000066400000000000000000000000141477773331400217020ustar00rootroot000000000000003.0 (quilt) osconfig-20250416.02/packaging/googet/000077500000000000000000000000001477773331400172365ustar00rootroot00000000000000osconfig-20250416.02/packaging/googet/google-osconfig-agent.goospec000066400000000000000000000021651477773331400250000ustar00rootroot00000000000000{ "name": "google-osconfig-agent", {{$package_version := printf "%s.0+win@1" .version -}} "version": "{{$package_version}}", "arch": "x86_64", "authors": "Google Inc.", "license": "http://www.apache.org/licenses/LICENSE-2.0", "description": "Google OSConfig agent", "source": "https://github.com/GoogleCloudPlatform/osconfig", "files": { "google_osconfig_agent.exe": "/Google/OSConfig/google_osconfig_agent.exe", "THIRD_PARTY_LICENSES": "/Google/OSConfig/THIRD_PARTY_LICENSES/", "LICENSE": "/Google/OSConfig/LICENSE.txt" }, "install": { "path": "packaging/googet/install.ps1" }, "uninstall": { "path": "packaging/googet/uninstall.ps1" }, "sources": [{ "include": [ "google_osconfig_agent.exe", "packaging/googet/install.ps1", "packaging/googet/uninstall.ps1", "THIRD_PARTY_LICENSES/**", "LICENSE" ] }], "build": { "linux": "/bin/bash", "linuxArgs": ["-c", "GOOS=windows $GO build -ldflags='-s -w -X main.version={{$package_version}}' -mod=readonly -o google_osconfig_agent.exe"] } } osconfig-20250416.02/packaging/googet/install.ps1000066400000000000000000000034721477773331400213370ustar00rootroot00000000000000# Copyright 2018 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. $ErrorActionPreference = 'Stop' function Set-ServiceConfig { # Restart service after 1s, then 2s. Reset error counter after 60s. sc.exe failure google_osconfig_agent reset= 60 actions= restart/1000/restart/2000 # Set dependency and delayed start sc.exe config google_osconfig_agent depend= "rpcss" start= delayed-auto # Create trigger to start the service on first IP address sc.exe triggerinfo google_osconfig_agent start/networkon } try { if (-not (Get-Service 'google_osconfig_agent' -ErrorAction SilentlyContinue)) { New-Service -DisplayName 'Google OSConfig Agent' ` -Name 'google_osconfig_agent' ` -BinaryPathName '"C:\Program Files\Google\OSConfig\google_osconfig_agent.exe"' ` -StartupType Automatic ` -Description 'Google OSConfig service agent' Set-ServiceConfig Start-Service google_osconfig_agent -Verbose -ErrorAction Stop } else { Set-ServiceConfig New-Item -Path 'C:\Program Files\Google\OSConfig\osconfig_agent_restart_required' -Force -Type File -ErrorAction SilentlyContinue | Out-Null } } catch { Write-Output $_.InvocationInfo.PositionMessage Write-Output "Install failed: $($_.Exception.Message)" exit 1 } osconfig-20250416.02/packaging/googet/uninstall.ps1000066400000000000000000000012611477773331400216740ustar00rootroot00000000000000# Copyright 2018 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. Stop-Service google_osconfig_agent -Verbose & sc.exe delete google_osconfig_agent osconfig-20250416.02/packaging/google-osconfig-agent.spec000066400000000000000000000051431477773331400230060ustar00rootroot00000000000000# Copyright 2018 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Don't build debuginfo packages. %global debug_package %{nil} Name: google-osconfig-agent Epoch: 1 Version: %{_version} Release: g1%{?dist} Summary: Google Compute Engine guest environment. License: ASL 2.0 Url: https://github.com/GoogleCloudPlatform/osconfig Source0: %{name}_%{version}.orig.tar.gz BuildArch: %{_arch} %if ! 0%{?el6} BuildRequires: systemd %endif %description Contains the OSConfig agent binary and startup scripts %prep %autosetup %build GOPATH=%{_gopath} CGO_ENABLED=0 %{_go} build -ldflags="-s -w -X main.version=%{version}-%{release}" -mod=readonly -o google_osconfig_agent %install install -d "%{buildroot}/%{_docdir}/%{name}" cp -r THIRD_PARTY_LICENSES "%buildroot/%_docdir/%name/THIRD_PARTY_LICENSES" install -d %{buildroot}%{_bindir} install -d %{buildroot}/var/lib/google_osconfig_agent install -p -m 0755 google_osconfig_agent %{buildroot}%{_bindir}/google_osconfig_agent %if 0%{?el6} install -d %{buildroot}/etc/init install -p -m 0644 %{name}.conf %{buildroot}/etc/init %else install -d %{buildroot}%{_unitdir} install -d %{buildroot}%{_presetdir} install -p -m 0644 %{name}.service %{buildroot}%{_unitdir} install -p -m 0644 90-%{name}.preset %{buildroot}%{_presetdir}/90-%{name}.preset %endif %files %{_docdir}/%{name} %defattr(-,root,root,-) %{_bindir}/google_osconfig_agent %if 0%{?el6} /etc/init/%{name}.conf %else %{_unitdir}/%{name}.service %{_presetdir}/90-%{name}.preset %endif %post %if 0%{?el6} if [ $1 -eq 1 ]; then # Start the service on first install start -q -n google-osconfig-agent fi %else %systemd_post google-osconfig-agent.service if [ $1 -eq 1 ]; then # Start the service on first install systemctl start google-osconfig-agent.service fi if [ $1 -eq 2 ]; then # If the old directory exists make sure we set the file there. [ -e /etc/osconfig ] && touch /etc/osconfig/osconfig_agent_restart_required touch /var/lib/google_osconfig_agent/osconfig_agent_restart_required fi %preun %systemd_preun google-osconfig-agent.service %postun %systemd_postun google-osconfig-agent.service %endif osconfig-20250416.02/policies/000077500000000000000000000000001477773331400156355ustar00rootroot00000000000000osconfig-20250416.02/policies/apt.go000066400000000000000000000201241477773331400167470ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package policies import ( "bytes" "context" "errors" "fmt" "io" "net/http" "sort" "strconv" "strings" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/osinfo" "github.com/GoogleCloudPlatform/osconfig/packages" "golang.org/x/crypto/openpgp" "golang.org/x/crypto/openpgp/armor" "cloud.google.com/go/osconfig/agentendpoint/apiv1beta/agentendpointpb" ) var debArchiveTypeMap = map[agentendpointpb.AptRepository_ArchiveType]string{ agentendpointpb.AptRepository_DEB: "deb", agentendpointpb.AptRepository_DEB_SRC: "deb-src", } const aptGPGFile = "/etc/apt/trusted.gpg.d/osconfig_agent_managed.gpg" func isArmoredGPGKey(keyData []byte) bool { var buf bytes.Buffer tee := io.TeeReader(bytes.NewReader(keyData), &buf) // Try decoding as armored decodedBlock, err := armor.Decode(tee) if err == nil && decodedBlock != nil { return true } return false } func getAptGPGKey(key string) (openpgp.EntityList, error) { resp, err := http.Get(key) if err != nil { return nil, err } defer resp.Body.Close() if resp.ContentLength > 1024*1024 { return nil, fmt.Errorf("key size of %d too large", resp.ContentLength) } responseBody, err := io.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("can not read response body for key %s, err: %v", key, err) } if isArmoredGPGKey(responseBody) { return openpgp.ReadArmoredKeyRing(bytes.NewBuffer(responseBody)) } return openpgp.ReadKeyRing(bytes.NewReader(responseBody)) } func containsEntity(es []*openpgp.Entity, e *openpgp.Entity) bool { for _, entity := range es { if entity.PrimaryKey.Fingerprint == e.PrimaryKey.Fingerprint { return true } } return false } func readInstanceOsInfo() (string, float64, error) { oi, err := osinfo.Get() if err != nil { return "", 0, fmt.Errorf("error getting osinfo: %v", err) } osVersion, err := strconv.ParseFloat(oi.Version, 64) if err != nil { osVersion = 0 } return oi.ShortName, osVersion, nil } func shouldUseSignedBy() bool { osShortName, osVersion, err := readInstanceOsInfo() if err != nil { return false // Default to not using signed-by approach } if (osShortName == "debian" && osVersion >= 12) || (osShortName == "ubuntu" && osVersion >= 24) { return true } return false } func getAptRepoLine(repo *agentendpointpb.AptRepository, useSignedBy bool) string { archiveType, ok := debArchiveTypeMap[repo.ArchiveType] if !ok { archiveType = "deb" } line := fmt.Sprintf("\n%s", archiveType) if useSignedBy { line = fmt.Sprintf("%s [signed-by=%s]", line, aptGPGFile) } line = fmt.Sprintf("%s %s %s", line, repo.Uri, repo.Distribution) for _, c := range repo.Components { line = fmt.Sprintf("%s %s", line, c) } return line } func aptRepositories(ctx context.Context, repos []*agentendpointpb.AptRepository, repoFile string) error { var es []*openpgp.Entity var keys []string for _, repo := range repos { key := repo.GetGpgKey() if key == "" { continue } keys = append(keys, key) } sort.Strings(keys) for _, key := range keys { entityList, err := getAptGPGKey(key) if err != nil { clog.Errorf(ctx, "Error fetching gpg key %q: %v", key, err) continue } for _, e := range entityList { if !containsEntity(es, e) { es = append(es, e) } } } if len(es) > 0 { var buf bytes.Buffer for _, e := range es { if err := e.Serialize(&buf); err != nil { clog.Errorf(ctx, "Error serializing gpg key: %v", err) } } if err := writeIfChanged(ctx, buf.Bytes(), aptGPGFile); err != nil { clog.Errorf(ctx, "Error writing gpg key: %v", err) } } /* # Repo file managed by Google OSConfig agent deb http://repo1-url/ repo1 main deb http://repo1-url/ repo2 main contrib non-free # For now, 'signed-by' keyring approach will be used for Debian 12+ and Ubuntu 24+ only. To avoid conflicting repos for old stable OSes versions e.g. deb [signed-by=/etc/apt/trusted.gpg.d/osconfig_agent_managed.gpg] http://repo1-url/ repo1 main NOTE: suggested by ofca@ */ var buf bytes.Buffer buf.WriteString("# Repo file managed by Google OSConfig agent\n") shouldUseSignedByBool := shouldUseSignedBy() for _, repo := range repos { line := getAptRepoLine(repo, shouldUseSignedByBool) buf.WriteString(line + "\n") } return writeIfChanged(ctx, buf.Bytes(), repoFile) } func aptChanges(ctx context.Context, aptInstalled, aptRemoved, aptUpdated []*agentendpointpb.Package) error { var err error var errs []string var installed []*packages.PkgInfo if len(aptInstalled) > 0 || len(aptUpdated) > 0 || len(aptRemoved) > 0 { installed, err = packages.InstalledDebPackages(ctx) if err != nil { return err } } var updates []*packages.PkgInfo if len(aptUpdated) > 0 { updates, err = packages.AptUpdates(ctx, packages.AptGetUpgradeType(packages.AptGetDistUpgrade), packages.AptGetUpgradeShowNew(false)) if err != nil { return err } } changes := getNecessaryChanges(installed, updates, aptInstalled, aptRemoved, aptUpdated) if changes.packagesToInstall != nil { // run apt-get update to update to latest changes. if _, err := packages.AptUpdate(ctx); err != nil { clog.Errorf(ctx, "Error running apt-get update") } clog.Infof(ctx, "Installing packages %s", changes.packagesToInstall) if err := packages.InstallAptPackages(ctx, changes.packagesToInstall); err != nil { clog.Errorf(ctx, "Error installing apt packages: %v", err) // Try fallback logic to install the packages individually. clog.Infof(ctx, "Trying to install packages individually") var installPkgErrs []string for _, pkg := range changes.packagesToInstall { if err = packages.InstallAptPackages(ctx, []string{pkg}); err != nil { installPkgErrs = append(installPkgErrs, fmt.Sprintf("Error installing apt package: %v. Error details: %v", pkg, err)) } } if len(installPkgErrs) > 0 { errorString := strings.Join(installPkgErrs, "\n") clog.Errorf(ctx, "Error installing apt packages individually: %v", errorString) errs = append(errs, fmt.Sprintf("error installing apt packages: %v", errorString)) } } } else { clog.Debugf(ctx, "No packages to install.") } if changes.packagesToUpgrade != nil { clog.Infof(ctx, "Upgrading packages %s", changes.packagesToUpgrade) if err := packages.InstallAptPackages(ctx, changes.packagesToUpgrade); err != nil { clog.Errorf(ctx, "Error upgrading apt packages: %v", err) errs = append(errs, fmt.Sprintf("error upgrading apt packages: %v", err)) } } else { clog.Debugf(ctx, "No packages to upgrade.") } if changes.packagesToRemove != nil { clog.Infof(ctx, "Removing packages %s", changes.packagesToRemove) if err := packages.RemoveAptPackages(ctx, changes.packagesToRemove); err != nil { clog.Errorf(ctx, "Error removing apt packages: %v", err) // Try fallback logic to remove the packages individually. clog.Infof(ctx, "Trying to remove packages individually") var removePkgErrs []string for _, pkg := range changes.packagesToRemove { if err = packages.RemoveAptPackages(ctx, []string{pkg}); err != nil { removePkgErrs = append(removePkgErrs, fmt.Sprintf("Error removing apt package: %v. Error details: %v", pkg, err)) } } if len(removePkgErrs) > 0 { errorString := strings.Join(removePkgErrs, "\n") clog.Errorf(ctx, "Error removing apt packages individually: %v", errorString) errs = append(errs, fmt.Sprintf("error removing apt packages: %v", errorString)) } } } else { clog.Debugf(ctx, "No packages to remove.") } if errs == nil { return nil } return errors.New(strings.Join(errs, ",\n")) } osconfig-20250416.02/policies/apt_test.go000066400000000000000000000101131477773331400200030ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package policies import ( "context" "fmt" "io/ioutil" "os" "path/filepath" "strings" "testing" "cloud.google.com/go/osconfig/agentendpoint/apiv1beta/agentendpointpb" ) func runAptRepositories(ctx context.Context, repos []*agentendpointpb.AptRepository) (string, error) { td, err := ioutil.TempDir(os.TempDir(), "") if err != nil { return "", fmt.Errorf("error creating temp dir: %v", err) } defer os.RemoveAll(td) testRepo := filepath.Join(td, "testRepo") if err := aptRepositories(ctx, repos, testRepo); err != nil { return "", fmt.Errorf("error running aptRepositories: %v", err) } data, err := ioutil.ReadFile(testRepo) if err != nil { return "", fmt.Errorf("error reading testRepo: %v", err) } return string(data), nil } func TestAptRepositories(t *testing.T) { tests := []struct { desc string repos []*agentendpointpb.AptRepository want string }{ {"no repos", []*agentendpointpb.AptRepository{}, "# Repo file managed by Google OSConfig agent\n"}, { "1 repo", []*agentendpointpb.AptRepository{ {Uri: "http://repo1-url/", Distribution: "distribution", Components: []string{"component1"}}, }, "# Repo file managed by Google OSConfig agent\n\ndeb http://repo1-url/ distribution component1\n", }, { "2 repos", []*agentendpointpb.AptRepository{ {Uri: "http://repo1-url/", Distribution: "distribution", Components: []string{"component1"}, ArchiveType: agentendpointpb.AptRepository_DEB_SRC}, {Uri: "http://repo2-url/", Distribution: "distribution", Components: []string{"component1", "component2"}, ArchiveType: agentendpointpb.AptRepository_DEB}, }, "# Repo file managed by Google OSConfig agent\n\ndeb-src http://repo1-url/ distribution component1\n\ndeb http://repo2-url/ distribution component1 component2\n", }, } for _, tt := range tests { got, err := runAptRepositories(context.Background(), tt.repos) if err != nil { t.Fatal(err) } if got != tt.want { t.Errorf("%s: got:\n%q\nwant:\n%q", tt.desc, got, tt.want) } } } func TestGetAptGPGKey(t *testing.T) { key := "https://packages.cloud.google.com/apt/doc/apt-key.gpg" entityList, err := getAptGPGKey(key) if err != nil { t.Fatal(err) } // check if Artifact Regitry key exist or not artifactRegistryKeyFound := false for _, e := range entityList { for key := range e.Identities { if strings.Contains(key, "Artifact Registry") { artifactRegistryKeyFound = true } } } if !artifactRegistryKeyFound { t.Errorf("Expected to find Artifact Registry key in Google Cloud Public GPG key, but its missed.") } } func TestUseSignedBy(t *testing.T) { tests := []struct { desc string repo *agentendpointpb.AptRepository want string }{ { "1 repo", &agentendpointpb.AptRepository{Uri: "http://repo1-url/", Distribution: "distribution", Components: []string{"component1"}}, "\ndeb [signed-by=/etc/apt/trusted.gpg.d/osconfig_agent_managed.gpg] http://repo1-url/ distribution component1", }, { "2 components", &agentendpointpb.AptRepository{Uri: "http://repo2-url/", Distribution: "distribution", Components: []string{"component1", "component2"}, ArchiveType: agentendpointpb.AptRepository_DEB}, "\ndeb [signed-by=/etc/apt/trusted.gpg.d/osconfig_agent_managed.gpg] http://repo2-url/ distribution component1 component2", }, } useSignedBy := true for _, tt := range tests { aptRepoLine := getAptRepoLine(tt.repo, useSignedBy) if aptRepoLine != tt.want { t.Errorf("%s: got:\n%q\nwant:\n%q", tt.desc, aptRepoLine, tt.want) } } } osconfig-20250416.02/policies/changes.go000066400000000000000000000044301477773331400175750ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package policies import ( "github.com/GoogleCloudPlatform/osconfig/packages" "cloud.google.com/go/osconfig/agentendpoint/apiv1beta/agentendpointpb" ) // changes represents the delta between the actual and the desired package installation state. type changes struct { packagesToInstall []string packagesToUpgrade []string packagesToRemove []string } // getNecessaryChanges compares the current state and the desired state to determine which packages // need to be installed, upgraded, or removed. func getNecessaryChanges(installedPkgs []*packages.PkgInfo, upgradablePkgs []*packages.PkgInfo, installPkgs, removePkgs, updatePkgs []*agentendpointpb.Package) changes { installedPkgMap := make(map[string]bool) for _, pkg := range installedPkgs { installedPkgMap[pkg.Name] = true } upgradeablePkgMap := make(map[string]bool) for _, pkg := range upgradablePkgs { upgradeablePkgMap[pkg.Name] = true } var pkgsToInstall []string var pkgsToRemove []string var pkgsToUpgrade []string for _, pkg := range installPkgs { if _, ok := installedPkgMap[pkg.Name]; !ok { pkgsToInstall = append(pkgsToInstall, pkg.Name) } } for _, pkg := range removePkgs { if _, ok := installedPkgMap[pkg.Name]; ok { pkgsToRemove = append(pkgsToRemove, pkg.Name) } } for _, pkg := range updatePkgs { if _, ok := upgradeablePkgMap[pkg.Name]; ok { pkgsToUpgrade = append(pkgsToUpgrade, pkg.Name) continue } // If not installed we need to install it. if _, ok := installedPkgMap[pkg.Name]; !ok { pkgsToInstall = append(pkgsToInstall, pkg.Name) } } return changes{ packagesToInstall: pkgsToInstall, packagesToUpgrade: pkgsToUpgrade, packagesToRemove: pkgsToRemove, } } osconfig-20250416.02/policies/changes_test.go000066400000000000000000000100121477773331400206250ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package policies import ( "reflect" "testing" "github.com/GoogleCloudPlatform/osconfig/packages" "cloud.google.com/go/osconfig/agentendpoint/apiv1beta/agentendpointpb" ) func TestGetNecessaryChanges(t *testing.T) { tests := [...]struct { name string installedPkgs []*packages.PkgInfo upgradablePkgs []*packages.PkgInfo installPkgs []*agentendpointpb.Package removePkgs []*agentendpointpb.Package updatePkgs []*agentendpointpb.Package want changes }{ { name: "install from empty", installedPkgs: createPkgInfos(), upgradablePkgs: createPkgInfos(), installPkgs: createPackages("foo"), removePkgs: createPackages(), updatePkgs: createPackages(), want: changes{ packagesToInstall: []string{"foo"}, packagesToUpgrade: []string{}, packagesToRemove: []string{}, }, }, { name: "upgrade from empty", installedPkgs: createPkgInfos(), upgradablePkgs: createPkgInfos(), installPkgs: createPackages(), removePkgs: createPackages(), updatePkgs: createPackages("foo"), want: changes{ packagesToInstall: []string{"foo"}, packagesToUpgrade: []string{}, packagesToRemove: []string{}, }, }, { name: "single upgrade", installedPkgs: createPkgInfos("foo"), upgradablePkgs: createPkgInfos("foo"), installPkgs: createPackages(), removePkgs: createPackages(), updatePkgs: createPackages("foo"), want: changes{ packagesToInstall: []string{}, packagesToUpgrade: []string{"foo"}, packagesToRemove: []string{}, }, }, { name: "remove", installedPkgs: createPkgInfos("foo"), upgradablePkgs: createPkgInfos("foo"), installPkgs: createPackages(), removePkgs: createPackages("foo"), updatePkgs: createPackages(), want: changes{ packagesToInstall: []string{}, packagesToUpgrade: []string{}, packagesToRemove: []string{"foo"}, }, }, { name: "mixed", installedPkgs: createPkgInfos("foo", "bar", "buz"), upgradablePkgs: createPkgInfos("bar", "boo"), installPkgs: createPackages("foo", "baz"), removePkgs: createPackages("buz"), updatePkgs: createPackages("bar"), want: changes{ packagesToInstall: []string{"baz"}, packagesToUpgrade: []string{"bar"}, packagesToRemove: []string{"buz"}, }, }, } for _, tt := range tests { got := getNecessaryChanges(tt.installedPkgs, tt.upgradablePkgs, tt.installPkgs, tt.removePkgs, tt.updatePkgs) if !equalChanges(&got, &tt.want) { t.Errorf("Did not get expected changes for '%s', got: %v, want: %v", tt.name, got, tt.want) } } } func equalChanges(got *changes, want *changes) bool { return equalSlices(got.packagesToInstall, want.packagesToInstall) && equalSlices(got.packagesToRemove, want.packagesToRemove) && equalSlices(got.packagesToUpgrade, want.packagesToUpgrade) } func equalSlices(got []string, want []string) bool { if len(got) == 0 && len(want) == 0 { return true } return reflect.DeepEqual(got, want) } func createPkgInfos(names ...string) []*packages.PkgInfo { var res []*packages.PkgInfo for _, n := range names { res = append(res, &packages.PkgInfo{Name: n}) } return res } func createPackages(names ...string) []*agentendpointpb.Package { var res []*agentendpointpb.Package for _, n := range names { res = append(res, &agentendpointpb.Package{Name: n}) } return res } osconfig-20250416.02/policies/googet.go000066400000000000000000000056101477773331400174520ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package policies import ( "bytes" "context" "errors" "fmt" "strings" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/packages" "cloud.google.com/go/osconfig/agentendpoint/apiv1beta/agentendpointpb" ) func googetRepositories(ctx context.Context, repos []*agentendpointpb.GooRepository, repoFile string) error { /* # Repo file managed by Google OSConfig agent - name: repo1-name url: https://repo1-url - name: repo1-name url: https://repo2-url */ var buf bytes.Buffer buf.WriteString("# Repo file managed by Google OSConfig agent\n") for _, repo := range repos { buf.WriteString(fmt.Sprintf("\n- name: %s\n", repo.Name)) buf.WriteString(fmt.Sprintf(" url: %s\n", repo.Url)) } return writeIfChanged(ctx, buf.Bytes(), repoFile) } func googetChanges(ctx context.Context, gooInstalled, gooRemoved, gooUpdated []*agentendpointpb.Package) error { var err error var errs []string var installed []*packages.PkgInfo if len(gooInstalled) > 0 || len(gooUpdated) > 0 || len(gooRemoved) > 0 { installed, err = packages.InstalledGooGetPackages(ctx) if err != nil { return err } } var updates []*packages.PkgInfo if len(gooUpdated) > 0 { updates, err = packages.GooGetUpdates(ctx) if err != nil { return err } } changes := getNecessaryChanges(installed, updates, gooInstalled, gooRemoved, gooUpdated) if changes.packagesToInstall != nil { clog.Infof(ctx, "Installing packages %s", changes.packagesToInstall) if err := packages.InstallGooGetPackages(ctx, changes.packagesToInstall); err != nil { errs = append(errs, fmt.Sprintf("error installing googet packages: %v", err)) } } if changes.packagesToUpgrade != nil { clog.Infof(ctx, "Upgrading packages %s", changes.packagesToUpgrade) if err := packages.InstallGooGetPackages(ctx, changes.packagesToUpgrade); err != nil { errs = append(errs, fmt.Sprintf("error upgrading googet packages: %v", err)) } } if changes.packagesToRemove != nil { clog.Infof(ctx, "Removing packages %s", changes.packagesToRemove) if err := packages.RemoveGooGetPackages(ctx, changes.packagesToRemove); err != nil { errs = append(errs, fmt.Sprintf("error removing googet packages: %v", err)) } } if errs == nil { return nil } return errors.New(strings.Join(errs, ",\n")) } osconfig-20250416.02/policies/googet_test.go000066400000000000000000000044621477773331400205150ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package policies import ( "context" "fmt" "io/ioutil" "os" "path/filepath" "testing" "cloud.google.com/go/osconfig/agentendpoint/apiv1beta/agentendpointpb" ) func runGooGetRepositories(ctx context.Context, repos []*agentendpointpb.GooRepository) (string, error) { td, err := ioutil.TempDir(os.TempDir(), "") if err != nil { return "", fmt.Errorf("error creating temp dir: %v", err) } defer os.RemoveAll(td) testRepo := filepath.Join(td, "testRepo") if err := googetRepositories(ctx, repos, testRepo); err != nil { return "", fmt.Errorf("error running googetRepositories: %v", err) } data, err := ioutil.ReadFile(testRepo) if err != nil { return "", fmt.Errorf("error reading testRepo: %v", err) } return string(data), nil } func TestGooGetRepositories(t *testing.T) { tests := []struct { desc string repos []*agentendpointpb.GooRepository want string }{ {"no repos", []*agentendpointpb.GooRepository{}, "# Repo file managed by Google OSConfig agent\n"}, { "1 repo", []*agentendpointpb.GooRepository{ {Url: "http://repo1-url/", Name: "name"}, }, "# Repo file managed by Google OSConfig agent\n\n- name: name\n url: http://repo1-url/\n", }, { "2 repos", []*agentendpointpb.GooRepository{ {Url: "http://repo1-url/", Name: "name1"}, {Url: "http://repo2-url/", Name: "name2"}, }, "# Repo file managed by Google OSConfig agent\n\n- name: name1\n url: http://repo1-url/\n\n- name: name2\n url: http://repo2-url/\n", }, } for _, tt := range tests { got, err := runGooGetRepositories(context.Background(), tt.repos) if err != nil { t.Fatal(err) } if got != tt.want { t.Errorf("%s: got:\n%q\nwant:\n%q", tt.desc, got, tt.want) } } } osconfig-20250416.02/policies/local.go000066400000000000000000000106371477773331400172650ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // package policies import ( "context" "encoding/json" "cloud.google.com/go/compute/metadata" "github.com/GoogleCloudPlatform/osconfig/clog" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/proto" "cloud.google.com/go/osconfig/agentendpoint/apiv1beta/agentendpointpb" ) // localConfig represents the structure of the config to the JSON parser. // // The types of members of the struct are wrappers for protobufs and delegate // the parsing to protojson lib via their UnmarshalJSON implementations. type localConfig struct { Packages []*pkg PackageRepositories []*packageRepository SoftwareRecipes []*softwareRecipe } type pkg struct { agentendpointpb.Package } func (r *pkg) UnmarshalJSON(b []byte) error { un := &protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true} return un.Unmarshal(b, &r.Package) } type packageRepository struct { agentendpointpb.PackageRepository } func (r *packageRepository) UnmarshalJSON(b []byte) error { un := &protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true} return un.Unmarshal(b, &r.PackageRepository) } type softwareRecipe struct { agentendpointpb.SoftwareRecipe } func (r *softwareRecipe) UnmarshalJSON(b []byte) error { un := &protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true} return un.Unmarshal(b, &r.SoftwareRecipe) } func readLocalConfig(ctx context.Context) (*localConfig, error) { s, err := metadata.Get("/instance/attributes/gce-software-declaration") if err != nil { clog.Debugf(ctx, "No local config: %v", err) return nil, nil } var lc localConfig return &lc, json.Unmarshal([]byte(s), &lc) } // GetId returns a repository Id that is used to group repositories for // override by higher priotiry policy(-ies). // For repositories that have no such Id, GetId returns "", in which // case the repository is never overridden. func getID(repo *agentendpointpb.PackageRepository) string { switch repo.Repository.(type) { case *agentendpointpb.PackageRepository_Yum: return "yum-" + repo.GetYum().GetId() case *agentendpointpb.PackageRepository_Zypper: return "zypper-" + repo.GetZypper().GetId() default: return "" } } // mergeConfigs merges the local config with the lookup response, giving priority to the lookup // result. If both arguments are nil, returns an empty policy. func mergeConfigs(local *localConfig, egp *agentendpointpb.EffectiveGuestPolicy) *agentendpointpb.EffectiveGuestPolicy { if egp == nil { egp = &agentendpointpb.EffectiveGuestPolicy{} } if local == nil { return egp } // Ids that are in the maps below repos := make(map[string]bool) pkgs := make(map[string]bool) recipes := make(map[string]bool) for _, v := range egp.GetPackages() { pkgs[v.Package.Name] = true } for _, v := range egp.GetPackageRepositories() { if id := getID(v.GetPackageRepository()); id != "" { repos[id] = true } } for _, v := range egp.GetSoftwareRecipes() { recipes[v.SoftwareRecipe.Name] = true } for _, v := range local.Packages { if _, ok := pkgs[v.Name]; !ok { sp := new(agentendpointpb.EffectiveGuestPolicy_SourcedPackage) sp.Package = &v.Package egp.Packages = append(egp.Packages, sp) } } for _, v := range local.PackageRepositories { id := getID(&v.PackageRepository) if id != "" { if _, ok := repos[id]; ok { continue } } sr := new(agentendpointpb.EffectiveGuestPolicy_SourcedPackageRepository) sr.PackageRepository = &v.PackageRepository egp.PackageRepositories = append(egp.PackageRepositories, sr) } for _, v := range local.SoftwareRecipes { if _, ok := recipes[v.Name]; !ok { sp := new(agentendpointpb.EffectiveGuestPolicy_SourcedSoftwareRecipe) sp.SoftwareRecipe = proto.Clone(&v.SoftwareRecipe).(*agentendpointpb.SoftwareRecipe) egp.SoftwareRecipes = append(egp.SoftwareRecipes, sp) } } return egp } osconfig-20250416.02/policies/local_test.go000066400000000000000000000062641477773331400203250ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package policies import ( "encoding/json" "testing" "cloud.google.com/go/osconfig/agentendpoint/apiv1beta/agentendpointpb" "google.golang.org/protobuf/encoding/prototext" ) const sampleConfig = ` { "packages": [ { "name": "my-package", "desiredState": "INSTALLED", "manager": "APT" }, { "name": "my-other-package", "desired_state": "INSTALLED", "manager": "APT" } ], "packageRepositories": [ { "apt": { "uri": "http://packages.cloud.google.com/apt", "archiveType": "DEB", "distribution": "google-cloud-monitoring-stretch", "components": [ "main" ], "gpgKey": "https://packages.cloud.google.com/apt/doc/apt-key.gpg" } }, { "yum": { "id": "my-yum", "display_name": "my-yum-name", "base_url": "http://my-base-url", "gpg_keys": [ "https://packages.cloud.google.com/apt/doc/apt-key.gpg" ] } } ], "softwareRecipes": [ { "name": "install-envoy", "desired_state": "INSTALLED", "installSteps": [ { "scriptRun": { "script": "" } } ] }, { "name": "install-something", "desired_state": "INSTALLED", "installSteps": [ { "scriptRun": { "script": "" } } ] } ] }` func TestMerging(t *testing.T) { s := []byte(sampleConfig) var lc localConfig if err := json.Unmarshal([]byte(s), &lc); err != nil { t.Errorf("Got error: %v", err) return } var pr agentendpointpb.EffectiveGuestPolicy var sr agentendpointpb.EffectiveGuestPolicy_SourcedSoftwareRecipe sr.Source = "policy1" sr.SoftwareRecipe = new(agentendpointpb.SoftwareRecipe) sr.SoftwareRecipe.Name = "install-something" sr.SoftwareRecipe.DesiredState = agentendpointpb.DesiredState_REMOVED pr.SoftwareRecipes = append(pr.SoftwareRecipes, &sr) pr2 := mergeConfigs(&lc, &pr) var wantmap = map[string]agentendpointpb.DesiredState{ "install-something": agentendpointpb.DesiredState_REMOVED, "install-envoy": agentendpointpb.DesiredState_INSTALLED, } for _, ssr := range pr2.SoftwareRecipes { gotState := ssr.SoftwareRecipe.DesiredState wantState, ok := wantmap[ssr.SoftwareRecipe.Name] if !ok { t.Errorf("Recipe ame: %s unexpected.", ssr.SoftwareRecipe.Name) continue } if gotState != wantState { t.Errorf("Recipe: %s got state: %d want state: %d", ssr.SoftwareRecipe.Name, gotState, wantState) } } rs := pr2.SoftwareRecipes[0].SoftwareRecipe.DesiredState want := agentendpointpb.DesiredState_REMOVED if rs != want { txt, _ := prototext.Marshal(pr2) t.Logf("Merged: %s", txt) t.Errorf("Wrong recipe state. Got: %d(%s), want: %d(%s).", rs, rs.String(), want, want.String()) } } osconfig-20250416.02/policies/policies.go000066400000000000000000000214421477773331400177760ustar00rootroot00000000000000// Copyright 2018 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package policies configures OS Guest Policies based on osconfig API response. package policies import ( "bytes" "context" "crypto/sha256" "hash" "io" "os" "time" "github.com/GoogleCloudPlatform/osconfig/agentconfig" "github.com/GoogleCloudPlatform/osconfig/agentendpoint" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/packages" "github.com/GoogleCloudPlatform/osconfig/policies/recipes" "github.com/GoogleCloudPlatform/osconfig/retryutil" "github.com/GoogleCloudPlatform/osconfig/tasker" "github.com/GoogleCloudPlatform/osconfig/util" "cloud.google.com/go/osconfig/agentendpoint/apiv1beta/agentendpointpb" ) func run(ctx context.Context) { var resp *agentendpointpb.EffectiveGuestPolicy client, err := agentendpoint.NewBetaClient(ctx) if err != nil { clog.Errorf(ctx, "agentendpoint.NewBetaClient Error: %v", err) } else { defer client.Close() resp, err = client.LookupEffectiveGuestPolicies(ctx) if err != nil { clog.Errorf(ctx, "Error running LookupEffectiveGuestPolicies: %v", err) } } local, err := readLocalConfig(ctx) if err != nil { clog.Errorf(ctx, "Error reading local software config: %v", err) } effective := mergeConfigs(local, resp) // We don't check the error from setConfig or installRecipes as all errors are already logged. setConfig(ctx, effective) installRecipes(ctx, effective) } // Run looks up osconfigs and applies them using tasker.Enqueue. func Run(ctx context.Context) { tasker.Enqueue(ctx, "Run GuestPolicies", func() { run(ctx) }) } func installRecipes(ctx context.Context, egp *agentendpointpb.EffectiveGuestPolicy) error { for _, recipe := range egp.GetSoftwareRecipes() { if r := recipe.GetSoftwareRecipe(); r != nil { if err := recipes.InstallRecipe(ctx, r); err != nil { clog.Errorf(ctx, "Error installing recipe: %v", err) } } } return nil } func setConfig(ctx context.Context, egp *agentendpointpb.EffectiveGuestPolicy) { var aptRepos []*agentendpointpb.AptRepository var yumRepos []*agentendpointpb.YumRepository var zypperRepos []*agentendpointpb.ZypperRepository var gooRepos []*agentendpointpb.GooRepository for _, repo := range egp.GetPackageRepositories() { if r := repo.GetPackageRepository().GetGoo(); r != nil { gooRepos = append(gooRepos, r) continue } if r := repo.GetPackageRepository().GetApt(); r != nil { aptRepos = append(aptRepos, r) continue } if r := repo.GetPackageRepository().GetYum(); r != nil { yumRepos = append(yumRepos, r) continue } if r := repo.GetPackageRepository().GetZypper(); r != nil { zypperRepos = append(zypperRepos, r) continue } } var gooInstallPkgs, gooRemovePkgs, gooUpdatePkgs []*agentendpointpb.Package var aptInstallPkgs, aptRemovePkgs, aptUpdatePkgs []*agentendpointpb.Package var yumInstallPkgs, yumRemovePkgs, yumUpdatePkgs []*agentendpointpb.Package var zypperInstallPkgs, zypperRemovePkgs, zypperUpdatePkgs []*agentendpointpb.Package for _, pkg := range egp.GetPackages() { switch pkg.GetPackage().GetManager() { case agentendpointpb.Package_ANY, agentendpointpb.Package_MANAGER_UNSPECIFIED: switch pkg.GetPackage().GetDesiredState() { case agentendpointpb.DesiredState_INSTALLED, agentendpointpb.DesiredState_DESIRED_STATE_UNSPECIFIED: gooInstallPkgs = append(gooInstallPkgs, pkg.GetPackage()) aptInstallPkgs = append(aptInstallPkgs, pkg.GetPackage()) yumInstallPkgs = append(yumInstallPkgs, pkg.GetPackage()) zypperInstallPkgs = append(zypperInstallPkgs, pkg.GetPackage()) case agentendpointpb.DesiredState_REMOVED: gooRemovePkgs = append(gooRemovePkgs, pkg.GetPackage()) aptRemovePkgs = append(aptRemovePkgs, pkg.GetPackage()) yumRemovePkgs = append(yumRemovePkgs, pkg.GetPackage()) zypperRemovePkgs = append(zypperRemovePkgs, pkg.GetPackage()) case agentendpointpb.DesiredState_UPDATED: gooUpdatePkgs = append(gooUpdatePkgs, pkg.GetPackage()) aptUpdatePkgs = append(aptUpdatePkgs, pkg.GetPackage()) yumUpdatePkgs = append(yumUpdatePkgs, pkg.GetPackage()) zypperUpdatePkgs = append(zypperUpdatePkgs, pkg.GetPackage()) } case agentendpointpb.Package_GOO: switch pkg.GetPackage().GetDesiredState() { case agentendpointpb.DesiredState_INSTALLED, agentendpointpb.DesiredState_DESIRED_STATE_UNSPECIFIED: gooInstallPkgs = append(gooInstallPkgs, pkg.GetPackage()) case agentendpointpb.DesiredState_REMOVED: gooRemovePkgs = append(gooRemovePkgs, pkg.GetPackage()) case agentendpointpb.DesiredState_UPDATED: gooUpdatePkgs = append(gooUpdatePkgs, pkg.GetPackage()) } case agentendpointpb.Package_APT: switch pkg.GetPackage().GetDesiredState() { case agentendpointpb.DesiredState_INSTALLED, agentendpointpb.DesiredState_DESIRED_STATE_UNSPECIFIED: aptInstallPkgs = append(aptInstallPkgs, pkg.GetPackage()) case agentendpointpb.DesiredState_REMOVED: aptRemovePkgs = append(aptRemovePkgs, pkg.GetPackage()) case agentendpointpb.DesiredState_UPDATED: aptUpdatePkgs = append(aptUpdatePkgs, pkg.GetPackage()) } case agentendpointpb.Package_YUM: switch pkg.GetPackage().GetDesiredState() { case agentendpointpb.DesiredState_INSTALLED, agentendpointpb.DesiredState_DESIRED_STATE_UNSPECIFIED: yumInstallPkgs = append(yumInstallPkgs, pkg.GetPackage()) case agentendpointpb.DesiredState_REMOVED: yumRemovePkgs = append(yumRemovePkgs, pkg.GetPackage()) case agentendpointpb.DesiredState_UPDATED: yumUpdatePkgs = append(yumUpdatePkgs, pkg.GetPackage()) } case agentendpointpb.Package_ZYPPER: switch pkg.GetPackage().GetDesiredState() { case agentendpointpb.DesiredState_INSTALLED, agentendpointpb.DesiredState_DESIRED_STATE_UNSPECIFIED: zypperInstallPkgs = append(zypperInstallPkgs, pkg.GetPackage()) case agentendpointpb.DesiredState_REMOVED: zypperRemovePkgs = append(zypperRemovePkgs, pkg.GetPackage()) case agentendpointpb.DesiredState_UPDATED: zypperUpdatePkgs = append(zypperUpdatePkgs, pkg.GetPackage()) } } } if packages.GooGetExists { if err := googetRepositories(ctx, gooRepos, agentconfig.GooGetRepoFilePath()); err != nil { clog.Errorf(ctx, "Error writing googet repo file: %v", err) } if err := retryutil.RetryFunc(ctx, 1*time.Minute, "Applying googet changes", func() error { return googetChanges(ctx, gooInstallPkgs, gooRemovePkgs, gooUpdatePkgs) }); err != nil { clog.Errorf(ctx, "Error performing googet changes: %v", err) } } if packages.AptExists { if err := aptRepositories(ctx, aptRepos, agentconfig.AptRepoFilePath()); err != nil { clog.Errorf(ctx, "Error writing apt repo file: %v", err) } if err := retryutil.RetryFunc(ctx, 1*time.Minute, "Applying apt changes", func() error { return aptChanges(ctx, aptInstallPkgs, aptRemovePkgs, aptUpdatePkgs) }); err != nil { clog.Errorf(ctx, "Error performing apt changes: %v", err) } } if packages.YumExists { if err := yumRepositories(ctx, yumRepos, agentconfig.YumRepoFilePath()); err != nil { clog.Errorf(ctx, "Error writing yum repo file: %v", err) } if err := retryutil.RetryFunc(ctx, 1*time.Minute, "Applying yum changes", func() error { return yumChanges(ctx, yumInstallPkgs, yumRemovePkgs, yumUpdatePkgs) }); err != nil { clog.Errorf(ctx, "Error performing yum changes: %v", err) } } if packages.ZypperExists { if err := zypperRepositories(ctx, zypperRepos, agentconfig.ZypperRepoFilePath()); err != nil { clog.Errorf(ctx, "Error writing zypper repo file: %v", err) } if err := retryutil.RetryFunc(ctx, 1*time.Minute, "Applying zypper changes.", func() error { return zypperChanges(ctx, zypperInstallPkgs, zypperRemovePkgs, zypperUpdatePkgs) }); err != nil { clog.Errorf(ctx, "Error performing zypper changes: %v", err) } } } func checksum(r io.Reader) hash.Hash { hash := sha256.New() io.Copy(hash, r) return hash } func writeIfChanged(ctx context.Context, content []byte, path string) error { file, err := os.Open(path) if err != nil && !os.IsNotExist(err) { return err } if !os.IsNotExist(err) { reader := bytes.NewReader(content) h1 := checksum(reader) h2 := checksum(file) file.Close() if bytes.Equal(h1.Sum(nil), h2.Sum(nil)) { return nil } } clog.Infof(ctx, "Writing repo file %s with updated contents", path) return util.AtomicWrite(path, content, 0644) } osconfig-20250416.02/policies/recipes/000077500000000000000000000000001477773331400172675ustar00rootroot00000000000000osconfig-20250416.02/policies/recipes/artifacts.go000066400000000000000000000071051477773331400216010ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package recipes import ( "context" "fmt" "io" "net/http" "net/url" "path" "path/filepath" "cloud.google.com/go/storage" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/external" "github.com/GoogleCloudPlatform/osconfig/util" "cloud.google.com/go/osconfig/agentendpoint/apiv1beta/agentendpointpb" ) // fetchArtifacts takes in a slice of artifacts and downloads them into the specified directory, // Returns a map of artifact names to their new locations on the local disk. func fetchArtifacts(ctx context.Context, artifacts []*agentendpointpb.SoftwareRecipe_Artifact, directory string) (map[string]string, error) { localNames := make(map[string]string) for _, a := range artifacts { clog.Debugf(ctx, "Downloading artifact: %q", a) path, err := fetchArtifact(ctx, a, directory) if err != nil { return nil, err } localNames[a.Id] = path } return localNames, nil } func fetchArtifact(ctx context.Context, artifact *agentendpointpb.SoftwareRecipe_Artifact, directory string) (string, error) { var checksum, extension string var reader io.ReadCloser switch { case artifact.GetGcs() != nil: gcs := artifact.GetGcs() extension = path.Ext(gcs.Object) cl, err := storage.NewClient(ctx) if err != nil { return "", fmt.Errorf("error creating gcs client: %v", err) } defer cl.Close() reader, err = external.FetchGCSObject(ctx, cl, gcs.Bucket, gcs.Object, gcs.Generation) if err != nil { return "", fmt.Errorf("error fetching artifact %q from GCS: %v", artifact.Id, err) } defer reader.Close() case artifact.GetRemote() != nil: remote := artifact.GetRemote() uri, err := url.Parse(remote.Uri) if err != nil { return "", fmt.Errorf("Could not parse url %q for artifact %q", remote.Uri, artifact.Id) } extension = path.Ext(uri.Path) checksum = remote.Checksum cl := &http.Client{} reader, err = getHTTPArtifact(ctx, cl, *uri) if err != nil { return "", fmt.Errorf("error fetching artifact %q: %v", artifact.Id, err) } defer reader.Close() default: return "", fmt.Errorf("unknown artifact type for artifact %v", artifact.Id) } localPath := getStoragePath(directory, artifact.Id, extension) if _, err := util.AtomicWriteFileStream(reader, checksum, localPath, 0600); err != nil { return "", fmt.Errorf("Error downloading stream: %v", err) } return localPath, nil } func getHTTPArtifact(ctx context.Context, client *http.Client, uri url.URL) (io.ReadCloser, error) { if !isSupportedURL(uri) { return nil, fmt.Errorf("error, unsupported protocol scheme %s", uri.Scheme) } reader, err := external.FetchRemoteObjectHTTP(ctx, client, uri.String()) if err != nil { return nil, err } return reader, nil } func isSupportedURL(uri url.URL) bool { return (uri.Scheme == "http") || (uri.Scheme == "https") } func getStoragePath(directory, fname, extension string) string { localpath := filepath.Join(directory, fname) if extension != "" { localpath = localpath + extension } return localpath } osconfig-20250416.02/policies/recipes/artifacts_test.go000066400000000000000000000027431477773331400226430ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package recipes import ( "context" "net/url" "strings" "testing" ) func TestFetchArtifacts_http_InvalidURL(t *testing.T) { uri := "ftp://google.com/agent.deb" u, err := url.Parse(uri) _, err = getHTTPArtifact(context.Background(), nil, *u) if err == nil || !strings.Contains(err.Error(), "unsupported protocol scheme") { t.Errorf("expected error (unsupported protocol); got(%v)", err) } } func TestRecipesgetStoragePathWithExtension(t *testing.T) { expect := "/tmp/artifact-id-1.txt" localpath := getStoragePath("/tmp", "artifact-id-1", ".txt") if localpath != expect { t.Errorf("Expected(%s); got(%s)", expect, localpath) } } func TestRecipesgetStoragePathWitouthExtension(t *testing.T) { expect := "/tmp/artifact-id-1" localpath := getStoragePath("/tmp", "artifact-id-1", "") if localpath != expect { t.Errorf("Expected(%s); got(%s)", expect, localpath) } } osconfig-20250416.02/policies/recipes/installrecipe.go000066400000000000000000000112541477773331400224570ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package recipes import ( "context" "fmt" "io/ioutil" "os" "path/filepath" "time" "github.com/GoogleCloudPlatform/osconfig/clog" "cloud.google.com/go/osconfig/agentendpoint/apiv1beta/agentendpointpb" ) // InstallRecipe installs a recipe. func InstallRecipe(ctx context.Context, recipe *agentendpointpb.SoftwareRecipe) error { ctx = clog.WithLabels(ctx, map[string]string{"recipe_name": recipe.GetName()}) steps := recipe.InstallSteps recipeDB, err := newRecipeDB() if err != nil { return err } installedRecipe, ok := recipeDB.getRecipe(recipe.Name) if ok { clog.Debugf(ctx, "Currently installed version of software recipe %s with version %s.", recipe.GetName(), installedRecipe.Version) if (installedRecipe.compare(recipe.Version)) && (recipe.DesiredState == agentendpointpb.DesiredState_UPDATED) { clog.Infof(ctx, "Upgrading software recipe %s from version %s to %s.", recipe.Name, installedRecipe.Version, recipe.GetVersion()) steps = recipe.UpdateSteps } else { clog.Debugf(ctx, "Skipping software recipe %s.", recipe.GetName()) return nil } } else { clog.Infof(ctx, "Installing software recipe %s.", recipe.GetName()) } clog.Debugf(ctx, "Creating working directory for recipe %s.", recipe.GetName()) runID := fmt.Sprintf("run_%d", time.Now().UnixNano()) runDir, err := createBaseDir(recipe, runID) if err != nil { return fmt.Errorf("failed to create base directory: %v", err) } defer func() { if err := os.RemoveAll(runDir); err != nil { clog.Warningf(ctx, "Failed to remove recipe working directory at %q: %v", runDir, err) } }() artifacts, err := fetchArtifacts(ctx, recipe.Artifacts, runDir) if err != nil { return fmt.Errorf("failed to obtain artifacts: %v", err) } runEnvs := []string{ fmt.Sprintf("RECIPE_NAME=%s", recipe.Name), fmt.Sprintf("RECIPE_VERSION=%s", recipe.Version), fmt.Sprintf("RUNID=%s", runID), } for artifactID, artifactPath := range artifacts { runEnvs = append(runEnvs, fmt.Sprintf("%s=%s", artifactID, artifactPath)) } for i, step := range steps { clog.Debugf(ctx, "Running step %d: %q", i, step) stepDir := filepath.Join(runDir, fmt.Sprintf("step%02d", i)) if err := os.MkdirAll(stepDir, 0755); err != nil { return fmt.Errorf("failed to create recipe step dir %q: %s", stepDir, err) } var err error var stepType string switch { case step.GetFileCopy() != nil: stepType = "CopyFile" err = stepCopyFile(step.GetFileCopy(), artifacts, runEnvs, stepDir) case step.GetArchiveExtraction() != nil: stepType = "ExtractArchive" err = stepExtractArchive(ctx, step.GetArchiveExtraction(), artifacts, runEnvs, stepDir) case step.GetMsiInstallation() != nil: stepType = "InstallMsi" err = stepInstallMsi(ctx, step.GetMsiInstallation(), artifacts, runEnvs, stepDir) case step.GetFileExec() != nil: stepType = "ExecFile" err = stepExecFile(ctx, step.GetFileExec(), artifacts, runEnvs, stepDir) case step.GetScriptRun() != nil: stepType = "RunScript" err = stepRunScript(ctx, step.GetScriptRun(), artifacts, runEnvs, stepDir) case step.GetDpkgInstallation() != nil: stepType = "InstallDpkg" err = stepInstallDpkg(ctx, step.GetDpkgInstallation(), artifacts) case step.GetRpmInstallation() != nil: stepType = "InstallRpm" err = stepInstallRpm(ctx, step.GetRpmInstallation(), artifacts) } if err != nil { recipeDB.addRecipe(recipe.Name, recipe.Version, false) if stepType == "" { return fmt.Errorf("unknown step type for step %d", i) } return fmt.Errorf("error running step %d (%s): %v", i, stepType, err) } } clog.Infof(ctx, "All steps completed successfully, marking recipe %s as installed.", recipe.Name) return recipeDB.addRecipe(recipe.Name, recipe.Version, true) } func createBaseDir(recipe *agentendpointpb.SoftwareRecipe, runID string) (string, error) { name := recipe.Name if recipe.Version != "" { name = fmt.Sprintf("%s_%s", name, recipe.Version) } dir, err := ioutil.TempDir("", fmt.Sprintf("%s_%s_", name, runID)) if err != nil { return "", fmt.Errorf("failed to create working dir for recipe: %q %s", recipe.Name, err) } return dir, nil } osconfig-20250416.02/policies/recipes/recipe.go000066400000000000000000000045441477773331400210740ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package recipes import ( "fmt" "strconv" "strings" ) type recipeVersion []int func (v recipeVersion) String() string { res := fmt.Sprintf("%d", v[0]) for _, val := range v[1:] { res = fmt.Sprintf("%s.%d", res, val) } return res } // Recipe represents an installed recipe. type Recipe struct { Name string Version recipeVersion InstallTime int64 Success bool } func (r *Recipe) setVersion(version string) error { var err error r.Version, err = convertVersion(version) return err } // compare returns true if the provided Version is greater than the recipe's // Version, false otherwise. func (r *Recipe) compare(version string) bool { if version == "" { return false } cVersion, err := convertVersion(version) if err != nil { return false } if len(r.Version) > len(cVersion) { topad := len(r.Version) - len(cVersion) for i := 0; i < topad; i++ { cVersion = append(cVersion, 0) } } else { topad := len(cVersion) - len(r.Version) for i := 0; i < topad; i++ { r.Version = append(r.Version, 0) } } for i := 0; i < len(r.Version); i++ { if r.Version[i] != cVersion[i] { return cVersion[i] > r.Version[i] } } return false } func convertVersion(version string) ([]int, error) { // ${ROOT}/recipe[_ver]/runId/recipe.yaml // recipe at time of application // ${ROOT}/recipe[_ver]/runId/artifacts/* // ${ROOT}/recipe[_ver]/runId/stepN_type/ if version == "" { return []int{0}, nil } var ret []int for idx, element := range strings.Split(version, ".") { if idx > 3 { return nil, fmt.Errorf("invalid Version string") } val, err := strconv.ParseInt(element, 10, 0) if err != nil || val < 0 { return nil, fmt.Errorf("invalid Version string") } ret = append(ret, int(val)) } return ret, nil } osconfig-20250416.02/policies/recipes/recipe_test.go000066400000000000000000000052501477773331400221260ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package recipes import ( "strings" "testing" ) func TestRecipe_SetVersion_ValidVersion(t *testing.T) { rec := &Recipe{} rec.setVersion("1.2.3.23") if rec.Version[0] != 1 || rec.Version[1] != 2 || rec.Version[2] != 3 || rec.Version[3] != 23 { t.Errorf("invalid Version set for the recipe") } } func TestRecipe_SetVersion_EmptyVersion(t *testing.T) { rec := &Recipe{} rec.setVersion("") if len(rec.Version) != 1 || rec.Version[0] != 0 { t.Errorf("invalid Version set for the recipe") } } func TestRecipe_SetVersion_InvalidVersion(t *testing.T) { rec := &Recipe{} err := rec.setVersion("12.32.23.23.23.23") if !strings.Contains(err.Error(), "invalid") { t.Errorf("setVersion should return error") } } func TestRecipe_SetVersion_InvalidCharacter(t *testing.T) { rec := &Recipe{} err := rec.setVersion("12.32.dsf.23") if !strings.Contains(err.Error(), "invalid") { t.Errorf("setVersion should return error") } } func TestRecipe_Compare_EmptyVersion(t *testing.T) { rec := &Recipe{Version: []int{1, 2, 3, 4}} if rec.compare("") { t.Errorf("should return false") } } func TestRecipe_Compare_InvalidInput(t *testing.T) { rec := &Recipe{Version: []int{1, 2, 3, 4}} if rec.compare("1.2.3.4.56.7") { t.Errorf("should return false") } } func TestRecipe_Compare_PaddingNeededAndCompare(t *testing.T) { rec := &Recipe{Version: []int{1, 2, 3, 4}} if !rec.compare("1.3") { t.Errorf("should return true") } } func TestRecipe_Compare_PaddingNeededToRecipe(t *testing.T) { rec := &Recipe{Version: []int{1, 3}} if rec.compare("1.2.3.4") { t.Errorf("should return false") } } func TestRecipe_Compare_IsGreater(t *testing.T) { rec := &Recipe{Version: []int{1, 2, 3, 4}} if !rec.compare("1.3.4.2") { t.Errorf("should return true") } } func TestRecipe_Compare_IsNotGreater(t *testing.T) { rec := &Recipe{Version: []int{1, 6, 3, 4}} if rec.compare("1.3.4.2") { t.Errorf("should return false") } } func TestRecipe_Compare_IsEqualVersion(t *testing.T) { rec := &Recipe{Version: []int{1, 6, 3, 4}} if rec.compare("1.6.3.4") { t.Errorf("should return false") } } osconfig-20250416.02/policies/recipes/recipedb.go000066400000000000000000000047711477773331400214040ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package recipes import ( "encoding/json" "io/ioutil" "os" "path/filepath" "runtime" "time" ) var ( dbDirWindows = "C:\\ProgramData\\Google" dbDirUnix = "/var/lib/google" dbFileName = "osconfig_recipedb" ) // RecipeDB represents local state of installed recipes. type RecipeDB map[string]Recipe // newRecipeDB instantiates a recipeDB. func newRecipeDB() (RecipeDB, error) { db := make(RecipeDB) f, err := os.Open(filepath.Join(getDbDir(), dbFileName)) if err != nil { if os.IsNotExist(err) { return db, nil } return nil, err } defer f.Close() bytes, err := ioutil.ReadAll(f) if err != nil { return nil, err } var recipelist []Recipe if err := json.Unmarshal(bytes, &recipelist); err != nil { return nil, err } for _, recipe := range recipelist { db[recipe.Name] = recipe } return db, nil } // getRecipe returns the Recipe object for the given recipe name. func (db RecipeDB) getRecipe(name string) (Recipe, bool) { r, ok := db[name] return r, ok } // addRecipe marks a recipe as installed. func (db RecipeDB) addRecipe(name, version string, success bool) error { versionNum, err := convertVersion(version) if err != nil { return err } db[name] = Recipe{Name: name, Version: versionNum, InstallTime: time.Now().Unix(), Success: success} var recipelist []Recipe for _, recipe := range db { recipelist = append(recipelist, recipe) } dbBytes, err := json.Marshal(recipelist) if err != nil { return err } dbDir := getDbDir() if err := os.MkdirAll(dbDir, 0755); err != nil { return err } f, err := ioutil.TempFile(dbDir, dbFileName+"_*") if err != nil { return err } if _, err := f.Write(dbBytes); err != nil { f.Close() return err } if err := f.Close(); err != nil { return err } return os.Rename(f.Name(), filepath.Join(dbDir, dbFileName)) } func getDbDir() string { if runtime.GOOS == "windows" { return dbDirWindows } return dbDirUnix } osconfig-20250416.02/policies/recipes/steps.go000066400000000000000000000332131477773331400207560ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package recipes import ( "archive/tar" "archive/zip" "compress/bzip2" "compress/gzip" "context" "errors" "fmt" "io" "os" "os/exec" "path/filepath" "runtime" "strconv" "strings" "time" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/packages" "github.com/GoogleCloudPlatform/osconfig/util" "github.com/ulikunitz/xz" "github.com/ulikunitz/xz/lzma" "cloud.google.com/go/osconfig/agentendpoint/apiv1beta/agentendpointpb" ) var extensionMap = map[agentendpointpb.SoftwareRecipe_Step_RunScript_Interpreter]string{ agentendpointpb.SoftwareRecipe_Step_RunScript_INTERPRETER_UNSPECIFIED: ".bat", agentendpointpb.SoftwareRecipe_Step_RunScript_SHELL: ".bat", agentendpointpb.SoftwareRecipe_Step_RunScript_POWERSHELL: ".ps1", } func stepCopyFile(step *agentendpointpb.SoftwareRecipe_Step_CopyFile, artifacts map[string]string, runEnvs []string, stepDir string) error { dest, err := util.NormPath(step.Destination) if err != nil { return err } permissions, err := parsePermissions(step.Permissions) if err != nil { return err } if _, err := os.Stat(dest); err != nil { if !os.IsNotExist(err) { return err } } else { // file exists if !step.Overwrite { return fmt.Errorf("file already exists at path %q and Overwrite = false", step.Destination) } if err := os.Chmod(dest, permissions); err != nil { return err } } artifact := step.GetArtifactId() src, ok := artifacts[artifact] if !ok { return fmt.Errorf("could not find location for artifact %q", artifact) } reader, err := os.Open(src) if err != nil { return err } defer reader.Close() _, err = util.AtomicWriteFileStream(reader, "", dest, permissions) return err } func parsePermissions(s string) (os.FileMode, error) { if s == "" { return 0755, nil } i, err := strconv.ParseUint(s, 8, 32) if err != nil { return 0, err } return os.FileMode(i), nil } func stepExtractArchive(ctx context.Context, step *agentendpointpb.SoftwareRecipe_Step_ExtractArchive, artifacts map[string]string, runEnvs []string, stepDir string) error { artifact := step.GetArtifactId() filename, ok := artifacts[artifact] if !ok { return fmt.Errorf("%q not found in artifact map", artifact) } switch typ := step.GetType(); typ { case agentendpointpb.SoftwareRecipe_Step_ExtractArchive_ZIP: return extractZip(filename, step.Destination) case agentendpointpb.SoftwareRecipe_Step_ExtractArchive_TAR_GZIP, agentendpointpb.SoftwareRecipe_Step_ExtractArchive_TAR_BZIP, agentendpointpb.SoftwareRecipe_Step_ExtractArchive_TAR_LZMA, agentendpointpb.SoftwareRecipe_Step_ExtractArchive_TAR_XZ, agentendpointpb.SoftwareRecipe_Step_ExtractArchive_TAR: return extractTar(ctx, filename, step.Destination, typ) default: return fmt.Errorf("Unrecognized archive type %q", typ) } } func zipIsDir(name string) bool { if os.PathSeparator == '\\' { return strings.HasSuffix(name, `\`) || strings.HasSuffix(name, "/") } return strings.HasSuffix(name, "/") } func extractZip(zipPath string, dst string) error { zr, err := zip.OpenReader(zipPath) if err != nil { return err } defer zr.Close() // Check for conflicts for _, f := range zr.File { filen, err := util.NormPath(util.SanitizePath(filepath.Join(dst, f.Name))) if err != nil { return err } stat, err := os.Stat(filen) if os.IsNotExist(err) { continue } if err != nil { return err } if zipIsDir(f.Name) && stat.IsDir() { // it's ok if directories already exist continue } return fmt.Errorf("file exists: %s", filen) } // Create files. for _, f := range zr.File { filen, err := util.NormPath(util.SanitizePath(filepath.Join(dst, f.Name))) if err != nil { return err } if zipIsDir(f.Name) { mode := f.Mode() if mode == 0 { mode = 0755 } if err := os.MkdirAll(filen, mode); err != nil { return err } // Setting to correct permissions in case the directory has already been created if err := os.Chmod(filen, mode); err != nil { return err } continue } filedir := filepath.Dir(filen) if err = os.MkdirAll(filedir, 0755); err != nil { return err } reader, err := f.Open() if err != nil { return err } mode := f.Mode() if mode == 0 { mode = 0755 } dst, err := os.OpenFile(filen, os.O_RDWR|os.O_CREATE, mode) if err != nil { return err } if _, err = io.Copy(dst, reader); err != nil { dst.Close() return err } reader.Close() if err := dst.Close(); err != nil { return err } if err := os.Chtimes(filen, time.Now(), f.ModTime()); err != nil { return err } } return nil } func decompress(reader io.Reader, archiveType agentendpointpb.SoftwareRecipe_Step_ExtractArchive_ArchiveType) (io.Reader, error) { switch archiveType { case agentendpointpb.SoftwareRecipe_Step_ExtractArchive_TAR_GZIP: // *gzip.Reader is a io.ReadCloser but it isn't necesary to call Close() on it. return gzip.NewReader(reader) case agentendpointpb.SoftwareRecipe_Step_ExtractArchive_TAR_BZIP: return bzip2.NewReader(reader), nil case agentendpointpb.SoftwareRecipe_Step_ExtractArchive_TAR_LZMA: return lzma.NewReader2(reader) case agentendpointpb.SoftwareRecipe_Step_ExtractArchive_TAR_XZ: return xz.NewReader(reader) case agentendpointpb.SoftwareRecipe_Step_ExtractArchive_TAR: return reader, nil default: return nil, fmt.Errorf("Unrecognized archive type %q when trying to decompress tar", archiveType) } } func checkForConflicts(tr *tar.Reader, dst string) error { for { header, err := tr.Next() if err == io.EOF { break } if err != nil { return err } filen, err := util.NormPath(filepath.Join(dst, header.Name)) if err != nil { return err } stat, err := os.Stat(filen) if os.IsNotExist(err) { continue } if err != nil { return err } if header.Typeflag == tar.TypeDir && stat.IsDir() { // it's ok if directories already exist continue } return fmt.Errorf("file exists: %s", filen) } return nil } func extractTar(ctx context.Context, tarName string, dst string, archiveType agentendpointpb.SoftwareRecipe_Step_ExtractArchive_ArchiveType) error { file, err := os.Open(tarName) if err != nil { return err } defer file.Close() decompressed, err := decompress(file, archiveType) if err != nil { return err } tr := tar.NewReader(decompressed) if err := checkForConflicts(tr, dst); err != nil { return err } file.Seek(0, 0) decompressed, err = decompress(file, archiveType) if err != nil { return err } tr = tar.NewReader(decompressed) for { var err error header, err := tr.Next() if err == io.EOF { break } if err != nil { return err } filen, err := util.NormPath(filepath.Join(dst, util.SanitizePath(header.Name))) if err != nil { return err } filedir := filepath.Dir(filen) if err := os.MkdirAll(filedir, 0700); err != nil { return err } switch header.Typeflag { case tar.TypeDir: if err := os.MkdirAll(filen, os.FileMode(header.Mode)); err != nil { return err } // Setting to correct permissions in case the directory has already been created if err := os.Chmod(filen, os.FileMode(header.Mode)); err != nil { return err } if err := chown(filen, header.Uid, header.Gid); err != nil { return err } case tar.TypeReg, tar.TypeRegA: dst, err := os.OpenFile(filen, os.O_RDWR|os.O_CREATE, os.FileMode(header.Mode)) if err != nil { return err } if _, err := io.Copy(dst, tr); err != nil { dst.Close() return err } if err := dst.Close(); err != nil { return err } case tar.TypeLink: if err := os.Link(header.Linkname, filen); err != nil { return err } continue case tar.TypeSymlink: if err := os.Symlink(header.Linkname, filen); err != nil { return err } continue case tar.TypeChar: if err := mkCharDevice(filen, uint32(header.Devmajor), uint32(header.Devminor)); err != nil { return err } if runtime.GOOS != "windows" { if err := os.Chmod(filen, os.FileMode(header.Mode)); err != nil { return err } } case tar.TypeBlock: if err := mkBlockDevice(filen, uint32(header.Devmajor), uint32(header.Devminor)); err != nil { return err } if runtime.GOOS != "windows" { if err := os.Chmod(filen, os.FileMode(header.Mode)); err != nil { return err } } case tar.TypeFifo: if err := mkFifo(filen, uint32(header.Mode)); err != nil { return err } default: clog.Infof(ctx, "Unknown file type for tar entry %s\n", filen) continue } if err := chown(filen, header.Uid, header.Gid); err != nil { return err } if err := os.Chtimes(filen, header.AccessTime, header.ModTime); err != nil { return err } } return nil } func stepInstallMsi(ctx context.Context, step *agentendpointpb.SoftwareRecipe_Step_InstallMsi, artifacts map[string]string, runEnvs []string, stepDir string) error { if runtime.GOOS != "windows" { return errors.New("SoftwareRecipe_Step_InstallMsi only applicable on Windows") } artifact := step.GetArtifactId() path, ok := artifacts[artifact] if !ok { return fmt.Errorf("%q not found in artifact map", artifact) } args := step.Flags if len(args) == 0 { args = []string{"/i", "/qn", "/norestart"} } args = append(args, path) exitCodes := step.AllowedExitCodes if len(exitCodes) == 0 { exitCodes = []int32{0, 1641, 3010} } return executeCommand(ctx, "C:\\Windows\\System32\\msiexec.exe", args, stepDir, runEnvs, exitCodes) } func stepInstallDpkg(ctx context.Context, step *agentendpointpb.SoftwareRecipe_Step_InstallDpkg, artifacts map[string]string) error { if !packages.DpkgExists { return fmt.Errorf("dpkg does not exist on system") } artifact := step.GetArtifactId() path, ok := artifacts[artifact] if !ok { return fmt.Errorf("%q not found in artifact map", artifact) } return packages.DpkgInstall(ctx, path) } func stepInstallRpm(ctx context.Context, step *agentendpointpb.SoftwareRecipe_Step_InstallRpm, artifacts map[string]string) error { if !packages.RPMExists { return fmt.Errorf("rpm does not exist on system") } artifact := step.GetArtifactId() path, ok := artifacts[artifact] if !ok { return fmt.Errorf("%q not found in artifact map", artifact) } return packages.RPMInstall(ctx, path) } func stepExecFile(ctx context.Context, step *agentendpointpb.SoftwareRecipe_Step_ExecFile, artifacts map[string]string, runEnvs []string, stepDir string) error { var path string switch { case step.GetArtifactId() != "": var ok bool artifact := step.GetArtifactId() path, ok = artifacts[artifact] if !ok { return fmt.Errorf("%q not found in artifact map", artifact) } // By default artifacts are created with 0644 if err := os.Chmod(path, 0755); err != nil { return fmt.Errorf("error setting execute permissions on artifact %s: %v", step.GetArtifactId(), err) } case step.GetLocalPath() != "": path = step.GetLocalPath() default: return fmt.Errorf("can't determine location type") } return executeCommand(ctx, path, step.Args, stepDir, runEnvs, []int32{0}) } func stepRunScript(ctx context.Context, step *agentendpointpb.SoftwareRecipe_Step_RunScript, artifacts map[string]string, runEnvs []string, stepDir string) error { var extension string if runtime.GOOS == "windows" { extension = extensionMap[step.Interpreter] } scriptPath := filepath.Join(stepDir, "recipe_script_source"+extension) if err := util.AtomicWrite(scriptPath, []byte(step.Script), 0755); err != nil { return err } var cmd string var args []string switch step.Interpreter { case agentendpointpb.SoftwareRecipe_Step_RunScript_INTERPRETER_UNSPECIFIED: cmd = scriptPath case agentendpointpb.SoftwareRecipe_Step_RunScript_SHELL: if runtime.GOOS == "windows" { cmd = scriptPath } else { args = append(args, scriptPath) cmd = "/bin/sh" } case agentendpointpb.SoftwareRecipe_Step_RunScript_POWERSHELL: if runtime.GOOS != "windows" { return fmt.Errorf("interpreter %q can only be used on Windows systems", step.Interpreter) } args = append(args, "-File", scriptPath) cmd = "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\PowerShell.exe" default: return fmt.Errorf("unsupported interpreter %q", step.Interpreter) } return executeCommand(ctx, cmd, args, stepDir, runEnvs, step.AllowedExitCodes) } func executeCommand(ctx context.Context, cmd string, args []string, workDir string, runEnvs []string, allowedExitCodes []int32) error { cmdObj := exec.Command(cmd, args...) cmdObj.Dir = workDir defaultEnv, err := createDefaultEnvironment() if err != nil { return fmt.Errorf("error creating default environment: %v", err) } cmdObj.Env = append(cmdObj.Env, defaultEnv...) cmdObj.Env = append(cmdObj.Env, runEnvs...) o, err := cmdObj.CombinedOutput() clog.Infof(ctx, "Combined output for %q command:\n%s", cmd, o) if err == nil { return nil } if v, ok := err.(*exec.ExitError); ok && len(allowedExitCodes) != 0 { result := int32(v.ExitCode()) for _, code := range allowedExitCodes { if result == code { return nil } } } return err } func chown(file string, uid, gid int) error { // os.Chown unsupported on windows if runtime.GOOS == "windows" { return nil } return os.Chown(file, uid, gid) } osconfig-20250416.02/policies/recipes/steps_linux.go000066400000000000000000000022061477773331400221730ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build linux // +build linux package recipes import ( "golang.org/x/sys/unix" ) func mkCharDevice(path string, devMajor, devMinor uint32) error { return unix.Mknod(path, unix.S_IFCHR, int(unix.Mkdev(devMajor, devMinor))) } func mkBlockDevice(path string, devMajor, devMinor uint32) error { return unix.Mknod(path, unix.S_IFBLK, int(unix.Mkdev(devMajor, devMinor))) } func mkFifo(path string, mode uint32) error { return unix.Mkfifo(path, mode) } func createDefaultEnvironment() ([]string, error) { return []string{}, nil } osconfig-20250416.02/policies/recipes/steps_windows.go000066400000000000000000000023221477773331400225250ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build windows // +build windows package recipes import ( "fmt" "golang.org/x/sys/windows" ) func mkCharDevice(path string, devMajor, devMinor uint32) error { return fmt.Errorf("Creating a char device is not supported on windows") } func mkBlockDevice(path string, devMajor, devMinor uint32) error { return fmt.Errorf("Creating a block device is not supported on windows") } func mkFifo(path string, mode uint32) error { return fmt.Errorf("Creating a fifo is not supported on windows") } func createDefaultEnvironment() ([]string, error) { return windows.GetCurrentProcessToken().Environ(false) } osconfig-20250416.02/policies/yum.go000066400000000000000000000066221477773331400170040ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package policies import ( "bytes" "context" "errors" "fmt" "strings" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/packages" "cloud.google.com/go/osconfig/agentendpoint/apiv1beta/agentendpointpb" ) func yumRepositories(ctx context.Context, repos []*agentendpointpb.YumRepository, repoFile string) error { // TODO: Would it be easier to just use templates? /* # Repo file managed by Google OSConfig agent [repo1] name=repo1-name baseurl=https://repo1-url enabled=1 gpgcheck=1 gpgkey=http://repo1-url/gpg [repo2] display_name=repo2-name baseurl=https://repo2-url enabled=1 gpgcheck=1 */ var buf bytes.Buffer buf.WriteString("# Repo file managed by Google OSConfig agent\n") for _, repo := range repos { buf.WriteString(fmt.Sprintf("\n[%s]\n", repo.Id)) if repo.DisplayName == "" { buf.WriteString(fmt.Sprintf("name=%s\n", repo.Id)) } else { buf.WriteString(fmt.Sprintf("name=%s\n", repo.DisplayName)) } buf.WriteString(fmt.Sprintf("baseurl=%s\n", repo.BaseUrl)) buf.WriteString("enabled=1\ngpgcheck=1\n") if len(repo.GpgKeys) > 0 { buf.WriteString(fmt.Sprintf("gpgkey=%s\n", repo.GpgKeys[0])) for _, k := range repo.GpgKeys[1:] { buf.WriteString(fmt.Sprintf(" %s\n", k)) } } } return writeIfChanged(ctx, buf.Bytes(), repoFile) } func yumChanges(ctx context.Context, yumInstalled, yumRemoved, yumUpdated []*agentendpointpb.Package) error { var err error var errs []string var installed []*packages.PkgInfo if len(yumInstalled) > 0 || len(yumUpdated) > 0 || len(yumRemoved) > 0 { installed, err = packages.InstalledRPMPackages(ctx) if err != nil { return err } } var updates []*packages.PkgInfo if len(yumUpdated) > 0 { updates, err = packages.YumUpdates(ctx) if err != nil { return err } } changes := getNecessaryChanges(installed, updates, yumInstalled, yumRemoved, yumUpdated) if changes.packagesToInstall != nil { clog.Infof(ctx, "Installing packages %s", changes.packagesToInstall) if err := packages.InstallYumPackages(ctx, changes.packagesToInstall); err != nil { errs = append(errs, fmt.Sprintf("error installing yum packages: %v", err)) } } if changes.packagesToUpgrade != nil { clog.Infof(ctx, "Upgrading packages %s", changes.packagesToUpgrade) if err := packages.InstallYumPackages(ctx, changes.packagesToUpgrade); err != nil { errs = append(errs, fmt.Sprintf("error upgrading yum packages: %v", err)) } } if changes.packagesToRemove != nil { clog.Infof(ctx, "Removing packages %s", changes.packagesToRemove) if err := packages.RemoveYumPackages(ctx, changes.packagesToRemove); err != nil { errs = append(errs, fmt.Sprintf("error removing yum packages: %v", err)) } } if errs == nil { return nil } return errors.New(strings.Join(errs, ",\n")) } osconfig-20250416.02/policies/yum_test.go000066400000000000000000000051471477773331400200440ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package policies import ( "context" "fmt" "io/ioutil" "os" "path/filepath" "testing" "cloud.google.com/go/osconfig/agentendpoint/apiv1beta/agentendpointpb" ) func runYumRepositories(ctx context.Context, repos []*agentendpointpb.YumRepository) (string, error) { td, err := ioutil.TempDir(os.TempDir(), "") if err != nil { return "", fmt.Errorf("error creating temp dir: %v", err) } defer os.RemoveAll(td) testRepo := filepath.Join(td, "testRepo") if err := yumRepositories(ctx, repos, testRepo); err != nil { return "", fmt.Errorf("error running yumRepositories: %v", err) } data, err := ioutil.ReadFile(testRepo) if err != nil { return "", fmt.Errorf("error reading testRepo: %v", err) } return string(data), nil } func TestYumRepositories(t *testing.T) { tests := []struct { desc string repos []*agentendpointpb.YumRepository want string }{ {"no repos", []*agentendpointpb.YumRepository{}, "# Repo file managed by Google OSConfig agent\n"}, { "1 repo", []*agentendpointpb.YumRepository{ {BaseUrl: "http://repo1-url/", Id: "id"}, }, "# Repo file managed by Google OSConfig agent\n\n[id]\nname=id\nbaseurl=http://repo1-url/\nenabled=1\ngpgcheck=1\n", }, { "2 repos", []*agentendpointpb.YumRepository{ {BaseUrl: "http://repo1-url/", Id: "id1", DisplayName: "displayName1", GpgKeys: []string{"https://url/key"}}, {BaseUrl: "http://repo1-url/", Id: "id2", DisplayName: "displayName2", GpgKeys: []string{"https://url/key1", "https://url/key2"}}, }, "# Repo file managed by Google OSConfig agent\n\n[id1]\nname=displayName1\nbaseurl=http://repo1-url/\nenabled=1\ngpgcheck=1\ngpgkey=https://url/key\n\n[id2]\nname=displayName2\nbaseurl=http://repo1-url/\nenabled=1\ngpgcheck=1\ngpgkey=https://url/key1\n https://url/key2\n", }, } for _, tt := range tests { got, err := runYumRepositories(context.Background(), tt.repos) if err != nil { t.Fatal(err) } if got != tt.want { t.Errorf("%s: got:\n%q\nwant:\n%q", tt.desc, got, tt.want) } } } osconfig-20250416.02/policies/zypper.go000066400000000000000000000067131477773331400175240ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package policies import ( "bytes" "context" "errors" "fmt" "strings" "github.com/GoogleCloudPlatform/osconfig/clog" "github.com/GoogleCloudPlatform/osconfig/packages" "cloud.google.com/go/osconfig/agentendpoint/apiv1beta/agentendpointpb" ) // TODO: Write repo_gpgcheck, pkg_gpgcheck, type func zypperRepositories(ctx context.Context, repos []*agentendpointpb.ZypperRepository, repoFile string) error { /* # Repo file managed by Google OSConfig agent [repo1] name=repo1-name baseurl=https://repo1-url enabled=1 gpgcheck=1 gpgkey=http://repo1-url/gpg [repo2] display_name=repo2-name baseurl=https://repo2-url enabled=1 gpgcheck=1 */ var buf bytes.Buffer buf.WriteString("# Repo file managed by Google OSConfig agent\n") for _, repo := range repos { buf.WriteString(fmt.Sprintf("\n[%s]\n", repo.Id)) if repo.DisplayName == "" { buf.WriteString(fmt.Sprintf("name=%s\n", repo.Id)) } else { buf.WriteString(fmt.Sprintf("name=%s\n", repo.DisplayName)) } buf.WriteString(fmt.Sprintf("baseurl=%s\n", repo.BaseUrl)) buf.WriteString("enabled=1\ngpgcheck=1\n") if len(repo.GpgKeys) > 0 { buf.WriteString(fmt.Sprintf("gpgkey=%s\n", repo.GpgKeys[0])) for _, k := range repo.GpgKeys[1:] { buf.WriteString(fmt.Sprintf(" %s\n", k)) } } } return writeIfChanged(ctx, buf.Bytes(), repoFile) } func zypperChanges(ctx context.Context, zypperInstalled, zypperRemoved, zypperUpdated []*agentendpointpb.Package) error { var err error var errs []string var installed []*packages.PkgInfo if len(zypperInstalled) > 0 || len(zypperUpdated) > 0 || len(zypperRemoved) > 0 { installed, err = packages.InstalledRPMPackages(ctx) if err != nil { return err } } var updates []*packages.PkgInfo if len(zypperUpdated) > 0 { updates, err = packages.ZypperUpdates(ctx) if err != nil { return err } } changes := getNecessaryChanges(installed, updates, zypperInstalled, zypperRemoved, zypperUpdated) if changes.packagesToInstall != nil { clog.Infof(ctx, "Installing packages %s", changes.packagesToInstall) if err := packages.InstallZypperPackages(ctx, changes.packagesToInstall); err != nil { errs = append(errs, fmt.Sprintf("error installing zypper packages: %v", err)) } } if changes.packagesToUpgrade != nil { clog.Infof(ctx, "Upgrading packages %s", changes.packagesToUpgrade) if err := packages.InstallZypperPackages(ctx, changes.packagesToUpgrade); err != nil { errs = append(errs, fmt.Sprintf("error upgrading zypper packages: %v", err)) } } if changes.packagesToRemove != nil { clog.Infof(ctx, "Removing packages %s", changes.packagesToRemove) if err := packages.RemoveZypperPackages(ctx, changes.packagesToRemove); err != nil { errs = append(errs, fmt.Sprintf("error removing zypper packages: %v", err)) } } if errs == nil { return nil } return errors.New(strings.Join(errs, ",\n")) } osconfig-20250416.02/policies/zypper_test.go000066400000000000000000000052051477773331400205560ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package policies import ( "context" "fmt" "io/ioutil" "os" "path/filepath" "testing" "cloud.google.com/go/osconfig/agentendpoint/apiv1beta/agentendpointpb" ) func runZypperRepositories(ctx context.Context, repos []*agentendpointpb.ZypperRepository) (string, error) { td, err := ioutil.TempDir(os.TempDir(), "") if err != nil { return "", fmt.Errorf("error creating temp dir: %v", err) } defer os.RemoveAll(td) testRepo := filepath.Join(td, "testRepo") if err := zypperRepositories(ctx, repos, testRepo); err != nil { return "", fmt.Errorf("error running zypperRepositories: %v", err) } data, err := ioutil.ReadFile(testRepo) if err != nil { return "", fmt.Errorf("error reading testRepo: %v", err) } return string(data), nil } func TestZypperRepositories(t *testing.T) { tests := []struct { desc string repos []*agentendpointpb.ZypperRepository want string }{ {"no repos", []*agentendpointpb.ZypperRepository{}, "# Repo file managed by Google OSConfig agent\n"}, { "1 repo", []*agentendpointpb.ZypperRepository{ {BaseUrl: "http://repo1-url/", Id: "id"}, }, "# Repo file managed by Google OSConfig agent\n\n[id]\nname=id\nbaseurl=http://repo1-url/\nenabled=1\ngpgcheck=1\n", }, { "2 repos", []*agentendpointpb.ZypperRepository{ {BaseUrl: "http://repo1-url/", Id: "id1", DisplayName: "displayName1", GpgKeys: []string{"https://url/key"}}, {BaseUrl: "http://repo1-url/", Id: "id2", DisplayName: "displayName2", GpgKeys: []string{"https://url/key1", "https://url/key2"}}, }, "# Repo file managed by Google OSConfig agent\n\n[id1]\nname=displayName1\nbaseurl=http://repo1-url/\nenabled=1\ngpgcheck=1\ngpgkey=https://url/key\n\n[id2]\nname=displayName2\nbaseurl=http://repo1-url/\nenabled=1\ngpgcheck=1\ngpgkey=https://url/key1\n https://url/key2\n", }, } for _, tt := range tests { got, err := runZypperRepositories(context.Background(), tt.repos) if err != nil { t.Fatal(err) } if got != tt.want { t.Errorf("%s: got:\n%q\nwant:\n%q", tt.desc, got, tt.want) } } } osconfig-20250416.02/presubmit_packagebuild/000077500000000000000000000000001477773331400205335ustar00rootroot00000000000000osconfig-20250416.02/presubmit_packagebuild/docker-image/000077500000000000000000000000001477773331400230625ustar00rootroot00000000000000osconfig-20250416.02/presubmit_packagebuild/docker-image/Dockerfile000066400000000000000000000022621477773331400250560ustar00rootroot00000000000000# Copyright 2018 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. FROM gcr.io/compute-image-tools/daisy:latest #FROM alpine # Needed for gsutil. FROM google/cloud-sdk:alpine RUN apk add --no-cache bash WORKDIR / COPY --from=0 /daisy daisy # Daisy image copies this from gcr.io/distroless/base, we copy here. COPY --from=0 /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt # Must be built from root of repo, where packagebuild dir is. COPY packagebuild packagebuild # Copy this Dockerfile for debugging. COPY presubmit_packagebuild/docker-image/Dockerfile Dockerfile COPY presubmit_packagebuild/docker-image/main.sh main.sh ENTRYPOINT ["/main.sh"] osconfig-20250416.02/presubmit_packagebuild/docker-image/build-container-img-cloudbuild.yaml000066400000000000000000000005661477773331400317320ustar00rootroot00000000000000timeout: 5400s steps: - name: 'gcr.io/kaniko-project/executor:v1.23.2' args: - --destination=europe-docker.pkg.dev/osconfig-agent-presubmits/osconfig-package-build-presubmit/osconfig-package-build-presubmit:latest - --context=/workspace - --dockerfile=presubmit_packagebuild/docker-image/Dockerfile options: defaultLogsBucketBehavior: REGIONAL_USER_OWNED_BUCKET osconfig-20250416.02/presubmit_packagebuild/docker-image/main.sh000077500000000000000000000074071477773331400243550ustar00rootroot00000000000000#!/bin/bash # Copyright 2019 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. PROJECT="$1" ZONE="$2" DISTROS="$3" # Distros to build GCS_OUTPUT_BUCKET="$4" # Destination for artifacts BUILD_DIR="$5" # Directory to build from VERSION="" # Workflow consisting entirely of separate IncludeWorkflow steps referencing # build_${distro}.wf.json, which should be checked out from guest-test-infra. function generate_build_workflow() { local WF="$1" config='{ "Name": "build-packages", "DefaultTimeout": "30m", "Vars": { "gcs_path": { "Value": "${SCRATCHPATH}/packages", "Description": "GCS path for built packages e.g. gs://my-bucket/packages" }, "repo_owner": { "Value": "GoogleCloudPlatform", "Description": "GitHub repo owner or organization" }, "repo_name": { "Description": "Github repo name", "Required": true }, "git_ref": { "Value": "master", "Description": "Git ref to check out and build" }, "version": { "Description": "Version to build" }, "build_dir": { "Description": "Directory to build from" } }, "Steps": {' for distro in ${DISTROS//,/ }; do distrodash=$(echo "$distro" | tr '_' '-') if [[ "$config" =~ IncludeWorkflow ]]; then # Append additional steps config="${config}," fi config="${config}\n"' "'"$distrodash"'": { "IncludeWorkflow": { "Path": "./workflows/build_'"$distro"'.wf.json", "Vars": { "gcs_path": "${gcs_path}", "repo_owner": "${repo_owner}", "repo_name": "${repo_name}", "git_ref": "${git_ref}", "build_dir": "${build_dir}", "version": "${version}" } } }' done config="$config"' } }' echo -e "$config" > "$WF" } # Sets service account used for daisy and gsutil commands below. Will use # default service account for VM or k8s node if not set. if [[ -n $GOOGLE_APPLICATION_CREDENTIALS ]]; then gcloud auth activate-service-account --key-file=$GOOGLE_APPLICATION_CREDENTIALS fi cd /packagebuild WF="build.wf.json" generate_build_workflow "$WF" echo "Generated workflow:" cat "$WF" ## Some vars such as REPO_OWNER and PULL_NUMBER are set by prow DAISY_VARS="repo_owner=${REPO_OWNER},repo_name=${REPO_NAME}" ## only add pull reference in case of presubmit jobs if [[ "$JOB_TYPE" == "presubmit" ]]; then DAISY_VARS+=",git_ref=pull/${PULL_NUMBER}/head" else DAISY_VARS+=",git_ref=${PULL_BASE_REF}" fi ## Build from subdir if requested if [[ -n "$BUILD_DIR" ]]; then DAISY_VARS+=",build_dir=${BUILD_DIR}" fi DAISY_CMD="/daisy -project ${PROJECT} -zone ${ZONE} -variables ${DAISY_VARS} ${WF}" echo "Running daisy workflow for package builds" echo "Daisy command: ${DAISY_CMD}" $DAISY_CMD 2>err | tee out if [[ ${PIPESTATUS[0]} -ne 0 ]]; then echo "error running daisy: stderr: $( 1*1+[0,1] => 1-2s // base=2 and extra=0 => 2*2+[0,2] => 4-6s // base=3 and extra=0 => 3*3+[0,3] => 9-12s // base=1 and extra=5 => 6*1+[0,6] => 6-12s // base=2 and extra=5 => 7*2+[0,7] => 14-21s // base=3 and extra=5 => 8*3+[0,8] => 24-32s // base=1 and extra=10 => 11*1+[0,11] => 11-22s // base=2 and extra=10 => 12*2+[0,12] => 24-36s // base=3 and extra=10 => 13*3+[0,13] => 39-52s rnd := rand.New(rand.NewSource(time.Now().UnixNano())) nf := math.Min(float64((base+extra)*base+rnd.Intn(base+extra)), 300) return time.Duration(int(nf)) * time.Second } // RetryFunc retries a function provided as a parameter for maxRetryTime. func RetryFunc(ctx context.Context, maxRetryTime time.Duration, desc string, f func() error) error { var tot time.Duration for i := 1; ; i++ { err := f() if err == nil { return nil } ns := RetrySleep(i, 0) tot += ns if tot > maxRetryTime { return err } clog.Errorf(ctx, "Error %s, attempt %d, retrying in %s: %v", desc, i, ns, err) currentSleeper.Sleep(ns) } } // RetryAPICall retries an API call for maxRetryTime. func RetryAPICall(ctx context.Context, maxRetryTime time.Duration, name string, f func() error) error { var tot time.Duration for i := 1; ; i++ { extra := 1 err := f() if err == nil { return nil } s, ok := status.FromError(err) if !ok { // Non API errors are not retried return err } if !isRetriable(s) { return humanReadableError(err, s) } if isResourceExhausted(s) { extra = 10 } ns := RetrySleep(i, extra) tot += ns if tot > maxRetryTime { // Return human readable error return errorFromStatus(s) } clog.Warningf(ctx, "Error calling %s, attempt %d, retrying in %s: %v", name, i, ns, err) currentSleeper.Sleep(ns) } } func humanReadableError(err error, s *status.Status) error { var ndr *metadata.NotDefinedError if errors.As(err, &ndr) { return fmt.Errorf("no service account set for instance") } return errorFromStatus(s) } func errorFromStatus(s *status.Status) error { return fmt.Errorf("code: %q, message: %q, details: %q", s.Code(), s.Message(), s.Details()) } func isRetriable(s *status.Status) bool { switch s.Code() { case codes.Aborted, codes.DeadlineExceeded, codes.Internal, codes.ResourceExhausted, codes.Unavailable: return true default: return false } } func isResourceExhausted(s *status.Status) bool { return s.Code() == codes.ResourceExhausted } type sleeper interface { Sleep(d time.Duration) } type defaultSleeper struct{} func (ds defaultSleeper) Sleep(d time.Duration) { time.Sleep(d) } osconfig-20250416.02/retryutil/retry_test.go000066400000000000000000000165311477773331400206320ustar00rootroot00000000000000package retryutil import ( "context" "fmt" "testing" "time" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func TestRetrySleep(t *testing.T) { tests := []struct { base int extra int expectedLowerBound time.Duration expectedUpperBound time.Duration }{ {base: 1, extra: 0, expectedLowerBound: 1 * time.Second, expectedUpperBound: 2 * time.Second}, {base: 2, extra: 0, expectedLowerBound: 4 * time.Second, expectedUpperBound: 6 * time.Second}, {base: 3, extra: 0, expectedLowerBound: 9 * time.Second, expectedUpperBound: 12 * time.Second}, {base: 1, extra: 5, expectedLowerBound: 6 * time.Second, expectedUpperBound: 12 * time.Second}, {base: 2, extra: 5, expectedLowerBound: 14 * time.Second, expectedUpperBound: 21 * time.Second}, {base: 3, extra: 5, expectedLowerBound: 24 * time.Second, expectedUpperBound: 32 * time.Second}, {base: 1, extra: 10, expectedLowerBound: 11 * time.Second, expectedUpperBound: 22 * time.Second}, {base: 2, extra: 10, expectedLowerBound: 24 * time.Second, expectedUpperBound: 36 * time.Second}, {base: 3, extra: 10, expectedLowerBound: 39 * time.Second, expectedUpperBound: 52 * time.Second}, } // Run each test case n times as RetrySleep have randomized nature. n := 100 for i, tt := range tests { t.Run(fmt.Sprintf("Test case %d", i), func(t *testing.T) { for i := 0; i < n; i++ { rd := RetrySleep(tt.base, tt.extra) if rd < tt.expectedLowerBound || rd > tt.expectedUpperBound { t.Errorf("unexpected sleep duration, expected range [%s, %s] got %s", tt.expectedLowerBound, tt.expectedUpperBound, rd) } } }) } } func TestRetryFunc(t *testing.T) { tests := []struct { name string maxRetryTime time.Duration expectedToFailTimes int failWith error expectedError error funcCalledLowerBound int funcCalledUpperBound int }{ { name: "Function does not fail", maxRetryTime: time.Minute, expectedToFailTimes: 0, failWith: nil, expectedError: nil, funcCalledLowerBound: 1, funcCalledUpperBound: 1, }, { name: "Function does fail, retry does not work", maxRetryTime: time.Second, expectedToFailTimes: 5, failWith: fmt.Errorf("failure"), expectedError: fmt.Errorf("failure"), funcCalledLowerBound: 1, funcCalledUpperBound: 2, }, { name: "Function does fail, retry does work", maxRetryTime: time.Minute, expectedToFailTimes: 5, failWith: fmt.Errorf("failure"), expectedError: nil, funcCalledLowerBound: 5, funcCalledUpperBound: 5, }, } currentSleeper = noOpSleeper{} // Avoid calling time.Sleep to speed up tests description := "test" ctx := context.Background() for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { f, count := callsCollector(tt.expectedToFailTimes, tt.failWith) err := RetryFunc(ctx, tt.maxRetryTime, description, f) if safeString(err) != safeString(tt.expectedError) { t.Errorf("unexpected error, exepcted %q, got %q", safeString(tt.expectedError), safeString(err)) } if *count < tt.funcCalledLowerBound || *count > tt.funcCalledUpperBound { t.Errorf("unexpected function calls count, expected range [%d, %d], got %d", tt.funcCalledLowerBound, tt.funcCalledUpperBound, *count) } }) } } func TestRetryAPICall(t *testing.T) { tests := []struct { name string maxRetryTime time.Duration callsCollector func(int, error) (func() error, *int) expectedToFailTimes int failWith error expectedError error funcCalledLowerBound int funcCalledUpperBound int }{ { name: "Function does not fail", maxRetryTime: time.Minute, expectedToFailTimes: 0, failWith: nil, expectedError: nil, funcCalledLowerBound: 1, funcCalledUpperBound: 1, }, { name: "Function fail with non API error", maxRetryTime: time.Second, expectedToFailTimes: 5, failWith: fmt.Errorf("failure"), expectedError: fmt.Errorf("failure"), funcCalledLowerBound: 1, funcCalledUpperBound: 1, }, { name: "Function fail with non retriable API error", maxRetryTime: time.Minute, expectedToFailTimes: 5, failWith: status.Error(codes.InvalidArgument, "invalid"), expectedError: fmt.Errorf("code: \"InvalidArgument\", message: \"invalid\", details: []"), funcCalledLowerBound: 1, funcCalledUpperBound: 1, }, { name: "Function fail with retriable API error, retry does not help", maxRetryTime: 2 * time.Minute, expectedToFailTimes: 10, failWith: status.Error(codes.DeadlineExceeded, "invalid"), expectedError: fmt.Errorf("code: \"DeadlineExceeded\", message: \"invalid\", details: []"), funcCalledLowerBound: 6, funcCalledUpperBound: 7, }, { name: "Function fail with retriable API error, retry does help", maxRetryTime: 2 * time.Minute, expectedToFailTimes: 3, failWith: status.Error(codes.DeadlineExceeded, "invalid"), expectedError: nil, funcCalledLowerBound: 3, funcCalledUpperBound: 3, }, { name: "Function fail with ResourceExhausted error, additional time between retries", maxRetryTime: 2 * time.Minute, expectedToFailTimes: 10, failWith: status.Error(codes.ResourceExhausted, "invalid"), expectedError: fmt.Errorf("code: \"ResourceExhausted\", message: \"invalid\", details: []"), funcCalledLowerBound: 3, funcCalledUpperBound: 4, }, } currentSleeper = noOpSleeper{} // Avoid calling time.Sleep to speed up tests description := "test" ctx := context.Background() for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { f, count := callsCollector(tt.expectedToFailTimes, tt.failWith) err := RetryAPICall(ctx, tt.maxRetryTime, description, f) if safeString(err) != safeString(tt.expectedError) { t.Errorf("unexpected error, exepcted %q, got %q", safeString(tt.expectedError), safeString(err)) } if *count < tt.funcCalledLowerBound || *count > tt.funcCalledUpperBound { t.Errorf("unexpected function calls count, expected range [%d, %d], got %d", tt.funcCalledLowerBound, tt.funcCalledUpperBound, *count) } }) } } func Test_defaultSleeper(t *testing.T) { sleeper := defaultSleeper{} timeToSleep := 200 * time.Millisecond before := time.Now() sleeper.Sleep(timeToSleep) after := time.Now() elapsed := after.Sub(before) // Tolerate 10% difference to reduce test flakiness. maxTimeDifference := timeToSleep / 10 if abs(elapsed.Milliseconds()-timeToSleep.Milliseconds()) > maxTimeDifference.Milliseconds() { t.Errorf("sleeper.Sleep, elapsed time %s bigger than expected %s", elapsed, timeToSleep) } } func abs(d int64) int64 { if d < 0 { return d * -1 } return d } func safeString(err error) string { if err == nil { return "" } return err.Error() } func callsCollector(expectedToFailTimes int, failWith error) (func() error, *int) { var c int return func() error { c++ if expectedToFailTimes <= c { return nil } return failWith }, &c } type noOpSleeper struct{} func (noOpSleeper) Sleep(d time.Duration) { /*no op*/ } osconfig-20250416.02/tasker/000077500000000000000000000000001477773331400153175ustar00rootroot00000000000000osconfig-20250416.02/tasker/tasker.go000066400000000000000000000035151477773331400171430ustar00rootroot00000000000000// Copyright 2018 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package tasker is a task queue for the osconfig_agent. package tasker import ( "context" "runtime/debug" "sync" "github.com/GoogleCloudPlatform/osconfig/agentconfig" "github.com/GoogleCloudPlatform/osconfig/clog" ) var ( tc chan *task wg sync.WaitGroup mx sync.Mutex ) func initTasker(ctx context.Context) { tc = make(chan *task) go tasker(ctx) } type task struct { run func() name string } // Enqueue adds a task to the task queue. // Calls to Enqueue after a Close will block. func Enqueue(ctx context.Context, name string, f func()) { mx.Lock() if tc == nil { initTasker(ctx) } tc <- &task{name: name, run: f} mx.Unlock() } // Close prevents any further tasks from being enqueued and waits for the queue to empty. // Subsequent calls to Close() will block. func Close() { mx.Lock() close(tc) wg.Wait() } func tasker(ctx context.Context) { wg.Add(1) defer wg.Done() for { clog.Debugf(ctx, "Waiting for tasks to run.") select { case t, ok := <-tc: // Indicates an empty and closed channel. if !ok { return } clog.Debugf(ctx, "Tasker running %q.", t.name) t.run() clog.Debugf(ctx, "Finished task %q.", t.name) if agentconfig.FreeOSMemory() { debug.FreeOSMemory() } } } } osconfig-20250416.02/tasker/tasker_test.go000066400000000000000000000023241477773331400201770ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package tasker import ( "context" "strconv" "testing" ) var notes []int // TestEnqueueTaskRunSequentially to set sequential // execution of tasks in tasker func TestEnqueueTaskRunSequentially(t *testing.T) { times := 10000 for i := 0; i < times; i++ { addToQueue(i) } Close() if len(notes) != times { t.Fatalf("len(notes) != times, %d != %d", len(notes), times) } for i := 1; i < times; i++ { if notes[i] < notes[i-1] { t.Errorf("task(%d) expected to run earlier", i) } } } func addToQueue(i int) { Enqueue(context.Background(), strconv.Itoa(i), func() { notes = append(notes, i) }) } osconfig-20250416.02/util/000077500000000000000000000000001477773331400150035ustar00rootroot00000000000000osconfig-20250416.02/util/mocks/000077500000000000000000000000001477773331400161175ustar00rootroot00000000000000osconfig-20250416.02/util/mocks/match.go000066400000000000000000000022651477773331400175470ustar00rootroot00000000000000// Copyright 2023 Canonical Ltd. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package utilmocks import ( "fmt" exec "os/exec" gomock "github.com/golang/mock/gomock" ) type eqCmdMatcher struct { x *exec.Cmd } func (e eqCmdMatcher) Matches(x any) bool { xCmd, ok := x.(*exec.Cmd) if !ok { return false } if fmt.Sprintf("%s", e.x.Env) != fmt.Sprintf("%s", xCmd.Env) { return false } return e.x.String() == xCmd.String() } func (e eqCmdMatcher) String() string { return fmt.Sprintf("is equal to %v (env: %s)", e.x, e.x.Env) } // EqCmd returns a matcher that matches on equality of exec.Cmd func EqCmd(x *exec.Cmd) gomock.Matcher { return eqCmdMatcher{x} } osconfig-20250416.02/util/mocks/mock_command_runner.go000066400000000000000000000042441477773331400224720ustar00rootroot00000000000000// Copyright 2020 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Code generated by MockGen. DO NOT EDIT. // Source: github.com/GoogleCloudPlatform/osconfig/util (interfaces: CommandRunner) // Package utilmocks is a generated GoMock package. package utilmocks import ( context "context" gomock "github.com/golang/mock/gomock" exec "os/exec" reflect "reflect" ) // MockCommandRunner is a mock of CommandRunner interface type MockCommandRunner struct { ctrl *gomock.Controller recorder *MockCommandRunnerMockRecorder } // MockCommandRunnerMockRecorder is the mock recorder for MockCommandRunner type MockCommandRunnerMockRecorder struct { mock *MockCommandRunner } // NewMockCommandRunner creates a new mock instance func NewMockCommandRunner(ctrl *gomock.Controller) *MockCommandRunner { mock := &MockCommandRunner{ctrl: ctrl} mock.recorder = &MockCommandRunnerMockRecorder{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use func (m *MockCommandRunner) EXPECT() *MockCommandRunnerMockRecorder { return m.recorder } // Run mocks base method func (m *MockCommandRunner) Run(ctx context.Context, command *exec.Cmd) ([]byte, []byte, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Run", ctx, command) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].([]byte) ret2, _ := ret[2].(error) return ret0, ret1, ret2 } // Run indicates an expected call of Run func (mr *MockCommandRunnerMockRecorder) Run(ctx, command interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockCommandRunner)(nil).Run), ctx, command) } osconfig-20250416.02/util/util.go000066400000000000000000000122741477773331400163150ustar00rootroot00000000000000// Copyright 2019 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package util contains common functions for use in the osconfig agent. package util import ( "bytes" "context" "crypto/sha256" "encoding/hex" "fmt" "io" "math/rand" "os" "os/exec" "path/filepath" "runtime" "strconv" "strings" "time" "github.com/GoogleCloudPlatform/osconfig/clog" ) // Logger holds log functions. type Logger struct { Debugf func(string, ...any) Infof func(string, ...any) Warningf func(string, ...any) Errorf func(string, ...any) Fatalf func(string, ...any) } // SanitizePath ensures that relative path does not contains ".." to avoid directory traversal attacks. // As well run filepath.Clean to remove redundant path segments. func SanitizePath(path string) string { sanitized := strings.ReplaceAll(path, "../", "") return filepath.Clean(sanitized) } // NormPath transforms a windows path into an extended-length path as described in // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath // when not running on windows it will just return the input path. func NormPath(path string) (string, error) { if strings.HasPrefix(path, `\\?\`) { return path, nil } path, err := filepath.Abs(path) if err != nil { return "", err } if runtime.GOOS != "windows" { return path, nil } return `\\?\` + strings.ReplaceAll(path, "/", `\`), nil } // Exists check for the existence of a file func Exists(name string) bool { if strings.TrimSpace(name) == "" { return false } if _, err := os.Stat(name); err != nil { return false } return true } // AtomicWriteFileStream attempts to atomically write data from the provided reader to the path // checking the checksum if provided. func AtomicWriteFileStream(r io.Reader, checksum, path string, mode os.FileMode) (string, error) { path, err := NormPath(path) if err != nil { return "", err } tmp, err := TempFile(filepath.Dir(path), filepath.Base(path), mode) if err != nil { return "", fmt.Errorf("unable to create temp file: %v", err) } tmpName := tmp.Name() // Make sure we cleanup on any errors. defer func() { if err != nil { tmp.Close() os.Remove(tmpName) } }() hasher := sha256.New() if _, err = io.Copy(io.MultiWriter(tmp, hasher), r); err != nil { return "", err } computed := hex.EncodeToString(hasher.Sum(nil)) if checksum != "" && !strings.EqualFold(checksum, computed) { return "", fmt.Errorf("got %q for checksum, expected %q", computed, checksum) } if err := tmp.Close(); err != nil { return "", err } return computed, os.Rename(tmpName, path) } // CommandRunner will execute the commands and return the results of that // execution. type CommandRunner interface { Run(ctx context.Context, command *exec.Cmd) ([]byte, []byte, error) } // DefaultRunner is a default CommandRunner. type DefaultRunner struct{} // Run takes precreated exec.Cmd and returns the stdout and stderr. func (r *DefaultRunner) Run(ctx context.Context, cmd *exec.Cmd) ([]byte, []byte, error) { clog.Debugf(ctx, "Running %q with args %q\n", cmd.Path, cmd.Args[1:]) var stdout, stderr bytes.Buffer cmd.Stdout = &stdout cmd.Stderr = &stderr err := cmd.Run() clog.DebugStructured( ctx, struct { Command string Args []string ExitCode any Stdout string Stderr string }{ Command: cmd.Path, Args: cmd.Args[1:], ExitCode: cmd.ProcessState.ExitCode(), Stdout: stdout.String(), Stderr: stderr.String(), }, "%s %q exit code: %d, output:\n%s", cmd.Path, cmd.Args[1:], cmd.ProcessState.ExitCode(), strings.ReplaceAll(stdout.String(), "\n", "\n ")) return stdout.Bytes(), stderr.Bytes(), err } // TempFile is a little bit like ioutil.TempFile but takes FileMode in // order to work nicely on Windows where File.Chmod is not supported. func TempFile(dir string, pattern string, mode os.FileMode) (f *os.File, err error) { r := strconv.Itoa(rand.New(rand.NewSource(time.Now().UnixNano())).Intn(99999)) name := filepath.Join(dir, pattern+r+".tmp") return os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, mode) } // AtomicWrite attempts to atomically write a file. func AtomicWrite(path string, content []byte, mode os.FileMode) (err error) { path, err = NormPath(path) if err != nil { return err } tmp, err := TempFile(filepath.Dir(path), filepath.Base(path), mode) if err != nil { return fmt.Errorf("unable to create temp file: %v", err) } tmpName := tmp.Name() // Make sure we cleanup on any errors. defer func() { if err != nil { tmp.Close() os.Remove(tmpName) } }() if _, err := tmp.Write(content); err != nil { return err } if err := tmp.Close(); err != nil { return err } return os.Rename(tmpName, path) } osconfig-20250416.02/util/util_test.go000066400000000000000000000017451477773331400173550ustar00rootroot00000000000000package util import ( "testing" ) func TestSanitizePath(t *testing.T) { tests := []struct { name string input string expectedOutput string }{ { name: "Basic file name", input: "test.yaml", expectedOutput: "test.yaml", }, { name: "Basic full path", input: "/x/test.yaml", expectedOutput: "/x/test.yaml", }, { name: "Relative path", input: "x/test.yaml", expectedOutput: "x/test.yaml", }, { name: "Relative path with traversal segment", input: "../x/test.yaml", expectedOutput: "x/test.yaml", }, { name: "Relative path with traversal segment", input: "/../x/test.yaml", expectedOutput: "/x/test.yaml", }, } for _, tt := range tests { if result := SanitizePath(tt.input); result != tt.expectedOutput { t.Errorf("Test %q failed, expectedOutput %q, got %q", tt.name, tt.expectedOutput, result) } } }