{"id":37132348,"url":"https://github.com/operate-first/opfcli","last_synced_at":"2026-01-14T15:26:39.377Z","repository":{"id":41595311,"uuid":"368245103","full_name":"operate-first/opfcli","owner":"operate-first","description":null,"archived":false,"fork":false,"pushed_at":"2022-04-29T17:32:40.000Z","size":89,"stargazers_count":0,"open_issues_count":0,"forks_count":9,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-08-09T21:39:13.366Z","etag":null,"topics":["hacktoberfest"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/operate-first.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-05-17T16:01:40.000Z","updated_at":"2022-08-22T06:57:20.000Z","dependencies_parsed_at":"2022-09-13T20:53:41.167Z","dependency_job_id":null,"html_url":"https://github.com/operate-first/opfcli","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":"operate-first/template","purl":"pkg:github/operate-first/opfcli","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/operate-first%2Fopfcli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/operate-first%2Fopfcli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/operate-first%2Fopfcli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/operate-first%2Fopfcli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/operate-first","download_url":"https://codeload.github.com/operate-first/opfcli/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/operate-first%2Fopfcli/sbom","scorecard":{"id":710887,"data":{"date":"2025-08-11","repo":{"name":"github.com/operate-first/opfcli","commit":"6217129245b339da5212da1a896426ac5623f258"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.2,"checks":[{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":9,"reason":"Found 20/21 approved changesets -- score normalized to 9","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/precommit.yml:1","Warn: no topLevel permission defined: .github/workflows/release.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/precommit.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/operate-first/opfcli/precommit.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/precommit.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/operate-first/opfcli/precommit.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/operate-first/opfcli/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:42: update your workflow using https://app.stepsecurity.io/secureworkflow/operate-first/opfcli/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:45: update your workflow using https://app.stepsecurity.io/secureworkflow/operate-first/opfcli/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:87: update your workflow using https://app.stepsecurity.io/secureworkflow/operate-first/opfcli/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:90: update your workflow using https://app.stepsecurity.io/secureworkflow/operate-first/opfcli/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:104: update your workflow using https://app.stepsecurity.io/secureworkflow/operate-first/opfcli/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:114: update your workflow using https://app.stepsecurity.io/secureworkflow/operate-first/opfcli/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:119: update your workflow using https://app.stepsecurity.io/secureworkflow/operate-first/opfcli/release.yml/main?enable=pin","Info:   0 out of   9 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: GNU General Public License v3.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v0.4.0 not signed: https://api.github.com/repos/operate-first/opfcli/releases/65702147","Warn: release artifact v0.3.0 not signed: https://api.github.com/repos/operate-first/opfcli/releases/62715515","Warn: release artifact v0.2.0 not signed: https://api.github.com/repos/operate-first/opfcli/releases/45846490","Warn: release artifact v0.1 not signed: https://api.github.com/repos/operate-first/opfcli/releases/44273352","Warn: release artifact v0.4.0 does not have provenance: https://api.github.com/repos/operate-first/opfcli/releases/65702147","Warn: release artifact v0.3.0 does not have provenance: https://api.github.com/repos/operate-first/opfcli/releases/62715515","Warn: release artifact v0.2.0 does not have provenance: https://api.github.com/repos/operate-first/opfcli/releases/45846490","Warn: release artifact v0.1 does not have provenance: https://api.github.com/repos/operate-first/opfcli/releases/44273352"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 22 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":9,"reason":"1 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GO-2022-0603 / GHSA-hp87-p4gw-j4gq"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-22T08:11:08.586Z","repository_id":41595311,"created_at":"2025-08-22T08:11:08.586Z","updated_at":"2025-08-22T08:11:08.586Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28424374,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T13:30:50.153Z","status":"ssl_error","status_checked_at":"2026-01-14T13:29:08.907Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hacktoberfest"],"created_at":"2026-01-14T15:26:38.536Z","updated_at":"2026-01-14T15:26:39.369Z","avatar_url":"https://github.com/operate-first.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# opfcli\n\n## Building\n\nTo build this tool from a checked out copy of the repository, run:\n\n```\nmake\n```\n\nThis will produce an executable named `opfcli-\u003cos\u003e-\u003carch\u003e` (for\nexample, `opfcli-linux-amd64`).\n\n## Usage\n\n```\nA command line tool for Operate First GitOps.\n\nUse opfcli to interact with an Operate First style Kubernetes\nconfiguration repository.\n\nUsage:\n  opfcli [command]\n\nAvailable Commands:\n  create-group      Create a group\n  create-project    Onboard a new project into Operate First\n  enable-monitoring Enable monitoring for a Kubernetes namespace\n  grant-access      Grant a group access to a namespace\n  help              Help about any command\n  onboard           Creates Groups, Namespaces, and Roles for a new Operate First project\n\nFlags:\n  -a, --app-name string   application name (default \"cluster-scope\")\n  -f, --config string     configuration file\n  -h, --help              help for opfcli\n  -R, --repodir string    path to opf repository\n```\n\n## create-group\n\n```\nCreate a group.\n\nCreate the group resource and associated kustomization file\n\nUsage:\n  opfcli create-group group [flags]\n\nFlags:\n  -h, --help                  help for create-project\n  -d, --display-name          short team description for easy identification of project\n  -n                          do not set a limitrange on this project\n  -u, --users                 comma seperated list of users to add to the group\n```\n\n## create-project\n\n```\nOnboard a new project into Operate First.\n\n- Register a new group\n- Register a new namespace with appropriate role bindings for your group\n\nUsage:\n  opfcli create-project projectName projectOwner [flags]\n\nFlags:\n  -d, --description string   Team description\n  -h, --help                 help for create-project\n  -n, --no-limitrange        Do not set a limitrange on this project\n  -q, --quota string         Set a quota on this project\n\nGlobal Flags:\n  -a, --app-name string      application name (default \"cluster-scope\")\n  -f, --config-file string   configuration file\n  -r, --repo-dir string      path to opf repository\n```\n\n## enable-monitoring\n\n```\nEnable monitoring for a Kubernetes namespace.\n\nThis will add a RoleBinding to the target namespace that permits\nPrometheus to access certain metrics about pods, services, etc.\n\nUsage:\n  opfcli enable-monitoring namespace [flags]\n\nFlags:\n  -h, --help   help for enable-monitoring\n```\n\n## grant-access\n\n```\nGrant a group access to a namespace.\n\nGrant a group access to a namespace with the specifed role\n(admin, edit, or view).\n\nUsage:\n  opfcli grant-access namespace group role [flags]\n\nFlags:\n  -h, --help   help for grant-access\n```\n\n## Onboard\n\nOnboard everything necessary for a new application into the Operate-First environment.\n\nThe onboard command expects an onboarding configuration file. These are the necessary and optional paramaters that make up the onboarding configuration file.\n\nNecessary parameters:\n  - `team_name` = name of the group looking to be onboarded\n  - `\u003cnamespaces[i]\u003e.name` = the name of the namespace(s) for you project (defined per namespace)\n  - `project_description` = short summary of your project\n  - `target_cluster` = name of the cluster to onboard to\n  - `env` = name of the environment in which the `target_cluster` lives\n  \nOptional parameters:\n  - `\u003cnamespaces[i]\u003e.quota` = Namespace Quota\n  - `\u003cnamespaces[i]\u003e.custom_quota` = a customizeable resource quota to be applied to its namespace\n  - `users` = users to be given access to the project when onboarding\n\n\nThis is an example of a valid configuration file using every option. Below each component will be discussed.\n\n```\nenv: MOC\nnamespaces:\n  - enable_monitoring: false\n    name: testproject\n    quota: testquota\n    disable_limit_range: false\n    project_display_name: testprojectdisplayname\n    custom_quota:\n      limits.cpu: '28'\n      requests.cpu: '28'\n      limits.memory: 32Gi\n      requests.memory: 32Gi\n      requests.storage: 100Gi\n      count/objectbucketclaims.objectbucket.io: 1\nproject_description: This is the configuration for a sample project / app to onboard\ntarget_cluster: Smaug\nteam_name: testgroup\nusers:\n  - testing_gh_handle_1\n  - testing_gh_handle_2\n\n```\n\n### `target_cluster` and `env`\n\nValues for `target_cluster` can be obtained by running:\n```\nkustomize build https://github.com/operate-first/apps/acm/overlays/moc/infra/managedclusters?ref=master | yq e -N '.metadata.name' -\n```\n  - Requires: [yq](https://github.com/mikefarah/yq#install) and [kustomize](https://kubectl.docs.kubernetes.io/installation/kustomize/)\n\nSimilarly, values for `env` can be obtained by running:\n\n```\ncurl -sX GET https://api.github.com/repos/operate-first/apps/contents/argocd/overlays/moc-infra/applications/envs | yq e '.[].name' -\n```\n  - Requires: [yq](https://github.com/mikefarah/yq#install)\n\nNOTE: the `opfcli` is made for use in `operate-first/apps` which is why these urls are either `curl`ed or used in kustomize build.\n\nIf you cannot install `kustomize` and or `yq`, our last known options for `env` and `target_cluster` are as follows:\n\n- env: `moc`\n  - target_cluster: `smaug`\n  - target_cluster: `infra`\n- env: `osc`\n  - target_cluster: `osc-cl1`\n- env: `emea`:\n  - target_cluster: `rick`\n  - target_cluster: `morty`\n\n### Namespace-Scoped Configurations\n\n1. `quota`s: Quota's are optional values that refer to names of common [ResourceQuotas in `operate-first/apps`](https://github.com/operate-first/apps/tree/master/cluster-scope/components/resourcequotas). They limit the resources able to be used in a specific namespace.\n\n2. `custom_quota`s: Custom quotas are optional configurations for a custom `ResourceQuota` to be used in a namespace. The values of a custom quota reflect those of our resourcequotas defined per namespace in operate-first/apps [see example](https://github.com/operate-first/apps/blob/master/cluster-scope/base/core/namespaces/sandbox/resourcequota.yaml).\n    - If a valid `quota` is selected but a `custom_quota` is also defined in your configuration file, it will default to creating the namespace using the `custom_quota`.\n    - All values are optional in a `custom_quota`.\n    - `custom_quota` options: `[limits.cpu, requests.cpu, limits.memory, requests.memroy, requests.storage, count/objectbucketclaims.objectbucket.io]`\n\n3. `disable_limit_range`: All requests to create and modify resources in Openshift are evaluated against each `LimitRange` object in the project. If the resource violates any of the enumerated constraints, the resource is rejected. Setting `disable_limit_range` to `true`, creates a namespace without the [operate-first default limit range](https://github.com/operate-first/apps/blob/master/cluster-scope/components/limitranges/default/limitrange.yaml).\n\n4. `display_project_name`: display-names in openshift are user-defined strings which provide an alternative, more human-readable way to refer to a namespace. For more information on this checkout the [openshift docs](https://docs.openshift.com/online/pro/architecture/core_concepts/projects_and_users.html#projects) on projects.\n\n### Users\n\nGitHub handles that will be used to authenticate OCP clusters via GitHub. These GitHub usernames are converted to OCP users and are also used to extend permissions via Openshift RBAC.\n\n### Usage\n\n```\nUsage:\n  opfcli onboard \u003cfile-path\u003e\n\nFlags:\n  -d, --display-name    provide a shorter name to use to refer to the project in openshift\n  -n, --no-limitrange   Do not set a resource limitrange on this project\n\n```\n\nUse \"opfcli [command] --help\" for more information about a command.\n\n## Configuration\n\nThe `opfcli` command will look for a configuration file `.opfcli.yaml`\nin two places:\n\n- It first checks in the top level of the current git repository. If\n  you are running the `opfcli` command outside of a git repository it\n  will instead check the current directory.\n\n- If it doesn't find a local configuration file, it will look for\n  `~/.opfcli.yaml`.\n\nUse the `OPF_LOGLEVEL` environment variable to set logging verbosity.\nThe default is `1` (informational), but you can also set it to `0`\n(warnings only) or `2` (or greater), which enables debug output.\n\n### Available configuration options\n\n- `app-name` -- sets the name of the directory containing your YAML\n  resources. This defaults to `cluster-scope`.\n\n## Examples\n\n### Create a project\n\n```\nopfcli create-project project1 group1 -d \"This is project1\"\n```\n\nThis will result in:\n\n```\ncluster-scope/\n├── base\n│   ├── core\n│   │   └── namespaces\n│   │       └── project1\n│   │           ├── kustomization.yaml\n│   │           └── namespace.yaml\n│   └── user.openshift.io\n│       └── groups\n│           └── group1\n│               ├── group.yaml\n│               └── kustomization.yaml\n└── components\n    └── project-admin-rolebindings\n        └── group1\n            ├── kustomization.yaml\n            └── rbac.yaml\n```\n\n### Create a group\n\n```\nopfcli create-group group2\n```\n\nThis will result in:\n\n```\ncluster-scope/\n└── base\n    └── user.openshift.io\n        └── groups\n            └── group1\n                ├── group.yaml\n                └── kustomization.yaml\n```\n\n### Grant access to a project\n\n```\nopfcli grant-access project1 group2 view\n```\n\nThis will result in:\n\n```\ncluster-scope/components/project-view-rolebindings/\n└── group2\n    ├── kustomization.yaml\n    └── rbac.yaml\n```\n\n(And will modify\n`cluster-scope/base/core/namespaces/project1/kustomization.yaml`)\n\n## License\n\nopfcli -- A tool for managing an Operate First style configuration repository.  \nCopyright (C) 2021 Operate First Team\n\nThis program is free software: you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with this program.  If not, see \u003chttps://www.gnu.org/licenses/\u003e.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foperate-first%2Fopfcli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foperate-first%2Fopfcli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foperate-first%2Fopfcli/lists"}