This repository has been archived by the owner on Jan 24, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 130
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ability to import K8S endpoints from kube config file (#381)
* Fix table passing issue * WIP: Import from kube config file * Minor tidy ups * Remove debugging code * Fix for error message being swallowed * Improvements to load, add edit name - tidied up selection component - move non-ui logic into helper - move record of clusters into helper - tidied up config helper - fixed select all intermediate state on bizare selections & first load - cleans a lot of table datasource interfaces * Specific fixes for upstream - Fix table header alignment - Fix checkbox table column alignment * Rename name column component, fix default context selection when invalid * Tidying up, add skip ssl, fix register of new * Allow user to skip connect by not suppling user * Tidying up, set AZK type, fixes * Minor fixes, subtle edit symbols * Fix case where cluster is register only but cannot connect, allow user to review final step * Add detection for EKS * Remove border between row that's errored and it's errror description row * Fix unit tests * Set initial state of skip ssl checkbox given request to kube * Fix unit tests * Remove some console.logs * Multiple small changes/fixes - tidy up - remove /kubeconfig.yaml fetch - fix select all at indeterminate state (should always select all) - fix apply for auto skip ssl * Fix connect error status message, change title of register endpoint stepper, minor changes * Improve table row error - remove border radius after expansion change - error rows have large indent to help show associated row - remove old styles that weren't applied following expansion change * Spacing * Changes following review * Changes following review * Fix build warning which is silent in dev world * Fixes following merge * Fix e2e test * Add icon for kube config import Co-authored-by: Richard Cox <[email protected]>
- Loading branch information
1 parent
d64f5bf
commit 37f53d5
Showing
80 changed files
with
1,963 additions
and
118 deletions.
There are no files selected for viewing
158 changes: 158 additions & 0 deletions
158
...om-src/frontend/app/custom/kubernetes/kube-config-registration/kube-config-auth.helper.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
import { ComponentFactoryResolver, Injector } from '@angular/core'; | ||
import { FormBuilder } from '@angular/forms'; | ||
|
||
import { entityCatalog } from '../../../../../store/src/entity-catalog/entity-catalog'; | ||
import { ConnectEndpointData } from '../../../features/endpoints/connect.service'; | ||
import { RowState } from '../../../shared/components/list/data-sources-controllers/list-data-source-types'; | ||
import { KUBERNETES_ENDPOINT_TYPE } from '../kubernetes-entity-factory'; | ||
import { EndpointAuthTypeConfig, IAuthForm } from './../../../core/extension/extension-types'; | ||
import { KubeConfigFileCluster, KubeConfigFileUser } from './kube-config.types'; | ||
|
||
/** | ||
* Auth helper tries to figure out the Kubernetes sub-type and auth to use | ||
* based on the kube config file contents | ||
*/ | ||
export class KubeConfigAuthHelper { | ||
|
||
authTypes: { [name: string]: EndpointAuthTypeConfig } = {}; | ||
|
||
public subTypes = []; | ||
|
||
constructor() { | ||
const epTypeInfo = entityCatalog.getAllEndpointTypes(false); | ||
const k8s = epTypeInfo.find(entity => entity.type === KUBERNETES_ENDPOINT_TYPE); | ||
if (k8s && k8s.definition) { | ||
const defn = k8s.definition; | ||
|
||
// Collect all of the auth types | ||
defn.authTypes.forEach(at => { | ||
this.authTypes[at.value] = at; | ||
}); | ||
|
||
this.subTypes.push({ id: '', name: 'Generic' }); | ||
|
||
// Collect all of the auth types for the sub-types | ||
defn.subTypes.forEach(st => { | ||
if (st.type !== 'config') { | ||
this.subTypes.push({ id: st.type, name: st.labelShort }); | ||
} | ||
st.authTypes.forEach(at => { | ||
this.authTypes[at.value] = at; | ||
}); | ||
}); | ||
|
||
// Sort the subtypes | ||
this.subTypes = this.subTypes.sort((a, b) => a.name.localeCompare(b.name)); | ||
} | ||
} | ||
|
||
// Try and parse the authentication metadata | ||
public parseAuth(cluster: KubeConfigFileCluster, user: KubeConfigFileUser): RowState { | ||
|
||
// Default subtype is generic Kubernetes | ||
cluster._subType = ''; | ||
|
||
// Certificate authentication first | ||
|
||
// In-file certificate authentication | ||
if (user.user['client-certificate-data'] && user.user['client-key-data']) { | ||
// We are good to go - create the form data | ||
|
||
// Default is generic kubernetes | ||
let subType = ''; | ||
const authType = 'kube-cert-auth'; | ||
if (cluster.cluster.server.indexOf('azmk8s.io') >= 0) { | ||
// Probably Azure | ||
subType = 'aks'; | ||
cluster._subType = 'aks'; | ||
} | ||
|
||
const authData = { | ||
authType, | ||
subType, | ||
values: { | ||
cert: user.user['client-certificate-data'], | ||
certKey: user.user['client-key-data'] | ||
} | ||
}; | ||
user._authData = authData; | ||
return {}; | ||
} | ||
|
||
if (user.user['client-certificate'] || user.user['client-key']) { | ||
cluster._additionalUserInfo = true; | ||
return { | ||
message: 'This endpoint will be registered but not connected (additional information is required)', | ||
info: true | ||
}; | ||
} | ||
|
||
const authProvider = user.user['auth-provider']; | ||
|
||
|
||
if (authProvider && authProvider.config) { | ||
if (authProvider.config['cmd-path'] && authProvider.config['cmd-path'].indexOf('gcloud') !== -1) { | ||
// GKE | ||
cluster._subType = 'gke'; | ||
// Can not connect to GKE - user must do so manually | ||
cluster._additionalUserInfo = true; | ||
return { | ||
message: 'This endpoint will be registered but not connected (additional information is required)', | ||
info: true | ||
}; | ||
} | ||
} | ||
|
||
if ( | ||
cluster.cluster.server.indexOf('eks.amazonaws.com') >= 0 || | ||
(user.user.exec && user.user.exec.command && user.user.exec.command === 'aws-iam-authenticator') | ||
) { | ||
// Probably EKS | ||
cluster._subType = 'eks'; | ||
cluster._additionalUserInfo = true; | ||
return { | ||
message: 'This endpoint will be registered but not connected (additional information is required)', | ||
info: true | ||
}; | ||
} | ||
|
||
return { message: 'Authentication mechanism is not supported', warning: true }; | ||
} | ||
|
||
// Use the auto component to get the data in the correct format for connecting to the endpoint | ||
public getAuthDataForConnect(resolver: ComponentFactoryResolver, injector: Injector, fb: FormBuilder, user: KubeConfigFileUser) | ||
: ConnectEndpointData | null { | ||
|
||
let data = null; | ||
|
||
// Get the component to us | ||
if (user && user._authData) { | ||
const authType = this.authTypes[user._authData.authType]; | ||
|
||
const factory = resolver.resolveComponentFactory<IAuthForm>(authType.component); | ||
|
||
const ref = factory.create(injector); | ||
|
||
const form = fb.group({ | ||
authType: authType.value, | ||
systemShared: false, | ||
authValues: fb.group(user._authData.values) | ||
}); | ||
|
||
ref.instance.formGroup = form; | ||
|
||
// Allow the auth form to supply body content if it needs to | ||
const endpointFormInstance = ref.instance as any; | ||
if (endpointFormInstance.getBody && endpointFormInstance.getValues) { | ||
data = { | ||
authType: authType.value, | ||
authVal: endpointFormInstance.getValues(user._authData.values), | ||
systemShared: false, | ||
bodyContent: endpointFormInstance.getBody() | ||
}; | ||
} | ||
ref.destroy(); | ||
} | ||
return data; | ||
} | ||
} |
3 changes: 3 additions & 0 deletions
3
.../kubernetes/kube-config-registration/kube-config-import/kube-config-import.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<div class="kubeconfig-import"> | ||
<app-table [dataSource]="dataSource" [columns]="columns"></app-table> | ||
</div> |
8 changes: 8 additions & 0 deletions
8
.../kubernetes/kube-config-registration/kube-config-import/kube-config-import.component.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
:host { | ||
display: flex; | ||
flex: 1; | ||
} | ||
|
||
.kubeconfig-import { | ||
flex: 1; | ||
} |
29 changes: 29 additions & 0 deletions
29
...bernetes/kube-config-registration/kube-config-import/kube-config-import.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; | ||
|
||
import { KubernetesBaseTestModules } from '../../kubernetes.testing.module'; | ||
import { KubeConfigImportComponent } from './kube-config-import.component'; | ||
|
||
describe('KubeConfigImportComponent', () => { | ||
let component: KubeConfigImportComponent; | ||
let fixture: ComponentFixture<KubeConfigImportComponent>; | ||
|
||
beforeEach(async(() => { | ||
TestBed.configureTestingModule({ | ||
imports: [ | ||
...KubernetesBaseTestModules | ||
], | ||
declarations: [KubeConfigImportComponent] | ||
}) | ||
.compileComponents(); | ||
})); | ||
|
||
beforeEach(() => { | ||
fixture = TestBed.createComponent(KubeConfigImportComponent); | ||
component = fixture.componentInstance; | ||
fixture.detectChanges(); | ||
}); | ||
|
||
it('should create', () => { | ||
expect(component).toBeTruthy(); | ||
}); | ||
}); |
Oops, something went wrong.