Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
devel:kubic
harbor-cli
harbor-cli-0.0.2.obscpio
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File harbor-cli-0.0.2.obscpio of Package harbor-cli
07070100000000000081A40000000000000000000000016717AEFE000000A0000000000000000000000000000000000000002000000000harbor-cli-0.0.2/.gitattributes/dagger.gen.go linguist-generated /internal/dagger/** linguist-generated /internal/querybuilder/** linguist-generated /internal/telemetry/** linguist-generated 07070100000001000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000001900000000harbor-cli-0.0.2/.github07070100000002000081A40000000000000000000000016717AEFE00000067000000000000000000000000000000000000002800000000harbor-cli-0.0.2/.github/dependabot.ymlversion: 2 updates: - package-ecosystem: gomod directory: "/" schedule: interval: daily07070100000003000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002300000000harbor-cli-0.0.2/.github/workflows07070100000004000081A40000000000000000000000016717AEFE00000487000000000000000000000000000000000000003600000000harbor-cli-0.0.2/.github/workflows/docker_publish.ymlname: Docker Publish on: push: tags: - "v*" jobs: docker-publish: runs-on: ubuntu-latest permissions: contents: write packages: write environment: production env: COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} COSIGN_KEY: ${{ secrets.COSIGN_KEY }} REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }} REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }} REGISTRY_ADDRESS: ${{ vars.REGISTRY_ADDRESS }} PUBLISH_ADDRESS: ${{ vars.PUBLISH_ADDRESS }} TAG: ${{ github.ref_name }} steps: - name: Checkout repo uses: actions/checkout@v4 with: fetch-depth: 0 - name: Call Docker-Publish Function uses: dagger/dagger-for-github@v6.13.0 with: version: "latest" verb: call args: "publish-image --source=. --cosign-password='${{ env.COSIGN_PASSWORD }}' --cosign-key='${{ env.COSIGN_KEY }}' --reg-username='${{ env.REGISTRY_USERNAME }}' --reg-password='${{ env.REGISTRY_PASSWORD }}' --reg-address='${{ env.REGISTRY_ADDRESS }}' --publish-address='${{ env.PUBLISH_ADDRESS }}' --tag='${{ env.TAG }}'" 07070100000005000081A40000000000000000000000016717AEFE000002F5000000000000000000000000000000000000003700000000harbor-cli-0.0.2/.github/workflows/publish_release.ymlname: Dagger Release Pipeline on: push: tags: - "v*" branches: [main] permissions: contents: write packages: write jobs: publish-release: if: startsWith(github.ref, 'refs/tags/') runs-on: ubuntu-latest steps: - name: Checkout repo uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Go uses: actions/setup-go@v5 with: go-version: "1.22.5" cache: true - name: Call Dagger Function uses: dagger/dagger-for-github@v6.13.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: version: "latest" verb: call args: release --source=. --github-token=${{ env.GITHUB_TOKEN }}07070100000006000081A40000000000000000000000016717AEFE00000586000000000000000000000000000000000000003400000000harbor-cli-0.0.2/.github/workflows/pull-request.ymlname: Dagger Pull Request Pipeline on: push: branches: [main] pull_request: paths-ignore: - '*.md' - 'assets/**' permissions: contents: write # This is required for actions/checkout packages: write # This is required for publishing the package jobs: test-code: if: github.event_name == 'pull_request' runs-on: ubuntu-latest steps: - name: Checkout repo uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Go uses: actions/setup-go@v5 with: go-version: "1.22.5" cache: true - name: Install dependencies run: go mod download - name: Test with the Go CLI run: go test -v ./... - name: Call Linting Function uses: dagger/dagger-for-github@v6.13.0 with: version: "latest" verb: call args: lint --source=. - name: Call Build Function uses: dagger/dagger-for-github@v6.1.0 with: version: "latest" verb: call args: build --source=. - name: Call Pull-Request Function uses: dagger/dagger-for-github@v6.13.0 if: always() env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: version: "latest" verb: call args: pull-request --source=. --github-token=${{ env.GITHUB_TOKEN }} 07070100000007000081A40000000000000000000000016717AEFE0000020D000000000000000000000000000000000000001C00000000harbor-cli-0.0.2/.gitignore# If you prefer the allow list template instead of the deny list, see community template: # https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore # # Binaries for programs and plugins *.exe *.exe~ *.dll *.so *.dylib # Test binary, built with `go test -c` *.test # Output of the go coverage tool, specifically when used with LiteIDE *.out # Dependency directories (remove the comment below to include it) # vendor/ # Go workspace file go.work /bin /harbor dist/ /dagger.gen.go /internal/* 07070100000008000081A40000000000000000000000016717AEFE000000A2000000000000000000000000000000000000002000000000harbor-cli-0.0.2/.golangci.yaml linters: enable: # default linters - errcheck - gosimple - govet - ineffassign - staticcheck - typecheck - unused - gofmt 07070100000009000081A40000000000000000000000016717AEFE0000083C000000000000000000000000000000000000002200000000harbor-cli-0.0.2/.goreleaser.yamlversion: 2 project_name: harbor before: hooks: - go mod tidy builds: - main: ./cmd/harbor/main.go env: - CGO_ENABLED=0 ldflags: - -w -s -X github.com/goharbor/harbor-cli/cmd/harbor/internal/version.GitCommit={{.FullCommit}} goos: - linux - windows - darwin goarch: - amd64 - arm64 ignore: - goos: windows goarch: arm - goos: windows goarch: arm64 mod_timestamp: "{{ .CommitTimestamp }}" archives: - format: tar.gz format_overrides: - goos: windows format: zip nfpms: - package_name: harbor homepage: https://github.com/goharbor/harbor-cli/ maintainer: Vadim Bauer description: |- [Sandbox] Official Harbor CLI formats: - rpm - deb - apk - archlinux sboms: - artifacts: archive checksum: name_template: 'checksums.txt' snapshot: version_template: "{{ .Tag }}-next" release: name_template: "HarborCLI {{.Tag}}" draft: false # Set to false to ensure that releases are published, not kept as drafts prerelease: auto # Auto-detect prereleases based on tag disable: false # Ensure release publishing is enabled github: owner: goharbor # Your GitHub repository owner name: harbor-cli # Your GitHub repository name changelog: use: github format: "{{.SHA}}: {{.Message}} (@{{.AuthorUsername}})" sort: asc filters: exclude: - "^docs:" - "^test:" - "merge conflict" groups: - title: Dependency updates regexp: '^.*?(.+)\(deps\)!?:.+$' order: 300 - title: "New Features" regexp: '^.*?feat(\(.+\))??!?:.+$' order: 100 - title: "Security updates" regexp: '^.*?sec(\(.+\))??!?:.+$' order: 150 - title: "Bug fixes" regexp: '^.*?(fix|refactor)(\(.+\))??!?:.+$' order: 200 - title: "Documentation updates" regexp: ^.*?docs?(\(.+\))??!?:.+$ order: 400 - title: "Build process updates" regexp: ^.*?(build|ci)(\(.+\))??!?:.+$ order: 400 - title: Other work order: 9999 0707010000000A000081A40000000000000000000000016717AEFE00000081000000000000000000000000000000000000002400000000harbor-cli-0.0.2/CODE_OF_CONDUCT.md# Code of Conduct Harbor follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). 0707010000000B000081A40000000000000000000000016717AEFE00000000000000000000000000000000000000000000002100000000harbor-cli-0.0.2/CONTRIBUTING.md0707010000000C000081A40000000000000000000000016717AEFE00002C5D000000000000000000000000000000000000001900000000harbor-cli-0.0.2/LICENSE 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. 0707010000000D000081A40000000000000000000000016717AEFE0000178D000000000000000000000000000000000000001B00000000harbor-cli-0.0.2/README.md ![harbor-3](https://github.com/goharbor/harbor-cli/assets/70086051/835ab686-1cce-4ac7-bc57-05a35c2b73cc) **Welcome to the Harbor CLI project! This powerful command-line tool facilitates seamless interaction with the Harbor container registry. It simplifies various tasks such as creating, updating, and managing projects, registries, and other resources in Harbor.** # Project Scope π§ͺ The Harbor CLI is designed to enhance your interaction with the Harbor container registry. Built on Golang, it offers a user-friendly interface to perform various tasks related to projects, registries, and more. Whether you're creating, updating, or managing resources, the Harbor CLI streamlines your workflow efficiently. # Project Features π€― πΉ Get details about projects, registries, repositories and more <br> πΉ Create new projects, registries, and other resources <br> πΉ Delete projects, registries, and other resources <br> πΉ Run commands with various flags for enhanced functionality <br> πΉ More features coming soon... π§ # Example Commandsπ‘ ```bash β harbor --help Official Harbor CLI Usage: harbor [command] Examples: // Base command: harbor // Display help about the command: harbor help Available Commands: completion Generate the autocompletion script for the specified shell help Help about any command login Log in to Harbor registry project Manage projects and assign resources to them registry Manage registries repo Manage repositories user Manage users version Version of Harbor CLI Flags: --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/bishal/.harbor/config.yaml") -h, --help help for harbor -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output Use "harbor [command] --help" for more information about a command. ``` #### Log in to Harbor Registry ```bash harbor login demo.goharbor.io -u admin -p Harbor12345 ``` #### Create a New Project ```bash harbor project create ``` #### List all Projects ```bash harbor project list # output ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β Project Name Access Level Type Repo Count Creation Time β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β library public project 0 1 hour ago β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ ``` #### List all Repository in a Project ```bash harbor repo list # output ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β Name Artifacts Pulls Last Modified Time β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β library/harbor-cli 1 0 0 minute ago β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ ``` # Supported Platforms Platform | Status --|-- Linux | β macOS | β Windows | β # Installation ## Linux and MacOS Homebrew is the recommended way to install Harbor CLI on MacOS and Linux. ## Windows ```shell winget install harbor ``` # Build From Source Make sure you have latest [Dagger](https://docs.dagger.io/) installed in your system. ```bash git clone https://github.com/goharbor/harbor-cli.git dagger call build ``` # Community * **Twitter:** [@project_harbor](https://twitter.com/project_harbor) * **User Group:** Join Harbor user email group: [harbor-users@lists.cncf.io](https://lists.cncf.io/g/harbor-users) to get update of Harbor's news, features, releases, or to provide suggestion and feedback. * **Developer Group:** Join Harbor developer group: [harbor-dev@lists.cncf.io](https://lists.cncf.io/g/harbor-dev) for discussion on Harbor development and contribution. * **Slack:** Join Harbor's community for discussion and ask questions: [Cloud Native Computing Foundation](https://slack.cncf.io/), channel: [#harbor](https://cloud-native.slack.com/messages/harbor/), [#harbor-dev](https://cloud-native.slack.com/messages/harbor-dev/) and [#harbor-cli](https://cloud-native.slack.com/messages/harbor-cli/). # License This project is licensed under the Apache 2.0 License. See the [LICENSE](https://github.com/goharbor/harbor-cli/blob/main/LICENSE) file for details. # Acknowledgements This project is maintained by the Harbor community. We thank all our contributors and users for their support. # β€οΈ Show your support For any questions or issues, please open an issue on our [GitHub Issues](https://github.com/goharbor/harbor-cli/issues) page.<br> Give a β if this project helped you, Thank YOU! 0707010000000E000081A40000000000000000000000016717AEFE00000DD3000000000000000000000000000000000000001C00000000harbor-cli-0.0.2/RELEASE.md## Overview This document provides a step-by-step guide for maintainers to create and publish a release for the project using GoReleaser. The release process is automated via GitHub Actions, and includes generating a changelog, signing the release, and pushing artifacts to the specified container registry. ## Prerequisites Before creating a release, ensure the following: - You have **write access** to the repository. - The required **repository secrets** and **environment variables** are set. - You have **cosign** installed locally to generate the signing key-pair for release verification. --- ### 1. Set Up Cosign Key-Pair Before releasing, you need to generate a cosign key-pair (in local env) to sign the release. **Steps**: 1. Install cosign (if not installed): ```bash cosign install ``` 2. Generate a new cosign key-pair: ```bash cosign generate-key-pair ``` This will generate two files: - `cosign.key` (the private key) - `cosign.pub` (the public key) 3. Set the **private key** and **password** as GitHub repository secrets: - **COSIGN_KEY**: Content of `cosign.key` - **COSIGN_PASSWORD**: Password used to generate the key-pair Navigate to **Settings > Secrets and Variables > Repository secrets** and add both secrets. --- ### 2. Configure GitHub Environments Next, create a new GitHub environment called **`production`** with the necessary secrets and variables for the release. #### Secrets for the Production Environment 1. **REGISTRY_USERNAME**: The username for authenticating with the container registry. 2. **REGISTRY_PASSWORD**: The password for authenticating with the container registry. **Steps**: - Go to **Settings > Environments**. - Click **Add environment** and name it `production`. - Add the secrets **REGISTRY_USERNAME** and **REGISTRY_PASSWORD** under the `production` environment. #### Environment Variables for the Production Environment 1. **REGISTRY_ADDRESS**: The address of the registry (e.g., `registry.bupd.xyz`). 2. **PUBLISH_ADDRESS**: The address to which the CLI artifacts will be published (e.g., `registry.bupd.xyz/harbor/cli`). **Steps**: - After adding secrets, add the following environment variables under `production`: - **REGISTRY_ADDRESS** - **PUBLISH_ADDRESS** --- ### 3. Create a GitHub Release Once the secrets and environment are set, follow these steps to create a release: 1. Go to the **GitHub repository** and click on **Releases**. 2. Click **Draft a new release**. 3. In the **Tag version** field, specify the version number (e.g., `v0.2.0`). 4. **Do not add a description**βthe changelog will be generated automatically via GitHub Actions. 5. Click **Publish Release**. Once the release is created, the GitHub Actions workflow will: - Generate the release changelog. - Sign the release using `cosign` (with the `COSIGN_KEY` and `COSIGN_PASSWORD`). - Push the CLI binaries to the container registry. --- ### 4. Verifying the Release Once the release is completed, you can verify it by: - Checking the GitHub Actions log for successful execution. - Pulling the image or artifact from the registry using: ```bash # example docker pull registry.bupd.xyz/harbor/cli:v0.2.0 ``` --- ### 5. Troubleshooting - **Missing GITHUB_TOKEN, GITLAB_TOKEN, or GITEA_TOKEN**: Ensure the required environment variables are set in GitHub secrets and accessible to the workflow. - **Error Signing Release**: Double-check that the `COSIGN_KEY` and `COSIGN_PASSWORD` secrets are correctly set in GitHub. --- 0707010000000F000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000001500000000harbor-cli-0.0.2/cmd07070100000010000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000001C00000000harbor-cli-0.0.2/cmd/harbor07070100000011000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002500000000harbor-cli-0.0.2/cmd/harbor/internal07070100000012000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002D00000000harbor-cli-0.0.2/cmd/harbor/internal/version07070100000013000081A40000000000000000000000016717AEFE0000025C000000000000000000000000000000000000003800000000harbor-cli-0.0.2/cmd/harbor/internal/version/version.gopackage version import "runtime/debug" var ( Version = "0.1.0" GitCommit = "" BuildTime = "" ReleaseChannel = "dev" GoVersion = "" OS = func() string { if info, ok := debug.ReadBuildInfo(); ok { for _, setting := range info.Settings { if setting.Key == "GOOS" { return setting.Value } } } return "" } Arch = func() string { if info, ok := debug.ReadBuildInfo(); ok { for _, setting := range info.Settings { if setting.Key == "GOARCH" { return setting.Value } } } return "" } System = OS() + "/" + Arch() ) 07070100000014000081A40000000000000000000000016717AEFE000000A5000000000000000000000000000000000000002400000000harbor-cli-0.0.2/cmd/harbor/main.gopackage main import ( "os" "github.com/goharbor/harbor-cli/cmd/harbor/root" ) func main() { err := root.RootCmd().Execute() if err != nil { os.Exit(1) } } 07070100000015000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002100000000harbor-cli-0.0.2/cmd/harbor/root07070100000016000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002A00000000harbor-cli-0.0.2/cmd/harbor/root/artifact07070100000017000081A40000000000000000000000016717AEFE000001A4000000000000000000000000000000000000003100000000harbor-cli-0.0.2/cmd/harbor/root/artifact/cmd.gopackage artifact import ( "github.com/spf13/cobra" ) func Artifact() *cobra.Command { cmd := &cobra.Command{ Use: "artifact", Short: "Manage artifacts", Long: `Manage artifacts in Harbor Repository`, Example: ` harbor artifact list`, } cmd.AddCommand( ListArtifactCommand(), InfoArtifactCommmand(), DeleteArtifactCommand(), ScanArtifactCommand(), ArtifactTagsCmd(), ) return cmd } 07070100000018000081A40000000000000000000000016717AEFE000003C5000000000000000000000000000000000000003400000000harbor-cli-0.0.2/cmd/harbor/root/artifact/delete.gopackage artifact import ( "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" "github.com/goharbor/harbor-cli/pkg/utils" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) func DeleteArtifactCommand() *cobra.Command { cmd := &cobra.Command{ Use: "delete", Short: "delete an artifact", Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { var err error if len(args) > 0 { projectName, repoName, reference := utils.ParseProjectRepoReference(args[0]) err = api.DeleteArtifact(projectName, repoName, reference) } else { projectName := prompt.GetProjectNameFromUser() repoName := prompt.GetRepoNameFromUser(projectName) reference := prompt.GetReferenceFromUser(repoName, projectName) err = api.DeleteArtifact(projectName, repoName, reference) } if err != nil { log.Errorf("failed to delete an artifact: %v", err) } }, } return cmd } 07070100000019000081A40000000000000000000000016717AEFE0000041A000000000000000000000000000000000000003200000000harbor-cli-0.0.2/cmd/harbor/root/artifact/info.gopackage artifact import ( "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" "github.com/goharbor/harbor-cli/pkg/utils" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) func InfoArtifactCommmand() *cobra.Command { cmd := &cobra.Command{ Use: "info", Short: "Get info of an artifact", Long: `Get info of an artifact`, Example: `harbor artifact info <project>/<repository>/<reference>`, Run: func(cmd *cobra.Command, args []string) { var err error if len(args) > 0 { projectName, repoName, reference := utils.ParseProjectRepoReference(args[0]) err = api.InfoArtifact(projectName, repoName, reference) } else { projectName := prompt.GetProjectNameFromUser() repoName := prompt.GetRepoNameFromUser(projectName) reference := prompt.GetReferenceFromUser(repoName, projectName) err = api.InfoArtifact(projectName, repoName, reference) } if err != nil { log.Errorf("failed to get info of an artifact: %v", err) } }, } return cmd } 0707010000001A000081A40000000000000000000000016717AEFE0000043F000000000000000000000000000000000000003200000000harbor-cli-0.0.2/cmd/harbor/root/artifact/list.gopackage artifact import ( "github.com/goharbor/go-client/pkg/sdk/v2.0/client/artifact" "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" "github.com/goharbor/harbor-cli/pkg/utils" artifactViews "github.com/goharbor/harbor-cli/pkg/views/artifact/list" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) func ListArtifactCommand() *cobra.Command { cmd := &cobra.Command{ Use: "list", Short: "list artifacts within a repository", Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { var err error var resp artifact.ListArtifactsOK if len(args) > 0 { projectName, repoName := utils.ParseProjectRepo(args[0]) resp, err = api.ListArtifact(projectName, repoName) } else { projectName := prompt.GetProjectNameFromUser() repoName := prompt.GetRepoNameFromUser(projectName) resp, err = api.ListArtifact(projectName, repoName) } if err != nil { log.Errorf("failed to list artifacts: %v", err) } artifactViews.ListArtifacts(resp.Payload) }, } return cmd } 0707010000001B000081A40000000000000000000000016717AEFE00000922000000000000000000000000000000000000003200000000harbor-cli-0.0.2/cmd/harbor/root/artifact/scan.gopackage artifact import ( "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" "github.com/goharbor/harbor-cli/pkg/utils" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) func ScanArtifactCommand() *cobra.Command { cmd := &cobra.Command{ Use: "scan", Short: "Scan an artifact", Long: `Scan an artifact in Harbor Repository`, Example: `harbor artifact scan start <project>/<repository>/<reference>`, } cmd.AddCommand( StartScanArtifactCommand(), StopScanArtifactCommand(), // LogScanArtifactCommand(), ) return cmd } func StartScanArtifactCommand() *cobra.Command { cmd := &cobra.Command{ Use: "start", Short: "Start a scan of an artifact", Long: `Start a scan of an artifact in Harbor Repository`, Example: `harbor artifact scan start <project>/<repository>/<reference>`, Run: func(cmd *cobra.Command, args []string) { var err error if len(args) > 0 { projectName, repoName, reference := utils.ParseProjectRepoReference(args[0]) err = api.StartScanArtifact(projectName, repoName, reference) } else { projectName := prompt.GetProjectNameFromUser() repoName := prompt.GetRepoNameFromUser(projectName) reference := prompt.GetReferenceFromUser(repoName, projectName) err = api.StartScanArtifact(projectName, repoName, reference) } if err != nil { log.Errorf("failed to start scan of artifact: %v", err) } }, } return cmd } func StopScanArtifactCommand() *cobra.Command { cmd := &cobra.Command{ Use: "stop", Short: "Stop a scan of an artifact", Long: `Stop a scan of an artifact in Harbor Repository`, Example: `harbor artifact scan stop <project>/<repository>/<reference>`, Run: func(cmd *cobra.Command, args []string) { var err error if len(args) > 0 { projectName, repoName, reference := utils.ParseProjectRepoReference(args[0]) err = api.StopScanArtifact(projectName, repoName, reference) } else { projectName := prompt.GetProjectNameFromUser() repoName := prompt.GetRepoNameFromUser(projectName) reference := prompt.GetReferenceFromUser(repoName, projectName) err = api.StopScanArtifact(projectName, repoName, reference) } if err != nil { log.Errorf("failed to stop scan of artifact: %v", err) } }, } return cmd } 0707010000001C000081A40000000000000000000000016717AEFE00000C9C000000000000000000000000000000000000003200000000harbor-cli-0.0.2/cmd/harbor/root/artifact/tags.gopackage artifact import ( "github.com/goharbor/go-client/pkg/sdk/v2.0/client/artifact" "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" "github.com/goharbor/harbor-cli/pkg/utils" "github.com/goharbor/harbor-cli/pkg/views/artifact/tags/create" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) func ArtifactTagsCmd() *cobra.Command { cmd := &cobra.Command{ Use: "tags", Short: "Manage tags of an artifact", Example: ` harbor artifact tags list <project>/<repository>/<reference>`, } cmd.AddCommand( ListTagsCmd(), DeleteTagsCmd(), CreateTagsCmd(), ) return cmd } func CreateTagsCmd() *cobra.Command { cmd := &cobra.Command{ Use: "create", Short: "Create a tag of an artifact", Example: `harbor artifact tags create <project>/<repository>/<reference> <tag>`, Run: func(cmd *cobra.Command, args []string) { var err error if len(args) > 0 { projectName, repoName, reference := utils.ParseProjectRepoReference(args[0]) tag := args[1] err = api.CreateTag(projectName, repoName, reference, tag) } else { var tagName string projectName := prompt.GetProjectNameFromUser() repoName := prompt.GetRepoNameFromUser(projectName) reference := prompt.GetReferenceFromUser(repoName, projectName) create.CreateTagView(&tagName) err = api.CreateTag(projectName, repoName, reference, tagName) } if err != nil { log.Errorf("failed to create tag: %v", err) } }, } return cmd } func ListTagsCmd() *cobra.Command { cmd := &cobra.Command{ Use: "list", Short: "List tags of an artifact", Example: `harbor artifact tags list <project>/<repository>/<reference>`, Run: func(cmd *cobra.Command, args []string) { var err error var resp artifact.ListTagsOK if len(args) > 0 { projectName, repoName, reference := utils.ParseProjectRepoReference(args[0]) resp, err = api.ListTags(projectName, repoName, reference) } else { projectName := prompt.GetProjectNameFromUser() repoName := prompt.GetRepoNameFromUser(projectName) reference := prompt.GetReferenceFromUser(repoName, projectName) resp, err = api.ListTags(projectName, repoName, reference) } if err != nil { log.Errorf("failed to list tags: %v", err) } log.Info(resp.Payload) }, } return cmd } func DeleteTagsCmd() *cobra.Command { cmd := &cobra.Command{ Use: "delete", Short: "Delete a tag of an artifact", Example: `harbor artifact tags delete <project>/<repository>/<reference> <tag>`, Run: func(cmd *cobra.Command, args []string) { var err error if len(args) > 0 { projectName, repoName, reference := utils.ParseProjectRepoReference(args[0]) tag := args[1] err = api.DeleteTag(projectName, repoName, reference, tag) } else { projectName := prompt.GetProjectNameFromUser() repoName := prompt.GetRepoNameFromUser(projectName) reference := prompt.GetReferenceFromUser(repoName, projectName) tag := prompt.GetTagFromUser(repoName, projectName, reference) err = api.DeleteTag(projectName, repoName, reference, tag) } if err != nil { log.Errorf("failed to delete tag: %v", err) } }, } return cmd } 0707010000001D000081A40000000000000000000000016717AEFE00000AB9000000000000000000000000000000000000002800000000harbor-cli-0.0.2/cmd/harbor/root/cmd.gopackage root import ( "fmt" "log" "os" "github.com/goharbor/harbor-cli/cmd/harbor/root/artifact" "github.com/goharbor/harbor-cli/cmd/harbor/root/project" "github.com/goharbor/harbor-cli/cmd/harbor/root/registry" repositry "github.com/goharbor/harbor-cli/cmd/harbor/root/repository" "github.com/goharbor/harbor-cli/cmd/harbor/root/user" "github.com/goharbor/harbor-cli/pkg/utils" "github.com/spf13/cobra" "github.com/spf13/viper" ) var ( output string cfgFile string verbose bool ) func InitConfig() { viper.SetConfigType("yaml") // cfgFile = viper.GetStering("config") viper.SetConfigFile(cfgFile) if cfgFile != utils.DefaultConfigPath { viper.SetConfigFile(cfgFile) } else { stat, err := os.Stat(utils.DefaultConfigPath) if !os.IsNotExist(err) && stat.Size() == 0 { log.Println("Config file is empty, creating a new one") } if os.IsNotExist(err) { log.Printf("Config file not found at %s, creating a new one", cfgFile) } if os.IsNotExist(err) || (!os.IsNotExist(err) && stat.Size() == 0) { if _, err := os.Stat(utils.HarborFolder); os.IsNotExist(err) { // Create the parent directory if it doesn't exist fmt.Println("Creating config file", utils.HarborFolder) if err := os.MkdirAll(utils.HarborFolder, os.ModePerm); err != nil { log.Fatal(err) } } err = utils.CreateConfigFile() if err != nil { log.Fatal(err) } err = utils.AddCredentialsToConfigFile(utils.Credential{}, cfgFile) if err != nil { log.Fatal(err) } log.Printf("Config file created at %s", cfgFile) } } if err := viper.ReadInConfig(); err != nil { log.Fatalf("Error reading config file: %s", err) } } func RootCmd() *cobra.Command { utils.SetLocation() root := &cobra.Command{ Use: "harbor", Short: "Official Harbor CLI", SilenceUsage: true, Long: "Official Harbor CLI", Example: ` // Base command: harbor // Display help about the command: harbor help `, // RunE: func(cmd *cobra.Command, args []string) error { // }, } cobra.OnInitialize(InitConfig) root.PersistentFlags().StringVarP(&output, "output-format", "o", "", "Output format. One of: json|yaml") root.PersistentFlags().StringVar(&cfgFile, "config", utils.DefaultConfigPath, "config file (default is $HOME/.harbor/config.yaml)") root.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "verbose output") err := viper.BindPFlag("output-format", root.PersistentFlags().Lookup("output-format")) if err != nil { fmt.Println(err.Error()) } root.AddCommand( versionCommand(), LoginCommand(), project.Project(), registry.Registry(), repositry.Repository(), user.User(), artifact.Artifact(), HealthCommand(), ) return root } 0707010000001E000081A40000000000000000000000016717AEFE00000221000000000000000000000000000000000000002B00000000harbor-cli-0.0.2/cmd/harbor/root/health.gopackage root import ( "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/views/health" "github.com/spf13/cobra" ) func HealthCommand() *cobra.Command { cmd := &cobra.Command{ Use: "health", Short: "Get the health status of Harbor components", RunE: func(cmd *cobra.Command, args []string) error { status, err := api.GetHealth() if err != nil { return err } health.PrintHealthStatus(status) return nil }, Example: ` # Get the health status of Harbor components`, } return cmd } 0707010000001F000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002800000000harbor-cli-0.0.2/cmd/harbor/root/labels07070100000020000081A40000000000000000000000016717AEFE0000000F000000000000000000000000000000000000002F00000000harbor-cli-0.0.2/cmd/harbor/root/labels/add.gopackage labels 07070100000021000081A40000000000000000000000016717AEFE000000B0000000000000000000000000000000000000002F00000000harbor-cli-0.0.2/cmd/harbor/root/labels/cmd.gopackage labels import "github.com/spf13/cobra" func Labels() *cobra.Command { cmd := &cobra.Command{ Use: "label", Short: "Manage labels in Harbor", } return cmd } 07070100000022000081A40000000000000000000000016717AEFE0000000F000000000000000000000000000000000000003200000000harbor-cli-0.0.2/cmd/harbor/root/labels/delete.gopackage labels 07070100000023000081A40000000000000000000000016717AEFE00000B9A000000000000000000000000000000000000002A00000000harbor-cli-0.0.2/cmd/harbor/root/login.gopackage root import ( "context" "fmt" "strings" "github.com/goharbor/go-client/pkg/harbor" "github.com/goharbor/go-client/pkg/sdk/v2.0/client/user" "github.com/goharbor/harbor-cli/pkg/utils" "github.com/goharbor/harbor-cli/pkg/views/login" "github.com/spf13/cobra" ) var ( serverAddress string Username string Password string Name string ) // LoginCommand creates a new `harbor login` command func LoginCommand() *cobra.Command { cmd := &cobra.Command{ Use: "login [server]", Short: "Log in to Harbor registry", Long: "Authenticate with Harbor Registry.", Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { if len(args) > 0 { serverAddress = args[0] } loginView := login.LoginView{ Server: serverAddress, Username: Username, Password: Password, Name: Name, } var err error if loginView.Server != "" && loginView.Username != "" && loginView.Password != "" && loginView.Name != "" { err = runLogin(loginView) } else { err = createLoginView(&loginView) } if err != nil { return err } return nil }, } flags := cmd.Flags() flags.StringVarP(&Name, "name", "", "", "name for the set of credentials") flags.StringVarP(&Username, "username", "u", "", "Username") flags.StringVarP(&Password, "password", "p", "", "Password") return cmd } // generateCredentialName creates a default credential name based on server and username func generateCredentialName(server, username string) string { if strings.HasPrefix(server, "http://") { server = strings.ReplaceAll(server, "http://", "") } if strings.HasPrefix(server, "https://") { server = strings.ReplaceAll(server, "https://", "") } if username != "" { return fmt.Sprintf("%s@%s", username, server) } return server } func createLoginView(loginView *login.LoginView) error { if loginView == nil { loginView = &login.LoginView{ Server: "", Username: "", Password: "", Name: "", } } login.CreateView(loginView) return runLogin(*loginView) } func runLogin(opts login.LoginView) error { opts.Server = utils.FormatUrl(opts.Server) clientConfig := &harbor.ClientSetConfig{ URL: opts.Server, Username: opts.Username, Password: opts.Password, } client := utils.GetClientByConfig(clientConfig) ctx := context.Background() _, err := client.User.GetCurrentUserInfo(ctx, &user.GetCurrentUserInfoParams{}) if err != nil { return fmt.Errorf("login failed, please check your credentials: %s", err) } if opts.Name == "" { opts.Name = generateCredentialName(opts.Server, opts.Username) } cred := utils.Credential{ Name: opts.Name, Username: opts.Username, Password: opts.Password, ServerAddress: opts.Server, } if err = utils.AddCredentialsToConfigFile(cred, utils.DefaultConfigPath); err != nil { return fmt.Errorf("failed to store the credential: %s", err) } return nil } 07070100000024000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002900000000harbor-cli-0.0.2/cmd/harbor/root/project07070100000025000081A40000000000000000000000016717AEFE000001A8000000000000000000000000000000000000003000000000harbor-cli-0.0.2/cmd/harbor/root/project/cmd.gopackage project import ( "github.com/spf13/cobra" ) func Project() *cobra.Command { cmd := &cobra.Command{ Use: "project", Short: "Manage projects and assign resources to them", Long: `Manage projects in Harbor`, Example: ` harbor project list`, } cmd.AddCommand( CreateProjectCommand(), DeleteProjectCommand(), ListProjectCommand(), ViewCommand(), LogsProjectCommmand(), ) return cmd } 07070100000026000081A40000000000000000000000016717AEFE000006A9000000000000000000000000000000000000003300000000harbor-cli-0.0.2/cmd/harbor/root/project/create.gopackage project import ( "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/views/project/create" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) // CreateProjectCommand creates a new `harbor create project` command func CreateProjectCommand() *cobra.Command { var opts create.CreateView cmd := &cobra.Command{ Use: "create [project name]", Short: "create project", Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { var err error createView := &create.CreateView{ ProjectName: opts.ProjectName, Public: opts.Public, RegistryID: opts.RegistryID, StorageLimit: opts.StorageLimit, ProxyCache: false, } if len(args) > 0 { opts.ProjectName = args[0] err = api.CreateProject(opts) } else { err = createProjectView(createView) } if err != nil { log.Errorf("failed to create project: %v", err) } }, } flags := cmd.Flags() flags.BoolVarP(&opts.Public, "public", "", false, "Project is public or private") flags.StringVarP(&opts.RegistryID, "registry-id", "", "", "ID of referenced registry when creating the proxy cache project") flags.StringVarP(&opts.StorageLimit, "storage-limit", "", "-1", "Storage quota of the project") flags.BoolVarP(&opts.ProxyCache, "proxy-cache", "", false, "Whether the project is a proxy cache project") return cmd } func createProjectView(createView *create.CreateView) error { if createView == nil { createView = &create.CreateView{ ProjectName: "", Public: false, RegistryID: "", StorageLimit: "-1", } } create.CreateProjectView(createView) return api.CreateProject(*createView) } 07070100000027000081A40000000000000000000000016717AEFE000002E6000000000000000000000000000000000000003300000000harbor-cli-0.0.2/cmd/harbor/root/project/delete.gopackage project import ( "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) // DeleteProjectCommand creates a new `harbor delete project` command func DeleteProjectCommand() *cobra.Command { cmd := &cobra.Command{ Use: "delete", Short: "delete project by name or id", Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { var err error if len(args) > 0 { err = api.DeleteProject(args[0]) } else { projectName := prompt.GetProjectNameFromUser() err = api.DeleteProject(projectName) } if err != nil { log.Errorf("failed to delete project: %v", err) } }, } return cmd } 07070100000028000081A40000000000000000000000016717AEFE00000530000000000000000000000000000000000000003100000000harbor-cli-0.0.2/cmd/harbor/root/project/list.gopackage project import ( "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/utils" list "github.com/goharbor/harbor-cli/pkg/views/project/list" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) // NewListProjectCommand creates a new `harbor list project` command func ListProjectCommand() *cobra.Command { var opts api.ListFlags cmd := &cobra.Command{ Use: "list", Short: "list project", Run: func(cmd *cobra.Command, args []string) { projects, err := api.ListProject(opts) if err != nil { log.Fatalf("failed to get projects list: %v", err) } FormatFlag := viper.GetString("output-format") if FormatFlag != "" { utils.PrintPayloadInJSONFormat(projects) return } list.ListProjects(projects.Payload) }, } flags := cmd.Flags() flags.StringVarP(&opts.Name, "name", "", "", "Name of the project") flags.Int64VarP(&opts.Page, "page", "", 1, "Page number") flags.Int64VarP(&opts.PageSize, "page-size", "", 10, "Size of per page") flags.BoolVarP(&opts.Public, "public", "", false, "Project is public or private") flags.StringVarP(&opts.Q, "query", "q", "", "Query string to query resources") flags.StringVarP(&opts.Sort, "sort", "", "", "Sort the resource list in ascending or descending order") return cmd } 07070100000029000081A40000000000000000000000016717AEFE0000042B000000000000000000000000000000000000003100000000harbor-cli-0.0.2/cmd/harbor/root/project/logs.gopackage project import ( "github.com/goharbor/go-client/pkg/sdk/v2.0/client/project" "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" "github.com/goharbor/harbor-cli/pkg/utils" auditLog "github.com/goharbor/harbor-cli/pkg/views/project/logs" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) func LogsProjectCommmand() *cobra.Command { cmd := &cobra.Command{ Use: "logs", Short: "get project logs", Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { var err error var resp *project.GetLogsOK if len(args) > 0 { resp, err = api.LogsProject(args[0]) } else { projectName := prompt.GetProjectNameFromUser() resp, err = api.LogsProject(projectName) } if err != nil { log.Fatalf("failed to get project logs: %v", err) } auditLog.LogsProject(resp.Payload) FormatFlag := viper.GetString("output-format") if FormatFlag != "" { utils.PrintPayloadInJSONFormat(resp) return } }, } return cmd } 0707010000002A000081A40000000000000000000000016717AEFE000002D5000000000000000000000000000000000000003100000000harbor-cli-0.0.2/cmd/harbor/root/project/view.gopackage project import ( "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) // GetProjectCommand creates a new `harbor get project` command func ViewCommand() *cobra.Command { cmd := &cobra.Command{ Use: "view [NAME|ID]", Short: "get project by name or id", Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { var err error if len(args) > 0 { err = api.GetProject(args[0]) } else { projectName := prompt.GetProjectNameFromUser() err = api.GetProject(projectName) } if err != nil { log.Errorf("failed to get project: %v", err) } }, } return cmd } 0707010000002B000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002A00000000harbor-cli-0.0.2/cmd/harbor/root/registry0707010000002C000081A40000000000000000000000016717AEFE000001B1000000000000000000000000000000000000003100000000harbor-cli-0.0.2/cmd/harbor/root/registry/cmd.gopackage registry import ( "github.com/spf13/cobra" ) func Registry() *cobra.Command { cmd := &cobra.Command{ Use: "registry", Short: "Manage registries", Long: `Manage registries in Harbor`, Example: ` harbor registry list`, } cmd.AddCommand( CreateRegistryCommand(), InfoRegistryCommand(), DeleteRegistryCommand(), ListRegistryCommand(), UpdateRegistryCommand(), ViewCommand(), ) return cmd } 0707010000002D000081A40000000000000000000000016717AEFE000008B9000000000000000000000000000000000000003400000000harbor-cli-0.0.2/cmd/harbor/root/registry/create.gopackage registry import ( "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/views/registry/create" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) // NewCreateRegistryCommand creates a new `harbor create registry` command func CreateRegistryCommand() *cobra.Command { var opts api.CreateRegView cmd := &cobra.Command{ Use: "create", Short: "create registry", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { var err error createView := &api.CreateRegView{ Name: opts.Name, Type: opts.Type, Description: opts.Description, URL: opts.URL, Credential: api.RegistryCredential{ AccessKey: opts.Credential.AccessKey, Type: opts.Credential.Type, AccessSecret: opts.Credential.AccessSecret, }, Insecure: opts.Insecure, } if opts.Name != "" && opts.Type != "" && opts.URL != "" { err = api.CreateRegistry(opts) } else { err = createRegistryView(createView) } if err != nil { log.Errorf("failed to create registry: %v", err) } }, } flags := cmd.Flags() flags.StringVarP(&opts.Name, "name", "", "", "Name of the registry") flags.StringVarP(&opts.Type, "type", "", "", "Type of the registry") flags.StringVarP(&opts.URL, "url", "", "", "Registry endpoint URL") flags.StringVarP(&opts.Description, "description", "", "", "Description of the registry") flags.BoolVarP( &opts.Insecure, "insecure", "", true, "Whether Harbor will verify the server certificate", ) flags.StringVarP( &opts.Credential.AccessKey, "credential-access-key", "", "", "Access key, e.g. user name when credential type is 'basic'", ) flags.StringVarP( &opts.Credential.AccessSecret, "credential-access-secret", "", "", "Access secret, e.g. password when credential type is 'basic'", ) flags.StringVarP( &opts.Credential.Type, "credential-type", "", "basic", "Credential type, such as 'basic', 'oauth'", ) return cmd } func createRegistryView(createView *api.CreateRegView) error { if createView == nil { createView = &api.CreateRegView{} } create.CreateRegistryView(createView) return api.CreateRegistry(*createView) } 0707010000002E000081A40000000000000000000000016717AEFE0000032E000000000000000000000000000000000000003400000000harbor-cli-0.0.2/cmd/harbor/root/registry/delete.gopackage registry import ( "strconv" "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) // NewDeleteRegistryCommand creates a new `harbor delete registry` command func DeleteRegistryCommand() *cobra.Command { cmd := &cobra.Command{ Use: "delete", Short: "delete registry by id", Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { var err error if len(args) > 0 { registryId, _ := strconv.ParseInt(args[0], 10, 64) err = api.DeleteRegistry(registryId) } else { registryId := prompt.GetRegistryNameFromUser() err = api.DeleteRegistry(registryId) } if err != nil { log.Errorf("failed to delete registry: %v", err) } }, } return cmd } 0707010000002F000081A40000000000000000000000016717AEFE000002D9000000000000000000000000000000000000003200000000harbor-cli-0.0.2/cmd/harbor/root/registry/info.gopackage registry import ( "strconv" "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) func InfoRegistryCommand() *cobra.Command { cmd := &cobra.Command{ Use: "info", Short: "get registry info", Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { var err error if len(args) > 0 { registryId, _ := strconv.ParseInt(args[0], 10, 64) err = api.InfoRegistry(registryId) } else { registryId := prompt.GetRegistryNameFromUser() err = api.InfoRegistry(registryId) } if err != nil { log.Errorf("failed to get registry info: %v", err) } }, } return cmd } 07070100000030000081A40000000000000000000000016717AEFE0000049C000000000000000000000000000000000000003200000000harbor-cli-0.0.2/cmd/harbor/root/registry/list.gopackage registry import ( "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/utils" "github.com/goharbor/harbor-cli/pkg/views/registry/list" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) // NewListRegistryCommand creates a new `harbor list registry` command func ListRegistryCommand() *cobra.Command { var opts api.ListFlags cmd := &cobra.Command{ Use: "list", Short: "list registry", Run: func(cmd *cobra.Command, args []string) { registry, err := api.ListRegistries(opts) if err != nil { log.Fatalf("failed to get projects list: %v", err) } FormatFlag := viper.GetString("output-format") if FormatFlag != "" { utils.PrintPayloadInJSONFormat(registry) return } list.ListRegistry(registry.Payload) }, } flags := cmd.Flags() flags.Int64VarP(&opts.Page, "page", "", 1, "Page number") flags.Int64VarP(&opts.PageSize, "page-size", "", 10, "Size of per page") flags.StringVarP(&opts.Q, "query", "q", "", "Query string to query resources") flags.StringVarP(&opts.Sort, "sort", "", "", "Sort the resource list in ascending or descending order") return cmd } 07070100000031000081A40000000000000000000000016717AEFE00000A4F000000000000000000000000000000000000003400000000harbor-cli-0.0.2/cmd/harbor/root/registry/update.gopackage registry import ( "strconv" "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" "github.com/goharbor/harbor-cli/pkg/views/registry/create" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) // NewUpdateRegistryCommand creates a new `harbor update registry` command func UpdateRegistryCommand() *cobra.Command { var opts api.CreateRegView cmd := &cobra.Command{ Use: "update", Short: "update registry", Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { var err error var registryId int64 updateView := &api.CreateRegView{ Name: opts.Name, Type: opts.Type, Description: opts.Description, URL: opts.URL, Credential: api.RegistryCredential{ AccessKey: opts.Credential.AccessKey, Type: opts.Credential.Type, AccessSecret: opts.Credential.AccessSecret, }, Insecure: opts.Insecure, } if len(args) > 0 { registryId, err = strconv.ParseInt(args[0], 10, 64) } else { registryId = prompt.GetRegistryNameFromUser() } if err != nil { log.Errorf("failed to parse registry id: %v", err) } if opts.Name != "" && opts.Type != "" && opts.URL != "" { err = api.UpdateRegistry(updateView, registryId) } else { err = updateRegistryView(updateView, registryId) } if err != nil { log.Errorf("failed to update registry: %v", err) } }, } flags := cmd.Flags() flags.StringVarP(&opts.Name, "name", "", "", "Name of the registry") flags.StringVarP(&opts.Type, "type", "", "", "Type of the registry") flags.StringVarP(&opts.URL, "url", "", "", "Registry endpoint URL") flags.StringVarP(&opts.Description, "description", "", "", "Description of the registry") flags.BoolVarP( &opts.Insecure, "insecure", "", true, "Whether or not the certificate will be verified when Harbor tries to access the server", ) flags.StringVarP( &opts.Credential.AccessKey, "credential-access-key", "", "", "Access key, e.g. user name when credential type is 'basic'", ) flags.StringVarP( &opts.Credential.AccessSecret, "credential-access-secret", "", "", "Access secret, e.g. password when credential type is 'basic'", ) flags.StringVarP( &opts.Credential.Type, "credential-type", "", "", "Credential type, such as 'basic', 'oauth'", ) return cmd } func updateRegistryView(updateView *api.CreateRegView, projectID int64) error { if updateView == nil { updateView = &api.CreateRegView{} } create.CreateRegistryView(updateView) return api.UpdateRegistry(updateView, projectID) } 07070100000032000081A40000000000000000000000016717AEFE000003B1000000000000000000000000000000000000003200000000harbor-cli-0.0.2/cmd/harbor/root/registry/view.gopackage registry import ( "strconv" "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) // NewGetRegistryCommand creates a new `harbor get registry` command func ViewCommand() *cobra.Command { cmd := &cobra.Command{ Use: "view", Short: "get registry by id", Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { var err error if len(args) > 0 { registryId, err := strconv.ParseInt(args[0], 10, 64) if err != nil { log.Errorf("failed to parse registry id: %v", err) } err = api.GetRegistry(registryId) if err != nil { log.Errorf("failed to get registry: %v", err) } } else { registryId := prompt.GetRegistryNameFromUser() err = api.GetRegistry(registryId) } if err != nil { log.Errorf("failed to get registry: %v", err) } }, } return cmd } 07070100000033000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002D00000000harbor-cli-0.0.2/cmd/harbor/root/replication07070100000034000081A40000000000000000000000016717AEFE0000014B000000000000000000000000000000000000003400000000harbor-cli-0.0.2/cmd/harbor/root/replication/cmd.gopackage replication import ( "github.com/spf13/cobra" ) func Replication() *cobra.Command { // replicationCmd represents the replication command. var replicationCmd = &cobra.Command{ Use: "replication", Aliases: []string{"repl"}, Short: "", Long: ``, } replicationCmd.AddCommand() return replicationCmd } 07070100000035000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002C00000000harbor-cli-0.0.2/cmd/harbor/root/repository07070100000036000081A40000000000000000000000016717AEFE00000139000000000000000000000000000000000000003300000000harbor-cli-0.0.2/cmd/harbor/root/repository/cmd.gopackage repository import "github.com/spf13/cobra" func Repository() *cobra.Command { cmd := &cobra.Command{ Use: "repo", Short: "Manage repositories", Long: `Manage repositories in Harbor context`, } cmd.AddCommand( ListRepositoryCommand(), RepoInfoCmd(), RepoDeleteCmd(), ) return cmd } 07070100000037000081A40000000000000000000000016717AEFE000003B1000000000000000000000000000000000000003600000000harbor-cli-0.0.2/cmd/harbor/root/repository/delete.gopackage repository import ( "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" "github.com/goharbor/harbor-cli/pkg/utils" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) func RepoDeleteCmd() *cobra.Command { cmd := &cobra.Command{ Use: "delete", Short: "Delete a repository", Example: ` harbor repository delete [project_name]/[repository_name]`, Long: `Delete a repository within a project in Harbor`, Run: func(cmd *cobra.Command, args []string) { var err error if len(args) > 0 { projectName, repoName := utils.ParseProjectRepo(args[0]) err = api.RepoDelete(projectName, repoName) } else { projectName := prompt.GetProjectNameFromUser() repoName := prompt.GetRepoNameFromUser(projectName) err = api.RepoDelete(projectName, repoName) } if err != nil { log.Errorf("failed to delete repository: %v", err) } }, } return cmd } 07070100000038000081A40000000000000000000000016717AEFE000003B6000000000000000000000000000000000000003400000000harbor-cli-0.0.2/cmd/harbor/root/repository/info.gopackage repository import ( "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" "github.com/goharbor/harbor-cli/pkg/utils" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) func RepoInfoCmd() *cobra.Command { cmd := &cobra.Command{ Use: "info", Short: "Get repository information", Example: ` harbor repo info <project_name>/<repo_name>`, Long: `Get information of a particular repository in a project`, Run: func(cmd *cobra.Command, args []string) { var err error if len(args) > 0 { projectName, repoName := utils.ParseProjectRepo(args[0]) err = api.RepoInfo(projectName, repoName) } else { projectName := prompt.GetProjectNameFromUser() repoName := prompt.GetRepoNameFromUser(projectName) err = api.RepoInfo(projectName, repoName) } if err != nil { log.Errorf("failed to get repository information: %v", err) } }, } return cmd } 07070100000039000081A40000000000000000000000016717AEFE00000388000000000000000000000000000000000000003400000000harbor-cli-0.0.2/cmd/harbor/root/repository/list.gopackage repository import ( "github.com/goharbor/go-client/pkg/sdk/v2.0/client/repository" "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" "github.com/goharbor/harbor-cli/pkg/views/repository/list" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) func ListRepositoryCommand() *cobra.Command { cmd := &cobra.Command{ Use: "list", Short: "list repositories within a project", Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { var err error var resp repository.ListRepositoriesOK if len(args) > 0 { resp, err = api.ListRepository(args[0]) } else { projectName := prompt.GetProjectNameFromUser() resp, err = api.ListRepository(projectName) } if err != nil { log.Errorf("failed to list repositories: %v", err) } list.ListRepositories(resp.Payload) }, } return cmd } 0707010000003A000081A40000000000000000000000016717AEFE00000013000000000000000000000000000000000000003600000000harbor-cli-0.0.2/cmd/harbor/root/repository/update.gopackage repository 0707010000003B000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002600000000harbor-cli-0.0.2/cmd/harbor/root/user0707010000003C000081A40000000000000000000000016717AEFE0000014F000000000000000000000000000000000000002D00000000harbor-cli-0.0.2/cmd/harbor/root/user/cmd.gopackage user import ( "github.com/spf13/cobra" ) func User() *cobra.Command { cmd := &cobra.Command{ Use: "user", Short: "Manage users", Long: `Manage users in Harbor`, Example: ` harbor user list`, } cmd.AddCommand( UserListCmd(), UserCreateCmd(), UserDeleteCmd(), ElevateUserCmd(), ) return cmd } 0707010000003D000081A40000000000000000000000016717AEFE00000556000000000000000000000000000000000000003000000000harbor-cli-0.0.2/cmd/harbor/root/user/create.gopackage user import ( "github.com/goharbor/harbor-cli/pkg/api" log "github.com/sirupsen/logrus" "github.com/goharbor/harbor-cli/pkg/views/user/create" "github.com/spf13/cobra" ) func UserCreateCmd() *cobra.Command { var opts create.CreateView cmd := &cobra.Command{ Use: "create", Short: "create user", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { var err error createView := &create.CreateView{ Email: opts.Email, Realname: opts.Realname, Comment: opts.Comment, Password: opts.Password, Username: opts.Username, } if opts.Email != "" && opts.Realname != "" && opts.Comment != "" && opts.Password != "" && opts.Username != "" { err = api.CreateUser(opts) } else { err = createUserView(createView) } if err != nil { log.Errorf("failed to create user: %v", err) } }, } flags := cmd.Flags() flags.StringVarP(&opts.Email, "email", "", "", "Email") flags.StringVarP(&opts.Realname, "realname", "", "", "Realname") flags.StringVarP(&opts.Comment, "comment", "", "", "Comment") flags.StringVarP(&opts.Password, "password", "", "", "Password") flags.StringVarP(&opts.Username, "username", "", "", "Username") return cmd } func createUserView(createView *create.CreateView) error { create.CreateUserView(createView) return api.CreateUser(*createView) } 0707010000003E000081A40000000000000000000000016717AEFE000002AD000000000000000000000000000000000000003000000000harbor-cli-0.0.2/cmd/harbor/root/user/delete.gopackage user import ( "strconv" "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) func UserDeleteCmd() *cobra.Command { cmd := &cobra.Command{ Use: "delete", Short: "delete user", Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { var err error if len(args) > 0 { userId, _ := strconv.ParseInt(args[0], 10, 64) err = api.DeleteUser(userId) } else { userId := prompt.GetUserIdFromUser() err = api.DeleteUser(userId) } if err != nil { log.Errorf("failed to delete user: %v", err) } }, } return cmd } 0707010000003F000081A40000000000000000000000016717AEFE00000380000000000000000000000000000000000000003100000000harbor-cli-0.0.2/cmd/harbor/root/user/elevate.gopackage user import ( "strconv" "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/prompt" "github.com/goharbor/harbor-cli/pkg/views" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) func ElevateUserCmd() *cobra.Command { cmd := &cobra.Command{ Use: "elevate", Short: "elevate user", Long: "elevate user to admin role", Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { var err error var userId int64 if len(args) > 0 { userId, _ = strconv.ParseInt(args[0], 10, 64) } else { userId = prompt.GetUserIdFromUser() } confirm, err := views.ConfirmElevation() if confirm { err = api.ElevateUser(userId) } else { log.Error("Permission denied for elevate user to admin.") } if err != nil { log.Errorf("failed to elevate user: %v", err) } }, } return cmd } 07070100000040000081A40000000000000000000000016717AEFE0000030E000000000000000000000000000000000000002E00000000harbor-cli-0.0.2/cmd/harbor/root/user/list.gopackage user import ( "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/utils" "github.com/goharbor/harbor-cli/pkg/views/user/list" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) func UserListCmd() *cobra.Command { cmd := &cobra.Command{ Use: "list", Short: "list users", Args: cobra.NoArgs, Aliases: []string{"ls"}, Run: func(cmd *cobra.Command, args []string) { response, err := api.ListUsers() if err != nil { log.Errorf("failed to list users: %v", err) return } FormatFlag := viper.GetString("output-format") if FormatFlag != "" { utils.PrintPayloadInJSONFormat(response.Payload) } else { list.ListUsers(response.Payload) } }, } return cmd } 07070100000041000081A40000000000000000000000016717AEFE00000341000000000000000000000000000000000000002C00000000harbor-cli-0.0.2/cmd/harbor/root/version.gopackage root import ( "fmt" "github.com/goharbor/harbor-cli/cmd/harbor/internal/version" "github.com/spf13/cobra" ) // versionCommand represents the version command func versionCommand() *cobra.Command { cmd := &cobra.Command{ Use: "version", Short: "Version of Harbor CLI", Long: `Get Harbor CLI version, git commit, go version, build time, release channel, os/arch, etc.`, Example: ` harbor version`, RunE: func(cmd *cobra.Command, args []string) error { return runVersion() }, } return cmd } func runVersion() error { fmt.Printf("Version: %s\n", version.Version) fmt.Printf("Go version: %s\n", version.GoVersion) fmt.Printf("Git commit: %s\n", version.GitCommit) fmt.Printf("Built: %s\n", version.BuildTime) fmt.Printf("OS/Arch: %s\n", version.System) return nil } 07070100000042000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000001800000000harbor-cli-0.0.2/dagger07070100000043000081A40000000000000000000000016717AEFE000000FE000000000000000000000000000000000000001D00000000harbor-cli-0.0.2/dagger.json{ "name": "harbor-cli", "sdk": "go", "dependencies": [ { "name": "cosign", "source": "github.com/scottames/daggerverse/cosign@8359122a7b90f2c8c6f3165570fdcbec6e923023" } ], "source": "dagger", "engineVersion": "v0.13.3" } 07070100000044000081A40000000000000000000000016717AEFE000000A0000000000000000000000000000000000000002700000000harbor-cli-0.0.2/dagger/.gitattributes/dagger.gen.go linguist-generated /internal/dagger/** linguist-generated /internal/querybuilder/** linguist-generated /internal/telemetry/** linguist-generated 07070100000045000081A40000000000000000000000016717AEFE0000004B000000000000000000000000000000000000002300000000harbor-cli-0.0.2/dagger/.gitignore/dagger.gen.go /internal/dagger /internal/querybuilder /internal/telemetry 07070100000046000081A40000000000000000000000016717AEFE00000804000000000000000000000000000000000000001F00000000harbor-cli-0.0.2/dagger/go.modmodule dagger/harbor-cli go 1.23.1 require ( github.com/99designs/gqlgen v0.17.49 github.com/Khan/genqlient v0.7.0 github.com/vektah/gqlparser/v2 v2.5.16 go.opentelemetry.io/otel v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 go.opentelemetry.io/otel/log v0.3.0 go.opentelemetry.io/otel/sdk v1.27.0 go.opentelemetry.io/otel/sdk/log v0.3.0 go.opentelemetry.io/otel/trace v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa golang.org/x/sync v0.8.0 google.golang.org/grpc v1.65.0 ) require ( github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/sosodev/duration v1.3.1 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect go.opentelemetry.io/otel/metric v1.27.0 // indirect golang.org/x/net v0.29.0 // indirect golang.org/x/sys v0.25.0 // indirect golang.org/x/text v0.18.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/protobuf v1.34.2 // indirect ) replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 replace go.opentelemetry.io/otel/log => go.opentelemetry.io/otel/log v0.3.0 replace go.opentelemetry.io/otel/sdk/log => go.opentelemetry.io/otel/sdk/log v0.3.0 07070100000047000081A40000000000000000000000016717AEFE00001C2A000000000000000000000000000000000000001F00000000harbor-cli-0.0.2/dagger/go.sumgithub.com/99designs/gqlgen v0.17.49 h1:b3hNGexHd33fBSAd4NDT/c3NCcQzcAVkknhN9ym36YQ= github.com/99designs/gqlgen v0.17.49/go.mod h1:tC8YFVZMed81x7UJ7ORUwXF4Kn6SXuucFqQBhN8+BU0= github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= 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/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/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 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/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= 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/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4= github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0vy5p8= github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 h1:oM0GTNKGlc5qHctWeIGTVyda4iFFalOzMZ3Ehj5rwB4= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88/go.mod h1:JGG8ebaMO5nXOPnvKEl+DiA4MGwFjCbjsxT1WHIEBPY= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 h1:ccBrA8nCY5mM0y5uO7FT0ze4S0TuFcWdDB2FxGMTjkI= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0/go.mod h1:/9pb6634zi2Lk8LYg9Q0X8Ar6jka4dkFOylBLbVQPCE= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 h1:QY7/0NeRPKlzusf40ZE4t1VlMKbqSNT7cJRYzWuja0s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0/go.mod h1:HVkSiDhTM9BoUJU8qE6j2eSWLLXvi1USXjyd2BXT8PY= go.opentelemetry.io/otel/log v0.3.0 h1:kJRFkpUFYtny37NQzL386WbznUByZx186DpEMKhEGZs= go.opentelemetry.io/otel/log v0.3.0/go.mod h1:ziCwqZr9soYDwGNbIL+6kAvQC+ANvjgG367HVcyR/ys= go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik= go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak= go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kTWmI= go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= go.opentelemetry.io/otel/sdk/log v0.3.0 h1:GEjJ8iftz2l+XO1GF2856r7yYVh74URiF9JMcAacr5U= go.opentelemetry.io/otel/sdk/log v0.3.0/go.mod h1:BwCxtmux6ACLuys1wlbc0+vGBd+xytjmjajwqqIul2g= go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 07070100000048000081A40000000000000000000000016717AEFE00001A03000000000000000000000000000000000000002000000000harbor-cli-0.0.2/dagger/main.gopackage main import ( "context" "dagger/harbor-cli/internal/dagger" "fmt" "log" ) const ( GOLANGCILINT_VERSION = "v1.61.0" GO_VERSION = "1.22.5" SYFT_VERSION = "v1.9.0" GORELEASER_VERSION = "v2.3.2" ) type HarborCli struct{} func (m *HarborCli) Build( ctx context.Context, // +optional // +defaultPath="./" source *dagger.Directory, ) []*dagger.Container { var builds []*dagger.Container fmt.Println("π οΈ Building with Dagger...") oses := []string{"linux", "darwin", "windows"} arches := []string{"amd64", "arm64"} for _, goos := range oses { for _, goarch := range arches { bin_path := fmt.Sprintf("build/%s/%s/", goos, goarch) builder := dag.Container(). From("golang:"+GO_VERSION+"-alpine"). WithMountedDirectory("/src", source). WithWorkdir("/src"). WithMountedCache("/go/pkg/mod", dag.CacheVolume("go-mod-"+GO_VERSION)). WithEnvVariable("GOMODCACHE", "/go/pkg/mod"). WithMountedCache("/go/build-cache", dag.CacheVolume("go-build-"+GO_VERSION)). WithEnvVariable("GOCACHE", "/go/build-cache"). WithEnvVariable("GOOS", goos). WithEnvVariable("GOARCH", goarch). WithExec([]string{"go", "build", "-o", bin_path + "harbor", "/src/cmd/harbor/main.go"}). WithWorkdir(bin_path).WithExec([]string{"ls"}).WithEntrypoint([]string{"./harbor"}) builds = append(builds, builder) } } return builds } func (m *HarborCli) Lint( ctx context.Context, // +optional // +defaultPath="./" source *dagger.Directory, ) *dagger.Container { fmt.Println("π Running linter with Dagger...") return dag.Container(). From("golangci/golangci-lint:"+GOLANGCILINT_VERSION+"-alpine"). WithMountedCache("/go/pkg/mod", dag.CacheVolume("go-mod-"+GO_VERSION)). WithEnvVariable("GOMODCACHE", "/go/pkg/mod"). WithMountedCache("/go/build-cache", dag.CacheVolume("go-build-"+GO_VERSION)). WithEnvVariable("GOCACHE", "/go/build-cache"). WithMountedDirectory("/src", source). WithWorkdir("/src"). WithExec([]string{"golangci-lint", "run", "--timeout", "5m"}) } func (m *HarborCli) PullRequest(ctx context.Context, // +optional // +defaultPath="./" source *dagger.Directory, githubToken string, ) { goreleaser := goreleaserContainer(source, githubToken).WithExec([]string{"release", "--snapshot", "--clean"}) _, err := goreleaser.Stderr(ctx) if err != nil { log.Printf("β Error occured during snapshot release for the recently merged pull-request: %s", err) return } log.Println("Pull-Request tasks completed successfully π") } func (m *HarborCli) Release( ctx context.Context, // +optional // +defaultPath="./" source *dagger.Directory, githubToken string, ) { goreleaser := goreleaserContainer(source, githubToken).WithExec([]string{"ls", "-la"}).WithExec([]string{"goreleaser", "release", "--clean"}) _, err := goreleaser.Stderr(ctx) if err != nil { log.Printf("Error occured during release: %s", err) return } log.Println("Release tasks completed successfully π") } // PublishImage publishes a Docker image to a registry with a specific tag and signs it using Cosign. // cosignKey: the secret used for signing the image // cosignPassword: the password for the cosign secret // regUsername: the username for the registry // regPassword: the password for the registry // publishAddress: the address of the registry to publish the image // tag: the version tag for the image func (m *HarborCli) PublishImage( ctx context.Context, // +optional // +defaultPath="./" source *dagger.Directory, cosignKey string, cosignPassword string, regUsername string, regPassword string, regAddress string, publishAddress string, tag string, ) string { var container *dagger.Container var filteredBuilders []*dagger.Container builders := m.Build(ctx, source) if len(builders) > 0 { fmt.Println(len(builders)) container = builders[0] builders = builders[3:6] } dir := dag.Directory() dir = dir.WithDirectory(".", container.Directory(".")) // Create a minimal cli_runtime container cli_runtime := dag.Container(). From("alpine:latest"). WithWorkdir("/root/"). WithFile("/root/harbor", dir.File("./harbor")). WithExec([]string{"ls"}). WithExec([]string{"./harbor", "--help"}). WithEntrypoint([]string{"./harbor"}) for _, builder := range builders { if !(buildPlatform(ctx, builder) == "linux/amd64") { filteredBuilders = append(filteredBuilders, builder) } } cosign_key := dag.SetSecret("cosign_key", cosignKey) cosign_password := dag.SetSecret("cosign_password", cosignPassword) regpassword := dag.SetSecret("reg_password", regPassword) publisher := cli_runtime.WithRegistryAuth(regAddress, regUsername, regpassword) // Push the versioned tag versionedAddress := fmt.Sprintf("%s:%s", publishAddress, tag) addr, err := publisher.Publish(ctx, versionedAddress, dagger.ContainerPublishOpts{PlatformVariants: filteredBuilders}) if err != nil { panic(err) } // Push the latest tag latestAddress := fmt.Sprintf("%s:latest", publishAddress) addr, err = publisher.Publish(ctx, latestAddress) if err != nil { panic(err) } _, err = dag.Cosign().Sign(ctx, cosign_key, cosign_password, []string{addr}, dagger.CosignSignOpts{RegistryUsername: regUsername, RegistryPassword: regpassword}) if err != nil { panic(err) } fmt.Printf("Successfully published image to %s π\n", addr) return addr } func buildPlatform(ctx context.Context, container *dagger.Container) string { platform, err := container.Platform(ctx) if err != nil { log.Fatalf("error getting platform", err) } return string(platform) } func goreleaserContainer(directoryArg *dagger.Directory, githubToken string) *dagger.Container { token := dag.SetSecret("github_token", githubToken) // Export the syft binary from the syft container as a file to generate SBOM syft := dag.Container().From(fmt.Sprintf("anchore/syft:%s", SYFT_VERSION)). WithMountedCache("/go/pkg/mod", dag.CacheVolume("gomod")). File("/syft") return dag.Container().From(fmt.Sprintf("goreleaser/goreleaser:%s", GORELEASER_VERSION)). WithMountedCache("/go/pkg/mod", dag.CacheVolume("gomod")). WithFile("/bin/syft", syft). WithMountedDirectory("/src", directoryArg).WithWorkdir("/src"). WithEnvVariable("TINI_SUBREAPER", "true"). WithSecretVariable("GITHUB_TOKEN", token) } func (m *HarborCli) RunDoc(ctx context.Context, source *dagger.Directory) *dagger.Directory { fmt.Println("Running doc.go file using Dagger...") return dag.Container(). From("golang:latest"). WithMountedDirectory("/src", source). WithWorkdir("/src/doc"). WithExec([]string{"go", "run", "doc.go"}). WithWorkdir("/src").Directory("/src/doc") }07070100000049000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000001500000000harbor-cli-0.0.2/doc0707010000004A000081A40000000000000000000000016717AEFE00000545000000000000000000000000000000000000001F00000000harbor-cli-0.0.2/doc/README.md# Harbor CLI Documentation Welcome to the Harbor CLI documentation guide! This document outlines the steps to generate the CLI documentation files. ## Overview The [doc.go](./doc.go) script is designed to create markdown files that detail the functions of commands available in the Harbor CLI. These files are generated based on the existing cli commands and it will be placed in the [cli-docs](./cli-docs) directory. ## Steps to Generate CLI Documentation 1. Clone the repository ```bash git clone https://github.com/goharbor/harbor-cli.git ``` 1. Navigate to the doc directory: ```bash cd harbor-cli/doc ``` change your directory to the `doc` folder where the `doc.go` script is located. 2. Run the `doc.go` file: ```bash go run doc.go ``` This generates markdown files for CLI commands that do not already exist in the [cli-docs](./cli-docs) directory. ## Generate Documentation using Dagger Make sure you have latest [Dagger](https://docs.dagger.io/) installed in your system. ```bash git clone https://github.com/goharbor/harbor-cli.git cd harbor-cli dagger call run-doc --source=. export --path=doc ``` This would runs the dagger function and generate markdown files in [cli-docs](./cli-docs). ### Note - For any newly generated markdown files, ensure to set the weight according to the order you want them to appear. 0707010000004B000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000001E00000000harbor-cli-0.0.2/doc/cli-docs0707010000004C000081A40000000000000000000000016717AEFE000002B1000000000000000000000000000000000000002800000000harbor-cli-0.0.2/doc/cli-docs/_index.md--- title: Harbor CLI Commands weight: 25 --- This section describes the comprehensive set of commands provided by the Harbor CLI, which enables you to efficiently manage and interact with your Harbor registry. The Harbor CLI commands are categorized by function, - `harbor` - Configure the Harbor CLI and set global flags to customize your experience. - `harbor artifact` - Manage artifacts in Harbor Repository - `harbor project` - Manage projects and assign resources to them - `harbor registry` - Manage registries in Harbor - `harbor repo` - Manage repositories in Harbor context - `harbor user` - Administer users in Harbor, including creating, updating, and managing user accounts0707010000004D000081A40000000000000000000000016717AEFE00000245000000000000000000000000000000000000003800000000harbor-cli-0.0.2/doc/cli-docs/harbor-artifact-delete.md--- title: harbor artifact delete weight: 35 --- ## harbor artifact delete ### Description ##### delete an artifact ```sh harbor artifact delete [flags] ``` ### Options ```sh -h, --help help for delete ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor artifact](harbor-artifact.md) - Manage artifacts 0707010000004E000081A40000000000000000000000016717AEFE000002BA000000000000000000000000000000000000003600000000harbor-cli-0.0.2/doc/cli-docs/harbor-artifact-info.md--- title: harbor artifact info weight: 25 --- ## harbor artifact info ### Description ##### Get info of an artifact ### Synopsis Get info of an artifact ```sh harbor artifact info [flags] ``` ### Examples ```sh harbor artifact info <project>/<repository>/<reference> ``` ### Options ```sh -h, --help help for info ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor artifact](harbor-artifact.md) - Manage artifacts 0707010000004F000081A40000000000000000000000016717AEFE0000024D000000000000000000000000000000000000003600000000harbor-cli-0.0.2/doc/cli-docs/harbor-artifact-list.md--- title: harbor artifact list weight: 30 --- ## harbor artifact list ### Description ##### list artifacts within a repository ```sh harbor artifact list [flags] ``` ### Options ```sh -h, --help help for list ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor artifact](harbor-artifact.md) - Manage artifacts 07070100000050000081A40000000000000000000000016717AEFE000002FA000000000000000000000000000000000000003C00000000harbor-cli-0.0.2/doc/cli-docs/harbor-artifact-scan-start.md--- title: harbor artifact scan start weight: 45 --- ## harbor artifact scan start ### Description ##### Start a scan of an artifact ### Synopsis Start a scan of an artifact in Harbor Repository ```sh harbor artifact scan start [flags] ``` ### Examples ```sh harbor artifact scan start <project>/<repository>/<reference> ``` ### Options ```sh -h, --help help for start ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor artifact scan](harbor-artifact-scan.md) - Scan an artifact 07070100000051000081A40000000000000000000000016717AEFE000002F3000000000000000000000000000000000000003B00000000harbor-cli-0.0.2/doc/cli-docs/harbor-artifact-scan-stop.md--- title: harbor artifact scan stop weight: 50 --- ## harbor artifact scan stop ### Description ##### Stop a scan of an artifact ### Synopsis Stop a scan of an artifact in Harbor Repository ```sh harbor artifact scan stop [flags] ``` ### Examples ```sh harbor artifact scan stop <project>/<repository>/<reference> ``` ### Options ```sh -h, --help help for stop ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor artifact scan](harbor-artifact-scan.md) - Scan an artifact 07070100000052000081A40000000000000000000000016717AEFE00000356000000000000000000000000000000000000003600000000harbor-cli-0.0.2/doc/cli-docs/harbor-artifact-scan.md--- title: harbor artifact scan weight: 40 --- ## harbor artifact scan ### Description ##### Scan an artifact ### Synopsis Scan an artifact in Harbor Repository ### Examples ```sh harbor artifact scan start <project>/<repository>/<reference> ``` ### Options ```sh -h, --help help for scan ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor artifact](harbor-artifact.md) - Manage artifacts * [harbor artifact scan start](harbor-artifact-scan-start.md) - Start a scan of an artifact * [harbor artifact scan stop](harbor-artifact-scan-stop.md) - Stop a scan of an artifact 07070100000053000081A40000000000000000000000016717AEFE000002CF000000000000000000000000000000000000003D00000000harbor-cli-0.0.2/doc/cli-docs/harbor-artifact-tags-create.md--- title: harbor artifact tags create weight: 60 --- ## harbor artifact tags create ### Description ##### Create a tag of an artifact ```sh harbor artifact tags create [flags] ``` ### Examples ```sh harbor artifact tags create <project>/<repository>/<reference> <tag> ``` ### Options ```sh -h, --help help for create ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor artifact tags](harbor-artifact-tags.md) - Manage tags of an artifact 07070100000054000081A40000000000000000000000016717AEFE000002CF000000000000000000000000000000000000003D00000000harbor-cli-0.0.2/doc/cli-docs/harbor-artifact-tags-delete.md--- title: harbor artifact tags delete weight: 70 --- ## harbor artifact tags delete ### Description ##### Delete a tag of an artifact ```sh harbor artifact tags delete [flags] ``` ### Examples ```sh harbor artifact tags delete <project>/<repository>/<reference> <tag> ``` ### Options ```sh -h, --help help for delete ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor artifact tags](harbor-artifact-tags.md) - Manage tags of an artifact 07070100000055000081A40000000000000000000000016717AEFE000002BC000000000000000000000000000000000000003B00000000harbor-cli-0.0.2/doc/cli-docs/harbor-artifact-tags-list.md--- title: harbor artifact tags list weight: 65 --- ## harbor artifact tags list ### Description ##### List tags of an artifact ```sh harbor artifact tags list [flags] ``` ### Examples ```sh harbor artifact tags list <project>/<repository>/<reference> ``` ### Options ```sh -h, --help help for list ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor artifact tags](harbor-artifact-tags.md) - Manage tags of an artifact 07070100000056000081A40000000000000000000000016717AEFE0000038A000000000000000000000000000000000000003600000000harbor-cli-0.0.2/doc/cli-docs/harbor-artifact-tags.md--- title: harbor artifact tags weight: 55 --- ## harbor artifact tags ### Description ##### Manage tags of an artifact ### Examples ```sh harbor artifact tags list <project>/<repository>/<reference> ``` ### Options ```sh -h, --help help for tags ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor artifact](harbor-artifact.md) - Manage artifacts * [harbor artifact tags create](harbor-artifact-tags-create.md) - Create a tag of an artifact * [harbor artifact tags delete](harbor-artifact-tags-delete.md) - Delete a tag of an artifact * [harbor artifact tags list](harbor-artifact-tags-list.md) - List tags of an artifact 07070100000057000081A40000000000000000000000016717AEFE000003EA000000000000000000000000000000000000003100000000harbor-cli-0.0.2/doc/cli-docs/harbor-artifact.md--- title: harbor artifact weight: 20 --- ## harbor artifact ### Description ##### Manage artifacts ### Synopsis Manage artifacts in Harbor Repository ### Examples ```sh harbor artifact list ``` ### Options ```sh -h, --help help for artifact ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor](harbor.md) - Official Harbor CLI * [harbor artifact delete](harbor-artifact-delete.md) - delete an artifact * [harbor artifact info](harbor-artifact-info.md) - Get info of an artifact * [harbor artifact list](harbor-artifact-list.md) - list artifacts within a repository * [harbor artifact scan](harbor-artifact-scan.md) - Scan an artifact * [harbor artifact tags](harbor-artifact-tags.md) - Manage tags of an artifact 07070100000058000081A40000000000000000000000016717AEFE0000027D000000000000000000000000000000000000002F00000000harbor-cli-0.0.2/doc/cli-docs/harbor-health.md--- title: harbor health weight: 80 --- ## harbor health ### Description ##### Get the health status of Harbor components ```sh harbor health [flags] ``` ### Examples ```sh # Get the health status of Harbor components ``` ### Options ```sh -h, --help help for health ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/Users/vadim/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor](harbor.md) - Official Harbor CLI 07070100000059000081A40000000000000000000000016717AEFE000002E4000000000000000000000000000000000000002E00000000harbor-cli-0.0.2/doc/cli-docs/harbor-login.md--- title: harbor login weight: 15 --- ## harbor login ### Description ##### Log in to Harbor registry ### Synopsis Authenticate with Harbor Registry. ```sh harbor login [server] [flags] ``` ### Options ```sh -h, --help help for login --name string name for the set of credentials -p, --password string Password -u, --username string Username ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor](harbor.md) - Official Harbor CLI 0707010000005A000081A40000000000000000000000016717AEFE000003DC000000000000000000000000000000000000003700000000harbor-cli-0.0.2/doc/cli-docs/harbor-project-create.md--- title: harbor project create weight: 80 --- ## harbor project create ### Description ##### create project ```sh harbor project create [flags] ``` ### Options ```sh -h, --help help for create --name string Name of the project --proxy-cache Whether the project is a proxy cache project --public Project is public or private (default true) --registry-id string ID of referenced registry when creating the proxy cache project --storage-limit string Storage quota of the project (default "-1") ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor project](harbor-project.md) - Manage projects and assign resources to them 0707010000005B000081A40000000000000000000000016717AEFE00000267000000000000000000000000000000000000003700000000harbor-cli-0.0.2/doc/cli-docs/harbor-project-delete.md--- title: harbor project delete weight: 100 --- ## harbor project delete ### Description ##### delete project by name or id ```sh harbor project delete [flags] ``` ### Options ```sh -h, --help help for delete ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor project](harbor-project.md) - Manage projects and assign resources to them 0707010000005C000081A40000000000000000000000016717AEFE000003A6000000000000000000000000000000000000003500000000harbor-cli-0.0.2/doc/cli-docs/harbor-project-list.md--- title: harbor project list weight: 85 --- ## harbor project list ### Description ##### list project ```sh harbor project list [flags] ``` ### Options ```sh -h, --help help for list --name string Name of the project --page int Page number (default 1) --page-size int Size of per page (default 10) --public Project is public or private -q, --query string Query string to query resources --sort string Sort the resource list in ascending or descending order ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor project](harbor-project.md) - Manage projects and assign resources to them 0707010000005D000081A40000000000000000000000016717AEFE00000252000000000000000000000000000000000000003500000000harbor-cli-0.0.2/doc/cli-docs/harbor-project-logs.md--- title: harbor project logs weight: 90 --- ## harbor project logs ### Description ##### get project logs ```sh harbor project logs [flags] ``` ### Options ```sh -h, --help help for logs ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor project](harbor-project.md) - Manage projects and assign resources to them 0707010000005E000081A40000000000000000000000016717AEFE00000265000000000000000000000000000000000000003500000000harbor-cli-0.0.2/doc/cli-docs/harbor-project-view.md--- title: harbor project view weight: 95 --- ## harbor project view ### Description ##### get project by name or id ```sh harbor project view [NAME|ID] [flags] ``` ### Options ```sh -h, --help help for view ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor project](harbor-project.md) - Manage projects and assign resources to them 0707010000005F000081A40000000000000000000000016717AEFE000003DA000000000000000000000000000000000000003000000000harbor-cli-0.0.2/doc/cli-docs/harbor-project.md--- title: harbor project weight: 75 --- ## harbor project ### Description ##### Manage projects and assign resources to them ### Synopsis Manage projects in Harbor ### Examples ```sh harbor project list ``` ### Options ```sh -h, --help help for project ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor](harbor.md) - Official Harbor CLI * [harbor project create](harbor-project-create.md) - create project * [harbor project delete](harbor-project-delete.md) - delete project by name or id * [harbor project list](harbor-project-list.md) - list project * [harbor project logs](harbor-project-logs.md) - get project logs * [harbor project view](harbor-project-view.md) - get project by name or id 07070100000060000081A40000000000000000000000016717AEFE00000538000000000000000000000000000000000000003800000000harbor-cli-0.0.2/doc/cli-docs/harbor-registry-create.md--- title: harbor registry create weight: 110 --- ## harbor registry create ### Description ##### create registry ```sh harbor registry create [flags] ``` ### Options ```sh --credential-access-key string Access key, e.g. user name when credential type is 'basic' --credential-access-secret string Access secret, e.g. password when credential type is 'basic' --credential-type string Credential type, such as 'basic', 'oauth' (default "basic") --description string Description of the registry -h, --help help for create --insecure Whether or not the certificate will be verified when Harbor tries to access the server (default true) --name string Name of the registry --type string Type of the registry (default "harbor") --url string Registry endpoint URL ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor registry](harbor-registry.md) - Manage registries 07070100000061000081A40000000000000000000000016717AEFE0000024A000000000000000000000000000000000000003800000000harbor-cli-0.0.2/doc/cli-docs/harbor-registry-delete.md--- title: harbor registry delete weight: 140 --- ## harbor registry delete ### Description ##### delete registry by id ```sh harbor registry delete [flags] ``` ### Options ```sh -h, --help help for delete ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor registry](harbor-registry.md) - Manage registries 07070100000062000081A40000000000000000000000016717AEFE0000023E000000000000000000000000000000000000003600000000harbor-cli-0.0.2/doc/cli-docs/harbor-registry-info.md--- title: harbor registry info weight: 120 --- ## harbor registry info ### Description ##### get registry info ```sh harbor registry info [flags] ``` ### Options ```sh -h, --help help for info ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor registry](harbor-registry.md) - Manage registries 07070100000063000081A40000000000000000000000016717AEFE00000331000000000000000000000000000000000000003600000000harbor-cli-0.0.2/doc/cli-docs/harbor-registry-list.md--- title: harbor registry list weight: 115 --- ## harbor registry list ### Description ##### list registry ```sh harbor registry list [flags] ``` ### Options ```sh -h, --help help for list --page int Page number (default 1) --page-size int Size of per page (default 10) -q, --query string Query string to query resources --sort string Sort the resource list in ascending or descending order ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor registry](harbor-registry.md) - Manage registries 07070100000064000081A40000000000000000000000016717AEFE00000513000000000000000000000000000000000000003800000000harbor-cli-0.0.2/doc/cli-docs/harbor-registry-update.md--- title: harbor registry update weight: 125 --- ## harbor registry update ### Description ##### update registry ```sh harbor registry update [flags] ``` ### Options ```sh --credential-access-key string Access key, e.g. user name when credential type is 'basic' --credential-access-secret string Access secret, e.g. password when credential type is 'basic' --credential-type string Credential type, such as 'basic', 'oauth' --description string Description of the registry -h, --help help for update --insecure Whether or not the certificate will be verified when Harbor tries to access the server (default true) --name string Name of the registry --type string Type of the registry --url string Registry endpoint URL ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor registry](harbor-registry.md) - Manage registries 07070100000065000081A40000000000000000000000016717AEFE0000023F000000000000000000000000000000000000003600000000harbor-cli-0.0.2/doc/cli-docs/harbor-registry-view.md--- title: harbor registry view weight: 130 --- ## harbor registry view ### Description ##### get registry by id ```sh harbor registry view [flags] ``` ### Options ```sh -h, --help help for view ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor registry](harbor-registry.md) - Manage registries 07070100000066000081A40000000000000000000000016717AEFE0000040E000000000000000000000000000000000000003100000000harbor-cli-0.0.2/doc/cli-docs/harbor-registry.md--- title: harbor registry weight: 105 --- ## harbor registry ### Description ##### Manage registries ### Synopsis Manage registries in Harbor ### Examples ```sh harbor registry list ``` ### Options ```sh -h, --help help for registry ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor](harbor.md) - Official Harbor CLI * [harbor registry create](harbor-registry-create.md) - create registry * [harbor registry delete](harbor-registry-delete.md) - delete registry by id * [harbor registry info](harbor-registry-info.md) - get registry info * [harbor registry list](harbor-registry-list.md) - list registry * [harbor registry update](harbor-registry-update.md) - update registry * [harbor registry view](harbor-registry-view.md) - get registry by id 07070100000067000081A40000000000000000000000016717AEFE000002C9000000000000000000000000000000000000003400000000harbor-cli-0.0.2/doc/cli-docs/harbor-repo-delete.md--- title: harbor repo delete weight: 160 --- ## harbor repo delete ### Description ##### Delete a repository ### Synopsis Delete a repository within a project in Harbor ```sh harbor repo delete [flags] ``` ### Examples ```sh harbor repository delete [project_name]/[repository_name] ``` ### Options ```sh -h, --help help for delete ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor repo](harbor-repo.md) - Manage repositories 07070100000068000081A40000000000000000000000016717AEFE000002C3000000000000000000000000000000000000003200000000harbor-cli-0.0.2/doc/cli-docs/harbor-repo-info.md--- title: harbor repo info weight: 155 --- ## harbor repo info ### Description ##### Get repository information ### Synopsis Get information of a particular repository in a project ```sh harbor repo info [flags] ``` ### Examples ```sh harbor repo info <project_name>/<repo_name> ``` ### Options ```sh -h, --help help for info ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor repo](harbor-repo.md) - Manage repositories 07070100000069000081A40000000000000000000000016717AEFE0000023D000000000000000000000000000000000000003200000000harbor-cli-0.0.2/doc/cli-docs/harbor-repo-list.md--- title: harbor repo list weight: 150 --- ## harbor repo list ### Description ##### list repositories within a project ```sh harbor repo list [flags] ``` ### Options ```sh -h, --help help for list ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor repo](harbor-repo.md) - Manage repositories 0707010000006A000081A40000000000000000000000016717AEFE00000308000000000000000000000000000000000000002D00000000harbor-cli-0.0.2/doc/cli-docs/harbor-repo.md--- title: harbor repo weight: 145 --- ## harbor repo ### Description ##### Manage repositories ### Synopsis Manage repositories in Harbor context ### Options ```sh -h, --help help for repo ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor](harbor.md) - Official Harbor CLI * [harbor repo delete](harbor-repo-delete.md) - Delete a repository * [harbor repo info](harbor-repo-info.md) - Get repository information * [harbor repo list](harbor-repo-list.md) - list repositories within a project 0707010000006B000081A40000000000000000000000016717AEFE000002DD000000000000000000000000000000000000003400000000harbor-cli-0.0.2/doc/cli-docs/harbor-user-create.md--- title: harbor user create weight: 170 --- ## harbor user create ### Description ##### create user ```sh harbor user create [flags] ``` ### Options ```sh --comment string Comment --email string Email -h, --help help for create --password string Password --realname string Realname --username string Username ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor user](harbor-user.md) - Manage users 0707010000006C000081A40000000000000000000000016717AEFE00000227000000000000000000000000000000000000003400000000harbor-cli-0.0.2/doc/cli-docs/harbor-user-delete.md--- title: harbor user delete weight: 185 --- ## harbor user delete ### Description ##### delete user ```sh harbor user delete [flags] ``` ### Options ```sh -h, --help help for delete ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor user](harbor-user.md) - Manage users 0707010000006D000081A40000000000000000000000016717AEFE00000256000000000000000000000000000000000000003500000000harbor-cli-0.0.2/doc/cli-docs/harbor-user-elevate.md--- title: harbor user elevate weight: 180 --- ## harbor user elevate ### Description ##### elevate user ### Synopsis elevate user to admin role ```sh harbor user elevate [flags] ``` ### Options ```sh -h, --help help for elevate ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor user](harbor-user.md) - Manage users 0707010000006E000081A40000000000000000000000016717AEFE0000021E000000000000000000000000000000000000003200000000harbor-cli-0.0.2/doc/cli-docs/harbor-user-list.md--- title: harbor user list weight: 175 --- ## harbor user list ### Description ##### list users ```sh harbor user list [flags] ``` ### Options ```sh -h, --help help for list ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor user](harbor-user.md) - Manage users 0707010000006F000081A40000000000000000000000016717AEFE00000333000000000000000000000000000000000000002D00000000harbor-cli-0.0.2/doc/cli-docs/harbor-user.md--- title: harbor user weight: 165 --- ## harbor user ### Description ##### Manage users ### Synopsis Manage users in Harbor ### Examples ```sh harbor user list ``` ### Options ```sh -h, --help help for user ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor](harbor.md) - Official Harbor CLI * [harbor user create](harbor-user-create.md) - create user * [harbor user delete](harbor-user-delete.md) - delete user * [harbor user elevate](harbor-user-elevate.md) - elevate user * [harbor user list](harbor-user-list.md) - list users 07070100000070000081A40000000000000000000000016717AEFE000002B6000000000000000000000000000000000000003000000000harbor-cli-0.0.2/doc/cli-docs/harbor-version.md--- title: harbor version weight: 10 --- ## harbor version ### Description ##### Version of Harbor CLI ### Synopsis Get Harbor CLI version, git commit, go version, build time, release channel, os/arch, etc. ```sh harbor version [flags] ``` ### Examples ```sh harbor version ``` ### Options ```sh -h, --help help for version ``` ### Options inherited from parent commands ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor](harbor.md) - Official Harbor CLI 07070100000071000081A40000000000000000000000016717AEFE000003D2000000000000000000000000000000000000002800000000harbor-cli-0.0.2/doc/cli-docs/harbor.md--- title: harbor weight: 5 --- ## harbor ### Description ##### Official Harbor CLI ### Synopsis Official Harbor CLI ### Examples ```sh // Base command: harbor // Display help about the command: harbor help ``` ### Options ```sh --config string config file (default is $HOME/.harbor/config.yaml) (default "/home/user/.harbor/config.yaml") -h, --help help for harbor -o, --output-format string Output format. One of: json|yaml -v, --verbose verbose output ``` ### SEE ALSO * [harbor artifact](harbor-artifact.md) - Manage artifacts * [harbor login](harbor-login.md) - Log in to Harbor registry * [harbor project](harbor-project.md) - Manage projects and assign resources to them * [harbor registry](harbor-registry.md) - Manage registries * [harbor repo](harbor-repo.md) - Manage repositories * [harbor user](harbor-user.md) - Manage users * [harbor version](harbor-version.md) - Version of Harbor CLI 07070100000072000081A40000000000000000000000016717AEFE00001100000000000000000000000000000000000000001C00000000harbor-cli-0.0.2/doc/doc.gopackage main import ( "bytes" "fmt" "io" "math/rand" "os" "path/filepath" "strings" cmd "github.com/goharbor/harbor-cli/cmd/harbor/root" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) const markdownExtension = ".md" const frontmdtemplate = `--- title: %s weight: %d --- ` func Doc() error { currentDir, err := os.Getwd() if err != nil { return err } folderName := "cli-docs" _, err = os.Stat(folderName) if os.IsNotExist(err) { err = os.Mkdir(folderName, 0755) if err != nil { log.Fatal("Error creating folder:", err) } } docDir := fmt.Sprintf("%s/%s", currentDir, folderName) err = MarkdownTreeCustom(cmd.RootCmd(), docDir, preblock, linkHandler) if err != nil { return err } fmt.Println("Documentation generated at " + docDir) return nil } func preblock(filename string) string { file := strings.Split(filename, markdownExtension) name := filepath.Base(file[0]) title := strings.ReplaceAll(name, "-", " ") randomNumber := rand.Intn(20) weight := randomNumber * 5 return fmt.Sprintf(frontmdtemplate, title, weight) } func linkHandler(s string) string { return s } func printOptions(buf *bytes.Buffer, cmd *cobra.Command) error { flags := cmd.NonInheritedFlags() flags.SetOutput(buf) if flags.HasAvailableFlags() { buf.WriteString("### Options\n\n```sh\n") flags.PrintDefaults() buf.WriteString("```\n\n") } parentFlags := cmd.InheritedFlags() parentFlags.SetOutput(buf) if parentFlags.HasAvailableFlags() { buf.WriteString("### Options inherited from parent commands\n\n```sh\n") parentFlags.PrintDefaults() buf.WriteString("```\n\n") } return nil } func MarkdownCustom(cmd *cobra.Command, w io.Writer, linkHandler func(string) string) error { cmd.InitDefaultHelpCmd() cmd.InitDefaultHelpFlag() buf := new(bytes.Buffer) name := cmd.CommandPath() buf.WriteString("## " + name + "\n\n") buf.WriteString("### Description\n\n") buf.WriteString("##### " + cmd.Short + "\n\n") if len(cmd.Long) > 0 { buf.WriteString("### Synopsis\n\n") buf.WriteString(cmd.Long + "\n\n") } if cmd.Runnable() { buf.WriteString(fmt.Sprintf("```sh\n%s\n```\n\n", cmd.UseLine())) } if len(cmd.Example) > 0 { buf.WriteString("### Examples\n\n") buf.WriteString(fmt.Sprintf("```sh\n%s\n```\n\n", cmd.Example)) } if err := printOptions(buf, cmd); err != nil { return err } if hasSeeAlso(cmd) { buf.WriteString("### SEE ALSO\n\n") if cmd.HasParent() { parent := cmd.Parent() pname := parent.CommandPath() link := pname + markdownExtension link = strings.ReplaceAll(link, " ", "-") buf.WriteString(fmt.Sprintf("* [%s](%s)\t - %s\n", pname, linkHandler(link), parent.Short)) cmd.VisitParents(func(c *cobra.Command) { if c.DisableAutoGenTag { cmd.DisableAutoGenTag = c.DisableAutoGenTag } }) } children := cmd.Commands() for _, child := range children { if !child.IsAvailableCommand() || child.IsAdditionalHelpTopicCommand() { continue } cname := name + " " + child.Name() link := cname + markdownExtension link = strings.ReplaceAll(link, " ", "-") buf.WriteString(fmt.Sprintf("* [%s](%s)\t - %s\n", cname, linkHandler(link), child.Short)) } buf.WriteString("\n") } _, err := buf.WriteTo(w) return err } func MarkdownTreeCustom(cmd *cobra.Command, dir string, filePrepender, linkHandler func(string) string) error { for _, c := range cmd.Commands() { if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() { continue } if err := MarkdownTreeCustom(c, dir, filePrepender, linkHandler); err != nil { return err } } basename := strings.ReplaceAll(cmd.CommandPath(), " ", "-") + markdownExtension filename := filepath.Join(dir, basename) if _, err := os.Stat(filename); err == nil { return nil } f, err := os.Create(filename) if err != nil { return err } defer f.Close() if _, err := io.WriteString(f, filePrepender(filename)); err != nil { return err } if err := MarkdownCustom(cmd, f, linkHandler); err != nil { return err } return nil } func hasSeeAlso(cmd *cobra.Command) bool { if cmd.HasParent() { return true } for _, c := range cmd.Commands() { if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() { continue } return true } return false } func main() { err := Doc() if err != nil { log.Fatal(err) } } 07070100000073000081A40000000000000000000000016717AEFE0000114D000000000000000000000000000000000000001800000000harbor-cli-0.0.2/go.modmodule github.com/goharbor/harbor-cli go 1.22.5 require ( github.com/charmbracelet/bubbles v0.18.0 github.com/charmbracelet/bubbletea v0.26.6 github.com/charmbracelet/huh v0.5.2 github.com/charmbracelet/lipgloss v0.12.1 github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.9.0 ) require ( github.com/atotto/clipboard v0.1.4 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/catppuccin/go v0.2.0 // indirect github.com/charmbracelet/x/ansi v0.1.4 // indirect github.com/charmbracelet/x/exp/strings v0.0.0-20240725160154-f9f6568126ec // indirect github.com/charmbracelet/x/input v0.1.3 // indirect github.com/charmbracelet/x/term v0.1.1 // indirect github.com/charmbracelet/x/windows v0.1.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/reflow v0.3.0 // indirect github.com/muesli/termenv v0.15.2 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/sagikazarmark/locafero v0.6.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sahilm/fuzzy v0.1.1 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/sync v0.8.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) require ( github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/analysis v0.23.0 // indirect github.com/go-openapi/errors v0.22.0 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/loads v0.22.0 // indirect github.com/go-openapi/runtime v0.28.0 // indirect github.com/go-openapi/spec v0.21.0 // indirect github.com/go-openapi/strfmt v0.23.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect github.com/go-openapi/validate v0.24.0 // indirect github.com/goharbor/go-client v0.210.0 github.com/google/uuid v1.6.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/spf13/pflag v1.0.5 // indirect go.mongodb.org/mongo-driver v1.16.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/sdk v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect golang.org/x/sys v0.25.0 // indirect golang.org/x/text v0.18.0 // indirect ) replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 replace go.opentelemetry.io/otel/log => go.opentelemetry.io/otel/log v0.3.0 replace go.opentelemetry.io/otel/sdk/log => go.opentelemetry.io/otel/sdk/log v0.3.0 07070100000074000081A40000000000000000000000016717AEFE00004393000000000000000000000000000000000000001800000000harbor-cli-0.0.2/go.sumgithub.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/catppuccin/go v0.2.0 h1:ktBeIrIP42b/8FGiScP9sgrWOss3lw0Z5SktRoithGA= github.com/catppuccin/go v0.2.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc= github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0= github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw= github.com/charmbracelet/bubbletea v0.26.6 h1:zTCWSuST+3yZYZnVSvbXwKOPRSNZceVeqpzOLN2zq1s= github.com/charmbracelet/bubbletea v0.26.6/go.mod h1:dz8CWPlfCCGLFbBlTY4N7bjLiyOGDJEnd2Muu7pOWhk= github.com/charmbracelet/huh v0.5.2 h1:ofeNkJ4iaFnzv46Njhx896DzLUe/j0L2QAf8znwzX4c= github.com/charmbracelet/huh v0.5.2/go.mod h1:Sf7dY0oAn6N/e3sXJFtFX9hdQLrUdO3z7AYollG9bAM= github.com/charmbracelet/lipgloss v0.12.1 h1:/gmzszl+pedQpjCOH+wFkZr/N90Snz40J/NR7A0zQcs= github.com/charmbracelet/lipgloss v0.12.1/go.mod h1:V2CiwIuhx9S1S1ZlADfOj9HmxeMAORuz5izHb0zGbB8= github.com/charmbracelet/x/ansi v0.1.4 h1:IEU3D6+dWwPSgZ6HBH+v6oUuZ/nVawMiWj5831KfiLM= github.com/charmbracelet/x/ansi v0.1.4/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= github.com/charmbracelet/x/exp/strings v0.0.0-20240725160154-f9f6568126ec h1:G79PnmxvVeo5FbAip3VPqAaBkOeXExwvhIBUfrXD5MA= github.com/charmbracelet/x/exp/strings v0.0.0-20240725160154-f9f6568126ec/go.mod h1:pBhA0ybfXv6hDjQUZ7hk1lVxBiUbupdw5R31yPUViVQ= github.com/charmbracelet/x/exp/term v0.0.0-20240524151031-ff83003bf67a h1:k/s6UoOSVynWiw7PlclyGO2VdVs5ZLbMIHiGp4shFZE= github.com/charmbracelet/x/exp/term v0.0.0-20240524151031-ff83003bf67a/go.mod h1:YBotIGhfoWhHDlnUpJMkjebGV2pdGRCn1Y4/Nk/vVcU= github.com/charmbracelet/x/input v0.1.3 h1:oy4TMhyGQsYs/WWJwu1ELUMFnjiUAXwtDf048fHbCkg= github.com/charmbracelet/x/input v0.1.3/go.mod h1:1gaCOyw1KI9e2j00j/BBZ4ErzRZqa05w0Ghn83yIhKU= github.com/charmbracelet/x/term v0.1.1 h1:3cosVAiPOig+EV4X9U+3LDgtwwAoEzJjNdwbXDjF6yI= github.com/charmbracelet/x/term v0.1.1/go.mod h1:wB1fHt5ECsu3mXYusyzcngVWWlu1KKUmmLhfgr/Flxw= github.com/charmbracelet/x/windows v0.1.2 h1:Iumiwq2G+BRmgoayww/qfcvof7W/3uLoelhxojXlRWg= github.com/charmbracelet/x/windows v0.1.2/go.mod h1:GLEO/l+lizvFDBPLIOk+49gdX49L9YWMB5t+DZd0jkQ= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= 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-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU= github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo= github.com/go-openapi/errors v0.22.0 h1:c4xY/OLxUBSTiepAg3j/MHuAv5mJhnf53LLMWFB+u/w= github.com/go-openapi/errors v0.22.0/go.mod h1:J3DmZScxCDufmIMsdOuDHxJbdOGC0xtUynjIx092vXE= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= github.com/go-openapi/loads v0.22.0 h1:ECPGd4jX1U6NApCGG1We+uEozOAvXvJSF4nnwHZ8Aco= github.com/go-openapi/loads v0.22.0/go.mod h1:yLsaTCS92mnSAZX5WWoxszLj0u+Ojl+Zs5Stn1oF+rs= github.com/go-openapi/runtime v0.28.0 h1:gpPPmWSNGo214l6n8hzdXYhPuJcGtziTOgUpvsFWGIQ= github.com/go-openapi/runtime v0.28.0/go.mod h1:QN7OzcS+XuYmkQLw05akXk0jRH/eZ3kb18+1KwW9gyc= github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY= github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= github.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c= github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58= github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ= github.com/goharbor/go-client v0.210.0 h1:QwgLcWNSC3MFhBe7lq3BxDPtKQiD3k6hf6Lt26NChOI= github.com/goharbor/go-client v0.210.0/go.mod h1:XMWHucuHU9VTRx6U6wYwbRuyCVhE6ffJGRjaeo0nvwo= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 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/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 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/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk= github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA= github.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= 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/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 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.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= go.mongodb.org/mongo-driver v1.16.0 h1:tpRsfBJMROVHKpdGyc1BBEzzjDUWjItxbVSZ8Ls4BQ4= go.mongodb.org/mongo-driver v1.16.0/go.mod h1:oB6AhJQvFQL4LEHyXi6aJzQJtBiTQHiAd83l0GdFaiw= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= 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= 07070100000075000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000001500000000harbor-cli-0.0.2/pkg07070100000076000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000001900000000harbor-cli-0.0.2/pkg/api07070100000077000081A40000000000000000000000016717AEFE00001234000000000000000000000000000000000000002D00000000harbor-cli-0.0.2/pkg/api/artifact_handler.gopackage api import ( "github.com/goharbor/go-client/pkg/sdk/v2.0/client/artifact" "github.com/goharbor/go-client/pkg/sdk/v2.0/client/scan" "github.com/goharbor/go-client/pkg/sdk/v2.0/models" "github.com/goharbor/harbor-cli/pkg/utils" log "github.com/sirupsen/logrus" ) // DeleteArtifact handles the deletion of an artifact. func DeleteArtifact(projectName, repoName, reference string) error { ctx, client, err := utils.ContextWithClient() if err != nil { return err } _, err = client.Artifact.DeleteArtifact(ctx, &artifact.DeleteArtifactParams{ ProjectName: projectName, RepositoryName: repoName, Reference: reference, }) if err != nil { log.Errorf("Failed to delete artifact: %v", err) return err } log.Infof("Artifact deleted successfully: %s/%s@%s", projectName, repoName, reference) return nil } // InfoArtifact retrieves information about a specific artifact. func InfoArtifact(projectName, repoName, reference string) error { ctx, client, err := utils.ContextWithClient() if err != nil { return err } response, err := client.Artifact.GetArtifact(ctx, &artifact.GetArtifactParams{ ProjectName: projectName, RepositoryName: repoName, Reference: reference, }) if err != nil { log.Errorf("Failed to get artifact info: %v", err) return err } utils.PrintPayloadInJSONFormat(response.Payload) return nil } // RunListArtifact lists all artifacts in a repository. func ListArtifact(projectName, repoName string) (artifact.ListArtifactsOK, error) { ctx, client, err := utils.ContextWithClient() if err != nil { return artifact.ListArtifactsOK{}, err } response, err := client.Artifact.ListArtifacts(ctx, &artifact.ListArtifactsParams{ ProjectName: projectName, RepositoryName: repoName, }) if err != nil { return artifact.ListArtifactsOK{}, err } return *response, nil } // StartScanArtifact initiates a scan on a specific artifact. func StartScanArtifact(projectName, repoName, reference string) error { ctx, client, err := utils.ContextWithClient() if err != nil { return err } _, err = client.Scan.ScanArtifact(ctx, &scan.ScanArtifactParams{ ProjectName: projectName, RepositoryName: repoName, Reference: reference, }) if err != nil { log.Errorf("Failed to start scan: %v", err) return err } log.Infof("Scan started successfully: %s/%s@%s", projectName, repoName, reference) return nil } // StopScanArtifact stops a scan on a specific artifact. func StopScanArtifact(projectName, repoName, reference string) error { ctx, client, err := utils.ContextWithClient() if err != nil { return err } _, err = client.Scan.StopScanArtifact(ctx, &scan.StopScanArtifactParams{ ProjectName: projectName, RepositoryName: repoName, Reference: reference, }) if err != nil { log.Errorf("Failed to stop scan: %v", err) return err } log.Infof("Scan stopped successfully: %s/%s@%s", projectName, repoName, reference) return nil } // DeleteTag deletes a tag from a specific artifact. func DeleteTag(projectName, repoName, reference, tag string) error { ctx, client, err := utils.ContextWithClient() if err != nil { return err } _, err = client.Artifact.DeleteTag(ctx, &artifact.DeleteTagParams{ ProjectName: projectName, RepositoryName: repoName, Reference: reference, TagName: tag, }) if err != nil { log.Errorf("Failed to delete tag: %v", err) return err } log.Infof("Tag deleted successfully: %s/%s@%s:%s", projectName, repoName, reference, tag) return nil } // ListTags lists all tags of a specific artifact. func ListTags(projectName, repoName, reference string) (artifact.ListTagsOK, error) { ctx, client, err := utils.ContextWithClient() if err != nil { return artifact.ListTagsOK{}, err } resp, err := client.Artifact.ListTags(ctx, &artifact.ListTagsParams{ ProjectName: projectName, RepositoryName: repoName, Reference: reference, }) if err != nil { log.Errorf("Failed to list tags: %v", err) return artifact.ListTagsOK{}, err } return *resp, nil } // CreateTag creates a tag for a specific artifact. func CreateTag(projectName, repoName, reference, tagName string) error { ctx, client, err := utils.ContextWithClient() if err != nil { return err } _, err = client.Artifact.CreateTag(ctx, &artifact.CreateTagParams{ ProjectName: projectName, RepositoryName: repoName, Reference: reference, Tag: &models.Tag{ Name: tagName, }, }) if err != nil { log.Errorf("Failed to create tag: %v", err) return err } log.Infof("Tag created successfully: %s/%s@%s:%s", projectName, repoName, reference, tagName) return nil } 07070100000078000081A40000000000000000000000016717AEFE000001C7000000000000000000000000000000000000002B00000000harbor-cli-0.0.2/pkg/api/health_handler.gopackage api import ( "fmt" "github.com/goharbor/go-client/pkg/sdk/v2.0/client/health" "github.com/goharbor/harbor-cli/pkg/utils" ) func GetHealth() (*health.GetHealthOK, error) { ctx, client, err := utils.ContextWithClient() if err != nil { return nil, err } response, err := client.Health.GetHealth(ctx, &health.GetHealthParams{}) if err != nil { return nil, fmt.Errorf("error getting health status: %w", err) } return response, nil } 07070100000079000081A40000000000000000000000016717AEFE00000A1C000000000000000000000000000000000000002C00000000harbor-cli-0.0.2/pkg/api/project_handler.gopackage api import ( "strconv" "github.com/goharbor/go-client/pkg/sdk/v2.0/client/project" "github.com/goharbor/go-client/pkg/sdk/v2.0/models" "github.com/goharbor/harbor-cli/pkg/utils" "github.com/goharbor/harbor-cli/pkg/views/project/create" log "github.com/sirupsen/logrus" ) func CreateProject(opts create.CreateView) error { ctx, client, err := utils.ContextWithClient() if err != nil { return err } registryID := new(int64) *registryID, _ = strconv.ParseInt(opts.RegistryID, 10, 64) if !opts.ProxyCache { registryID = nil } storageLimit, _ := strconv.ParseInt(opts.StorageLimit, 10, 64) public := strconv.FormatBool(opts.Public) response, err := client.Project.CreateProject(ctx, &project.CreateProjectParams{Project: &models.ProjectReq{ProjectName: opts.ProjectName, RegistryID: registryID, StorageLimit: &storageLimit, Public: &opts.Public, Metadata: &models.ProjectMetadata{Public: public}}}) if err != nil { return err } if response != nil { log.Info("Project created successfully") } return nil } func GetProject(projectName string) error { ctx, client, err := utils.ContextWithClient() if err != nil { return err } response, err := client.Project.GetProject(ctx, &project.GetProjectParams{ProjectNameOrID: projectName}) if err != nil { return err } utils.PrintPayloadInJSONFormat(response) return nil } func DeleteProject(projectName string) error { ctx, client, err := utils.ContextWithClient() if err != nil { return err } _, err = client.Project.DeleteProject(ctx, &project.DeleteProjectParams{ProjectNameOrID: projectName}) if err != nil { return err } log.Info("project deleted successfully") return nil } func ListProject(opts ...ListFlags) (project.ListProjectsOK, error) { ctx, client, err := utils.ContextWithClient() if err != nil { return project.ListProjectsOK{}, err } var listFlags ListFlags if len(opts) > 0 { listFlags = opts[0] } response, err := client.Project.ListProjects(ctx, &project.ListProjectsParams{Page: &listFlags.Page, PageSize: &listFlags.PageSize, Q: &listFlags.Q, Sort: &listFlags.Sort, Name: &listFlags.Name, Public: &listFlags.Public}) if err != nil { return project.ListProjectsOK{}, err } return *response, nil } func LogsProject(projectName string) (*project.GetLogsOK, error) { ctx, client, err := utils.ContextWithClient() if err != nil { return nil, err } response, err := client.Project.GetLogs(ctx, &project.GetLogsParams{ ProjectName: projectName, Context: ctx, }) if err != nil { return nil, err } return response, nil } 0707010000007A000081A40000000000000000000000016717AEFE00000D9C000000000000000000000000000000000000002D00000000harbor-cli-0.0.2/pkg/api/registry_handler.gopackage api import ( "github.com/goharbor/go-client/pkg/sdk/v2.0/client/registry" "github.com/goharbor/go-client/pkg/sdk/v2.0/models" "github.com/goharbor/harbor-cli/pkg/utils" log "github.com/sirupsen/logrus" ) func ListRegistries(opts ...ListFlags) (*registry.ListRegistriesOK, error) { ctx, client, err := utils.ContextWithClient() if err != nil { return nil, err } var listFlags ListFlags if len(opts) > 0 { listFlags = opts[0] } response, err := client.Registry.ListRegistries(ctx, ®istry.ListRegistriesParams{ Page: &listFlags.Page, PageSize: &listFlags.PageSize, Q: &listFlags.Q, Name: &listFlags.Name, Sort: &listFlags.Sort, }) if err != nil { return nil, err } return response, nil } func CreateRegistry(opts CreateRegView) error { ctx, client, err := utils.ContextWithClient() if err != nil { return err } _, err = client.Registry.CreateRegistry( ctx, ®istry.CreateRegistryParams{ Registry: &models.Registry{ Credential: &models.RegistryCredential{ AccessKey: opts.Credential.AccessKey, AccessSecret: opts.Credential.AccessSecret, Type: opts.Credential.Type, }, Description: opts.Description, Insecure: opts.Insecure, Name: opts.Name, Type: opts.Type, URL: opts.URL, }, }, ) if err != nil { return err } log.Infof("Registry %s created", opts.Name) return nil } func DeleteRegistry(registryName int64) error { ctx, client, err := utils.ContextWithClient() if err != nil { return err } _, err = client.Registry.DeleteRegistry(ctx, ®istry.DeleteRegistryParams{ID: registryName}) if err != nil { return err } log.Info("registry deleted successfully") return nil } func InfoRegistry(registryId int64) error { ctx, client, err := utils.ContextWithClient() if err != nil { return err } response, err := client.Registry.GetRegistry(ctx, ®istry.GetRegistryParams{ID: registryId}) if err != nil { return err } utils.PrintPayloadInJSONFormat(response.Payload) return nil } func GetRegistry(registryId int64) error { ctx, client, err := utils.ContextWithClient() if err != nil { return err } response, err := client.Registry.GetRegistry(ctx, ®istry.GetRegistryParams{ID: registryId}) if err != nil { return err } utils.PrintPayloadInJSONFormat(response.GetPayload()) return nil } func UpdateRegistry(updateView *CreateRegView, projectID int64) error { ctx, client, err := utils.ContextWithClient() if err != nil { return err } registryUpdate := &models.RegistryUpdate{ Name: &updateView.Name, Description: &updateView.Description, URL: &updateView.URL, AccessKey: &updateView.Credential.AccessKey, AccessSecret: &updateView.Credential.AccessSecret, CredentialType: &updateView.Credential.Type, Insecure: &updateView.Insecure, } _, err = client.Registry.UpdateRegistry( ctx, ®istry.UpdateRegistryParams{ID: projectID, Registry: registryUpdate}, ) if err != nil { return err } log.Info("registry updated successfully") return nil } // Get List of Registry Providers func GetRegistryProviders() ([]string, error) { ctx, client, err := utils.ContextWithClient() if err != nil { return nil, err } response, err := client.Registry.ListRegistryProviderTypes( ctx, ®istry.ListRegistryProviderTypesParams{}, ) if err != nil { return nil, err } return response.Payload, nil } 0707010000007B000081A40000000000000000000000016717AEFE0000000C000000000000000000000000000000000000003000000000harbor-cli-0.0.2/pkg/api/replication_handler.gopackage api 0707010000007C000081A40000000000000000000000016717AEFE00000542000000000000000000000000000000000000002F00000000harbor-cli-0.0.2/pkg/api/repository_handler.gopackage api import ( "github.com/goharbor/go-client/pkg/sdk/v2.0/client/repository" "github.com/goharbor/harbor-cli/pkg/utils" log "github.com/sirupsen/logrus" ) func RepoDelete(projectName, repoName string) error { ctx, client, err := utils.ContextWithClient() if err != nil { return err } _, err = client.Repository.DeleteRepository(ctx, &repository.DeleteRepositoryParams{ProjectName: projectName, RepositoryName: repoName}) if err != nil { return err } log.Infof("Repository %s/%s deleted successfully", projectName, repoName) return nil } func RepoInfo(projectName, repoName string) error { ctx, client, err := utils.ContextWithClient() if err != nil { return err } response, err := client.Repository.GetRepository(ctx, &repository.GetRepositoryParams{ProjectName: projectName, RepositoryName: repoName}) if err != nil { return err } utils.PrintPayloadInJSONFormat(response.Payload) return nil } func ListRepository(projectName string) (repository.ListRepositoriesOK, error) { ctx, client, err := utils.ContextWithClient() if err != nil { return repository.ListRepositoriesOK{}, err } response, err := client.Repository.ListRepositories(ctx, &repository.ListRepositoriesParams{ProjectName: projectName}) if err != nil { return repository.ListRepositoriesOK{}, err } return *response, nil } 0707010000007D000081A40000000000000000000000016717AEFE0000021A000000000000000000000000000000000000002200000000harbor-cli-0.0.2/pkg/api/types.gopackage api type ListFlags struct { Name string Page int64 PageSize int64 Q string Sort string Public bool } // CreateView for Registry type CreateRegView struct { Name string Type string Description string URL string Credential RegistryCredential Insecure bool } // Credential for Registry type RegistryCredential struct { AccessKey string `json:"access_key,omitempty"` Type string `json:"type,omitempty"` AccessSecret string `json:"access_secret,omitempty"` } 0707010000007E000081A40000000000000000000000016717AEFE00000700000000000000000000000000000000000000002900000000harbor-cli-0.0.2/pkg/api/user_handler.gopackage api import ( "github.com/goharbor/go-client/pkg/sdk/v2.0/client/user" "github.com/goharbor/go-client/pkg/sdk/v2.0/models" "github.com/goharbor/harbor-cli/pkg/utils" "github.com/goharbor/harbor-cli/pkg/views/user/create" log "github.com/sirupsen/logrus" ) func CreateUser(opts create.CreateView) error { ctx, client, err := utils.ContextWithClient() if err != nil { return err } response, err := client.User.CreateUser(ctx, &user.CreateUserParams{ UserReq: &models.UserCreationReq{ Email: opts.Email, Realname: opts.Realname, Comment: opts.Comment, Password: opts.Password, Username: opts.Username, }, }) if err != nil { return err } if response != nil { log.Infof("User `%s` created successfully", opts.Username) } return nil } func DeleteUser(userId int64) error { ctx, client, err := utils.ContextWithClient() if err != nil { return err } _, err = client.User.DeleteUser(ctx, &user.DeleteUserParams{UserID: userId}) if err != nil { return err } log.Infof("User deleted successfully with id %d", userId) return nil } func ElevateUser(userId int64) error { ctx, client, err := utils.ContextWithClient() if err != nil { return err } UserSysAdminFlag := &models.UserSysAdminFlag{ SysadminFlag: true, } _, err = client.User.SetUserSysAdmin(ctx, &user.SetUserSysAdminParams{UserID: userId, SysadminFlag: UserSysAdminFlag}) if err != nil { return err } log.Infof("user elevated role to admin successfully with id %d", userId) return nil } func ListUsers() (*user.ListUsersOK, error) { ctx, client, err := utils.ContextWithClient() if err != nil { return nil, err } response, err := client.User.ListUsers(ctx, &user.ListUsersParams{}) if err != nil { return nil, err } return response, nil } 0707010000007F000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000001F00000000harbor-cli-0.0.2/pkg/constants07070100000080000081A40000000000000000000000016717AEFE000000ED000000000000000000000000000000000000002C00000000harbor-cli-0.0.2/pkg/constants/constants.gopackage constants const ( HarborCredentialName = "HARBORCREDENTIALNAME" CredentialNameOption = "credential-name" CredentialNameHelp = "Name of the credential to use for authentication (defaults to the current logged in session)" ) 07070100000081000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000001C00000000harbor-cli-0.0.2/pkg/prompt07070100000082000081A40000000000000000000000016717AEFE000007E0000000000000000000000000000000000000002600000000harbor-cli-0.0.2/pkg/prompt/prompt.gopackage prompt import ( "github.com/goharbor/harbor-cli/pkg/api" aview "github.com/goharbor/harbor-cli/pkg/views/artifact/select" tview "github.com/goharbor/harbor-cli/pkg/views/artifact/tags/select" pview "github.com/goharbor/harbor-cli/pkg/views/project/select" rview "github.com/goharbor/harbor-cli/pkg/views/registry/select" repoView "github.com/goharbor/harbor-cli/pkg/views/repository/select" uview "github.com/goharbor/harbor-cli/pkg/views/user/select" log "github.com/sirupsen/logrus" ) func GetRegistryNameFromUser() int64 { registryId := make(chan int64) go func() { response, _ := api.ListRegistries() rview.RegistryList(response.Payload, registryId) }() return <-registryId } func GetProjectNameFromUser() string { projectName := make(chan string) go func() { response, _ := api.ListProject() pview.ProjectList(response.Payload, projectName) }() return <-projectName } func GetRepoNameFromUser(projectName string) string { repositoryName := make(chan string) go func() { response, err := api.ListRepository(projectName) if err != nil { log.Fatal(err) } repoView.RepositoryList(response.Payload, repositoryName) }() return <-repositoryName } // complete the function func GetReferenceFromUser(repositoryName string, projectName string) string { reference := make(chan string) go func() { response, _ := api.ListArtifact(projectName, repositoryName) aview.ListArtifacts(response.Payload, reference) }() return <-reference } func GetUserIdFromUser() int64 { userId := make(chan int64) go func() { response, _ := api.ListUsers() uview.UserList(response.Payload, userId) }() return <-userId } func GetTagFromUser(repoName, projectName, reference string) string { tag := make(chan string) go func() { response, _ := api.ListTags(projectName, repoName, reference) tview.ListTags(response.Payload, tag) }() return <-tag } func GetTagNameFromUser() string { repoName := make(chan string) go func() { }() return <-repoName } 07070100000083000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000001B00000000harbor-cli-0.0.2/pkg/utils07070100000084000081A40000000000000000000000016717AEFE000005B2000000000000000000000000000000000000002500000000harbor-cli-0.0.2/pkg/utils/client.gopackage utils import ( "context" "fmt" "os" "sync" "github.com/goharbor/go-client/pkg/harbor" v2client "github.com/goharbor/go-client/pkg/sdk/v2.0/client" log "github.com/sirupsen/logrus" "github.com/spf13/viper" ) var ( clientInstance *v2client.HarborAPI clientOnce sync.Once clientErr error ) func GetClient() (*v2client.HarborAPI, error) { clientOnce.Do(func() { credentialName := viper.GetString("current-credential-name") clientInstance = GetClientByCredentialName(credentialName) if clientErr != nil { log.Errorf("failed to initialize client: %v", clientErr) } }) return clientInstance, clientErr } func ContextWithClient() (context.Context, *v2client.HarborAPI, error) { client, err := GetClient() if err != nil { return nil, nil, err } ctx := context.Background() return ctx, client, nil } func GetClientByConfig(clientConfig *harbor.ClientSetConfig) *v2client.HarborAPI { cs, err := harbor.NewClientSet(clientConfig) if err != nil { panic(err) } return cs.V2() } // Returns Harbor v2 client after resolving the credential name func GetClientByCredentialName(credentialName string) *v2client.HarborAPI { credential, err := GetCredentials(credentialName) if err != nil { fmt.Print(err) os.Exit(1) } clientConfig := &harbor.ClientSetConfig{ URL: credential.ServerAddress, Username: credential.Username, Password: credential.Password, } return GetClientByConfig(clientConfig) } 07070100000085000081A40000000000000000000000016717AEFE000007D8000000000000000000000000000000000000002500000000harbor-cli-0.0.2/pkg/utils/config.gopackage utils import ( "log" "os" "path/filepath" "github.com/spf13/viper" ) type Credential struct { Name string `yaml:"name"` Username string `yaml:"username"` Password string `yaml:"password"` ServerAddress string `yaml:"serveraddress"` } type HarborConfig struct { CurrentCredentialName string `yaml:"current-credential-name"` Credentials []Credential `yaml:"credentials"` } var ( HarborFolder string DefaultConfigPath string ) func SetLocation() { home, err := os.UserHomeDir() if err != nil { log.Fatal(err) } HarborFolder = filepath.Join(home, ".harbor") DefaultConfigPath = filepath.Join(HarborFolder, "config.yaml") } func (hc *HarborConfig) GetCurrentCredentialName() string { return hc.CurrentCredentialName } func CreateConfigFile() error { if _, err := os.Stat(DefaultConfigPath); os.IsNotExist(err) { if _, err := os.Create(DefaultConfigPath); err != nil { return err } } return nil } func AddCredentialsToConfigFile(credential Credential, configPath string) error { if _, err := os.Stat(configPath); os.IsNotExist(err) { return err } viper.SetConfigFile(configPath) err := viper.ReadInConfig() if err != nil { return err } c := HarborConfig{} err = viper.Unmarshal(&c) if err != nil { return err } if c.Credentials == nil { c.Credentials = []Credential{} } c.Credentials = append(c.Credentials, credential) c.CurrentCredentialName = credential.Name viper.Set("current-credential-name", credential.Name) viper.Set("credentials", c.Credentials) err = viper.WriteConfig() if err != nil { return err } return nil } func GetCredentials(credentialName string) (Credential, error) { err := viper.ReadInConfig() if err != nil { return Credential{}, err } c := HarborConfig{} err = viper.Unmarshal(&c) if err != nil { return Credential{}, err } for _, cred := range c.Credentials { if cred.Name == credentialName { return cred, nil } } return Credential{}, nil } 07070100000086000081A40000000000000000000000016717AEFE0000000E000000000000000000000000000000000000002400000000harbor-cli-0.0.2/pkg/utils/error.gopackage utils 07070100000087000081A40000000000000000000000016717AEFE00000C8C000000000000000000000000000000000000002500000000harbor-cli-0.0.2/pkg/utils/helper.gopackage utils import ( "errors" "fmt" "regexp" "strconv" "strings" "time" ) func FormatCreatedTime(timestamp string) (string, error) { t, err := time.Parse(time.RFC3339Nano, timestamp) if err != nil { return "", err } duration := time.Since(t) minutes := int(duration.Minutes()) hours := int(duration.Hours()) days := int(duration.Hours() / 24) if minutes < 60 { return fmt.Sprintf("%d minute ago", minutes), nil } else if hours < 24 { return fmt.Sprintf("%d hour ago", hours), nil } else { return fmt.Sprintf("%d day ago", days), nil } } func FormatUrl(url string) string { // Check if URL starts with "http://" or "https://" if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") { // If not, prepend "https://" url = "https://" + url } return url } func FormatSize(size int64) string { mbSize := float64(size) / (1024 * 1024) return fmt.Sprintf("%.2fMiB", mbSize) } func ValidateUserName(username string) bool { pattern := `^[a-zA-Z0-9]{1,255}$` re := regexp.MustCompile(pattern) return re.MatchString(username) } func ValidateEmail(email string) bool { pattern := `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$` re := regexp.MustCompile(pattern) return re.MatchString(email) } func ValidateFL(name string) bool { pattern := `^[A-Za-z]{1,20}\s[A-Za-z]{1,20}$` re := regexp.MustCompile(pattern) return re.MatchString(name) } // check if the password format is vaild func ValidatePassword(password string) error { if len(password) < 8 || len(password) > 256 { return errors.New("worong! the password length must be at least 8 characters and at most 256 characters") } // checking the password has a minimum of one lower case letter if done, _ := regexp.MatchString("([a-z])+", password); !done { return errors.New("worong! the password doesn't have a lowercase letter") } // checking the password has a minimmum of one upper case letter if done, _ := regexp.MatchString("([A-Z])+", password); !done { return errors.New("worong! the password doesn't have an upppercase letter") } // checking if the password has a minimum of one digit if done, _ := regexp.Match("([0-9])+", []byte(password)); !done { return errors.New("worong! the password doesn't have a digit number") } return nil } // check if the tag name is valid func ValidateTagName(tagName string) bool { pattern := `^[\w][\w.-]{0,127}$` re := regexp.MustCompile(pattern) return re.MatchString(tagName) } // check if the project name is valid func ValidateProjectName(projectName string) bool { pattern := `^[a-z0-9][a-z0-9._-]{0,254}$` re := regexp.MustCompile(pattern) return re.MatchString(projectName) } func ValidateStorageLimit(sl string) error { storageLimit, err := strconv.Atoi(sl) if err != nil { return errors.New("the storage limit only takes integer values") } if storageLimit < -1 || (storageLimit > -1 && storageLimit < 0) || storageLimit > 1024 { return errors.New("the maximum value for the storage cannot exceed 1024 terabytes and -1 for no limit") } return nil } func ValidateRegistryName(rn string) bool { pattern := `^[\w][\w.-]{0,63}$` re := regexp.MustCompile(pattern) return re.MatchString(rn) } 07070100000088000081A40000000000000000000000016717AEFE0000035F000000000000000000000000000000000000002400000000harbor-cli-0.0.2/pkg/utils/utils.gopackage utils import ( "encoding/json" "fmt" "strings" log "github.com/sirupsen/logrus" ) // Returns Harbor v2 client for given clientConfig func PrintPayloadInJSONFormat(payload any) { if payload == nil { return } jsonStr, err := json.MarshalIndent(payload, "", " ") if err != nil { panic(err) } fmt.Println(string(jsonStr)) } func ParseProjectRepo(projectRepo string) (string, string) { split := strings.Split(projectRepo, "/") if len(split) != 2 { log.Fatalf("invalid project/repository format: %s", projectRepo) } return split[0], split[1] } func ParseProjectRepoReference(projectRepoReference string) (string, string, string) { split := strings.Split(projectRepoReference, "/") if len(split) != 3 { log.Fatalf("invalid project/repository/reference format: %s", projectRepoReference) } return split[0], split[1], split[2] } 07070100000089000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000001B00000000harbor-cli-0.0.2/pkg/views0707010000008A000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002400000000harbor-cli-0.0.2/pkg/views/artifact0707010000008B000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002900000000harbor-cli-0.0.2/pkg/views/artifact/list0707010000008C000081A40000000000000000000000016717AEFE000004E9000000000000000000000000000000000000003100000000harbor-cli-0.0.2/pkg/views/artifact/list/view.gopackage list import ( "fmt" "github.com/charmbracelet/bubbles/table" tea "github.com/charmbracelet/bubbletea" "github.com/goharbor/go-client/pkg/sdk/v2.0/models" "github.com/goharbor/harbor-cli/pkg/utils" "github.com/goharbor/harbor-cli/pkg/views/base/tablelist" "os" "strconv" ) var columns = []table.Column{ {Title: "ID", Width: 6}, {Title: "Artifact Digest", Width: 20}, {Title: "Type", Width: 12}, {Title: "Size", Width: 12}, {Title: "Vulnerabilities", Width: 15}, {Title: "Push Time", Width: 12}, } func ListArtifacts(artifacts []*models.Artifact) { var rows []table.Row for _, artifact := range artifacts { pushTime, _ := utils.FormatCreatedTime(artifact.PushTime.String()) artifactSize := utils.FormatSize(artifact.Size) var totalVulnerabilities int64 for _, scan := range artifact.ScanOverview { totalVulnerabilities += scan.Summary.Total } rows = append(rows, table.Row{ strconv.FormatInt(int64(artifact.ID), 10), artifact.Digest[:16], artifact.Type, artifactSize, strconv.FormatInt(totalVulnerabilities, 10), pushTime, }) } m := tablelist.NewModel(columns, rows, len(rows)) if _, err := tea.NewProgram(m).Run(); err != nil { fmt.Println("Error running program:", err) os.Exit(1) } } 0707010000008D000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002B00000000harbor-cli-0.0.2/pkg/views/artifact/select0707010000008E000081A40000000000000000000000016717AEFE000002B1000000000000000000000000000000000000003300000000harbor-cli-0.0.2/pkg/views/artifact/select/view.gopackage registry import ( "fmt" "os" "github.com/charmbracelet/bubbles/list" tea "github.com/charmbracelet/bubbletea" "github.com/goharbor/go-client/pkg/sdk/v2.0/models" "github.com/goharbor/harbor-cli/pkg/views/base/selection" ) func ListArtifacts(artifacts []*models.Artifact, choice chan<- string) { itemsList := make([]list.Item, len(artifacts)) for i, a := range artifacts { itemsList[i] = selection.Item(a.Digest) } m := selection.NewModel(itemsList, "Artifact") p, err := tea.NewProgram(m, tea.WithAltScreen()).Run() if err != nil { fmt.Println("Error running program:", err) os.Exit(1) } if p, ok := p.(selection.Model); ok { choice <- p.Choice } } 0707010000008F000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002900000000harbor-cli-0.0.2/pkg/views/artifact/tags07070100000090000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000003000000000harbor-cli-0.0.2/pkg/views/artifact/tags/create07070100000091000081A40000000000000000000000016717AEFE000002C0000000000000000000000000000000000000003800000000harbor-cli-0.0.2/pkg/views/artifact/tags/create/view.gopackage create import ( "errors" "strings" "github.com/charmbracelet/huh" "github.com/goharbor/harbor-cli/pkg/utils" log "github.com/sirupsen/logrus" ) func CreateTagView(tagName *string) { theme := huh.ThemeCharm() err := huh.NewForm( huh.NewGroup( huh.NewInput(). Title("Tag Name"). Value(tagName). Validate(func(str string) error { if strings.TrimSpace(str) == "" { return errors.New("tag name cannot be empty or only spaces") } if isVaild := utils.ValidateTagName(str); !isVaild { return errors.New("please enter the correct tag name format") } return nil }), ), ).WithTheme(theme).Run() if err != nil { log.Fatal(err) } } 07070100000092000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000003000000000harbor-cli-0.0.2/pkg/views/artifact/tags/select07070100000093000081A40000000000000000000000016717AEFE0000028E000000000000000000000000000000000000003800000000harbor-cli-0.0.2/pkg/views/artifact/tags/select/view.gopackage registry import ( "fmt" "os" "github.com/charmbracelet/bubbles/list" tea "github.com/charmbracelet/bubbletea" "github.com/goharbor/go-client/pkg/sdk/v2.0/models" "github.com/goharbor/harbor-cli/pkg/views/base/selection" ) func ListTags(tag []*models.Tag, choice chan<- string) { itemsList := make([]list.Item, len(tag)) for i, t := range tag { itemsList[i] = selection.Item(t.Name) } m := selection.NewModel(itemsList, "Tag") p, err := tea.NewProgram(m, tea.WithAltScreen()).Run() if err != nil { fmt.Println("Error running program:", err) os.Exit(1) } if p, ok := p.(selection.Model); ok { choice <- p.Choice } } 07070100000094000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002000000000harbor-cli-0.0.2/pkg/views/base07070100000095000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002A00000000harbor-cli-0.0.2/pkg/views/base/selection07070100000096000081A40000000000000000000000016717AEFE0000077E000000000000000000000000000000000000003300000000harbor-cli-0.0.2/pkg/views/base/selection/model.gopackage selection import ( "fmt" "io" "strings" "github.com/charmbracelet/bubbles/list" tea "github.com/charmbracelet/bubbletea" "github.com/goharbor/harbor-cli/pkg/views" ) const listHeight = 14 type Item string func (i Item) FilterValue() string { return "" } type ItemDelegate struct{} func (d ItemDelegate) Height() int { return 1 } func (d ItemDelegate) Spacing() int { return 0 } func (d ItemDelegate) Update(_ tea.Msg, _ *list.Model) tea.Cmd { return nil } func (d ItemDelegate) Render(w io.Writer, m list.Model, index int, listItem list.Item) { i, ok := listItem.(Item) if !ok { return } str := fmt.Sprintf("%d. %s", index+1, i) fn := views.ItemStyle.Render if index == m.Index() { fn = func(s ...string) string { return views.SelectedItemStyle.Render("> " + strings.Join(s, " ")) } } fmt.Fprint(w, fn(str)) } type Model struct { List list.Model Choice string } func NewModel(items []list.Item, construct string) Model { const defaultWidth = 20 l := list.New(items, ItemDelegate{}, defaultWidth, listHeight) l.Title = "Select an " + construct l.SetShowStatusBar(false) l.SetFilteringEnabled(false) l.Styles.Title = views.TitleStyle l.Styles.PaginationStyle = views.PaginationStyle l.Styles.HelpStyle = views.HelpStyle return Model{List: l} } func (m Model) Init() tea.Cmd { return nil } func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.WindowSizeMsg: m.List.SetWidth(msg.Width) return m, nil case tea.KeyMsg: switch keypress := msg.String(); keypress { case "enter": i, ok := m.List.SelectedItem().(Item) if ok { m.Choice = string(i) } return m, tea.Quit } } var cmd tea.Cmd m.List, cmd = m.List.Update(msg) return m, cmd } func (m Model) View() string { if m.Choice != "" { return "" } return "\n" + m.List.View() } 07070100000097000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002A00000000harbor-cli-0.0.2/pkg/views/base/tablelist07070100000098000081A40000000000000000000000016717AEFE00000408000000000000000000000000000000000000003300000000harbor-cli-0.0.2/pkg/views/base/tablelist/model.gopackage tablelist import ( "github.com/charmbracelet/bubbles/table" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" "github.com/goharbor/harbor-cli/pkg/views" ) type Model struct { Table table.Model } func NewModel(columns []table.Column, rows []table.Row, height int) Model { t := table.New( table.WithColumns(columns), table.WithRows(rows), table.WithFocused(true), table.WithHeight(height), ) // Set the styles for the table s := table.DefaultStyles() s.Header = s.Header. BorderStyle(lipgloss.NormalBorder()). BorderBottom(true). Bold(false) s.Selected = s.Selected. Foreground(s.Cell.GetForeground()). Background(s.Cell.GetBackground()). Bold(false) t.SetStyles(s) return Model{Table: t} } func (m Model) Init() tea.Cmd { return tea.Quit } func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { var cmd tea.Cmd m.Table, cmd = m.Table.Update(msg) return m, cmd } func (m Model) View() string { return views.BaseStyle.Render(m.Table.View()) + "\n" } 07070100000099000081A40000000000000000000000016717AEFE0000016B000000000000000000000000000000000000002B00000000harbor-cli-0.0.2/pkg/views/confirmation.gopackage views import ( "github.com/charmbracelet/huh" log "github.com/sirupsen/logrus" ) func ConfirmElevation() (bool, error) { var confirm bool err := huh.NewConfirm(). Title("Are you sure to elevate the user to admin role?"). Affirmative("Yes"). Negative("No"). Value(&confirm).Run() if err != nil { log.Fatal(err) } return confirm, nil } 0707010000009A000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002200000000harbor-cli-0.0.2/pkg/views/health0707010000009B000081A40000000000000000000000016717AEFE000003F2000000000000000000000000000000000000002A00000000harbor-cli-0.0.2/pkg/views/health/view.gopackage health import ( "fmt" "os" "github.com/charmbracelet/bubbles/table" tea "github.com/charmbracelet/bubbletea" "github.com/goharbor/go-client/pkg/sdk/v2.0/client/health" "github.com/goharbor/harbor-cli/pkg/views" "github.com/goharbor/harbor-cli/pkg/views/base/tablelist" ) var columns = []table.Column{ {Title: "Component", Width: 18}, {Title: "Status", Width: 26}, } func PrintHealthStatus(status *health.GetHealthOK) { var rows []table.Row fmt.Printf("Harbor Health Status:: %s\n", styleStatus(status.Payload.Status)) for _, component := range status.Payload.Components { rows = append(rows, table.Row{ component.Name, styleStatus(component.Status), }) } m := tablelist.NewModel(columns, rows, len(rows)) if _, err := tea.NewProgram(m).Run(); err != nil { fmt.Println("Error running program:", err) os.Exit(1) } } func styleStatus(status string) string { if status == "healthy" { return views.GreenStyle.Render(status) } return views.RedStyle.Render(status) } 0707010000009C000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002100000000harbor-cli-0.0.2/pkg/views/login0707010000009D000081A40000000000000000000000016717AEFE0000072F000000000000000000000000000000000000002B00000000harbor-cli-0.0.2/pkg/views/login/create.gopackage login import ( "errors" "net/url" "strings" "github.com/charmbracelet/huh" "github.com/goharbor/harbor-cli/pkg/utils" log "github.com/sirupsen/logrus" ) type LoginView struct { Server string Username string Password string Name string } func CreateView(loginView *LoginView) { theme := huh.ThemeCharm() err := huh.NewForm( huh.NewGroup( huh.NewInput(). Title("Server"). Value(&loginView.Server). Validate(func(str string) error { if strings.TrimSpace(str) == "" { return errors.New("server cannot be empty or only spaces") } formattedUrl := utils.FormatUrl(str) if _, err := url.ParseRequestURI(formattedUrl); err != nil { return errors.New("please enter the correct server format") } return nil }), huh.NewInput(). Title("User Name"). Value(&loginView.Username). Validate(func(str string) error { if strings.TrimSpace(str) == "" { return errors.New("username cannot be empty or only spaces") } if isValid := utils.ValidateUserName(str); !isValid { return errors.New("please enter correct username format") } return nil }), huh.NewInput(). Title("Password"). EchoMode(huh.EchoModePassword). Value(&loginView.Password). Validate(func(str string) error { if strings.TrimSpace(str) == "" { return errors.New("password cannot be empty or only spaces") } if err := utils.ValidatePassword(str); err != nil { return err } return nil }), huh.NewInput(). Title("Name of Credential"). Value(&loginView.Name). Validate(func(str string) error { if str == "" { return errors.New("credential name cannot be empty") } return nil }), ), ).WithTheme(theme).Run() if err != nil { log.Fatal(err) } } 0707010000009E000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002300000000harbor-cli-0.0.2/pkg/views/project0707010000009F000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002A00000000harbor-cli-0.0.2/pkg/views/project/create070701000000A0000081A40000000000000000000000016717AEFE00000B90000000000000000000000000000000000000003200000000harbor-cli-0.0.2/pkg/views/project/create/view.gopackage create import ( "context" "errors" "fmt" "strings" "github.com/charmbracelet/huh" "github.com/goharbor/go-client/pkg/sdk/v2.0/client/registry" "github.com/goharbor/harbor-cli/pkg/utils" log "github.com/sirupsen/logrus" "github.com/spf13/viper" ) type CreateView struct { ProjectName string Public bool RegistryID string StorageLimit string ProxyCache bool } func getRegistryList() (*registry.ListRegistriesOK, error) { credentialName := viper.GetString("current-credential-name") client := utils.GetClientByCredentialName(credentialName) ctx := context.Background() response, err := client.Registry.ListRegistries(ctx, ®istry.ListRegistriesParams{}) if err != nil { return nil, err } return response, nil } func CreateProjectView(createView *CreateView) { theme := huh.ThemeCharm() // I want it to be a map of registry ID to registry name registries, _ := getRegistryList() registryOptions := map[string]string{} for _, registry := range registries.Payload { regiId := fmt.Sprintf("%d", registry.ID) registryOptions[regiId] = fmt.Sprintf("%s (%s)", registry.Name, registry.URL) } var registrySelectOptions []huh.Option[string] for id, name := range registryOptions { registrySelectOptions = append(registrySelectOptions, huh.NewOption(name, id)) } err := huh.NewForm( huh.NewGroup( huh.NewInput(). Title("Project Name"). Value(&createView.ProjectName). Validate(func(str string) error { if strings.TrimSpace(str) == "" { return errors.New("project name cannot be empty or only spaces") } if isValid := utils.ValidateProjectName(str); !isValid { return errors.New("please enter correct project name format") } return nil }), huh.NewConfirm(). Title("Public"). Value(&createView.Public). Affirmative("yes"). Negative("no"), huh.NewInput(). Title("Storage Limit"). Value(&createView.StorageLimit). Validate(func(str string) error { // Assuming StorageLimit is an int64 if strings.TrimSpace(str) == "" { return errors.New("storage limit cannot be empty or only spaces") } if err := utils.ValidateStorageLimit(str); err != nil { return err } return nil }), huh.NewConfirm(). Title("Proxy Cache"). Value(&createView.ProxyCache). Affirmative("yes"). Negative("no"), ), huh.NewGroup( huh.NewSelect[string](). Validate(func(str string) error { if createView.ProxyCache && str == "" { return errors.New("registry ID cannot be empty") } return nil }). Description("Select a registry to reference when creating the proxy cache project"). Title("Registry ID"). Value(&createView.RegistryID). Options(registrySelectOptions...), ).WithHideFunc(func() bool { return !createView.ProxyCache || len(registryOptions) == 0 }), ).WithTheme(theme).Run() if err != nil { log.Fatal(err) } } 070701000000A1000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002800000000harbor-cli-0.0.2/pkg/views/project/list070701000000A2000081A40000000000000000000000016717AEFE0000053F000000000000000000000000000000000000003000000000harbor-cli-0.0.2/pkg/views/project/list/view.gopackage list import ( "fmt" "os" "strconv" "github.com/charmbracelet/bubbles/table" tea "github.com/charmbracelet/bubbletea" "github.com/goharbor/go-client/pkg/sdk/v2.0/models" "github.com/goharbor/harbor-cli/pkg/utils" "github.com/goharbor/harbor-cli/pkg/views/base/tablelist" ) var columns = []table.Column{ {Title: "ID", Width: 6}, {Title: "Project Name", Width: 12}, {Title: "Access Level", Width: 12}, {Title: "Type", Width: 12}, {Title: "Repo Count", Width: 12}, {Title: "Creation Time", Width: 30}, } func ListProjects(projects []*models.Project) { var rows []table.Row for _, project := range projects { accessLevel := "public" if project.Metadata.Public != "true" { accessLevel = "private" } projectType := "project" if project.RegistryID != 0 { projectType = "proxy cache" } createdTime, _ := utils.FormatCreatedTime(project.CreationTime.String()) rows = append(rows, table.Row{ strconv.FormatInt(int64(project.ProjectID), 10), // ProjectID project.Name, // Project Name accessLevel, // Access Level projectType, // Type strconv.FormatInt(project.RepoCount, 10), createdTime, // Creation Time }) } m := tablelist.NewModel(columns, rows, len(rows)) if _, err := tea.NewProgram(m).Run(); err != nil { fmt.Println("Error running program:", err) os.Exit(1) } } 070701000000A3000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002800000000harbor-cli-0.0.2/pkg/views/project/logs070701000000A4000081A40000000000000000000000016717AEFE000003AF000000000000000000000000000000000000003000000000harbor-cli-0.0.2/pkg/views/project/logs/view.gopackage project import ( "fmt" "os" "github.com/charmbracelet/bubbles/table" tea "github.com/charmbracelet/bubbletea" "github.com/goharbor/go-client/pkg/sdk/v2.0/models" "github.com/goharbor/harbor-cli/pkg/utils" "github.com/goharbor/harbor-cli/pkg/views/base/tablelist" ) var columns = []table.Column{ {Title: "Username", Width: 12}, {Title: "Resource", Width: 24}, {Title: "Resouce Type", Width: 12}, {Title: "Operation", Width: 12}, {Title: "Timestamp", Width: 30}, } func LogsProject(logs []*models.AuditLog) { var rows []table.Row for _, log := range logs { createTime, _ := utils.FormatCreatedTime(log.OpTime.String()) rows = append(rows, table.Row{ log.Username, log.Resource, log.ResourceType, log.Operation, createTime, }) } m := tablelist.NewModel(columns, rows, len(rows)) if _, err := tea.NewProgram(m).Run(); err != nil { fmt.Println("Error running program:", err) os.Exit(1) } } 070701000000A5000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002A00000000harbor-cli-0.0.2/pkg/views/project/select070701000000A6000081A40000000000000000000000016717AEFE00000297000000000000000000000000000000000000003200000000harbor-cli-0.0.2/pkg/views/project/select/view.gopackage project import ( "fmt" "os" "github.com/charmbracelet/bubbles/list" tea "github.com/charmbracelet/bubbletea" "github.com/goharbor/go-client/pkg/sdk/v2.0/models" "github.com/goharbor/harbor-cli/pkg/views/base/selection" ) func ProjectList(project []*models.Project, choice chan<- string) { items := make([]list.Item, len(project)) for i, p := range project { items[i] = selection.Item(p.Name) } m := selection.NewModel(items, "Project") p, err := tea.NewProgram(m, tea.WithAltScreen()).Run() if err != nil { fmt.Println("Error running program:", err) os.Exit(1) } if p, ok := p.(selection.Model); ok { choice <- p.Choice } } 070701000000A7000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002400000000harbor-cli-0.0.2/pkg/views/registry070701000000A8000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002B00000000harbor-cli-0.0.2/pkg/views/registry/create070701000000A9000081A40000000000000000000000016717AEFE00000A54000000000000000000000000000000000000003300000000harbor-cli-0.0.2/pkg/views/registry/create/view.gopackage create import ( "errors" "net/url" "strconv" "strings" "github.com/charmbracelet/huh" "github.com/goharbor/harbor-cli/pkg/api" "github.com/goharbor/harbor-cli/pkg/utils" log "github.com/sirupsen/logrus" ) // struct to hold registry options type RegistryOption struct { ID string Name string } func CreateRegistryView(createView *api.CreateRegView) { registries, _ := api.GetRegistryProviders() // Initialize a slice to hold registry options var registryOptions []RegistryOption // Iterate over registries to populate registryOptions for i, registry := range registries { registryOptions = append(registryOptions, RegistryOption{ ID: strconv.FormatInt(int64(i), 10), Name: registry, }) } // Initialize a slice to hold select options var registrySelectOptions []huh.Option[string] // Iterate over registryOptions to populate registrySelectOptions for _, option := range registryOptions { registrySelectOptions = append( registrySelectOptions, huh.NewOption(option.Name, option.Name), ) } theme := huh.ThemeCharm() err := huh.NewForm( huh.NewGroup( huh.NewSelect[string](). Title("Select a Registry Provider"). Value(&createView.Type). Options(registrySelectOptions...). Validate(func(str string) error { if str == "" { return errors.New("registry provider cannot be empty") } return nil }), huh.NewInput(). Title("Name"). Value(&createView.Name). Validate(func(str string) error { if strings.TrimSpace(str) == "" { return errors.New("name cannot be empty or only spaces") } if isVaild := utils.ValidateRegistryName(str); !isVaild { return errors.New("please enter the correct name format") } return nil }), huh.NewInput(). Title("Description"). Value(&createView.Description), huh.NewInput(). Title("URL"). Value(&createView.URL). Validate(func(str string) error { if strings.TrimSpace(str) == "" { return errors.New("url cannot be empty or only spaces") } formattedUrl := utils.FormatUrl(str) if _, err := url.ParseRequestURI(formattedUrl); err != nil { return errors.New("please enter the correct url format") } return nil }), huh.NewInput(). Title("Access Key"). Value(&createView.Credential.AccessKey), huh.NewInput(). Title("Access Secret"). Value(&createView.Credential.AccessSecret), huh.NewConfirm(). Title("Verify Cert"). Value(&createView.Insecure). Affirmative("yes"). Negative("no"), ), ).WithTheme(theme).Run() if err != nil { log.Fatal(err) } } 070701000000AA000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002900000000harbor-cli-0.0.2/pkg/views/registry/list070701000000AB000081A40000000000000000000000016717AEFE00000459000000000000000000000000000000000000003100000000harbor-cli-0.0.2/pkg/views/registry/list/view.gopackage list import ( "fmt" "os" "github.com/charmbracelet/bubbles/table" tea "github.com/charmbracelet/bubbletea" "github.com/goharbor/go-client/pkg/sdk/v2.0/models" "github.com/goharbor/harbor-cli/pkg/utils" "github.com/goharbor/harbor-cli/pkg/views/base/tablelist" ) var columns = []table.Column{ {Title: "ID", Width: 6}, {Title: "Name", Width: 12}, {Title: "Status", Width: 12}, {Title: "Endpoint URL", Width: 26}, {Title: "Provider", Width: 12}, {Title: "Creation Time", Width: 24}, // {Title: "Verify Remote Cert", Width: 12}, // {Title: "Description", Width: 12}, } func ListRegistry(registry []*models.Registry) { var rows []table.Row for _, regis := range registry { createdTime, _ := utils.FormatCreatedTime(regis.CreationTime.String()) rows = append(rows, table.Row{ fmt.Sprintf("%d", regis.ID), regis.Name, regis.Status, regis.URL, regis.Type, createdTime, // regis.Description, }) } m := tablelist.NewModel(columns, rows, len(rows)) if _, err := tea.NewProgram(m).Run(); err != nil { fmt.Println("Error running program:", err) os.Exit(1) } } 070701000000AC000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002B00000000harbor-cli-0.0.2/pkg/views/registry/select070701000000AD000081A40000000000000000000000016717AEFE000002E4000000000000000000000000000000000000003300000000harbor-cli-0.0.2/pkg/views/registry/select/view.gopackage registry import ( "fmt" "os" "github.com/charmbracelet/bubbles/list" tea "github.com/charmbracelet/bubbletea" "github.com/goharbor/go-client/pkg/sdk/v2.0/models" "github.com/goharbor/harbor-cli/pkg/views/base/selection" ) func RegistryList(registry []*models.Registry, choice chan<- int64) { itemsList := make([]list.Item, len(registry)) items := map[string]int64{} for i, r := range registry { items[r.Name] = r.ID itemsList[i] = selection.Item(r.Name) } m := selection.NewModel(itemsList, "Registry") p, err := tea.NewProgram(m, tea.WithAltScreen()).Run() if err != nil { fmt.Println("Error running program:", err) os.Exit(1) } if p, ok := p.(selection.Model); ok { choice <- items[p.Choice] } } 070701000000AE000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002600000000harbor-cli-0.0.2/pkg/views/repository070701000000AF000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002B00000000harbor-cli-0.0.2/pkg/views/repository/list070701000000B0000081A40000000000000000000000016717AEFE000003BD000000000000000000000000000000000000003300000000harbor-cli-0.0.2/pkg/views/repository/list/view.gopackage list import ( "fmt" "os" "strconv" "github.com/charmbracelet/bubbles/table" tea "github.com/charmbracelet/bubbletea" "github.com/goharbor/go-client/pkg/sdk/v2.0/models" "github.com/goharbor/harbor-cli/pkg/utils" "github.com/goharbor/harbor-cli/pkg/views/base/tablelist" ) var columns = []table.Column{ {Title: "Name", Width: 24}, {Title: "Artifacts", Width: 12}, {Title: "Pulls", Width: 12}, {Title: "Last Modified Time", Width: 30}, } func ListRepositories(repos []*models.Repository) { var rows []table.Row for _, repo := range repos { createdTime, _ := utils.FormatCreatedTime(repo.UpdateTime.String()) rows = append(rows, table.Row{ repo.Name, fmt.Sprintf("%d", repo.ArtifactCount), strconv.FormatInt(repo.PullCount, 10), createdTime, }) } m := tablelist.NewModel(columns, rows, len(rows)) if _, err := tea.NewProgram(m).Run(); err != nil { fmt.Println("Error running program:", err) os.Exit(1) } } 070701000000B1000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002D00000000harbor-cli-0.0.2/pkg/views/repository/select070701000000B2000081A40000000000000000000000016717AEFE000002EE000000000000000000000000000000000000003500000000harbor-cli-0.0.2/pkg/views/repository/select/view.gopackage project import ( "fmt" "os" "strings" "github.com/charmbracelet/bubbles/list" tea "github.com/charmbracelet/bubbletea" "github.com/goharbor/go-client/pkg/sdk/v2.0/models" "github.com/goharbor/harbor-cli/pkg/views/base/selection" ) func RepositoryList(repos []*models.Repository, choice chan<- string) { itemsList := make([]list.Item, len(repos)) for i, r := range repos { split := strings.Split(r.Name, "/") itemsList[i] = selection.Item(strings.Join(split[1:], "/")) } m := selection.NewModel(itemsList, "Repository") p, err := tea.NewProgram(m, tea.WithAltScreen()).Run() if err != nil { fmt.Println("Error running program:", err) os.Exit(1) } if p, ok := p.(selection.Model); ok { choice <- p.Choice } } 070701000000B3000081A40000000000000000000000016717AEFE000002CF000000000000000000000000000000000000002500000000harbor-cli-0.0.2/pkg/views/styles.gopackage views import ( "github.com/charmbracelet/bubbles/list" "github.com/charmbracelet/lipgloss" ) var ( TitleStyle = lipgloss.NewStyle().MarginLeft(2) ItemStyle = lipgloss.NewStyle().PaddingLeft(4) SelectedItemStyle = lipgloss.NewStyle().PaddingLeft(2).Foreground(lipgloss.Color("170")) PaginationStyle = list.DefaultStyles().PaginationStyle.PaddingLeft(4) HelpStyle = list.DefaultStyles().HelpStyle.PaddingLeft(4).PaddingBottom(1) RedStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#FF0000")) GreenStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#04B575")) ) var BaseStyle = lipgloss.NewStyle(). BorderStyle(lipgloss.NormalBorder()).Padding(0, 1) 070701000000B4000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002000000000harbor-cli-0.0.2/pkg/views/user070701000000B5000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002700000000harbor-cli-0.0.2/pkg/views/user/create070701000000B6000081A40000000000000000000000016717AEFE000007F1000000000000000000000000000000000000002F00000000harbor-cli-0.0.2/pkg/views/user/create/view.gopackage create import ( "errors" "strings" "github.com/charmbracelet/huh" "github.com/goharbor/harbor-cli/pkg/utils" log "github.com/sirupsen/logrus" ) type CreateView struct { Username string Email string Realname string Comment string Password string } func CreateUserView(createView *CreateView) { theme := huh.ThemeCharm() err := huh.NewForm( huh.NewGroup( huh.NewInput(). Title("User Name"). Value(&createView.Username). Validate(func(str string) error { if strings.TrimSpace(str) == "" { return errors.New("user name cannot be empty") } if isVaild := utils.ValidateUserName(str); !isVaild { return errors.New("username cannot contain special characters") } return nil }), huh.NewInput(). Title("Email"). Value(&createView.Email). Validate(func(str string) error { if strings.TrimSpace(str) == "" { return errors.New("email cannot be empty or only spaces") } if isVaild := utils.ValidateEmail(str); !isVaild { return errors.New("please enter correct email format") } return nil }), huh.NewInput(). Title("First and Last Name"). Value(&createView.Realname). Validate(func(str string) error { if strings.TrimSpace(str) == "" { return errors.New("real name cannot be empty") } if isValid := utils.ValidateFL(str); !isValid { return errors.New("please enter correct first and last name format, like `Bob Dylan`") } return nil }), huh.NewInput(). Title("Password"). EchoMode(huh.EchoModePassword). Value(&createView.Password). Validate(func(str string) error { if strings.TrimSpace(str) == "" { return errors.New("password cannot be empty or only spaces") } if err := utils.ValidatePassword(str); err != nil { return err } return nil }), huh.NewInput(). Title("Comment"). Value(&createView.Comment), ), ).WithTheme(theme).Run() if err != nil { log.Fatal(err) } } 070701000000B7000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002500000000harbor-cli-0.0.2/pkg/views/user/list070701000000B8000081A40000000000000000000000016717AEFE00000418000000000000000000000000000000000000002D00000000harbor-cli-0.0.2/pkg/views/user/list/view.gopackage list import ( "fmt" "os" "strconv" "github.com/charmbracelet/bubbles/table" tea "github.com/charmbracelet/bubbletea" "github.com/goharbor/go-client/pkg/sdk/v2.0/models" "github.com/goharbor/harbor-cli/pkg/utils" "github.com/goharbor/harbor-cli/pkg/views/base/tablelist" ) var columns = []table.Column{ {Title: "ID", Width: 6}, {Title: "Name", Width: 16}, {Title: "Administrator", Width: 16}, {Title: "Email", Width: 20}, {Title: "Registration Time", Width: 24}, } func ListUsers(users []*models.UserResp) { var rows []table.Row for _, user := range users { isAdmin := "No" if user.SysadminFlag { isAdmin = "Yes" } createdTime, _ := utils.FormatCreatedTime(user.CreationTime.String()) rows = append(rows, table.Row{ strconv.FormatInt(int64(user.UserID), 10), // UserID user.Username, isAdmin, user.Email, createdTime, }) } m := tablelist.NewModel(columns, rows, len(rows)) if _, err := tea.NewProgram(m).Run(); err != nil { fmt.Println("Error running program:", err) os.Exit(1) } } 070701000000B9000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000002700000000harbor-cli-0.0.2/pkg/views/user/select070701000000BA000081A40000000000000000000000016717AEFE000002DD000000000000000000000000000000000000002F00000000harbor-cli-0.0.2/pkg/views/user/select/view.gopackage user import ( "fmt" "os" "github.com/charmbracelet/bubbles/list" tea "github.com/charmbracelet/bubbletea" "github.com/goharbor/go-client/pkg/sdk/v2.0/models" "github.com/goharbor/harbor-cli/pkg/views/base/selection" ) func UserList(users []*models.UserResp, choice chan<- int64) { itemsList := make([]list.Item, len(users)) items := map[string]int64{} for i, r := range users { items[r.Username] = r.UserID itemsList[i] = selection.Item(r.Username) } m := selection.NewModel(itemsList, "User") p, err := tea.NewProgram(m, tea.WithAltScreen()).Run() if err != nil { fmt.Println("Error running program:", err) os.Exit(1) } if p, ok := p.(selection.Model); ok { choice <- items[p.Choice] } } 070701000000BB000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000001600000000harbor-cli-0.0.2/test070701000000BC000041ED0000000000000000000000026717AEFE00000000000000000000000000000000000000000000001A00000000harbor-cli-0.0.2/test/e2e070701000000BD000081A40000000000000000000000016717AEFE000008AF000000000000000000000000000000000000002800000000harbor-cli-0.0.2/test/e2e/login_test.gopackage e2e import ( "testing" "github.com/goharbor/harbor-cli/cmd/harbor/root" "github.com/stretchr/testify/assert" ) func initialize(t *testing.T) { cds := root.RootCmd() err := cds.Execute() assert.NoError(t, err, "Expected no error for Root command") } func Test_Login_Success(t *testing.T) { initialize(t) // Initialize the root command cmd := root.LoginCommand() validServerAddresses := []string{ "http://demo.goharbor.io:80", "https://demo.goharbor.io:443", "http://demo.goharbor.io", "https://demo.goharbor.io", // "demo.goharbor.io", } for _, serverAddress := range validServerAddresses { t.Run("ValidServer_"+serverAddress, func(t *testing.T) { args := []string{serverAddress} cmd.SetArgs(args) assert.NoError(t, cmd.Flags().Set("name", "test")) assert.NoError(t, cmd.Flags().Set("username", "admin")) assert.NoError(t, cmd.Flags().Set("password", "Harbor12345")) err := cmd.Execute() assert.NoError(t, err, "Expected no error for server: %s", serverAddress) }) } } func Test_Login_Failure_WrongServer(t *testing.T) { cmd := root.LoginCommand() args := []string{"wrongserver"} cmd.SetArgs(args) assert.NoError(t, cmd.Flags().Set("name", "test")) assert.NoError(t, cmd.Flags().Set("username", "admin")) assert.NoError(t, cmd.Flags().Set("password", "Harbor12345")) err := cmd.Execute() assert.Error(t, err, "Expected error for invalid server") } func Test_Login_Failure_WrongUsername(t *testing.T) { cmd := root.LoginCommand() args := []string{"http://demo.goharbor.io"} cmd.SetArgs(args) assert.NoError(t, cmd.Flags().Set("name", "test")) assert.NoError(t, cmd.Flags().Set("username", "wrong")) assert.NoError(t, cmd.Flags().Set("password", "Harbor12345")) err := cmd.Execute() assert.Error(t, err, "Expected error for wrong username") } func Test_Login_Failure_WrongPassword(t *testing.T) { cmd := root.LoginCommand() args := []string{"http://demo.goharbor.io"} cmd.SetArgs(args) assert.NoError(t, cmd.Flags().Set("name", "test")) assert.NoError(t, cmd.Flags().Set("username", "admin")) assert.NoError(t, cmd.Flags().Set("password", "wrong")) err := cmd.Execute() assert.Error(t, err, "Expected error for wrong password") } 070701000000BE000081A40000000000000000000000016717AEFE00000023000000000000000000000000000000000000002200000000harbor-cli-0.0.2/test/e2e/test.mde2e tests for cmd can slide in here07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!436 blocks
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor