├── backstage.json ├── .prettierignore ├── packages ├── app │ ├── public │ │ ├── robots.txt │ │ ├── favicon.ico │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── apple-touch-icon.png │ │ ├── android-chrome-192x192.png │ │ ├── manifest.json │ │ └── safari-pinned-tab.svg │ ├── cypress.json │ ├── cypress │ │ ├── .eslintrc.json │ │ └── integration │ │ │ └── app.js │ ├── src │ │ ├── setupTests.ts │ │ ├── components │ │ │ └── Root │ │ │ │ └── index.ts │ │ ├── index.tsx │ │ ├── apis.ts │ │ ├── App.test.tsx │ │ └── App.tsx │ └── .eslintrc.js └── backend │ ├── .eslintrc.js │ ├── src │ ├── index.test.ts │ ├── plugins │ │ ├── cad.ts │ │ ├── proxy.ts │ │ ├── app.ts │ │ ├── catalog.ts │ │ └── auth.ts │ └── types.ts │ └── package.json ├── MAINTAINERS ├── .release-please-manifest.json ├── images └── cad-plugin-landing.png ├── release-please-config.json ├── .dockerignore ├── lerna.json ├── tsconfig.json ├── .github ├── ISSUE_TEMPLATE │ ├── feature_request.md │ ├── config.yml │ └── bug.md ├── release-please.yml ├── header-checker-lint.yml └── workflows │ └── ci.yml ├── .gitignore ├── .eslintrc.js ├── plugins ├── cad-backend │ ├── src │ │ ├── index.ts │ │ ├── run.ts │ │ └── service │ │ │ ├── lib.ts │ │ │ └── standaloneServer.ts │ ├── .eslintrc.js │ ├── CHANGELOG.md │ └── package.json └── cad │ ├── src │ ├── index.ts │ ├── components │ │ ├── LandingPage │ │ │ └── index.ts │ │ ├── PackagesTable │ │ │ ├── index.ts │ │ │ └── components │ │ │ │ └── SyncStatusVisual.tsx │ │ ├── AddPackagePage │ │ │ ├── index.ts │ │ │ └── utils │ │ │ │ ├── kptfile.ts │ │ │ │ └── resource.ts │ │ ├── PackageRevisionPage │ │ │ ├── index.ts │ │ │ └── updatedResourcesMap │ │ │ │ └── processUpdatedResourcesMap.ts │ │ ├── ResourceEditorDialog │ │ │ ├── index.ts │ │ │ └── components │ │ │ │ └── FirstClassEditors │ │ │ │ ├── RoleEditor │ │ │ │ └── index.ts │ │ │ │ ├── IngressEditor │ │ │ │ └── index.ts │ │ │ │ ├── KptfileEditor │ │ │ │ └── index.ts │ │ │ │ ├── ServiceEditor │ │ │ │ └── index.ts │ │ │ │ ├── ConfigMapEditor │ │ │ │ └── index.ts │ │ │ │ ├── NamespaceEditor │ │ │ │ ├── index.ts │ │ │ │ └── NamespaceEditor.tsx │ │ │ │ ├── SetLabelsEditor │ │ │ │ └── index.ts │ │ │ │ ├── RoleBindingEditor │ │ │ │ └── index.ts │ │ │ │ ├── ResourceQuotaEditor │ │ │ │ └── index.ts │ │ │ │ ├── ServiceAccountEditor │ │ │ │ ├── index.ts │ │ │ │ └── ServiceAccountEditor.tsx │ │ │ │ ├── ApplyReplacementsEditor │ │ │ │ └── index.ts │ │ │ │ ├── DeploymentEditor │ │ │ │ └── index.ts │ │ │ │ ├── Controls │ │ │ │ ├── index.ts │ │ │ │ └── SingleTextFieldAccordion.tsx │ │ │ │ ├── styles.ts │ │ │ │ └── util │ │ │ │ └── deletable.ts │ │ ├── ResourceViewerDialog │ │ │ ├── index.ts │ │ │ └── components │ │ │ │ └── FirstClassViewers │ │ │ │ └── StructuredMetadata │ │ │ │ └── resources │ │ │ │ ├── configMap.ts │ │ │ │ ├── setLabels.ts │ │ │ │ ├── starlarkRun.ts │ │ │ │ ├── ingressClass.ts │ │ │ │ ├── resourceQuota.ts │ │ │ │ ├── clusterIssuer.ts │ │ │ │ ├── job.ts │ │ │ │ ├── deployment.ts │ │ │ │ ├── apiService.ts │ │ │ │ ├── roleBinding.ts │ │ │ │ ├── customResourceDefinition.ts │ │ │ │ ├── persistentVolumeClaim.ts │ │ │ │ ├── applyReplacements.ts │ │ │ │ ├── service.ts │ │ │ │ ├── secret.ts │ │ │ │ ├── statefulSet.ts │ │ │ │ ├── kptfile.ts │ │ │ │ └── role.ts │ │ ├── PackageManagementPage │ │ │ └── index.ts │ │ ├── RegisterRepositoryPage │ │ │ └── index.ts │ │ ├── RepositoryPage │ │ │ └── index.ts │ │ ├── Links │ │ │ ├── styles.ts │ │ │ ├── index.ts │ │ │ ├── RegisterRepositoryLink.tsx │ │ │ ├── LandingPageLink.tsx │ │ │ ├── PackagesLink.tsx │ │ │ ├── RepositoryLink.tsx │ │ │ └── PackageLink.tsx │ │ └── Controls │ │ │ ├── index.ts │ │ │ ├── Badge.tsx │ │ │ ├── Chip.tsx │ │ │ ├── PackageIcon.tsx │ │ │ ├── ConfirmationDialog.tsx │ │ │ ├── Checkbox.tsx │ │ │ ├── IconButton.tsx │ │ │ ├── Select.tsx │ │ │ ├── MultiSelect.tsx │ │ │ └── YamlViewer.tsx │ ├── apis │ │ └── index.ts │ ├── types │ │ ├── Features.ts │ │ ├── KubernetesStatus.ts │ │ ├── RepositorySummary.ts │ │ ├── ApiGroup.ts │ │ ├── Namespace.ts │ │ ├── StarlarkRun.ts │ │ ├── ServiceAccount.ts │ │ ├── ConfigMap.ts │ │ ├── SetLabels.ts │ │ ├── SetNamespace.ts │ │ ├── KubernetesResource.ts │ │ ├── Role.ts │ │ ├── Job.ts │ │ ├── Function.ts │ │ ├── Secret.ts │ │ ├── IngressClass.ts │ │ ├── RoleBinding.ts │ │ ├── ClusterIssuer.ts │ │ ├── APIService.ts │ │ ├── ResourceQuota.ts │ │ ├── ConfigManagement.ts │ │ ├── PersistentVolumeClaim.ts │ │ ├── Service.ts │ │ ├── CustomResourceDefinition.ts │ │ ├── ApplyReplacement.ts │ │ ├── Deployment.ts │ │ ├── Kptfile.ts │ │ ├── PackageRevisionResource.ts │ │ ├── StatefulSet.ts │ │ ├── Ingress.ts │ │ └── Repository.ts │ ├── utils │ │ ├── formatDate.ts │ │ ├── revisionSummary.ts │ │ ├── yaml.ts │ │ ├── string.ts │ │ ├── selectItem.ts │ │ ├── kubernetesResource.ts │ │ ├── featureFlags.ts │ │ ├── secret.ts │ │ └── repositorySummary.ts │ ├── plugin.ts │ └── routes.ts │ ├── .eslintrc.js │ ├── dev │ └── index.tsx │ └── package.json ├── hack ├── README.md ├── install-package-repositories.sh ├── create-kind-cluster.sh ├── resources │ └── package-repositories.yaml └── install-porch.sh ├── CONTRIBUTING.md ├── package.json └── app-config.yaml /backstage.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.12.1" 3 | } 4 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | dist 2 | dist-types 3 | coverage 4 | .vscode 5 | **/CHANGELOG.md 6 | -------------------------------------------------------------------------------- /packages/app/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | -------------------------------------------------------------------------------- /MAINTAINERS: -------------------------------------------------------------------------------- 1 | Christopher Fry 2 | Morten Torkildsen 3 | -------------------------------------------------------------------------------- /.release-please-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins/cad": "0.4.0", 3 | "plugins/cad-backend": "0.1.0" 4 | } 5 | -------------------------------------------------------------------------------- /images/cad-plugin-landing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kptdev/kpt-backstage-plugins/HEAD/images/cad-plugin-landing.png -------------------------------------------------------------------------------- /packages/app/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kptdev/kpt-backstage-plugins/HEAD/packages/app/public/favicon.ico -------------------------------------------------------------------------------- /release-please-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": { 3 | "plugins/cad": {}, 4 | "plugins/cad-backend": {} 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/app/cypress.json: -------------------------------------------------------------------------------- 1 | { 2 | "baseUrl": "http://localhost:3001", 3 | "fixturesFolder": false, 4 | "pluginsFile": false 5 | } 6 | -------------------------------------------------------------------------------- /packages/app/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kptdev/kpt-backstage-plugins/HEAD/packages/app/public/favicon-16x16.png -------------------------------------------------------------------------------- /packages/app/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kptdev/kpt-backstage-plugins/HEAD/packages/app/public/favicon-32x32.png -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | node_modules 3 | packages/*/dist 4 | packages/*/node_modules 5 | plugins/*/dist 6 | plugins/*/node_modules 7 | Dockerfile 8 | -------------------------------------------------------------------------------- /packages/app/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kptdev/kpt-backstage-plugins/HEAD/packages/app/public/apple-touch-icon.png -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": ["packages/*", "plugins/*"], 3 | "npmClient": "yarn", 4 | "useWorkspaces": true, 5 | "version": "0.1.0" 6 | } 7 | -------------------------------------------------------------------------------- /packages/app/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kptdev/kpt-backstage-plugins/HEAD/packages/app/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@backstage/cli/config/tsconfig.json", 3 | "include": [ 4 | "packages/*/src", 5 | "plugins/*/src", 6 | "plugins/*/dev", 7 | "plugins/*/migrations" 8 | ], 9 | "exclude": ["node_modules"], 10 | "compilerOptions": { 11 | "lib": ["ES2021"], 12 | "outDir": "dist-types", 13 | "rootDir": "." 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/app/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Backstage", 3 | "name": "Backstage", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "48x48", 8 | "type": "image/png" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /packages/app/cypress/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["cypress"], 3 | "extends": ["plugin:cypress/recommended"], 4 | "rules": { 5 | "jest/expect-expect": [ 6 | "error", 7 | { 8 | "assertFunctionNames": ["expect", "cy.contains"] 9 | } 10 | ], 11 | "import/no-extraneous-dependencies": [ 12 | "error", 13 | { 14 | "devDependencies": true, 15 | "optionalDependencies": true, 16 | "peerDependencies": true, 17 | "bundledDependencies": true 18 | } 19 | ] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 'Feature Request' 3 | about: 'Suggest new features and changes' 4 | labels: enhancement 5 | --- 6 | 7 | 8 | 9 | ## Feature Suggestion 10 | 11 | 12 | 13 | ## Possible Implementation 14 | 15 | 16 | 17 | ## Context 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /.github/release-please.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | handleGHRelease: true 16 | manifest: true 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # macOS 2 | .DS_Store 3 | 4 | # Logs 5 | logs 6 | *.log 7 | npm-debug.log* 8 | yarn-debug.log* 9 | yarn-error.log* 10 | lerna-debug.log* 11 | 12 | # Coverage directory generated when running tests with coverage 13 | coverage 14 | 15 | # Dependencies 16 | node_modules/ 17 | 18 | # Node version directives 19 | .nvmrc 20 | 21 | # dotenv environment variables file 22 | .env 23 | .env.test 24 | 25 | # Build output 26 | dist 27 | dist-types 28 | 29 | # Temporary change files created by Vim 30 | *.swp 31 | 32 | # MkDocs build output 33 | site 34 | 35 | # Local configuration files 36 | *.local.yaml 37 | 38 | # Sensitive credentials 39 | *-credentials.yaml 40 | 41 | # Vscode settings 42 | .vscode 43 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module.exports = { 18 | root: true, 19 | }; 20 | -------------------------------------------------------------------------------- /packages/app/src/setupTests.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import '@testing-library/jest-dom'; 18 | -------------------------------------------------------------------------------- /plugins/cad-backend/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export * from './service/router'; 18 | -------------------------------------------------------------------------------- /plugins/cad/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { cadPlugin, CadPage } from './plugin'; 18 | -------------------------------------------------------------------------------- /packages/app/src/components/Root/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Backstage Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { Root } from './Root'; 18 | -------------------------------------------------------------------------------- /plugins/cad/src/components/LandingPage/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { LandingPage } from './LandingPage'; 18 | -------------------------------------------------------------------------------- /plugins/cad/src/components/PackagesTable/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { PackagesTable } from './PackagesTable'; 18 | -------------------------------------------------------------------------------- /packages/app/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); 18 | -------------------------------------------------------------------------------- /plugins/cad/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); 18 | -------------------------------------------------------------------------------- /plugins/cad/src/apis/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export * from './ConfigAsDataApi'; 18 | export * from './PorchRestApi'; 19 | -------------------------------------------------------------------------------- /plugins/cad/src/components/AddPackagePage/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { AddPackagePage } from './AddPackagePage'; 18 | -------------------------------------------------------------------------------- /packages/backend/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); 18 | -------------------------------------------------------------------------------- /plugins/cad-backend/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); 18 | -------------------------------------------------------------------------------- /plugins/cad/src/components/PackageRevisionPage/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { PackageRevisionPage } from './PackageRevisionPage'; 18 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceEditorDialog/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { ResourceEditorDialog } from './ResourceEditorDialog'; 18 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceViewerDialog/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { ResourceViewerDialog } from './ResourceViewerDialog'; 18 | -------------------------------------------------------------------------------- /plugins/cad/src/components/PackageManagementPage/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { PackageManagementPage } from './PackageManagementPage'; 18 | -------------------------------------------------------------------------------- /plugins/cad/src/components/RegisterRepositoryPage/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { RegisterRepositoryPage } from './RegisterRepositoryPage'; 18 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/RoleEditor/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { RoleEditor } from './RoleEditor'; 18 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/IngressEditor/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { IngressEditor } from './IngressEditor'; 18 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/KptfileEditor/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { KptfileEditor } from './KptfileEditor'; 18 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/ServiceEditor/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { ServiceEditor } from './ServiceEditor'; 18 | -------------------------------------------------------------------------------- /plugins/cad/src/components/RepositoryPage/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { PackagesPage } from './PackagesPage'; 18 | export { RepositoryPage } from './RepositoryPage'; 19 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/ConfigMapEditor/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { ConfigMapEditor } from './ConfigMapEditor'; 18 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/NamespaceEditor/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { NamespaceEditor } from './NamespaceEditor'; 18 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/SetLabelsEditor/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { SetLabelsEditor } from './SetLabelsEditor'; 18 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/RoleBindingEditor/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { RoleBindingEditor } from './RoleBindingEditor'; 18 | -------------------------------------------------------------------------------- /plugins/cad/src/types/Features.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export type GetFeaturesResponse = { 18 | authentication: string; 19 | namespace: string; 20 | gitOps: string; 21 | }; 22 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/ResourceQuotaEditor/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { ResourceQuotaEditor } from './ResourceQuotaEditor'; 18 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/ServiceAccountEditor/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { ServiceAccountEditor } from './ServiceAccountEditor'; 18 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/ApplyReplacementsEditor/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { ApplyReplacementsEditor } from './ApplyReplacementsEditor'; 18 | -------------------------------------------------------------------------------- /.github/header-checker-lint.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | allowedCopyrightHolders: 16 | - 'Google LLC' 17 | allowedLicenses: 18 | - 'Apache-2.0' 19 | sourceFileExtensions: 20 | - 'js' 21 | - 'ts' 22 | - 'tsx' 23 | - 'yaml' 24 | - 'yml' 25 | -------------------------------------------------------------------------------- /hack/README.md: -------------------------------------------------------------------------------- 1 | # Hack Directory 2 | 3 | This directory contains scripts to aid in the development of the kpt Backstage 4 | Plugins. 5 | 6 | ## Prerequisites 7 | 8 | Depending on the script you are executing, you must have 9 | [kind](https://kind.sigs.k8s.io), 10 | [kubectl](https://kubernetes.io/docs/tasks/tools), and 11 | [jq](https://stedolan.github.io/jq) installed. 12 | 13 | ## Key Scripts 14 | 15 | - [create-kind-cluster.sh](create-kind-cluster.sh): Creates a ready to use dev 16 | kind cluster with Porch and example package repositories already installed 17 | 18 | - [install-porch.sh](install-porch.sh): Installs the latest Porch release on the 19 | cluster `kubectl` is targetting 20 | 21 | - [install-package-repositories.sh](install-package-repositories.sh): Installs 22 | example package repositories on the cluster `kubectl` is targetting 23 | -------------------------------------------------------------------------------- /packages/app/cypress/integration/app.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | describe('App', () => { 18 | it('should render the catalog', () => { 19 | cy.visit('/'); 20 | cy.contains('My Company Catalog'); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/DeploymentEditor/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { DeploymentEditor } from './DeploymentEditor'; 18 | export { StatefulSetEditor } from './StatefulSetEditor'; 19 | -------------------------------------------------------------------------------- /plugins/cad/src/types/KubernetesStatus.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export type KubernetesStatus = { 18 | apiVersion: string; 19 | kind: string; 20 | code: number; 21 | message: string; 22 | reason: string; 23 | status: string; 24 | }; 25 | -------------------------------------------------------------------------------- /packages/app/src/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import '@backstage/cli/asset-types'; 18 | import React from 'react'; 19 | import ReactDOM from 'react-dom'; 20 | import App from './App'; 21 | 22 | ReactDOM.render(, document.getElementById('root')); 23 | -------------------------------------------------------------------------------- /plugins/cad/src/components/Links/styles.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { makeStyles } from '@material-ui/core'; 18 | 19 | export const useLinkStyles = makeStyles({ 20 | breadcrumb: { 21 | color: 'inherit', 22 | textDecoration: 'underline', 23 | }, 24 | }); 25 | -------------------------------------------------------------------------------- /packages/backend/src/index.test.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { PluginEnvironment } from './types'; 18 | 19 | describe('test', () => { 20 | it('unbreaks the test runner', () => { 21 | const unbreaker = {} as PluginEnvironment; 22 | expect(unbreaker).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /plugins/cad/src/types/RepositorySummary.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { PackageSummary } from '../utils/packageSummary'; 18 | import { Repository } from './Repository'; 19 | 20 | export type RepositorySummary = { 21 | repository: Repository; 22 | packageSummaries?: PackageSummary[]; 23 | }; 24 | -------------------------------------------------------------------------------- /plugins/cad/src/components/Links/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { LandingPageLink } from './LandingPageLink'; 18 | export { PackageLink } from './PackageLink'; 19 | export { PackagesLink } from './PackagesLink'; 20 | export { RegisterRepositoryLink } from './RegisterRepositoryLink'; 21 | export { RepositoryLink } from './RepositoryLink'; 22 | -------------------------------------------------------------------------------- /plugins/cad/dev/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Backstage Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import React from 'react'; 17 | import { createDevApp } from '@backstage/dev-utils'; 18 | import { cadPlugin, CadPage } from '../src/plugin'; 19 | 20 | createDevApp() 21 | .registerPlugin(cadPlugin) 22 | .addPage({ 23 | element: , 24 | title: 'Root Page', 25 | path: '/config-as-data', 26 | }) 27 | .render(); 28 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/Controls/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { EditorAccordion } from './EditorAccordion'; 18 | export { KeyValueEditorAccordion } from './KeyValueEditorAccordion'; 19 | export { ResourceMetadataAccordion } from './ResourceMetadataAccordion'; 20 | export { SingleTextFieldAccordion } from './SingleTextFieldAccordion'; 21 | -------------------------------------------------------------------------------- /plugins/cad/src/types/ApiGroup.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export type ListApiGroups = { 18 | kind: string; 19 | apiVersion: string; 20 | groups: ApiGroup[]; 21 | }; 22 | 23 | export type ApiGroup = { 24 | name: string; 25 | preferredVersion: ApiGroupVersion; 26 | versions: ApiGroupVersion[]; 27 | }; 28 | 29 | export type ApiGroupVersion = { 30 | groupVersion: string; 31 | version: string; 32 | }; 33 | -------------------------------------------------------------------------------- /plugins/cad/src/types/Namespace.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesKeyValueObject } from './KubernetesResource'; 18 | 19 | export type Namespace = { 20 | kind: string; 21 | apiVersion: string; 22 | metadata: NamespaceMetadata; 23 | }; 24 | 25 | export type NamespaceMetadata = { 26 | name: string; 27 | labels?: KubernetesKeyValueObject; 28 | annotations?: KubernetesKeyValueObject; 29 | }; 30 | -------------------------------------------------------------------------------- /packages/backend/src/plugins/cad.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { createRouter } from '@kpt/backstage-plugin-cad-backend'; 18 | import { Router } from 'express'; 19 | import { PluginEnvironment } from '../types'; 20 | 21 | export default async function createPlugin( 22 | env: PluginEnvironment, 23 | ): Promise { 24 | return await createRouter({ 25 | config: env.config, 26 | logger: env.logger, 27 | }); 28 | } 29 | -------------------------------------------------------------------------------- /plugins/cad/src/types/StarlarkRun.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesKeyValueObject } from './KubernetesResource'; 18 | 19 | export type StarlarkRun = { 20 | kind: string; 21 | apiVersion: string; 22 | metadata: StarlarkRunMetadata; 23 | source: string; 24 | }; 25 | 26 | export type StarlarkRunMetadata = { 27 | name: string; 28 | labels?: KubernetesKeyValueObject; 29 | annotations?: KubernetesKeyValueObject; 30 | }; 31 | -------------------------------------------------------------------------------- /plugins/cad/src/types/ServiceAccount.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesKeyValueObject } from './KubernetesResource'; 18 | 19 | export type ServiceAccount = { 20 | kind: string; 21 | apiVersion: string; 22 | metadata: ServiceAccountMetadata; 23 | }; 24 | 25 | export type ServiceAccountMetadata = { 26 | name: string; 27 | namespace?: string; 28 | labels?: KubernetesKeyValueObject; 29 | annotations?: KubernetesKeyValueObject; 30 | }; 31 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | blank_issues_enabled: true 16 | contact_links: 17 | - name: kpt Documentation 18 | url: https://kpt.dev/ 19 | about: Learn more about using kpt 20 | - name: kpt Slack Channel 21 | url: https://kubernetes.slack.com/app_redirect?channel=kpt 22 | about: Discuss kpt topics with the kpt team on Slack 23 | - name: kpt Mailing List 24 | url: https://groups.google.com/g/kpt-users 25 | about: Join the kpt mailing list 26 | -------------------------------------------------------------------------------- /packages/backend/src/plugins/proxy.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { createRouter } from '@backstage/plugin-proxy-backend'; 18 | import { Router } from 'express'; 19 | import { PluginEnvironment } from '../types'; 20 | 21 | export default async function createPlugin( 22 | env: PluginEnvironment, 23 | ): Promise { 24 | return await createRouter({ 25 | logger: env.logger, 26 | config: env.config, 27 | discovery: env.discovery, 28 | }); 29 | } 30 | -------------------------------------------------------------------------------- /plugins/cad/src/types/ConfigMap.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesKeyValueObject } from './KubernetesResource'; 18 | 19 | export type ConfigMap = { 20 | kind: string; 21 | apiVersion: string; 22 | metadata: ConfigMapMetadata; 23 | data: KubernetesKeyValueObject; 24 | }; 25 | 26 | export type ConfigMapMetadata = { 27 | name: string; 28 | namespace?: string; 29 | labels?: KubernetesKeyValueObject; 30 | annotations?: KubernetesKeyValueObject; 31 | }; 32 | -------------------------------------------------------------------------------- /plugins/cad/src/types/SetLabels.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesKeyValueObject } from './KubernetesResource'; 18 | 19 | export type SetLabels = { 20 | kind: string; 21 | apiVersion: string; 22 | metadata: SetLabelsMetadata; 23 | labels: KubernetesKeyValueObject; 24 | }; 25 | 26 | export type SetLabelsMetadata = { 27 | name: string; 28 | namespace?: string; 29 | labels?: KubernetesKeyValueObject; 30 | annotations?: KubernetesKeyValueObject; 31 | }; 32 | -------------------------------------------------------------------------------- /plugins/cad/src/types/SetNamespace.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesKeyValueObject } from './KubernetesResource'; 18 | 19 | export type SetNamespace = { 20 | kind: string; 21 | apiVersion: string; 22 | metadata: SetNamespaceMetadata; 23 | namespace: string; 24 | }; 25 | 26 | export type SetNamespaceMetadata = { 27 | name: string; 28 | namespace?: string; 29 | labels?: KubernetesKeyValueObject; 30 | annotations?: KubernetesKeyValueObject; 31 | }; 32 | -------------------------------------------------------------------------------- /plugins/cad/src/types/KubernetesResource.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export type KubernetesResource = { 18 | kind: string; 19 | apiVersion: string; 20 | metadata: KubernetesResourceMetadata; 21 | }; 22 | 23 | export type KubernetesResourceMetadata = { 24 | name: string; 25 | namespace?: string; 26 | labels?: KubernetesKeyValueObject; 27 | annotations?: KubernetesKeyValueObject; 28 | }; 29 | 30 | export type KubernetesKeyValueObject = { 31 | [key: string]: string; 32 | }; 33 | -------------------------------------------------------------------------------- /packages/backend/src/plugins/app.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { createRouter } from '@backstage/plugin-app-backend'; 18 | import { Router } from 'express'; 19 | import { PluginEnvironment } from '../types'; 20 | 21 | export default async function createPlugin( 22 | env: PluginEnvironment, 23 | ): Promise { 24 | return await createRouter({ 25 | logger: env.logger, 26 | config: env.config, 27 | database: env.database, 28 | appPackageName: 'app', 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /plugins/cad/src/components/Links/RegisterRepositoryLink.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Link } from '@backstage/core-components'; 18 | import { useRouteRef } from '@backstage/core-plugin-api'; 19 | import React from 'react'; 20 | import { registerRepositoryRouteRef } from '../../routes'; 21 | 22 | export const RegisterRepositoryLink = () => { 23 | const repositoryRef = useRouteRef(registerRepositoryRouteRef); 24 | 25 | return Register Repository; 26 | }; 27 | -------------------------------------------------------------------------------- /plugins/cad/src/utils/formatDate.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import moment from 'moment'; 18 | 19 | const DATE_FORMAT = `MMMM D, YYYY`; 20 | const DATE_TIME_FORMAT = `MMMM D, YYYY h:mm A`; 21 | 22 | export const formatCreationTimestamp = ( 23 | timestamp?: string, 24 | includeTime: boolean = false, 25 | ): string => { 26 | if (!timestamp) return ''; 27 | 28 | const timeFormat = includeTime ? DATE_TIME_FORMAT : DATE_FORMAT; 29 | 30 | return moment(timestamp).format(timeFormat); 31 | }; 32 | -------------------------------------------------------------------------------- /hack/install-package-repositories.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2023 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Exit on error 17 | set -euo pipefail 18 | 19 | SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd) 20 | 21 | echo "Verify script prerequisites" 22 | if ! [ -x "$(command -v kubectl)" ]; then 23 | echo 'Error: kubectl is not installed. Follow https://kubernetes.io/docs/tasks/tools to install kubectl.' 24 | exit 1 25 | fi 26 | 27 | echo "Install example package repositories" 28 | kubectl apply -f $SCRIPT_DIR/resources/package-repositories.yaml 29 | -------------------------------------------------------------------------------- /packages/backend/src/plugins/catalog.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { CatalogBuilder } from '@backstage/plugin-catalog-backend'; 18 | import { Router } from 'express'; 19 | import { PluginEnvironment } from '../types'; 20 | 21 | export default async function createPlugin( 22 | env: PluginEnvironment, 23 | ): Promise { 24 | const builder = await CatalogBuilder.create(env); 25 | const { processingEngine, router } = await builder.build(); 26 | await processingEngine.start(); 27 | return router; 28 | } 29 | -------------------------------------------------------------------------------- /packages/backend/src/plugins/auth.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { createRouter } from '@backstage/plugin-auth-backend'; 18 | import { Router } from 'express'; 19 | import { PluginEnvironment } from '../types'; 20 | 21 | export default async function createPlugin( 22 | env: PluginEnvironment, 23 | ): Promise { 24 | return await createRouter({ 25 | logger: env.logger, 26 | config: env.config, 27 | database: env.database, 28 | discovery: env.discovery, 29 | tokenManager: env.tokenManager, 30 | }); 31 | } 32 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceViewerDialog/components/FirstClassViewers/StructuredMetadata/resources/configMap.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { ConfigMap } from '../../../../../../types/ConfigMap'; 18 | import { KubernetesResource } from '../../../../../../types/KubernetesResource'; 19 | import { Metadata } from '../StructuredMetadata'; 20 | 21 | export const getConfigMapStructuredMetadata = ( 22 | resource: KubernetesResource, 23 | ): Metadata => { 24 | const configMap = resource as ConfigMap; 25 | 26 | return { 27 | data: configMap.data, 28 | }; 29 | }; 30 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to this project must be accompanied by a Contributor License 9 | Agreement. You (or your employer) retain the copyright to your contribution; 10 | this simply gives us permission to use and redistribute your contributions as 11 | part of the project. Head over to to see 12 | your current agreements on file or to sign a new one. 13 | 14 | You generally only need to submit a CLA once, so if you've already submitted one 15 | (even if it was for a different project), you probably don't need to do it 16 | again. 17 | 18 | ## Code Reviews 19 | 20 | All submissions, including submissions by project members, require review. We 21 | use GitHub pull requests for this purpose. Consult 22 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 23 | information on using pull requests. 24 | 25 | ## Community Guidelines 26 | 27 | This project follows [Google's Open Source Community 28 | Guidelines](https://opensource.google/conduct/). 29 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceViewerDialog/components/FirstClassViewers/StructuredMetadata/resources/setLabels.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesResource } from '../../../../../../types/KubernetesResource'; 18 | import { SetLabels } from '../../../../../../types/SetLabels'; 19 | import { Metadata } from '../StructuredMetadata'; 20 | 21 | export const getSetLabelsStructuredMetadata = ( 22 | resource: KubernetesResource, 23 | ): Metadata => { 24 | const setLabels = resource as SetLabels; 25 | 26 | return { 27 | setLabels: setLabels.labels, 28 | }; 29 | }; 30 | -------------------------------------------------------------------------------- /packages/app/src/apis.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { 18 | ScmIntegrationsApi, 19 | scmIntegrationsApiRef, 20 | ScmAuth, 21 | } from '@backstage/integration-react'; 22 | import { 23 | AnyApiFactory, 24 | configApiRef, 25 | createApiFactory, 26 | } from '@backstage/core-plugin-api'; 27 | 28 | export const apis: AnyApiFactory[] = [ 29 | createApiFactory({ 30 | api: scmIntegrationsApiRef, 31 | deps: { configApi: configApiRef }, 32 | factory: ({ configApi }) => ScmIntegrationsApi.fromConfig(configApi), 33 | }), 34 | ScmAuth.createDefaultApiFactory(), 35 | ]; 36 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceViewerDialog/components/FirstClassViewers/StructuredMetadata/resources/starlarkRun.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesResource } from '../../../../../../types/KubernetesResource'; 18 | import { StarlarkRun } from '../../../../../../types/StarlarkRun'; 19 | import { Metadata } from '../StructuredMetadata'; 20 | 21 | export const getStarlarkRunStructuredMetadata = ( 22 | resource: KubernetesResource, 23 | ): Metadata => { 24 | const starlarkRun = resource as StarlarkRun; 25 | 26 | return { 27 | source: starlarkRun.source, 28 | }; 29 | }; 30 | -------------------------------------------------------------------------------- /plugins/cad/src/types/Role.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesKeyValueObject } from './KubernetesResource'; 18 | 19 | export type Role = { 20 | kind: string; 21 | apiVersion: string; 22 | metadata: RoleMetadata; 23 | rules: PolicyRule[]; 24 | }; 25 | 26 | export type RoleMetadata = { 27 | name: string; 28 | namespace?: string; 29 | labels?: KubernetesKeyValueObject; 30 | annotations?: KubernetesKeyValueObject; 31 | }; 32 | 33 | export type PolicyRule = { 34 | apiGroups?: string[]; 35 | resources?: string[]; 36 | resourceNames?: string[]; 37 | verbs?: string[]; 38 | }; 39 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceViewerDialog/components/FirstClassViewers/StructuredMetadata/resources/ingressClass.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { IngressClass } from '../../../../../../types/IngressClass'; 18 | import { KubernetesResource } from '../../../../../../types/KubernetesResource'; 19 | import { Metadata } from '../StructuredMetadata'; 20 | 21 | export const getIngressClassStructuredMetadata = ( 22 | resource: KubernetesResource, 23 | ): Metadata => { 24 | const ingressClass = resource as IngressClass; 25 | 26 | return { 27 | controller: ingressClass.spec.controller, 28 | }; 29 | }; 30 | -------------------------------------------------------------------------------- /plugins/cad/src/types/Job.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesKeyValueObject } from './KubernetesResource'; 18 | import { PodTemplateSpec } from './Pod'; 19 | 20 | export type Job = { 21 | apiVersion: string; 22 | kind: string; 23 | metadata: JobMetadata; 24 | spec: JobSpec; 25 | }; 26 | 27 | export type JobMetadata = { 28 | name: string; 29 | namespace?: string; 30 | labels?: KubernetesKeyValueObject; 31 | annotations?: KubernetesKeyValueObject; 32 | }; 33 | 34 | export type JobSpec = { 35 | completions?: number; 36 | parallelism?: number; 37 | template: PodTemplateSpec; 38 | }; 39 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceViewerDialog/components/FirstClassViewers/StructuredMetadata/resources/resourceQuota.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesResource } from '../../../../../../types/KubernetesResource'; 18 | import { ResourceQuota } from '../../../../../../types/ResourceQuota'; 19 | import { Metadata } from '../StructuredMetadata'; 20 | 21 | export const getResourceQuotaStructuredMetadata = ( 22 | resource: KubernetesResource, 23 | ): Metadata => { 24 | const resourceQuota = resource as ResourceQuota; 25 | 26 | return { 27 | 'Resource Limits': resourceQuota.spec.hard, 28 | }; 29 | }; 30 | -------------------------------------------------------------------------------- /plugins/cad/src/components/Controls/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export { Autocomplete } from './Autocomplete'; 18 | export { Badge } from './Badge'; 19 | export { ConfirmationDialog } from './ConfirmationDialog'; 20 | export { Checkbox } from './Checkbox'; 21 | export { Chip } from './Chip'; 22 | export { IconButton } from './IconButton'; 23 | export { MultiSelect } from './MultiSelect'; 24 | export { PackageIcon } from './PackageIcon'; 25 | export { RadioGroup } from './RadioGroup'; 26 | export type { RadioOption } from './RadioGroup'; 27 | export { Select } from './Select'; 28 | export { YamlViewer } from './YamlViewer'; 29 | -------------------------------------------------------------------------------- /plugins/cad/src/types/Function.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export type Function = { 18 | apiVersion: string; 19 | kind: string; 20 | metadata: FunctionMetadata; 21 | spec: FunctionSpec; 22 | }; 23 | 24 | export type FunctionMetadata = { 25 | name: string; 26 | namespace?: string; 27 | creationTimestamp?: string; 28 | }; 29 | 30 | export type FunctionSpec = { 31 | description: string; 32 | documentationUrl?: string; 33 | functionTypes: string[]; 34 | keywords: string[]; 35 | image: string; 36 | repositoryRef: FunctionRepositoryRef; 37 | }; 38 | 39 | export type FunctionRepositoryRef = { 40 | name: string; 41 | }; 42 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/styles.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { makeStyles } from '@material-ui/core'; 18 | 19 | export const useEditorStyles = makeStyles({ 20 | root: { 21 | margin: '2px', 22 | }, 23 | multiControlRow: { 24 | display: 'flex', 25 | alignItems: 'center', 26 | '& > *:not(:last-child)': { 27 | marginRight: '8px', 28 | }, 29 | }, 30 | buttonRow: { 31 | marginTop: '12px', 32 | '& > button': { 33 | marginRight: '8px', 34 | }, 35 | }, 36 | iconButton: { 37 | height: '42px', 38 | width: '42px', 39 | }, 40 | }); 41 | -------------------------------------------------------------------------------- /plugins/cad/src/utils/revisionSummary.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { PackageRevision } from '../types/PackageRevision'; 18 | import { PackageRevisionResourcesMap } from '../types/PackageRevisionResource'; 19 | 20 | export type RevisionSummary = { 21 | revision: PackageRevision; 22 | resourcesMap: PackageRevisionResourcesMap; 23 | }; 24 | 25 | export const getRevisionSummary = ( 26 | revision: PackageRevision, 27 | resourcesMap: PackageRevisionResourcesMap, 28 | ): RevisionSummary => { 29 | const revisionSummary: RevisionSummary = { 30 | revision, 31 | resourcesMap, 32 | }; 33 | 34 | return revisionSummary; 35 | }; 36 | -------------------------------------------------------------------------------- /plugins/cad-backend/src/run.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { getRootLogger } from '@backstage/backend-common'; 18 | import yn from 'yn'; 19 | import { startStandaloneServer } from './service/standaloneServer'; 20 | 21 | const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007; 22 | const enableCors = yn(process.env.PLUGIN_CORS, { default: false }); 23 | const logger = getRootLogger(); 24 | 25 | startStandaloneServer({ port, enableCors, logger }).catch(err => { 26 | logger.error(err); 27 | process.exit(1); 28 | }); 29 | 30 | process.on('SIGINT', () => { 31 | logger.info('CTRL+C pressed; exiting.'); 32 | process.exit(0); 33 | }); 34 | -------------------------------------------------------------------------------- /plugins/cad/src/types/Secret.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesKeyValueObject } from './KubernetesResource'; 18 | 19 | export type ListSecrets = { 20 | kind: string; 21 | apiVersion: string; 22 | items: Secret[]; 23 | }; 24 | 25 | export type Secret = { 26 | kind: string; 27 | apiVersion: string; 28 | metadata: SecretMetadata; 29 | type: string; 30 | stringData?: KubernetesKeyValueObject; 31 | data: KubernetesKeyValueObject; 32 | immutable?: boolean; 33 | }; 34 | 35 | export type SecretMetadata = { 36 | name: string; 37 | namespace?: string; 38 | labels?: KubernetesKeyValueObject; 39 | annotations?: KubernetesKeyValueObject; 40 | }; 41 | -------------------------------------------------------------------------------- /plugins/cad/src/utils/yaml.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { dump, load } from 'js-yaml'; 18 | 19 | export type Yaml = any; 20 | 21 | export const loadYaml = (yamlString: string): Yaml => { 22 | return load(yamlString); 23 | }; 24 | 25 | export const dumpYaml = (yaml: Yaml): string => { 26 | return dump(yaml, { noArrayIndent: true, quotingType: '"' }); 27 | }; 28 | 29 | export const createMultiResourceYaml = (resourcesYaml: string[]): string => { 30 | return resourcesYaml.join('\n---\n'); 31 | }; 32 | 33 | export const getResourcesFromMultiResourceYaml = ( 34 | multiResourceYaml: string, 35 | ): string[] => { 36 | return multiResourceYaml.split('\n---\n'); 37 | }; 38 | -------------------------------------------------------------------------------- /packages/app/src/App.test.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React from 'react'; 18 | import { renderWithEffects } from '@backstage/test-utils'; 19 | import App from './App'; 20 | 21 | describe('App', () => { 22 | it('should render', async () => { 23 | process.env = { 24 | NODE_ENV: 'test', 25 | APP_CONFIG: [ 26 | { 27 | data: { 28 | app: { title: 'Test' }, 29 | backend: { baseUrl: 'http://localhost:7007' }, 30 | }, 31 | context: 'test', 32 | }, 33 | ] as any, 34 | }; 35 | 36 | const rendered = await renderWithEffects(); 37 | expect(rendered.baseElement).toBeInTheDocument(); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /plugins/cad/src/utils/string.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export const toLowerCase = (str: string): string => { 18 | return str.toLocaleLowerCase('us-EN'); 19 | }; 20 | 21 | export const emptyIfUndefined = (str?: string): string => { 22 | return str ?? ''; 23 | }; 24 | 25 | export const isNumber = (value: string): boolean => { 26 | return !!value && /^\d*$/.test(value); 27 | }; 28 | 29 | export const getNumber = (value: string): number | undefined => { 30 | return isNumber(value) ? parseInt(value, 10) : undefined; 31 | }; 32 | 33 | export const getNumberOrString = ( 34 | value: string, 35 | ): string | number | undefined => { 36 | return isNumber(value) ? parseInt(value, 10) : value || undefined; 37 | }; 38 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceViewerDialog/components/FirstClassViewers/StructuredMetadata/resources/clusterIssuer.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { ClusterIssuer } from '../../../../../../types/ClusterIssuer'; 18 | import { KubernetesResource } from '../../../../../../types/KubernetesResource'; 19 | import { Metadata } from '../StructuredMetadata'; 20 | 21 | export const getClusterIssuerStructuredMetadata = ( 22 | resource: KubernetesResource, 23 | ): Metadata => { 24 | const clusterIssuer = resource as ClusterIssuer; 25 | 26 | return { 27 | server: clusterIssuer.spec.acme.server, 28 | email: clusterIssuer.spec.acme.email, 29 | privateKeySecretName: clusterIssuer.spec.acme.privateKeySecretRef?.name, 30 | }; 31 | }; 32 | -------------------------------------------------------------------------------- /plugins/cad/src/types/IngressClass.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesKeyValueObject } from './KubernetesResource'; 18 | 19 | export type IngressClass = { 20 | apiVersion: string; 21 | kind: string; 22 | metadata: IngressClassMetadata; 23 | spec: IngressClassSpec; 24 | }; 25 | 26 | export type IngressClassMetadata = { 27 | name: string; 28 | labels?: KubernetesKeyValueObject; 29 | annotations?: KubernetesKeyValueObject; 30 | }; 31 | 32 | export type IngressClassSpec = { 33 | controller: string; 34 | parameters?: IngressClassParametersReference; 35 | }; 36 | 37 | export type IngressClassParametersReference = { 38 | apiGroup?: string; 39 | kind: string; 40 | name: string; 41 | scope?: string; 42 | namespace?: string; 43 | }; 44 | -------------------------------------------------------------------------------- /packages/app/public/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | Created by potrace 1.11, written by Peter Selinger 2001-2013 -------------------------------------------------------------------------------- /plugins/cad/src/components/Controls/Badge.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Badge as MaterialBadge, makeStyles } from '@material-ui/core'; 18 | import React, { ReactNode } from 'react'; 19 | 20 | type BadgeProps = { 21 | badgeContent: number; 22 | children: ReactNode; 23 | }; 24 | 25 | const useStyles = makeStyles({ 26 | badge: { 27 | paddingLeft: '2px', 28 | paddingRight: '2px', 29 | }, 30 | }); 31 | 32 | export const Badge = ({ badgeContent, children }: BadgeProps) => { 33 | const classes = useStyles(); 34 | 35 | return ( 36 | 42 | {children} 43 | 44 | ); 45 | }; 46 | -------------------------------------------------------------------------------- /plugins/cad/src/types/RoleBinding.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesKeyValueObject } from './KubernetesResource'; 18 | 19 | export type RoleBinding = { 20 | kind: string; 21 | apiVersion: string; 22 | metadata: RoleBindingMetadata; 23 | roleRef: RoleBindingRoleRef; 24 | subjects: RoleBindingSubject[]; 25 | }; 26 | 27 | export type RoleBindingMetadata = { 28 | name: string; 29 | namespace?: string; 30 | labels?: KubernetesKeyValueObject; 31 | annotations?: KubernetesKeyValueObject; 32 | }; 33 | 34 | export type RoleBindingRoleRef = { 35 | kind: string; 36 | name: string; 37 | apiGroup: string; 38 | }; 39 | 40 | export type RoleBindingSubject = { 41 | kind: string; 42 | name: string; 43 | apiGroup?: string; 44 | namespace?: string; 45 | }; 46 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/util/deletable.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | type DeleteField = { _isDeleted?: boolean }; 18 | 19 | export type Deletable = T & DeleteField; 20 | 21 | export const isActiveElement = (element: T): boolean => 22 | !element._isDeleted; 23 | 24 | export const getActiveElements = (list: T[]): T[] => 25 | list.filter(isActiveElement); 26 | 27 | export const undefinedIfEmpty = (list: T[]): T[] | undefined => 28 | list.length > 0 ? list : undefined; 29 | 30 | export const updateList = ( 31 | list: T[], 32 | newValue: T | undefined, 33 | idx: number, 34 | ): T[] => { 35 | list[idx] = newValue || { ...list[idx], _isDeleted: true }; 36 | return list; 37 | }; 38 | -------------------------------------------------------------------------------- /plugins/cad/src/types/ClusterIssuer.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesKeyValueObject } from './KubernetesResource'; 18 | 19 | export type ClusterIssuer = { 20 | kind: string; 21 | apiVersion: string; 22 | metadata: ClusterIssuerMetadata; 23 | spec: ClusterIssuerSpec; 24 | }; 25 | 26 | export type ClusterIssuerMetadata = { 27 | name: string; 28 | namespace?: string; 29 | labels?: KubernetesKeyValueObject; 30 | annotations?: KubernetesKeyValueObject; 31 | }; 32 | 33 | export type ClusterIssuerSpec = { 34 | acme: ACMEIssuer; 35 | }; 36 | 37 | export type ACMEIssuer = { 38 | server: string; 39 | email?: string; 40 | privateKeySecretRef?: ACMEIssuerPrivateKeySecretRef; 41 | }; 42 | 43 | export type ACMEIssuerPrivateKeySecretRef = { 44 | name: string; 45 | }; 46 | -------------------------------------------------------------------------------- /plugins/cad-backend/src/service/lib.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubeConfig } from '@kubernetes/client-node'; 18 | import { ClusterLocatorMethodType } from './config'; 19 | 20 | export const getKubernetesConfig = ( 21 | clusterLocatorMethodType: ClusterLocatorMethodType, 22 | ): KubeConfig => { 23 | const kubeConfig = new KubeConfig(); 24 | 25 | switch (clusterLocatorMethodType) { 26 | case ClusterLocatorMethodType.IN_CLUSTER: 27 | kubeConfig.loadFromCluster(); 28 | break; 29 | case ClusterLocatorMethodType.CURRENT_CONTEXT: 30 | kubeConfig.loadFromDefault(); 31 | break; 32 | default: 33 | throw new Error( 34 | `Unknown cluster locator method type, ${clusterLocatorMethodType}`, 35 | ); 36 | } 37 | 38 | return kubeConfig; 39 | }; 40 | -------------------------------------------------------------------------------- /plugins/cad/src/components/Links/LandingPageLink.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Link } from '@backstage/core-components'; 18 | import { useRouteRef } from '@backstage/core-plugin-api'; 19 | import React from 'react'; 20 | import { rootRouteRef } from '../../routes'; 21 | import { useLinkStyles } from './styles'; 22 | 23 | type RepositoriesLinkProps = { 24 | breadcrumb?: boolean; 25 | }; 26 | 27 | export const LandingPageLink = ({ breadcrumb }: RepositoriesLinkProps) => { 28 | const packageManagementRef = useRouteRef(rootRouteRef); 29 | 30 | const classes = useLinkStyles(); 31 | const className = breadcrumb ? classes.breadcrumb : ''; 32 | 33 | return ( 34 | 35 | Package Management 36 | 37 | ); 38 | }; 39 | -------------------------------------------------------------------------------- /plugins/cad/src/types/APIService.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesKeyValueObject } from './KubernetesResource'; 18 | 19 | export type APIService = { 20 | apiVersion: string; 21 | kind: string; 22 | metadata: APIServiceMetadata; 23 | spec: APIServiceSpec; 24 | }; 25 | 26 | export type APIServiceMetadata = { 27 | name: string; 28 | labels?: KubernetesKeyValueObject; 29 | annotations?: KubernetesKeyValueObject; 30 | }; 31 | 32 | export type APIServiceSpec = { 33 | service: ServiceReference; 34 | group: string; 35 | version: string; 36 | insecureSkipTLSVerify?: boolean; 37 | groupPriorityMinimum?: number; 38 | versionPriority?: number; 39 | }; 40 | 41 | export type ServiceReference = { 42 | namespace: string; 43 | name: string; 44 | port?: number; 45 | }; 46 | -------------------------------------------------------------------------------- /plugins/cad/src/types/ResourceQuota.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesKeyValueObject } from './KubernetesResource'; 18 | 19 | export type ResourceQuota = { 20 | kind: string; 21 | apiVersion: string; 22 | metadata: ResourceQuotaMetadata; 23 | spec: ResourceQuotaSpec; 24 | }; 25 | 26 | export type ResourceQuotaMetadata = { 27 | name: string; 28 | namespace?: string; 29 | labels?: KubernetesKeyValueObject; 30 | annotations?: KubernetesKeyValueObject; 31 | }; 32 | 33 | export type ResourceQuotaSpec = { 34 | hard?: ResourceQuotaSpecHard; 35 | }; 36 | 37 | export type ResourceQuotaSpecHard = { 38 | 'requests.cpu'?: string; 39 | 'requests.memory'?: string; 40 | 'limits.cpu'?: string; 41 | 'limits.memory'?: string; 42 | cpu?: string; 43 | memory?: string; 44 | }; 45 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceViewerDialog/components/FirstClassViewers/StructuredMetadata/resources/job.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Job } from '../../../../../../types/Job'; 18 | import { KubernetesResource } from '../../../../../../types/KubernetesResource'; 19 | import { Metadata } from '../StructuredMetadata'; 20 | import { getPodTemplatedStructuredMetadata } from './podTemplate'; 21 | 22 | export const getJobStructuredMetadata = ( 23 | resource: KubernetesResource, 24 | ): Metadata => { 25 | const job = resource as Job; 26 | 27 | const podMetadata: Metadata = getPodTemplatedStructuredMetadata( 28 | job.spec.template, 29 | ); 30 | 31 | return { 32 | completions: job.spec.completions, 33 | parallelism: job.spec.parallelism, 34 | ...podMetadata, 35 | }; 36 | }; 37 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceViewerDialog/components/FirstClassViewers/StructuredMetadata/resources/deployment.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Deployment } from '../../../../../../types/Deployment'; 18 | import { KubernetesResource } from '../../../../../../types/KubernetesResource'; 19 | import { Metadata } from '../StructuredMetadata'; 20 | import { getPodTemplatedStructuredMetadata } from './podTemplate'; 21 | 22 | export const getDeploymentStructuredMetadata = ( 23 | resource: KubernetesResource, 24 | ): Metadata => { 25 | const deployment = resource as Deployment; 26 | 27 | const podMetadata: Metadata = getPodTemplatedStructuredMetadata( 28 | deployment.spec.template, 29 | ); 30 | 31 | return { 32 | replicas: deployment.spec.replicas, 33 | ...podMetadata, 34 | }; 35 | }; 36 | -------------------------------------------------------------------------------- /packages/backend/src/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Logger } from 'winston'; 18 | import { Config } from '@backstage/config'; 19 | import { 20 | PluginCacheManager, 21 | PluginDatabaseManager, 22 | PluginEndpointDiscovery, 23 | TokenManager, 24 | UrlReader, 25 | } from '@backstage/backend-common'; 26 | import { PluginTaskScheduler } from '@backstage/backend-tasks'; 27 | import { PermissionEvaluator } from '@backstage/plugin-permission-common'; 28 | 29 | export type PluginEnvironment = { 30 | logger: Logger; 31 | database: PluginDatabaseManager; 32 | cache: PluginCacheManager; 33 | config: Config; 34 | reader: UrlReader; 35 | discovery: PluginEndpointDiscovery; 36 | tokenManager: TokenManager; 37 | scheduler: PluginTaskScheduler; 38 | permissions: PermissionEvaluator; 39 | }; 40 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 'Bug Report' 3 | about: 'Report an issue' 4 | labels: bug 5 | --- 6 | 7 | 8 | 9 | ## Expected Behavior 10 | 11 | 12 | 13 | ## Current Behavior 14 | 15 | 16 | 17 | ## Steps to Reproduce 18 | 19 | 20 | 21 | 22 | ## Possible Solution 23 | 24 | 25 | 26 | 27 | ## Context 28 | 29 | 30 | 31 | 32 | 33 | ## Your Environment 34 | 35 | 36 | 37 | - Browser Information: 38 | - Backstage version (in `backstage.json`): 39 | - `@kpt/backstage-plugin-cad` version: 40 | - `@kpt/backstage-plugin-cad-backend` version: 41 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceViewerDialog/components/FirstClassViewers/StructuredMetadata/resources/apiService.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { APIService } from '../../../../../../types/APIService'; 18 | import { KubernetesResource } from '../../../../../../types/KubernetesResource'; 19 | import { Metadata } from '../StructuredMetadata'; 20 | 21 | export const getAPIServiceStructuredMetadata = ( 22 | resource: KubernetesResource, 23 | ): Metadata => { 24 | const apiService = resource as APIService; 25 | 26 | const serviceSpec = apiService.spec.service; 27 | 28 | const groupVersion = `${apiService.spec.group}/${apiService.spec.version}`; 29 | const service = `${serviceSpec.namespace}/${serviceSpec.name}:${ 30 | serviceSpec.port ?? 443 31 | }`; 32 | 33 | return { 34 | apiService: `${groupVersion} → ${service}`, 35 | }; 36 | }; 37 | -------------------------------------------------------------------------------- /plugins/cad/src/types/ConfigManagement.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesKeyValueObject } from './KubernetesResource'; 18 | 19 | export type ListConfigManagements = { 20 | kind: string; 21 | apiVersion: string; 22 | items: ConfigManagement[]; 23 | }; 24 | 25 | export type ConfigManagement = { 26 | apiVersion: string; 27 | kind: string; 28 | metadata: ConfigManagementMetadata; 29 | spec: ConfigManagementSpec; 30 | status?: ConfigManagementStatus; 31 | }; 32 | 33 | export type ConfigManagementMetadata = { 34 | name: string; 35 | labels?: KubernetesKeyValueObject; 36 | annotations?: KubernetesKeyValueObject; 37 | }; 38 | 39 | export type ConfigManagementSpec = { 40 | enableMultiRepo: boolean; 41 | }; 42 | 43 | export type ConfigManagementStatus = { 44 | configManagementVersion?: string; 45 | healthy: boolean; 46 | }; 47 | -------------------------------------------------------------------------------- /plugins/cad-backend/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [0.1.0](https://github.com/GoogleContainerTools/kpt-backstage-plugins/compare/backstage-plugin-cad-backend-v0.0.0...backstage-plugin-cad-backend-v0.1.0) (2022-12-08) 4 | 5 | 6 | ### Features 7 | 8 | * add kubernetes service account authentication ([#187](https://github.com/GoogleContainerTools/kpt-backstage-plugins/issues/187)) ([f5d16d6](https://github.com/GoogleContainerTools/kpt-backstage-plugins/commit/f5d16d6f28bd4d5b3fd4e4d961e59b1eedc8aeb9)) 9 | * add support for google oidc authentication ([#189](https://github.com/GoogleContainerTools/kpt-backstage-plugins/issues/189)) ([d16a535](https://github.com/GoogleContainerTools/kpt-backstage-plugins/commit/d16a535e3463befc907a1407048c837ead8ad1c4)) 10 | * add support for okta authentication ([#188](https://github.com/GoogleContainerTools/kpt-backstage-plugins/issues/188)) ([3fd56ba](https://github.com/GoogleContainerTools/kpt-backstage-plugins/commit/3fd56ba81e8464c3ef842e141fd528c86a8a4d87)) 11 | * make git ops delivery tool configurable ([#203](https://github.com/GoogleContainerTools/kpt-backstage-plugins/issues/203)) ([8058d63](https://github.com/GoogleContainerTools/kpt-backstage-plugins/commit/8058d63877648d800d93f6f0ee796b986bfe1374)) 12 | * make porch resources namespace configurable ([#196](https://github.com/GoogleContainerTools/kpt-backstage-plugins/issues/196)) ([f3ff3e4](https://github.com/GoogleContainerTools/kpt-backstage-plugins/commit/f3ff3e42a0f24cda882d3b8e22f973607869bef5)) 13 | -------------------------------------------------------------------------------- /plugins/cad/src/components/Controls/Chip.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Chip as MaterialChip, makeStyles } from '@material-ui/core'; 18 | import React from 'react'; 19 | 20 | type ChipProps = { 21 | label: string; 22 | selected: boolean; 23 | onClick: () => void; 24 | }; 25 | 26 | const useStyles = makeStyles({ 27 | chip: { 28 | marginBottom: 0, 29 | transitionDuration: '0s !important', 30 | '& > span': { 31 | fontWeight: 'normal', 32 | }, 33 | }, 34 | }); 35 | 36 | export const Chip = ({ label, selected, onClick }: ChipProps) => { 37 | const classes = useStyles(); 38 | 39 | return ( 40 | 47 | ); 48 | }; 49 | -------------------------------------------------------------------------------- /plugins/cad/src/types/PersistentVolumeClaim.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesKeyValueObject } from './KubernetesResource'; 18 | 19 | export type PersistentVolumeClaim = { 20 | kind: string; 21 | apiVersion: string; 22 | metadata: PersistentVolumeClaimMetadata; 23 | spec: PersistentVolumeClaimSpec; 24 | }; 25 | 26 | export type PersistentVolumeClaimMetadata = { 27 | name: string; 28 | namespace?: string; 29 | labels?: KubernetesKeyValueObject; 30 | annotations?: KubernetesKeyValueObject; 31 | }; 32 | 33 | export type PersistentVolumeClaimSpec = { 34 | accessModes?: string[]; 35 | resources?: PersistentVolumeClaimResources; 36 | }; 37 | 38 | export type PersistentVolumeClaimResources = { 39 | requests?: PersistentVolumeClaimResourcesRequests; 40 | }; 41 | 42 | export type PersistentVolumeClaimResourcesRequests = { 43 | storage?: string; 44 | }; 45 | -------------------------------------------------------------------------------- /packages/backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backend", 3 | "version": "0.0.0", 4 | "main": "dist/index.cjs.js", 5 | "types": "src/index.ts", 6 | "private": true, 7 | "backstage": { 8 | "role": "backend" 9 | }, 10 | "scripts": { 11 | "start": "backstage-cli package start", 12 | "build": "backstage-cli package build", 13 | "lint": "backstage-cli package lint", 14 | "test": "backstage-cli package test", 15 | "clean": "backstage-cli package clean" 16 | }, 17 | "dependencies": { 18 | "@backstage/backend-common": "^0.18.3", 19 | "@backstage/backend-tasks": "^0.5.0", 20 | "@backstage/config": "^1.0.7", 21 | "@backstage/plugin-app-backend": "^0.3.43", 22 | "@backstage/plugin-auth-backend": "^0.18.1", 23 | "@backstage/plugin-catalog-backend": "^1.8.0", 24 | "@backstage/plugin-permission-common": "^0.7.4", 25 | "@backstage/plugin-permission-node": "^0.7.6", 26 | "@backstage/plugin-proxy-backend": "^0.2.37", 27 | "@kpt/backstage-plugin-cad-backend": "*", 28 | "app": "link:../app", 29 | "better-sqlite3": "^7.5.0", 30 | "dockerode": "^3.3.1", 31 | "express": "^4.17.1", 32 | "express-promise-router": "^4.1.0", 33 | "luxon": "^2.0.2", 34 | "winston": "^3.2.1" 35 | }, 36 | "devDependencies": { 37 | "@backstage/cli": "^0.22.5", 38 | "@types/dockerode": "^3.3.0", 39 | "@types/express": "^4.17.6", 40 | "@types/express-serve-static-core": "^4.17.5", 41 | "@types/luxon": "^2.0.4" 42 | }, 43 | "files": [ 44 | "dist" 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /plugins/cad-backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@kpt/backstage-plugin-cad-backend", 3 | "version": "0.1.0", 4 | "main": "src/index.ts", 5 | "types": "src/index.ts", 6 | "license": "Apache-2.0", 7 | "publishConfig": { 8 | "access": "public", 9 | "main": "dist/index.cjs.js", 10 | "types": "dist/index.d.ts" 11 | }, 12 | "backstage": { 13 | "role": "backend-plugin" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/GoogleContainerTools/kpt-backstage-plugins", 18 | "directory": "plugins/cad-backend" 19 | }, 20 | "scripts": { 21 | "start": "backstage-cli package start", 22 | "build": "backstage-cli package build", 23 | "lint": "backstage-cli package lint", 24 | "test": "backstage-cli package test", 25 | "prepack": "backstage-cli package prepack", 26 | "postpack": "backstage-cli package postpack", 27 | "clean": "backstage-cli package clean" 28 | }, 29 | "dependencies": { 30 | "@backstage/backend-common": "^0.18.3", 31 | "@backstage/config": "^1.0.7", 32 | "@kubernetes/client-node": "^0.16.0", 33 | "@types/express": "*", 34 | "express": "^4.17.1", 35 | "express-promise-router": "^4.1.0", 36 | "node-fetch": "^2.6.7", 37 | "request": "^2.88.2", 38 | "winston": "^3.2.1", 39 | "yn": "^4.0.0" 40 | }, 41 | "devDependencies": { 42 | "@backstage/cli": "^0.22.5", 43 | "@types/supertest": "^2.0.8", 44 | "msw": "^0.35.0", 45 | "supertest": "^6.1.6" 46 | }, 47 | "files": [ 48 | "dist" 49 | ] 50 | } 51 | -------------------------------------------------------------------------------- /plugins/cad/src/types/Service.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesKeyValueObject } from './KubernetesResource'; 18 | 19 | export type Service = { 20 | kind: string; 21 | apiVersion: string; 22 | metadata: ServiceMetadata; 23 | spec: ServiceSpec; 24 | }; 25 | 26 | export type ServiceMetadata = { 27 | name: string; 28 | namespace?: string; 29 | labels?: KubernetesKeyValueObject; 30 | annotations?: KubernetesKeyValueObject; 31 | }; 32 | 33 | export type ServiceSpec = { 34 | type?: string; 35 | externalTrafficPolicy?: string; 36 | externalName?: string; 37 | sessionAffinity?: string; 38 | selector?: KubernetesKeyValueObject; 39 | ports?: ServicePort[]; 40 | clusterIP?: string; 41 | }; 42 | 43 | export type ServicePort = { 44 | name?: string; 45 | appProtocol?: string; 46 | protocol?: string; 47 | port?: number; 48 | targetPort?: number | string; 49 | nodePort?: number; 50 | }; 51 | -------------------------------------------------------------------------------- /plugins/cad/src/utils/selectItem.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { SelectItem } from '@backstage/core-components'; 18 | import { startCase } from 'lodash'; 19 | 20 | type StringFormatFn = (str: string) => string; 21 | 22 | type BuildSelectItemsProps = { 23 | labelFn?: StringFormatFn | false; 24 | }; 25 | 26 | export const sortByLabel = (selectItems: T[]): T[] => { 27 | const compareLabel = (item1: SelectItem, item2: SelectItem): number => 28 | item1.label > item2.label ? 1 : -1; 29 | 30 | return selectItems.sort(compareLabel); 31 | }; 32 | 33 | export const buildSelectItemsFromList = ( 34 | items: string[], 35 | options?: BuildSelectItemsProps, 36 | ): SelectItem[] => { 37 | const thisLabelFn = 38 | options?.labelFn !== false 39 | ? options?.labelFn || startCase 40 | : (label: string) => label; 41 | 42 | return items.map(item => ({ label: thisLabelFn(item), value: item })); 43 | }; 44 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | name: CI 16 | 17 | on: 18 | push: 19 | pull_request: 20 | 21 | jobs: 22 | lint: 23 | name: Lint 24 | runs-on: ubuntu-latest 25 | steps: 26 | - uses: actions/checkout@v3 27 | - uses: actions/setup-node@v3 28 | with: 29 | node-version: 16 30 | - name: Install dependencies 31 | run: yarn install --frozen-lockfile 32 | - name: Lint 33 | run: yarn lint:all 34 | - name: Type checking and declarations 35 | run: yarn tsc:full 36 | - name: Prettier 37 | run: yarn prettier:check 38 | 39 | test: 40 | name: Test 41 | runs-on: ubuntu-latest 42 | steps: 43 | - uses: actions/checkout@v3 44 | - uses: actions/setup-node@v3 45 | with: 46 | node-version: 16 47 | - name: Install dependencies 48 | run: yarn install --frozen-lockfile 49 | - name: Run tests 50 | run: yarn test:all 51 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceViewerDialog/components/FirstClassViewers/StructuredMetadata/resources/roleBinding.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesResource } from '../../../../../../types/KubernetesResource'; 18 | import { 19 | RoleBinding, 20 | RoleBindingSubject, 21 | } from '../../../../../../types/RoleBinding'; 22 | import { Metadata } from '../StructuredMetadata'; 23 | 24 | export const getRoleBindingStructuredMetadata = ( 25 | resource: KubernetesResource, 26 | ): Metadata => { 27 | const roleBinding = resource as RoleBinding; 28 | 29 | const getSubjectDescription = (subject: RoleBindingSubject): string => 30 | `→ ${subject.kind} ${subject.namespace ? `${subject.namespace}/` : ''}${ 31 | subject.name 32 | }`; 33 | 34 | return { 35 | binding: [ 36 | `${roleBinding.roleRef.kind} ${roleBinding.roleRef.name}`, 37 | ...roleBinding.subjects.map(getSubjectDescription), 38 | ], 39 | }; 40 | }; 41 | -------------------------------------------------------------------------------- /plugins/cad/src/utils/kubernetesResource.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesResource } from '../types/KubernetesResource'; 18 | 19 | export const removeInternalKptAnnotations = ( 20 | resource: KubernetesResource, 21 | ): void => { 22 | const resourceMetadata = resource.metadata; 23 | 24 | if (resourceMetadata.annotations) { 25 | const internalAnnotations = Object.keys( 26 | resourceMetadata.annotations, 27 | ).filter(annotation => annotation.startsWith('internal.kpt.dev/')); 28 | 29 | internalAnnotations.forEach( 30 | internalAnnotation => 31 | delete resourceMetadata.annotations?.[internalAnnotation], 32 | ); 33 | 34 | if (Object.keys(resourceMetadata.annotations).length === 0) { 35 | delete resourceMetadata.annotations; 36 | } 37 | } 38 | }; 39 | 40 | export const getGroupVersionKind = (resource: KubernetesResource): string => { 41 | return `${resource.apiVersion}/${resource.kind}`; 42 | }; 43 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceViewerDialog/components/FirstClassViewers/StructuredMetadata/resources/customResourceDefinition.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { CustomResourceDefinition } from '../../../../../../types/CustomResourceDefinition'; 18 | import { KubernetesResource } from '../../../../../../types/KubernetesResource'; 19 | import { Metadata } from '../StructuredMetadata'; 20 | 21 | export const getCustomResourceDefinitionStructuredMetadata = ( 22 | resource: KubernetesResource, 23 | ): Metadata => { 24 | const crd = resource as CustomResourceDefinition; 25 | 26 | const names = crd.spec.names; 27 | 28 | return { 29 | groupVersionKinds: crd.spec.versions.map( 30 | version => `${crd.spec.group}/${version.name}/${names.kind}`, 31 | ), 32 | resourceNames: [ 33 | `singular: ${names.singular}`, 34 | `plural: ${names.plural}`, 35 | `list kind: ${names.listKind}`, 36 | ], 37 | scope: crd.spec.scope, 38 | }; 39 | }; 40 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceViewerDialog/components/FirstClassViewers/StructuredMetadata/resources/persistentVolumeClaim.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesResource } from '../../../../../../types/KubernetesResource'; 18 | import { PersistentVolumeClaim } from '../../../../../../types/PersistentVolumeClaim'; 19 | import { Metadata } from '../StructuredMetadata'; 20 | 21 | export const getPersistentVolumeClaimStructuredMetadata = ( 22 | resource: KubernetesResource, 23 | ): Metadata => { 24 | const persistentVolumeClaim = resource as PersistentVolumeClaim; 25 | 26 | const getVolumeClaimDescription = (): string => { 27 | const storage = persistentVolumeClaim.spec.resources?.requests?.storage; 28 | const accessMethods = (persistentVolumeClaim.spec.accessModes ?? []).join( 29 | ', ', 30 | ); 31 | 32 | return `${storage} ${accessMethods}`; 33 | }; 34 | 35 | return { 36 | volumeClaim: getVolumeClaimDescription(), 37 | }; 38 | }; 39 | -------------------------------------------------------------------------------- /plugins/cad/src/utils/featureFlags.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { ConfigAsDataApi } from '../apis'; 18 | 19 | let configSyncEnabled = false; 20 | 21 | export const isConfigSyncEnabled = (): boolean => configSyncEnabled; 22 | 23 | export const allowFunctionRepositoryRegistration = (): boolean => false; 24 | 25 | export const showRegisteredFunctionRepositories = (): boolean => false; 26 | 27 | export const loadFeatures = async (api: ConfigAsDataApi): Promise => { 28 | const features = await api.getFeatures(); 29 | 30 | if (features.gitOps === 'config-sync') { 31 | const { groups } = await api.listApiGroups(); 32 | 33 | const configManagementGroupExists = !!groups.find( 34 | apiGroup => apiGroup.name === 'configmanagement.gke.io', 35 | ); 36 | 37 | if (configManagementGroupExists) { 38 | const { items: configManagements } = await api.listConfigManagements(); 39 | 40 | configSyncEnabled = configManagements.length > 0; 41 | } 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /plugins/cad/src/components/Links/PackagesLink.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Link } from '@backstage/core-components'; 18 | import { useRouteRef } from '@backstage/core-plugin-api'; 19 | import React from 'react'; 20 | import { packagesRouteRef } from '../../routes'; 21 | import { ContentDetails } from '../../utils/repository'; 22 | import { useLinkStyles } from './styles'; 23 | 24 | type PackagesLinkProps = { 25 | contentDetails: ContentDetails; 26 | breadcrumb?: boolean; 27 | }; 28 | 29 | export const PackagesLink = ({ 30 | contentDetails, 31 | breadcrumb, 32 | }: PackagesLinkProps) => { 33 | const packagesRef = useRouteRef(packagesRouteRef); 34 | 35 | const classes = useLinkStyles(); 36 | const className = breadcrumb ? classes.breadcrumb : ''; 37 | 38 | return ( 39 | 43 | {contentDetails.contentSummary}s 44 | 45 | ); 46 | }; 47 | -------------------------------------------------------------------------------- /hack/create-kind-cluster.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2023 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -euo pipefail 17 | 18 | CAD_CLUSTER_NAME=cad-cluster 19 | SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd) 20 | 21 | echo "Verify script prerequisites" 22 | if ! [ -x "$(command -v kind)" ]; then 23 | echo 'Error: kind is not installed. Follow https://kind.sigs.k8s.io to install kind.' 24 | exit 1 25 | fi 26 | 27 | if ! [ -x "$(command -v kubectl)" ]; then 28 | echo 'Error: kubectl is not installed. Follow https://kubernetes.io/docs/tasks/tools to install kubectl.' 29 | exit 1 30 | fi 31 | 32 | if ! [ -x "$(command -v jq)" ]; then 33 | echo 'Error: jq is not installed. Follow https://stedolan.github.io/jq to install jq.' 34 | exit 1 35 | fi 36 | 37 | echo "Create kind cluster" 38 | kind create cluster --name $CAD_CLUSTER_NAME 39 | 40 | echo "Install Porch" 41 | $SCRIPT_DIR/install-porch.sh 42 | 43 | echo "Install example package repositories" 44 | $SCRIPT_DIR/install-package-repositories.sh 45 | 46 | echo "kind cluster ready" 47 | -------------------------------------------------------------------------------- /plugins/cad/src/components/Controls/PackageIcon.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { SvgIcon } from '@material-ui/core'; 18 | import DraftsIcon from '@material-ui/icons/Drafts'; 19 | import React, { Fragment } from 'react'; 20 | import { PackageRevisionLifecycle } from '../../types/PackageRevision'; 21 | 22 | const DraftPackageIcon = () => ; 23 | 24 | const ProposedPackageIcon = () => ( 25 | 26 | 27 | 28 | ); 29 | 30 | type PackageIconProps = { 31 | lifecycle: PackageRevisionLifecycle; 32 | }; 33 | 34 | export const PackageIcon = ({ lifecycle }: PackageIconProps) => { 35 | switch (lifecycle) { 36 | case PackageRevisionLifecycle.DRAFT: 37 | return ; 38 | 39 | case PackageRevisionLifecycle.PROPOSED: 40 | return ; 41 | 42 | default: 43 | } 44 | 45 | return ; 46 | }; 47 | -------------------------------------------------------------------------------- /plugins/cad/src/types/CustomResourceDefinition.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesKeyValueObject } from './KubernetesResource'; 18 | 19 | export type CustomResourceDefinition = { 20 | apiVersion: string; 21 | kind: string; 22 | metadata: CustomResourceDefinitionMetadata; 23 | spec: CustomResourceDefinitionSpec; 24 | }; 25 | 26 | export type CustomResourceDefinitionMetadata = { 27 | name: string; 28 | labels?: KubernetesKeyValueObject; 29 | annotations?: KubernetesKeyValueObject; 30 | }; 31 | 32 | export type CustomResourceDefinitionSpec = { 33 | group: string; 34 | names: CustomResourceDefinitionNames; 35 | scope: string; 36 | versions: CustomResourceDefinitionVersion[]; 37 | }; 38 | 39 | export type CustomResourceDefinitionNames = { 40 | plural: string; 41 | singular: string; 42 | shortNames: string[]; 43 | kind: string; 44 | listKind: string; 45 | categories?: string[]; 46 | }; 47 | 48 | export type CustomResourceDefinitionVersion = { 49 | name: string; 50 | storage: boolean; 51 | served: boolean; 52 | }; 53 | -------------------------------------------------------------------------------- /plugins/cad/src/types/ApplyReplacement.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesKeyValueObject } from './KubernetesResource'; 18 | 19 | export type ApplyReplacement = { 20 | kind: string; 21 | apiVersion: string; 22 | metadata: ApplyReplacementMetadata; 23 | replacements: ApplyReplacementReplacement[]; 24 | }; 25 | 26 | export type ApplyReplacementMetadata = { 27 | name: string; 28 | labels?: KubernetesKeyValueObject; 29 | annotations?: KubernetesKeyValueObject; 30 | }; 31 | 32 | export type ApplyReplacementReplacement = { 33 | source: ReplacementSource; 34 | targets: ReplacementTarget[]; 35 | }; 36 | 37 | export type ReplacementSource = ReplacementResourceSelector & { 38 | fieldPath?: string; 39 | }; 40 | 41 | export type ReplacementTarget = { 42 | select: ReplacementResourceSelector; 43 | fieldPaths: string[]; 44 | options?: ReplacementOptions; 45 | }; 46 | 47 | export type ReplacementResourceSelector = { 48 | kind?: string; 49 | name?: string; 50 | }; 51 | 52 | export type ReplacementOptions = { 53 | delimiter?: string; 54 | index?: number; 55 | }; 56 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/Controls/SingleTextFieldAccordion.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { TextField } from '@material-ui/core'; 18 | import React, { Fragment } from 'react'; 19 | import { AccordionState, EditorAccordion } from './EditorAccordion'; 20 | 21 | type OnValueUpdated = (value: string) => void; 22 | 23 | type SingleTextFieldAccordionProps = { 24 | id: string; 25 | title: string; 26 | state: AccordionState; 27 | value: string; 28 | onValueUpdated: OnValueUpdated; 29 | }; 30 | 31 | export const SingleTextFieldAccordion = ({ 32 | id, 33 | title, 34 | state, 35 | value, 36 | onValueUpdated, 37 | }: SingleTextFieldAccordionProps) => { 38 | return ( 39 | 40 | 41 | onValueUpdated(e.target.value)} 46 | fullWidth 47 | /> 48 | 49 | 50 | ); 51 | }; 52 | -------------------------------------------------------------------------------- /plugins/cad/src/types/Deployment.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesKeyValueObject } from './KubernetesResource'; 18 | import { PodTemplateSpec } from './Pod'; 19 | 20 | export type Deployment = { 21 | apiVersion: string; 22 | kind: string; 23 | metadata: DeploymentMetadata; 24 | spec: DeploymentSpec; 25 | }; 26 | 27 | export type DeploymentMetadata = { 28 | name: string; 29 | namespace?: string; 30 | labels?: KubernetesKeyValueObject; 31 | annotations?: KubernetesKeyValueObject; 32 | }; 33 | 34 | export type DeploymentSpec = { 35 | replicas?: number; 36 | selector: LabelSelector; 37 | template: PodTemplateSpec; 38 | strategy?: DeploymentStrategy; 39 | minReadySeconds?: number; 40 | progressDeadlineSeconds?: number; 41 | revisionHistoryLimit?: number; 42 | }; 43 | 44 | export type LabelSelector = { 45 | matchLabels: KubernetesKeyValueObject; 46 | }; 47 | 48 | export type DeploymentStrategy = { 49 | type?: string; 50 | rollingUpdate?: RollingUpdateDeployment; 51 | }; 52 | 53 | export type RollingUpdateDeployment = { 54 | maxUnavailable?: number | string; 55 | maxSurge?: number | string; 56 | }; 57 | -------------------------------------------------------------------------------- /plugins/cad/src/types/Kptfile.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesKeyValueObject } from './KubernetesResource'; 18 | 19 | export type Kptfile = { 20 | kind: string; 21 | apiVersion: string; 22 | metadata: KptfileMetadata; 23 | info: KptfileInfo; 24 | pipeline: KptfilePipeline; 25 | upstream?: KptfileUpstream; 26 | }; 27 | 28 | export type KptfileMetadata = { 29 | name: string; 30 | labels?: KubernetesKeyValueObject; 31 | annotations?: KubernetesKeyValueObject; 32 | }; 33 | 34 | export type KptfileInfo = { 35 | description?: string; 36 | keywords?: string[]; 37 | site?: string; 38 | readinessGates?: ReadinessGate[]; 39 | }; 40 | 41 | export type ReadinessGate = { 42 | conditionType: string; 43 | }; 44 | 45 | export type KptfilePipeline = { 46 | mutators?: KptfileFunction[]; 47 | validators?: KptfileFunction[]; 48 | }; 49 | 50 | export type KptfileFunction = { 51 | image: string; 52 | configPath?: string; 53 | }; 54 | 55 | export type KptfileUpstream = { 56 | git?: KptfileGitUpstream; 57 | }; 58 | 59 | export type KptfileGitUpstream = { 60 | repo: string; 61 | directory: string; 62 | ref: string; 63 | }; 64 | -------------------------------------------------------------------------------- /plugins/cad/src/components/Controls/ConfirmationDialog.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { 18 | Button, 19 | Dialog, 20 | DialogActions, 21 | DialogContent, 22 | DialogContentText, 23 | DialogTitle, 24 | } from '@material-ui/core'; 25 | import React from 'react'; 26 | 27 | type ConfirmationDialogProps = { 28 | title: string; 29 | contentText: string; 30 | actionText: string; 31 | open: boolean; 32 | onClose: () => void; 33 | onAction: () => void; 34 | }; 35 | 36 | export const ConfirmationDialog = ({ 37 | title, 38 | contentText, 39 | actionText, 40 | open, 41 | onClose, 42 | onAction, 43 | }: ConfirmationDialogProps) => { 44 | return ( 45 | 46 | {title} 47 | 48 | {contentText} 49 | 50 | 51 | 54 | 57 | 58 | 59 | ); 60 | }; 61 | -------------------------------------------------------------------------------- /plugins/cad/src/utils/secret.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesKeyValueObject } from '../types/KubernetesResource'; 18 | import { Secret } from '../types/Secret'; 19 | 20 | export const getBasicAuthSecret = ( 21 | name: string, 22 | username: string, 23 | password: string, 24 | ): Secret => { 25 | const basicAuthSecret = { 26 | apiVersion: 'v1', 27 | kind: 'Secret', 28 | metadata: { 29 | name: name, 30 | }, 31 | type: 'kubernetes.io/basic-auth', 32 | data: { 33 | username: btoa(username), 34 | password: btoa(password), 35 | }, 36 | }; 37 | 38 | return basicAuthSecret; 39 | }; 40 | 41 | export const getOpagueSecret = ( 42 | name: string, 43 | namespace: string, 44 | data: KubernetesKeyValueObject, 45 | ): Secret => { 46 | const basicOpagueSecret = { 47 | apiVersion: 'v1', 48 | kind: 'Secret', 49 | metadata: { 50 | name: name, 51 | namespace: namespace, 52 | }, 53 | type: 'Opaque', 54 | data: data, 55 | }; 56 | 57 | return basicOpagueSecret; 58 | }; 59 | 60 | export const isBasicAuthSecret = (secret: Secret): boolean => { 61 | return secret.type === 'kubernetes.io/basic-auth'; 62 | }; 63 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceViewerDialog/components/FirstClassViewers/StructuredMetadata/resources/applyReplacements.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesResource } from '../../../../../../types/KubernetesResource'; 18 | import { Metadata } from '../StructuredMetadata'; 19 | 20 | export const getApplyReplacementsStructuredMetadata = ( 21 | resource: KubernetesResource, 22 | ): Metadata => { 23 | const applyReplacements = resource as any; 24 | 25 | const customMetadata: Metadata = {}; 26 | 27 | for (const [index, replacement] of applyReplacements.replacements.entries()) { 28 | const name = 29 | applyReplacements.replacements.length > 1 30 | ? `Replacement ${index + 1}` 31 | : 'Replacement'; 32 | 33 | const targetDetails = replacement.targets.map( 34 | (target: any) => 35 | `Target: ${target.select.kind} ${ 36 | target.select.name 37 | } ${target.fieldPaths.join(', ')}`, 38 | ); 39 | 40 | customMetadata[name] = [ 41 | `Source: ${replacement.source.kind} ${replacement.source.name} ${replacement.source.fieldPath}`, 42 | ...targetDetails, 43 | ]; 44 | } 45 | 46 | return customMetadata; 47 | }; 48 | -------------------------------------------------------------------------------- /plugins/cad/src/components/Controls/Checkbox.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { 18 | Checkbox as MaterialCheckbox, 19 | FormControlLabel, 20 | FormHelperText, 21 | makeStyles, 22 | } from '@material-ui/core'; 23 | import React, { ChangeEvent } from 'react'; 24 | 25 | type CheckboxProps = { 26 | label: string; 27 | checked: boolean; 28 | onChange: (checked: boolean) => void; 29 | helperText?: JSX.Element | string; 30 | }; 31 | 32 | const useStyles = makeStyles({ 33 | description: { 34 | marginLeft: '32px', 35 | marginTop: '0', 36 | }, 37 | }); 38 | 39 | export const Checkbox = ({ 40 | label, 41 | checked, 42 | onChange, 43 | helperText, 44 | }: CheckboxProps) => { 45 | const classes = useStyles(); 46 | 47 | return ( 48 |
49 | } 51 | label={label} 52 | onChange={(_: ChangeEvent<{}>, isChecked: boolean) => 53 | onChange(isChecked) 54 | } 55 | /> 56 | {helperText && ( 57 | 58 | {helperText} 59 | 60 | )} 61 |
62 | ); 63 | }; 64 | -------------------------------------------------------------------------------- /plugins/cad-backend/src/service/standaloneServer.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { 18 | createServiceBuilder, 19 | loadBackendConfig, 20 | } from '@backstage/backend-common'; 21 | import { Server } from 'http'; 22 | import { Logger } from 'winston'; 23 | import { createRouter } from './router'; 24 | 25 | export interface ServerOptions { 26 | port: number; 27 | enableCors: boolean; 28 | logger: Logger; 29 | } 30 | 31 | export async function startStandaloneServer( 32 | options: ServerOptions, 33 | ): Promise { 34 | const logger = options.logger.child({ service: 'cad-backend-backend' }); 35 | const config = await loadBackendConfig({ logger, argv: process.argv }); 36 | 37 | logger.debug('Starting application server...'); 38 | const router = await createRouter({ 39 | config, 40 | logger, 41 | }); 42 | 43 | let service = createServiceBuilder(module) 44 | .setPort(options.port) 45 | .addRouter('/cad-backend', router); 46 | if (options.enableCors) { 47 | service = service.enableCors({ origin: 'http://localhost:3000' }); 48 | } 49 | 50 | return await service.start().catch(err => { 51 | logger.error(err); 52 | process.exit(1); 53 | }); 54 | } 55 | 56 | module.hot?.accept(); 57 | -------------------------------------------------------------------------------- /plugins/cad/src/plugin.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { 18 | createApiFactory, 19 | createPlugin, 20 | createRoutableExtension, 21 | discoveryApiRef, 22 | fetchApiRef, 23 | googleAuthApiRef, 24 | oktaAuthApiRef, 25 | } from '@backstage/core-plugin-api'; 26 | import { configAsDataApiRef, PorchRestAPI } from './apis'; 27 | import { rootRouteRef } from './routes'; 28 | 29 | export const cadPlugin = createPlugin({ 30 | id: 'config-as-data', 31 | routes: { 32 | root: rootRouteRef, 33 | }, 34 | apis: [ 35 | createApiFactory({ 36 | api: configAsDataApiRef, 37 | deps: { 38 | discoveryApi: discoveryApiRef, 39 | fetchApi: fetchApiRef, 40 | googleAuthApi: googleAuthApiRef, 41 | oktaAuthApi: oktaAuthApiRef, 42 | }, 43 | factory: ({ discoveryApi, fetchApi, googleAuthApi, oktaAuthApi }) => 44 | new PorchRestAPI(discoveryApi, fetchApi, googleAuthApi, oktaAuthApi), 45 | }), 46 | ], 47 | }); 48 | 49 | export const CadPage = cadPlugin.provide( 50 | createRoutableExtension({ 51 | name: 'config-as-data', 52 | component: () => 53 | import('./components/LandingPage').then(m => m.LandingPage), 54 | mountPoint: rootRouteRef, 55 | }), 56 | ); 57 | -------------------------------------------------------------------------------- /plugins/cad/src/components/PackageRevisionPage/updatedResourcesMap/processUpdatedResourcesMap.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { cloneDeep } from 'lodash'; 18 | import { ConfigAsDataApi } from '../../../apis'; 19 | import { PackageRevisionResourcesMap } from '../../../types/PackageRevisionResource'; 20 | import { processApplyReplacementsUpdates } from './resources/applyReplacements'; 21 | import { processSetLabelsUpdates } from './resources/setLabels'; 22 | 23 | type ProcessMapFn = ( 24 | api: ConfigAsDataApi, 25 | originalMap: PackageRevisionResourcesMap, 26 | currentMap: PackageRevisionResourcesMap, 27 | ) => Promise; 28 | 29 | export const processUpdatedResourcesMap = async ( 30 | api: ConfigAsDataApi, 31 | originalMap: PackageRevisionResourcesMap, 32 | currentMap: PackageRevisionResourcesMap, 33 | ): Promise => { 34 | const processMapFns: ProcessMapFn[] = [ 35 | processApplyReplacementsUpdates, 36 | processSetLabelsUpdates, 37 | ]; 38 | 39 | let resourcesMap = cloneDeep(currentMap); 40 | 41 | for (const processMapFn of processMapFns) { 42 | resourcesMap = await processMapFn(api, originalMap, resourcesMap); 43 | } 44 | 45 | return resourcesMap; 46 | }; 47 | -------------------------------------------------------------------------------- /plugins/cad/src/types/PackageRevisionResource.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export type ListPackageRevisionResources = { 18 | kind: string; 19 | apiVersion: string; 20 | items: PackageRevisionResources[]; 21 | }; 22 | 23 | export type PackageRevisionResources = { 24 | apiVersion: string; 25 | kind: string; 26 | metadata: PackageRevisionResourcesMetadata; 27 | spec: PackageRevisionResourcesSpec; 28 | status?: PackageRevisionResourcesStatus; 29 | }; 30 | 31 | export type PackageRevisionResourcesMetadata = { 32 | name: string; 33 | namespace?: string; 34 | resourceVersion?: string; 35 | }; 36 | 37 | export type PackageRevisionResourcesSpec = { 38 | resources: PackageRevisionResourcesMap; 39 | }; 40 | 41 | export type PackageRevisionResourcesMap = { 42 | [key: string]: string; 43 | }; 44 | 45 | export type PackageRevisionResourcesStatus = { 46 | renderStatus?: RenderStatus; 47 | }; 48 | 49 | export type RenderStatus = { 50 | error: string; 51 | result: ResultList; 52 | }; 53 | 54 | export type ResultList = { 55 | items: Result[]; 56 | }; 57 | 58 | export type Result = { 59 | image: string; 60 | results: ResultItem[]; 61 | }; 62 | 63 | export type ResultItem = { 64 | message: string; 65 | severity: string; 66 | }; 67 | -------------------------------------------------------------------------------- /plugins/cad/src/components/Links/RepositoryLink.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Link } from '@backstage/core-components'; 18 | import { useRouteRef } from '@backstage/core-plugin-api'; 19 | import React from 'react'; 20 | import { repositoryRouteRef } from '../../routes'; 21 | import { Repository } from '../../types/Repository'; 22 | import { getRepositoryTitle } from '../../utils/repository'; 23 | import { useLinkStyles } from './styles'; 24 | 25 | type RepositoryLinkProps = { 26 | repository: Repository; 27 | breadcrumb?: boolean; 28 | stopPropagation?: boolean; 29 | }; 30 | 31 | export const RepositoryLink = ({ 32 | repository, 33 | breadcrumb, 34 | stopPropagation, 35 | }: RepositoryLinkProps) => { 36 | const repositoryRef = useRouteRef(repositoryRouteRef); 37 | 38 | const classes = useLinkStyles(); 39 | const className = breadcrumb ? classes.breadcrumb : ''; 40 | 41 | const repositoryName = repository.metadata.name; 42 | 43 | return ( 44 | { 47 | if (stopPropagation) { 48 | e.stopPropagation(); 49 | } 50 | }} 51 | to={repositoryRef({ repositoryName })} 52 | > 53 | {getRepositoryTitle(repository)} 54 | 55 | ); 56 | }; 57 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kpt-backstage-plugins", 3 | "version": "0.1.0", 4 | "private": true, 5 | "engines": { 6 | "node": "16 || 18" 7 | }, 8 | "scripts": { 9 | "dev": "NODE_ENV=development concurrently \"yarn start\" \"yarn start-backend\"", 10 | "start": "yarn workspace app start", 11 | "start-backend": "yarn workspace backend start", 12 | "build": "backstage-cli repo build --all", 13 | "build-image": "docker build --target backstage-app --tag kpt-backstage-plugins .", 14 | "tsc": "tsc", 15 | "tsc:full": "tsc --skipLibCheck false --incremental false", 16 | "clean": "backstage-cli clean && lerna run clean", 17 | "diff": "lerna run diff --", 18 | "test": "backstage-cli test", 19 | "test:all": "lerna run test -- --coverage", 20 | "lint": "backstage-cli repo lint --since origin/main", 21 | "lint:all": "backstage-cli repo lint", 22 | "prettier:check": "prettier --check .", 23 | "prettier:write": "prettier --write .", 24 | "create-plugin": "backstage-cli create-plugin --scope internal", 25 | "remove-plugin": "backstage-cli remove-plugin" 26 | }, 27 | "workspaces": { 28 | "packages": [ 29 | "packages/*", 30 | "plugins/*" 31 | ] 32 | }, 33 | "devDependencies": { 34 | "@backstage/cli": "^0.22.5", 35 | "@spotify/prettier-config": "^12.0.0", 36 | "concurrently": "^6.0.0", 37 | "lerna": "^4.0.0", 38 | "prettier": "^2.3.2", 39 | "typescript": "~4.5.4" 40 | }, 41 | "resolutions": { 42 | "@types/react": "^17", 43 | "@types/react-dom": "^17" 44 | }, 45 | "prettier": "@spotify/prettier-config", 46 | "lint-staged": { 47 | "*.{js,jsx,ts,tsx,mjs,cjs}": [ 48 | "eslint --fix", 49 | "prettier --write" 50 | ], 51 | "*.{json,md}": [ 52 | "prettier --write" 53 | ] 54 | }, 55 | "dependencies": { 56 | "@types/react": "^17", 57 | "@types/react-dom": "^17" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /packages/app/src/App.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { UserSettingsPage } from '@backstage/plugin-user-settings'; 18 | import React from 'react'; 19 | import { Navigate, Route } from 'react-router'; 20 | import { apis } from './apis'; 21 | import { Root } from './components/Root'; 22 | 23 | import { createApp } from '@backstage/app-defaults'; 24 | import { AppRouter, FlatRoutes } from '@backstage/core-app-api'; 25 | import { AlertDisplay, OAuthRequestDialog } from '@backstage/core-components'; 26 | import { CatalogEntityPage, CatalogIndexPage } from '@backstage/plugin-catalog'; 27 | import { CadPage } from '@kpt/backstage-plugin-cad'; 28 | 29 | const app = createApp({ 30 | apis, 31 | }); 32 | 33 | const routes = ( 34 | 35 | 36 | } /> 37 | } 40 | /> 41 | } /> 42 | } /> 43 | 44 | ); 45 | 46 | export default app.createRoot( 47 | <> 48 | 49 | 50 | 51 | {routes} 52 | 53 | , 54 | ); 55 | -------------------------------------------------------------------------------- /plugins/cad/src/types/StatefulSet.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesKeyValueObject } from './KubernetesResource'; 18 | import { PersistentVolumeClaim } from './PersistentVolumeClaim'; 19 | import { PodTemplateSpec } from './Pod'; 20 | 21 | export type StatefulSet = { 22 | apiVersion: string; 23 | kind: string; 24 | metadata: StatefulSetMetadata; 25 | spec: StatefulSetSpec; 26 | }; 27 | 28 | export type StatefulSetMetadata = { 29 | name: string; 30 | namespace?: string; 31 | labels?: KubernetesKeyValueObject; 32 | annotations?: KubernetesKeyValueObject; 33 | }; 34 | 35 | export type StatefulSetSpec = { 36 | replicas?: number; 37 | selector: LabelSelector; 38 | serviceName: string; 39 | template: PodTemplateSpec; 40 | podManagementPolicy?: string; 41 | updateStrategy?: StatefulSetUpdateStrategy; 42 | revisionHistoryLimit?: number; 43 | minReadySeconds?: number; 44 | volumeClaimTemplates?: PersistentVolumeClaim[]; 45 | }; 46 | 47 | export type LabelSelector = { 48 | matchLabels: KubernetesKeyValueObject; 49 | }; 50 | 51 | export type StatefulSetUpdateStrategy = { 52 | type?: string; 53 | rollingUpdate?: RollingUpdateStatefulSetStrategy; 54 | }; 55 | 56 | export type RollingUpdateStatefulSetStrategy = { 57 | partition?: number; 58 | maxUnavailable?: number | string; 59 | }; 60 | -------------------------------------------------------------------------------- /plugins/cad/src/components/AddPackagePage/utils/kptfile.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Kptfile, KptfileFunction } from '../../../types/Kptfile'; 18 | import { PackageResource } from '../../../utils/packageRevisionResources'; 19 | 20 | type Pipeline = 'mutator' | 'validator'; 21 | 22 | export const findKptfileFunctionConfig = ( 23 | resources: PackageResource[], 24 | fn: KptfileFunction, 25 | ): PackageResource | undefined => { 26 | return resources.find(resource => resource.filename === fn.configPath); 27 | }; 28 | 29 | export const isFunctionConfigDeletable = ( 30 | resource: PackageResource, 31 | ): boolean => { 32 | return ( 33 | resource.isLocalConfigResource && 34 | resource.filename !== 'package-context.yaml' 35 | ); 36 | }; 37 | 38 | export const removeKptfileFunction = ( 39 | kptfile: Kptfile, 40 | pipeline: Pipeline, 41 | fn: KptfileFunction, 42 | ): void => { 43 | const kptPipeline = kptfile.pipeline; 44 | 45 | if (pipeline === 'mutator' && kptPipeline.mutators) { 46 | kptPipeline.mutators = kptPipeline.mutators.filter( 47 | mutatorFn => mutatorFn !== fn, 48 | ); 49 | } 50 | 51 | if (pipeline === 'validator' && kptPipeline.validators) { 52 | kptPipeline.validators = kptPipeline.validators.filter( 53 | validatorFn => validatorFn !== fn, 54 | ); 55 | } 56 | }; 57 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceViewerDialog/components/FirstClassViewers/StructuredMetadata/resources/service.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesResource } from '../../../../../../types/KubernetesResource'; 18 | import { Service, ServicePort } from '../../../../../../types/Service'; 19 | import { Metadata } from '../StructuredMetadata'; 20 | 21 | export const getServiceStructuredMetadata = ( 22 | resource: KubernetesResource, 23 | ): Metadata => { 24 | const service = resource as Service; 25 | 26 | const getExposedPortsDescription = (ports: ServicePort[]) => { 27 | const getPortDescription = (port: ServicePort): string => { 28 | const namePrefix = port.name ? `${port.name}: ` : ''; 29 | const portAndProtocol = `${port.protocol ?? 'TCP'} ${port.port}`; 30 | const targetPort = port.targetPort ? `→ ${port.targetPort}` : ''; 31 | 32 | return `${namePrefix} ${portAndProtocol} ${targetPort}`; 33 | }; 34 | 35 | return ports.map(getPortDescription); 36 | }; 37 | 38 | return { 39 | type: service.spec.type, 40 | externalTrafficPolicy: service.spec.externalTrafficPolicy, 41 | sessionAffinity: service.spec.sessionAffinity, 42 | selector: service.spec.selector, 43 | clusterIP: service.spec.clusterIP, 44 | exposedPorts: getExposedPortsDescription(service.spec.ports ?? []), 45 | }; 46 | }; 47 | -------------------------------------------------------------------------------- /app-config.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | app: 16 | title: Kpt Backstage Plugins 17 | baseUrl: http://localhost:3000 18 | 19 | organization: 20 | name: Kpt Backstage Plugins 21 | 22 | backend: 23 | baseUrl: http://localhost:7007 24 | listen: 25 | port: 7007 26 | # Uncomment the following host directive to bind to all IPv4 interfaces and 27 | # not just the baseUrl hostname. 28 | # host: 0.0.0.0 29 | csp: 30 | connect-src: ["'self'", 'http:', 'https:'] 31 | # Content-Security-Policy directives follow the Helmet format: https://helmetjs.github.io/#reference 32 | # Default Helmet Content-Security-Policy values can be removed by setting the key to false 33 | cors: 34 | origin: http://localhost:3000 35 | methods: [GET, POST, PUT, DELETE] 36 | credentials: true 37 | database: 38 | client: better-sqlite3 39 | connection: ':memory:' 40 | cache: 41 | store: memory 42 | 43 | configAsData: 44 | # The namespace where Porch managed resources live. 45 | resourcesNamespace: default 46 | 47 | # Determines the GitOps delivery tool to use. 48 | gitOpsDeliveryTool: config-sync 49 | 50 | clusterLocatorMethod: 51 | # Determines how the client will locate the Kubernetes cluster. 52 | type: current-context 53 | 54 | # Determines how the client will authenticate with the Kubernetes cluster. 55 | authProvider: current-context 56 | -------------------------------------------------------------------------------- /plugins/cad/src/components/Controls/IconButton.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { 18 | IconButton as MaterialIconButton, 19 | makeStyles, 20 | Tooltip, 21 | } from '@material-ui/core'; 22 | import React, { ReactNode } from 'react'; 23 | 24 | type IconButtonProps = { 25 | title: string; 26 | className?: string; 27 | inTable?: boolean; 28 | stopPropagation?: boolean; 29 | children: ReactNode; 30 | onClick?: () => void; 31 | }; 32 | 33 | const useStyles = makeStyles({ 34 | inTableStyle: { 35 | position: 'absolute', 36 | transform: 'translateY(-50%)', 37 | }, 38 | }); 39 | 40 | export const IconButton = ({ 41 | title, 42 | className, 43 | inTable, 44 | stopPropagation, 45 | onClick, 46 | children, 47 | }: IconButtonProps) => { 48 | const classes = useStyles(); 49 | 50 | const finalClassName = 51 | className || (inTable ? classes.inTableStyle : undefined); 52 | 53 | return ( 54 | 55 | { 59 | if (!onClick) return; 60 | 61 | if (stopPropagation) { 62 | e.stopPropagation(); 63 | } 64 | 65 | onClick(); 66 | }} 67 | > 68 | {children} 69 | 70 | 71 | ); 72 | }; 73 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceViewerDialog/components/FirstClassViewers/StructuredMetadata/resources/secret.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { 18 | KubernetesKeyValueObject, 19 | KubernetesResource, 20 | } from '../../../../../../types/KubernetesResource'; 21 | import { Secret } from '../../../../../../types/Secret'; 22 | import { Metadata } from '../StructuredMetadata'; 23 | 24 | const getSecrets = ( 25 | data: KubernetesKeyValueObject | undefined, 26 | stringData: KubernetesKeyValueObject | undefined, 27 | ): KubernetesKeyValueObject | undefined => { 28 | const secretData: KubernetesKeyValueObject = {}; 29 | 30 | if (data) { 31 | const keys = Object.keys(data); 32 | for (const key of keys) { 33 | secretData[key] = Buffer.from(data[key], 'base64').toString(); 34 | } 35 | } 36 | 37 | if (stringData) { 38 | const keys = Object.keys(stringData); 39 | for (const key of keys) { 40 | secretData[key] = stringData[key]; 41 | } 42 | } 43 | 44 | return Object.keys(secretData).length > 0 ? secretData : undefined; 45 | }; 46 | 47 | export const getSecretStructuredMetadata = ( 48 | resource: KubernetesResource, 49 | ): Metadata => { 50 | const secret = resource as Secret; 51 | 52 | return { 53 | type: `${secret.type} ${secret.immutable ? '(immutable)' : ''}`, 54 | secrets: getSecrets(secret.data, secret.stringData) ?? 'none', 55 | }; 56 | }; 57 | -------------------------------------------------------------------------------- /plugins/cad/src/components/Links/PackageLink.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Link } from '@backstage/core-components'; 18 | import { useRouteRef } from '@backstage/core-plugin-api'; 19 | import React from 'react'; 20 | import { packageRouteRef } from '../../routes'; 21 | import { PackageRevision } from '../../types/PackageRevision'; 22 | import { getPackageRevisionTitle } from '../../utils/packageRevision'; 23 | import { useLinkStyles } from './styles'; 24 | 25 | type PackageLinkProps = { 26 | packageRevision: PackageRevision; 27 | breadcrumb?: boolean; 28 | packageNameOnly?: boolean; 29 | stopPropagation?: boolean; 30 | }; 31 | 32 | export const PackageLink = ({ 33 | packageRevision, 34 | breadcrumb, 35 | packageNameOnly, 36 | stopPropagation, 37 | }: PackageLinkProps) => { 38 | const packageRef = useRouteRef(packageRouteRef); 39 | 40 | const classes = useLinkStyles(); 41 | const className = breadcrumb ? classes.breadcrumb : ''; 42 | 43 | const repositoryName = packageRevision.spec.repository; 44 | const packageName = packageRevision.metadata.name; 45 | 46 | return ( 47 | { 50 | if (stopPropagation) { 51 | e.stopPropagation(); 52 | } 53 | }} 54 | to={packageRef({ repositoryName, packageName })} 55 | > 56 | {getPackageRevisionTitle(packageRevision, !!packageNameOnly)} 57 | 58 | ); 59 | }; 60 | -------------------------------------------------------------------------------- /hack/resources/package-repositories.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: config.porch.kpt.dev/v1alpha1 16 | kind: Repository 17 | metadata: 18 | labels: 19 | kpt.dev/repository-access: read-only 20 | kpt.dev/repository-content: external-blueprints 21 | name: kpt-samples 22 | namespace: default 23 | spec: 24 | content: Package 25 | description: kpt Samples 26 | git: 27 | branch: main 28 | directory: / 29 | repo: https://github.com/GoogleContainerTools/kpt-samples.git 30 | type: git 31 | --- 32 | apiVersion: config.porch.kpt.dev/v1alpha1 33 | kind: Repository 34 | metadata: 35 | labels: 36 | kpt.dev/repository-access: read-only 37 | kpt.dev/repository-content: external-blueprints 38 | name: nephio-example-packages 39 | namespace: default 40 | spec: 41 | content: Package 42 | description: Nephio Example Packages 43 | git: 44 | branch: main 45 | directory: / 46 | repo: https://github.com/nephio-project/nephio-example-packages 47 | type: git 48 | --- 49 | apiVersion: config.porch.kpt.dev/v1alpha1 50 | kind: Repository 51 | metadata: 52 | labels: 53 | kpt.dev/repository-access: read-only 54 | kpt.dev/repository-content: external-blueprints 55 | name: nephio-free5gc-packages 56 | namespace: default 57 | spec: 58 | content: Package 59 | description: Nephio free5GC Packages 60 | git: 61 | branch: main 62 | directory: / 63 | repo: https://github.com/nephio-project/free5gc-packages 64 | type: git 65 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceViewerDialog/components/FirstClassViewers/StructuredMetadata/resources/statefulSet.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesResource } from '../../../../../../types/KubernetesResource'; 18 | import { StatefulSet } from '../../../../../../types/StatefulSet'; 19 | import { Metadata } from '../StructuredMetadata'; 20 | import { getPersistentVolumeClaimStructuredMetadata } from './persistentVolumeClaim'; 21 | import { getPodTemplatedStructuredMetadata } from './podTemplate'; 22 | 23 | export const getStatefulSetStructuredMetadata = ( 24 | resource: KubernetesResource, 25 | ): Metadata => { 26 | const statefulSet = resource as StatefulSet; 27 | 28 | const podMetadata: Metadata = getPodTemplatedStructuredMetadata( 29 | statefulSet.spec.template, 30 | ); 31 | 32 | const volumeClaimMetadata: Metadata = {}; 33 | 34 | const volumeClaimTemplates = statefulSet.spec.volumeClaimTemplates ?? []; 35 | for (const [index, volumeClaim] of volumeClaimTemplates.entries()) { 36 | const name = 37 | volumeClaimTemplates.length > 1 38 | ? `volumeClaim${index + 1}` 39 | : `volumeClaim`; 40 | 41 | volumeClaimMetadata[name] = 42 | getPersistentVolumeClaimStructuredMetadata(volumeClaim).volumeClaim; 43 | } 44 | 45 | return { 46 | replicas: statefulSet.spec.replicas, 47 | serviceName: statefulSet.spec.serviceName, 48 | ...podMetadata, 49 | ...volumeClaimMetadata, 50 | }; 51 | }; 52 | -------------------------------------------------------------------------------- /hack/install-porch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2023 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Exit on error 17 | set -euo pipefail 18 | 19 | echo "Verify script prerequisites" 20 | if ! [ -x "$(command -v kubectl)" ]; then 21 | echo 'Error: kubectl is not installed. Follow https://kubernetes.io/docs/tasks/tools to install kubectl.' 22 | exit 1 23 | fi 24 | 25 | if ! [ -x "$(command -v jq)" ]; then 26 | echo 'Error: jq is not installed. Follow https://stedolan.github.io/jq to install jq.' 27 | exit 1 28 | fi 29 | 30 | echo "Find latest published release of Porch" 31 | LATEST_PORCH_RELEASE=`curl -s https://api.github.com/repos/GoogleContainerTools/kpt/releases | jq -r '[.[].name | select( . != null ) | select(contains("porch"))][0]'` 32 | PORCH_VERSION=`echo "$LATEST_PORCH_RELEASE" | cut -d/ -f 2` 33 | 34 | echo "Download Porch $PORCH_VERSION deployment blueprint" 35 | TMPDIR=`mktemp -d -t porch-XXXXXX` 36 | curl -Lso $TMPDIR/deployment-blueprint.tar.gz https://github.com/GoogleContainerTools/kpt/releases/download/$LATEST_PORCH_RELEASE/deployment-blueprint.tar.gz 37 | mkdir $TMPDIR/porch-install 38 | tar xzf $TMPDIR/deployment-blueprint.tar.gz -C $TMPDIR/porch-install 39 | 40 | CLUSTER_NAME=`kubectl config current-context` 41 | echo "Apply Porch resources to cluster $CLUSTER_NAME" 42 | kubectl apply -f $TMPDIR/porch-install 1> /dev/null 43 | kubectl wait deployment --for=condition=Available --timeout=60s -n porch-system porch-server 1> /dev/null 44 | rm -rf $TMPDIR 45 | 46 | echo "Porch is installed and ready for use" 47 | -------------------------------------------------------------------------------- /plugins/cad/src/components/Controls/Select.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { SelectItem } from '@backstage/core-components'; 18 | import { 19 | FormControl, 20 | FormHelperText, 21 | InputLabel, 22 | MenuItem, 23 | Select as MaterialSelect, 24 | } from '@material-ui/core'; 25 | import React, { ChangeEvent } from 'react'; 26 | 27 | type SelectProps = { 28 | label: string; 29 | selected: string; 30 | items: SelectItem[]; 31 | onChange: (value: string) => void; 32 | className?: string; 33 | helperText?: string; 34 | }; 35 | 36 | export const Select = ({ 37 | label, 38 | selected, 39 | items, 40 | onChange, 41 | className, 42 | helperText, 43 | }: SelectProps) => { 44 | const handleChange = ( 45 | event: ChangeEvent<{ name?: string | undefined; value: unknown }>, 46 | ): void => { 47 | onChange(event.target.value as string); 48 | }; 49 | 50 | return ( 51 | 52 | {label} 53 | 59 | {items.map(item => ( 60 | 61 | {item.label} 62 | 63 | ))} 64 | 65 | {helperText} 66 | 67 | ); 68 | }; 69 | -------------------------------------------------------------------------------- /plugins/cad/src/types/Ingress.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesKeyValueObject } from './KubernetesResource'; 18 | 19 | export type Ingress = { 20 | apiVersion: string; 21 | kind: string; 22 | metadata: IngressMetadata; 23 | spec: IngressSpec; 24 | }; 25 | 26 | export type IngressMetadata = { 27 | name: string; 28 | namespace?: string; 29 | labels?: KubernetesKeyValueObject; 30 | annotations?: KubernetesKeyValueObject; 31 | }; 32 | 33 | export type IngressSpec = { 34 | tls?: IngressTLS[]; 35 | ingressClassName?: string; 36 | defaultBackend?: IngressBackend; 37 | rules?: IngressRule[]; 38 | }; 39 | 40 | export type IngressTLS = { 41 | hosts?: string[]; 42 | secretName?: string; 43 | }; 44 | 45 | export type IngressRule = { 46 | host?: string; 47 | http?: HTTPIngressRuleValue; 48 | }; 49 | 50 | export type HTTPIngressRuleValue = { 51 | paths: HTTPIngressPath[]; 52 | }; 53 | 54 | export type HTTPIngressPath = { 55 | pathType: string; 56 | path?: string; 57 | backend: IngressBackend; 58 | }; 59 | 60 | export type IngressBackend = { 61 | service?: IngressServiceBackend; 62 | resource?: IngressResourceBackend; 63 | }; 64 | 65 | export type IngressServiceBackend = { 66 | name: string; 67 | port: ServiceBackendPort; 68 | }; 69 | 70 | export type ServiceBackendPort = { 71 | name?: string; 72 | number?: number; 73 | }; 74 | 75 | export type IngressResourceBackend = { 76 | apiGroup?: string; 77 | kind: string; 78 | name: string; 79 | }; 80 | -------------------------------------------------------------------------------- /plugins/cad/src/components/PackagesTable/components/SyncStatusVisual.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { 18 | StatusError, 19 | StatusOK, 20 | StatusPending, 21 | StatusWarning, 22 | } from '@backstage/core-components'; 23 | import React, { Fragment } from 'react'; 24 | import { SyncStatus, SyncStatusState } from '../../../utils/configSync'; 25 | 26 | type SyncStatusVisualProps = { 27 | syncStatus: SyncStatus | undefined | null; 28 | }; 29 | 30 | export const SyncStatusVisual = ({ syncStatus }: SyncStatusVisualProps) => { 31 | if (syncStatus) { 32 | switch (syncStatus.state) { 33 | case SyncStatusState.SYNCED: 34 | return ( 35 | 36 | 37 | {syncStatus.state} 38 | 39 | ); 40 | case SyncStatusState.RECONCILING: 41 | case SyncStatusState.PENDING: 42 | return ( 43 | 44 | 45 | {syncStatus.state} 46 | 47 | ); 48 | case SyncStatusState.STALLED: 49 | case SyncStatusState.ERROR: 50 | return ( 51 | 52 | 53 | {syncStatus.state} 54 | 55 | ); 56 | default: 57 | } 58 | } 59 | 60 | if (syncStatus === null) { 61 | return ( 62 | 63 | 64 | Not installed 65 | 66 | ); 67 | } 68 | 69 | return ; 70 | }; 71 | -------------------------------------------------------------------------------- /plugins/cad/src/components/Controls/MultiSelect.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { SelectItem } from '@backstage/core-components'; 18 | import { 19 | FormControl, 20 | FormHelperText, 21 | InputLabel, 22 | MenuItem, 23 | Select as MaterialSelect, 24 | } from '@material-ui/core'; 25 | import React, { ChangeEvent } from 'react'; 26 | 27 | type MultiSelectProps = { 28 | label: string; 29 | value: string[]; 30 | items: SelectItem[]; 31 | onChange: (items: string[]) => void; 32 | className?: string; 33 | helperText?: string; 34 | }; 35 | 36 | export const MultiSelect = ({ 37 | label, 38 | value, 39 | items, 40 | onChange, 41 | className, 42 | helperText, 43 | }: MultiSelectProps) => { 44 | const handleChange = ( 45 | event: ChangeEvent<{ name?: string | undefined; value: unknown }>, 46 | ): void => { 47 | onChange(event.target.value as string[]); 48 | }; 49 | 50 | return ( 51 | 52 | {label} 53 | 60 | {items.map(item => ( 61 | 62 | {item.label} 63 | 64 | ))} 65 | 66 | {helperText} 67 | 68 | ); 69 | }; 70 | -------------------------------------------------------------------------------- /plugins/cad/src/components/Controls/YamlViewer.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import Editor, { DiffEditor, loader } from '@monaco-editor/react'; 18 | import * as monaco from 'monaco-editor'; 19 | import React from 'react'; 20 | 21 | type YamlViewerProps = { 22 | height?: string; 23 | width?: string; 24 | original?: string; 25 | value: string; 26 | showDiff?: boolean; 27 | allowEdit?: boolean; 28 | onUpdatedValue?: (newValue: string) => void; 29 | }; 30 | 31 | export const YamlViewer = ({ 32 | original, 33 | value, 34 | showDiff, 35 | allowEdit, 36 | onUpdatedValue, 37 | }: YamlViewerProps) => { 38 | loader.config({ monaco }); 39 | 40 | const handleUpdatedValue = (yaml?: string): void => { 41 | if (onUpdatedValue && yaml) { 42 | onUpdatedValue(yaml); 43 | } 44 | }; 45 | 46 | const sharedEditorOptions: monaco.editor.IStandaloneEditorConstructionOptions = 47 | { 48 | minimap: { enabled: false }, 49 | readOnly: !allowEdit, 50 | scrollBeyondLastLine: false, 51 | }; 52 | 53 | if (showDiff) { 54 | return ( 55 | 64 | ); 65 | } 66 | 67 | return ( 68 | 74 | ); 75 | }; 76 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceViewerDialog/components/FirstClassViewers/StructuredMetadata/resources/kptfile.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Kptfile, KptfileFunction } from '../../../../../../types/Kptfile'; 18 | import { KubernetesResource } from '../../../../../../types/KubernetesResource'; 19 | import { getFunctionNameAndTagFromImage } from '../../../../../../utils/function'; 20 | import { Metadata } from '../StructuredMetadata'; 21 | 22 | const getKptFunctionDescription = (fn: KptfileFunction): string => { 23 | const functionNameAndTag = getFunctionNameAndTagFromImage(fn.image); 24 | 25 | if (fn.configPath) { 26 | return `${functionNameAndTag}, ${fn.configPath} config`; 27 | } 28 | 29 | return functionNameAndTag; 30 | }; 31 | 32 | export const getKptfileStructuredMetadata = ( 33 | resource: KubernetesResource, 34 | ): Metadata => { 35 | const kptFile = resource as Kptfile; 36 | const readinessGates = kptFile.info.readinessGates; 37 | 38 | return { 39 | description: kptFile.info.description, 40 | keywords: kptFile.info.keywords, 41 | site: kptFile.info.site, 42 | readinessGates: readinessGates 43 | ? readinessGates.map(gate => gate.conditionType) 44 | : undefined, 45 | upstream: kptFile.upstream?.git 46 | ? `${kptFile.upstream.git.repo}/${kptFile.upstream.git.directory}@${kptFile.upstream?.git?.ref}` 47 | : '', 48 | mutators: kptFile.pipeline?.mutators?.map(getKptFunctionDescription), 49 | validators: kptFile.pipeline?.validators?.map(getKptFunctionDescription), 50 | }; 51 | }; 52 | -------------------------------------------------------------------------------- /plugins/cad/src/components/AddPackagePage/utils/resource.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesResource } from '../../../types/KubernetesResource'; 18 | import { PackageResource } from '../../../utils/packageRevisionResources'; 19 | import { dumpYaml } from '../../../utils/yaml'; 20 | 21 | export const createResource = ( 22 | apiVersion: string, 23 | kind: string, 24 | name: string, 25 | localConfig: boolean = true, 26 | ): KubernetesResource => { 27 | const resource: KubernetesResource = { 28 | apiVersion: apiVersion, 29 | kind: kind, 30 | metadata: { 31 | name: name, 32 | }, 33 | }; 34 | 35 | if (localConfig) { 36 | resource.metadata.annotations = { 37 | 'config.kubernetes.io/local-config': 'true', 38 | }; 39 | } 40 | 41 | return resource; 42 | }; 43 | 44 | export const addNewPackageResource = ( 45 | newPackageResources: PackageResource[], 46 | resource: KubernetesResource, 47 | filename: string, 48 | ): PackageResource => { 49 | const packageResource: PackageResource = { 50 | filename: filename, 51 | yaml: dumpYaml(resource), 52 | } as PackageResource; 53 | 54 | newPackageResources.push(packageResource); 55 | 56 | return packageResource; 57 | }; 58 | 59 | export const addUpdatedPackageResource = ( 60 | updatedPackageResources: PackageResource[], 61 | packageResource: PackageResource, 62 | resource: KubernetesResource, 63 | ): PackageResource => { 64 | packageResource.yaml = dumpYaml(resource); 65 | 66 | updatedPackageResources.push(packageResource); 67 | 68 | return packageResource; 69 | }; 70 | -------------------------------------------------------------------------------- /plugins/cad/src/types/Repository.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesKeyValueObject } from './KubernetesResource'; 18 | 19 | export type ListRepositories = { 20 | kind: string; 21 | apiVersion: string; 22 | items: Repository[]; 23 | }; 24 | 25 | export type Repository = { 26 | apiVersion: string; 27 | kind: string; 28 | metadata: RepositoryMetadata; 29 | spec: RepositorySpec; 30 | status?: RepositoryStatus; 31 | }; 32 | 33 | export type RepositoryMetadata = { 34 | name: string; 35 | namespace?: string; 36 | labels?: KubernetesKeyValueObject; 37 | }; 38 | 39 | export type RepositorySpec = { 40 | type: RepositoryType; 41 | description: string; 42 | content: RepositoryContent; 43 | deployment?: boolean; 44 | git?: RepositoryGitDetails; 45 | oci?: RepositoryOciDetails; 46 | }; 47 | 48 | export type RepositoryStatus = { 49 | conditions?: Condition[]; 50 | }; 51 | 52 | export type Condition = { 53 | type: string; 54 | status: string; 55 | lastTransitionTime: string; 56 | reason: string; 57 | message: string; 58 | }; 59 | 60 | export enum RepositoryType { 61 | GIT = 'git', 62 | OCI = 'oci', 63 | } 64 | 65 | export enum RepositoryContent { 66 | PACKAGE = 'Package', 67 | FUNCTION = 'Function', 68 | } 69 | 70 | export type RepositoryGitDetails = { 71 | repo: string; 72 | branch: string; 73 | createBranch?: boolean; 74 | directory: string; 75 | secretRef?: RepositorySecretRef; 76 | }; 77 | 78 | export type RepositorySecretRef = { 79 | name: string; 80 | }; 81 | 82 | export type RepositoryOciDetails = { 83 | registry: string; 84 | secretRef?: RepositorySecretRef; 85 | }; 86 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceViewerDialog/components/FirstClassViewers/StructuredMetadata/resources/role.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KubernetesResource } from '../../../../../../types/KubernetesResource'; 18 | import { Role } from '../../../../../../types/Role'; 19 | import { Metadata } from '../StructuredMetadata'; 20 | 21 | export const getRoleStructuredMetadata = ( 22 | resource: KubernetesResource, 23 | ): Metadata => { 24 | const role = resource as Role; 25 | 26 | const customMetadata: Metadata = {}; 27 | 28 | for (const [index, rule] of role.rules.entries()) { 29 | const name = 30 | role.rules.length > 1 ? `permissions${index + 1}` : 'permissions'; 31 | 32 | const mapAsterix = 33 | (description: string) => 34 | (value: string): string => 35 | value === '*' ? description : value; 36 | 37 | const groups = (rule.apiGroups ?? ['*']) 38 | .map(mapAsterix('all groups')) 39 | .map(apiGroup => apiGroup || 'core'); 40 | const resources = (rule.resources ?? ['*']).map( 41 | mapAsterix('all resources'), 42 | ); 43 | const verbs = (rule.verbs ?? ['*']).map(mapAsterix('all verbs')); 44 | 45 | const groupsList = groups.join(', '); 46 | const resourcesList = resources.join(', '); 47 | const verbsList = verbs.join(', '); 48 | const resoureNamesList = 49 | (rule.resourceNames ?? []).length > 0 50 | ? `- ${rule.resourceNames?.join(', ')}` 51 | : ``; 52 | 53 | customMetadata[name] = [ 54 | `${groupsList} ${resourcesList} ${resoureNamesList}`, 55 | `→ ${verbsList}`, 56 | ]; 57 | } 58 | 59 | return customMetadata; 60 | }; 61 | -------------------------------------------------------------------------------- /plugins/cad/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@kpt/backstage-plugin-cad", 3 | "version": "0.4.0", 4 | "main": "src/index.ts", 5 | "types": "src/index.ts", 6 | "license": "Apache-2.0", 7 | "publishConfig": { 8 | "access": "public", 9 | "main": "dist/index.esm.js", 10 | "types": "dist/index.d.ts" 11 | }, 12 | "backstage": { 13 | "role": "frontend-plugin" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/GoogleContainerTools/kpt-backstage-plugins", 18 | "directory": "plugins/cad" 19 | }, 20 | "scripts": { 21 | "build": "backstage-cli package build", 22 | "start": "backstage-cli package start", 23 | "lint": "backstage-cli package lint", 24 | "test": "backstage-cli package test", 25 | "diff": "backstage-cli plugin:diff", 26 | "prepack": "backstage-cli package prepack", 27 | "postpack": "backstage-cli package postpack", 28 | "clean": "backstage-cli package clean" 29 | }, 30 | "dependencies": { 31 | "@backstage/core-components": "^0.12.5", 32 | "@backstage/core-plugin-api": "^1.5.0", 33 | "@backstage/theme": "^0.2.18", 34 | "@material-ui/core": "^4.12.2", 35 | "@material-ui/icons": "^4.9.1", 36 | "@material-ui/lab": "4.0.0-alpha.57", 37 | "@monaco-editor/loader": "1.3.0", 38 | "@monaco-editor/react": "4.4.2", 39 | "diff": "^5.0.0", 40 | "js-yaml": "^4.0.0", 41 | "lodash": "^4.17.21", 42 | "moment": "^2.29.1", 43 | "monaco-editor": "^0.33.0", 44 | "react-use": "^17.2.4" 45 | }, 46 | "peerDependencies": { 47 | "react": "^16.13.1 || ^17.0.0", 48 | "react-router-dom": "6.0.0-beta.0" 49 | }, 50 | "devDependencies": { 51 | "@backstage/cli": "^0.22.5", 52 | "@backstage/core-app-api": "^1.6.0", 53 | "@backstage/dev-utils": "^1.0.13", 54 | "@backstage/test-utils": "^1.2.6", 55 | "@testing-library/jest-dom": "^5.10.1", 56 | "@testing-library/react": "^12.1.3", 57 | "@testing-library/user-event": "^14.0.0", 58 | "@types/diff": "^5.0.2", 59 | "@types/jest": "*", 60 | "@types/js-yaml": "^4.0.0", 61 | "@types/node": "*", 62 | "cross-fetch": "^3.1.5", 63 | "msw": "^0.35.0" 64 | }, 65 | "files": [ 66 | "dist", 67 | "config.d.ts" 68 | ], 69 | "configSchema": "config.d.ts" 70 | } 71 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/NamespaceEditor/NamespaceEditor.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React, { useEffect, useState } from 'react'; 18 | import { Namespace, NamespaceMetadata } from '../../../../../types/Namespace'; 19 | import { dumpYaml, loadYaml } from '../../../../../utils/yaml'; 20 | import { ResourceMetadataAccordion } from '../Controls'; 21 | import { useEditorStyles } from '../styles'; 22 | 23 | type OnUpdatedYamlFn = (yaml: string) => void; 24 | 25 | type ResourceEditorProps = { 26 | yaml: string; 27 | onUpdatedYaml: OnUpdatedYamlFn; 28 | }; 29 | 30 | type State = { 31 | metadata: NamespaceMetadata; 32 | }; 33 | 34 | export const NamespaceEditor = ({ 35 | yaml, 36 | onUpdatedYaml, 37 | }: ResourceEditorProps) => { 38 | const resourceYaml = loadYaml(yaml) as Namespace; 39 | 40 | const createResourceState = (): State => ({ 41 | metadata: resourceYaml.metadata, 42 | }); 43 | 44 | const [state, setState] = useState(createResourceState); 45 | const [expanded, setExpanded] = useState(); 46 | 47 | const classes = useEditorStyles(); 48 | 49 | useEffect(() => { 50 | resourceYaml.metadata = state.metadata; 51 | 52 | onUpdatedYaml(dumpYaml(resourceYaml)); 53 | }, [state, onUpdatedYaml, resourceYaml]); 54 | 55 | return ( 56 |
57 | setState(s => ({ ...s, metadata }))} 63 | /> 64 |
65 | ); 66 | }; 67 | -------------------------------------------------------------------------------- /plugins/cad/src/utils/repositorySummary.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { PackageRevision } from '../types/PackageRevision'; 18 | import { Repository } from '../types/Repository'; 19 | import { RepositorySummary } from '../types/RepositorySummary'; 20 | import { filterPackageSummaries, getPackageSummaries } from './packageSummary'; 21 | 22 | export const getRepositorySummaries = ( 23 | allRepositories: Repository[], 24 | ): RepositorySummary[] => { 25 | const repositorySummaries: RepositorySummary[] = allRepositories.map( 26 | repository => ({ repository: repository, downstreamRepositories: [] }), 27 | ); 28 | 29 | return repositorySummaries; 30 | }; 31 | 32 | export const getRepositorySummary = ( 33 | repositorySummaries: RepositorySummary[], 34 | name: string, 35 | ): RepositorySummary => { 36 | const repositorySummary = repositorySummaries.find( 37 | summary => summary.repository.metadata.name === name, 38 | ); 39 | 40 | if (!repositorySummary) { 41 | throw new Error(`Repository ${name} does not exist`); 42 | } 43 | 44 | return repositorySummary; 45 | }; 46 | 47 | export const populatePackageSummaries = ( 48 | repositorySummaries: RepositorySummary[], 49 | packageRevisions: PackageRevision[], 50 | ) => { 51 | const allPackageSummaries = getPackageSummaries( 52 | packageRevisions, 53 | repositorySummaries, 54 | repositorySummaries.map(summary => summary.repository), 55 | ); 56 | 57 | repositorySummaries.forEach(repositorySummary => { 58 | repositorySummary.packageSummaries = filterPackageSummaries( 59 | allPackageSummaries, 60 | { repository: repositorySummary.repository }, 61 | ); 62 | }); 63 | }; 64 | -------------------------------------------------------------------------------- /plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/ServiceAccountEditor/ServiceAccountEditor.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React, { useEffect, useState } from 'react'; 18 | import { 19 | ServiceAccount, 20 | ServiceAccountMetadata, 21 | } from '../../../../../types/ServiceAccount'; 22 | import { dumpYaml, loadYaml } from '../../../../../utils/yaml'; 23 | import { ResourceMetadataAccordion } from '../Controls'; 24 | import { useEditorStyles } from '../styles'; 25 | 26 | type OnUpdatedYamlFn = (yaml: string) => void; 27 | 28 | type ResourceEditorProps = { 29 | yaml: string; 30 | onUpdatedYaml: OnUpdatedYamlFn; 31 | }; 32 | 33 | type State = { 34 | metadata: ServiceAccountMetadata; 35 | }; 36 | 37 | export const ServiceAccountEditor = ({ 38 | yaml, 39 | onUpdatedYaml, 40 | }: ResourceEditorProps) => { 41 | const resourceYaml = loadYaml(yaml) as ServiceAccount; 42 | 43 | const createResourceState = (): State => ({ 44 | metadata: resourceYaml.metadata, 45 | }); 46 | 47 | const [state, setState] = useState(createResourceState()); 48 | const [expanded, setExpanded] = useState(); 49 | 50 | const classes = useEditorStyles(); 51 | 52 | useEffect(() => { 53 | resourceYaml.metadata = state.metadata; 54 | 55 | onUpdatedYaml(dumpYaml(resourceYaml)); 56 | }, [state, onUpdatedYaml, resourceYaml]); 57 | 58 | return ( 59 |
60 | setState(s => ({ ...s, metadata }))} 65 | /> 66 |
67 | ); 68 | }; 69 | -------------------------------------------------------------------------------- /plugins/cad/src/routes.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2022 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { createRouteRef, createSubRouteRef } from '@backstage/core-plugin-api'; 18 | 19 | export const rootRouteRef = createRouteRef({ 20 | id: 'config-as-data', 21 | }); 22 | 23 | export const registerRepositoryRouteRef = createSubRouteRef({ 24 | id: 'register-repository', 25 | path: '/repositories/register', 26 | parent: rootRouteRef, 27 | }); 28 | 29 | export const repositoryRouteRef = createSubRouteRef({ 30 | id: 'named-repository', 31 | path: '/repositories/:repositoryName', 32 | parent: rootRouteRef, 33 | }); 34 | 35 | export const packagesRouteRef = createSubRouteRef({ 36 | id: 'named-package-content-type', 37 | path: '/packages/:packageContent', 38 | parent: rootRouteRef, 39 | }); 40 | 41 | export const addPackageRouteRef = createSubRouteRef({ 42 | id: 'add-package', 43 | path: '/packages/:packageContent/add', 44 | parent: rootRouteRef, 45 | }); 46 | 47 | export const addPackageToRepoRouteRef = createSubRouteRef({ 48 | id: 'add-package', 49 | path: '/repositories/:repositoryName/packages/add', 50 | parent: rootRouteRef, 51 | }); 52 | 53 | export const packageRouteRef = createSubRouteRef({ 54 | id: 'named-package', 55 | path: '/repositories/:repositoryName/packages/:packageName', 56 | parent: rootRouteRef, 57 | }); 58 | 59 | export const clonePackageRouteRef = createSubRouteRef({ 60 | id: 'clone-package', 61 | path: '/repositories/:repositoryName/packages/:packageName/clone', 62 | parent: rootRouteRef, 63 | }); 64 | 65 | export const editPackageRouteRef = createSubRouteRef({ 66 | id: 'edit-package', 67 | path: '/repositories/:repositoryName/packages/:packageName/edit', 68 | parent: rootRouteRef, 69 | }); 70 | --------------------------------------------------------------------------------