Skip to content

Commit b641b50

Browse files
authored
Merge pull request #157 from keboola/pepa_PS-3682_decryptK8sToken
PS-3682 Decrypt K8S token
2 parents bc0e0f5 + d7c5c97 commit b641b50

16 files changed

+759
-188
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Keboola\JobQueueInternalClient\DataPlane\Config;
6+
7+
use Keboola\JobQueueInternalClient\DataPlane\Config\Encryption\EncryptionConfigInterface;
8+
9+
class DataPlaneConfig
10+
{
11+
private string $id;
12+
private KubernetesConfig $kubernetes;
13+
private EncryptionConfigInterface $encryption;
14+
15+
public function __construct(
16+
string $id,
17+
KubernetesConfig $kubernetes,
18+
EncryptionConfigInterface $encryption
19+
) {
20+
$this->id = $id;
21+
$this->kubernetes = $kubernetes;
22+
$this->encryption = $encryption;
23+
}
24+
25+
public function getId(): string
26+
{
27+
return $this->id;
28+
}
29+
30+
public function getKubernetes(): KubernetesConfig
31+
{
32+
return $this->kubernetes;
33+
}
34+
35+
public function getEncryption(): EncryptionConfigInterface
36+
{
37+
return $this->encryption;
38+
}
39+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Keboola\JobQueueInternalClient\DataPlane\Config\Encryption;
6+
7+
use Keboola\ObjectEncryptor\ObjectEncryptor;
8+
use Keboola\ObjectEncryptor\ObjectEncryptorFactory;
9+
10+
class AwsEncryptionConfig implements EncryptionConfigInterface
11+
{
12+
private string $stackId;
13+
private string $kmsRegion;
14+
private string $kmsKeyId;
15+
private ?string $kmsRoleArn;
16+
17+
public function __construct(string $stackId, string $kmsRegion, string $kmsKeyId, ?string $kmsRoleArn)
18+
{
19+
$this->stackId = $stackId;
20+
$this->kmsRegion = $kmsRegion;
21+
$this->kmsKeyId = $kmsKeyId;
22+
$this->kmsRoleArn = $kmsRoleArn;
23+
}
24+
25+
public function getStackId(): string
26+
{
27+
return $this->stackId;
28+
}
29+
30+
public function getKmsRegion(): string
31+
{
32+
return $this->kmsRegion;
33+
}
34+
35+
public function getKmsKeyId(): string
36+
{
37+
return $this->kmsKeyId;
38+
}
39+
40+
public function getKmsRoleArn(): ?string
41+
{
42+
return $this->kmsRoleArn;
43+
}
44+
45+
public function createEncryptor(): ObjectEncryptor
46+
{
47+
return ObjectEncryptorFactory::getAwsEncryptor(
48+
$this->stackId,
49+
$this->kmsKeyId,
50+
$this->kmsRegion,
51+
$this->kmsRoleArn,
52+
);
53+
}
54+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Keboola\JobQueueInternalClient\DataPlane\Config\Encryption;
6+
7+
use Keboola\ObjectEncryptor\ObjectEncryptor;
8+
9+
interface EncryptionConfigInterface
10+
{
11+
public function createEncryptor(): ObjectEncryptor;
12+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Keboola\JobQueueInternalClient\DataPlane\Config\Encryption;
6+
7+
use Keboola\ObjectEncryptor\ObjectEncryptor;
8+
9+
class TestingEncryptorConfig implements EncryptionConfigInterface
10+
{
11+
private ObjectEncryptor $encryptor;
12+
13+
public function __construct(ObjectEncryptor $encryptor)
14+
{
15+
$this->encryptor = $encryptor;
16+
}
17+
18+
public function createEncryptor(): ObjectEncryptor
19+
{
20+
return $this->encryptor;
21+
}
22+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Keboola\JobQueueInternalClient\DataPlane\Config;
6+
7+
use Keboola\ObjectEncryptor\ObjectEncryptor;
8+
9+
class KubernetesConfig
10+
{
11+
private string $apiUrl;
12+
private string $token;
13+
private string $certificateAuthority;
14+
private string $namespace;
15+
16+
public function __construct(string $apiUrl, string $token, string $certificateAuthority, string $namespace)
17+
{
18+
$this->apiUrl = $apiUrl;
19+
$this->token = $token;
20+
$this->certificateAuthority = $certificateAuthority;
21+
$this->namespace = $namespace;
22+
}
23+
24+
public function getApiUrl(): string
25+
{
26+
return $this->apiUrl;
27+
}
28+
29+
public function getToken(): string
30+
{
31+
return $this->token;
32+
}
33+
34+
public function getTokenDecrypted(ObjectEncryptor $encryptor): string
35+
{
36+
return $encryptor->decryptGeneric($this->token);
37+
}
38+
39+
public function getCertificateAuthority(): string
40+
{
41+
return $this->certificateAuthority;
42+
}
43+
44+
public function getNamespace(): string
45+
{
46+
return $this->namespace;
47+
}
48+
}

src/DataPlane/DataPlaneConfigRepository.php

Lines changed: 59 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
namespace Keboola\JobQueueInternalClient\DataPlane;
66

7+
use Keboola\JobQueueInternalClient\DataPlane\Config\DataPlaneConfig;
8+
use Keboola\JobQueueInternalClient\DataPlane\Config\Encryption\AwsEncryptionConfig;
9+
use Keboola\JobQueueInternalClient\DataPlane\Config\KubernetesConfig;
710
use Keboola\JobQueueInternalClient\DataPlane\Exception\DataPlaneNotFoundException;
811
use Keboola\ManageApi\Client as ManageApiClient;
912
use Keboola\ManageApi\ClientException;
@@ -13,32 +16,22 @@ class DataPlaneConfigRepository
1316
{
1417
private ManageApiClient $manageApiClient;
1518
private DataPlaneConfigValidator $configValidator;
19+
private string $stackId;
20+
private string $kmsRegion;
1621

17-
public function __construct(ManageApiClient $manageApiClient, DataPlaneConfigValidator $configValidator)
18-
{
22+
public function __construct(
23+
ManageApiClient $manageApiClient,
24+
DataPlaneConfigValidator $configValidator,
25+
string $stackId,
26+
string $kmsRegion
27+
) {
1928
$this->manageApiClient = $manageApiClient;
2029
$this->configValidator = $configValidator;
30+
$this->stackId = $stackId;
31+
$this->kmsRegion = $kmsRegion;
2132
}
2233

23-
/**
24-
* @return null|array{
25-
* id: string,
26-
* parameters: array{
27-
* kubernetes: array{
28-
* apiUrl: string,
29-
* token: string,
30-
* certificateAuthority: string,
31-
* namespace: string,
32-
* },
33-
* encryption: array{
34-
* type: 'aws',
35-
* kmsKeyId: string,
36-
* kmsRoleArn: string,
37-
* },
38-
* }
39-
* }
40-
*/
41-
public function fetchProjectDataPlane(string $projectId): ?array
34+
public function fetchProjectDataPlane(string $projectId): ?DataPlaneConfig
4235
{
4336
$project = $this->manageApiClient->getProject($projectId);
4437

@@ -49,34 +42,13 @@ public function fetchProjectDataPlane(string $projectId): ?array
4942
return null;
5043
}
5144

52-
$dataPlaneId = (string) $dataPlane['id'];
53-
$dataPlaneConfig = $this->configValidator->validateDataPlaneConfig(
54-
$dataPlaneId,
55-
$dataPlane['parameters'] ?? []
45+
return $this->mapDataPlaneConfig(
46+
(string) $dataPlane['id'],
47+
$dataPlane['parameters'] ?? [],
5648
);
57-
58-
return [
59-
'id' => $dataPlaneId,
60-
'parameters' => $dataPlaneConfig,
61-
];
6249
}
6350

64-
/**
65-
* @return array{
66-
* kubernetes: array{
67-
* apiUrl: string,
68-
* token: string,
69-
* certificateAuthority: string,
70-
* namespace: string,
71-
* },
72-
* encryption: array{
73-
* type: 'aws',
74-
* kmsKeyId: string,
75-
* kmsRoleArn: string,
76-
* },
77-
* }
78-
*/
79-
public function fetchDataPlaneConfig(string $dataPlaneId): array
51+
public function fetchDataPlaneConfig(string $dataPlaneId): DataPlaneConfig
8052
{
8153
if (!ctype_digit($dataPlaneId)) {
8254
throw new RuntimeException(sprintf(
@@ -98,6 +70,46 @@ public function fetchDataPlaneConfig(string $dataPlaneId): array
9870
throw $e;
9971
}
10072

101-
return $this->configValidator->validateDataPlaneConfig($dataPlaneId, $dataPlane['parameters'] ?? []);
73+
return $this->mapDataPlaneConfig(
74+
$dataPlaneId,
75+
$dataPlane['parameters'] ?? [],
76+
);
77+
}
78+
79+
private function mapDataPlaneConfig(string $dataPlaneId, array $data): DataPlaneConfig
80+
{
81+
$data = $this->configValidator->validateDataPlaneConfig($dataPlaneId, $data);
82+
83+
$kubernetesData = $data['kubernetes'];
84+
$kubernetesConfig = new KubernetesConfig(
85+
$kubernetesData['apiUrl'],
86+
$kubernetesData['#token'],
87+
$kubernetesData['certificateAuthority'],
88+
$kubernetesData['namespace'],
89+
);
90+
91+
$encryptionData = $data['encryption'];
92+
switch ($encryptionData['type']) {
93+
case DataPlaneConfigValidator::ENCRYPTION_TYPE_AWS:
94+
$encryptionConfig = new AwsEncryptionConfig(
95+
$this->stackId,
96+
$this->kmsRegion,
97+
$encryptionData['kmsKeyId'],
98+
$encryptionData['kmsRoleArn'],
99+
);
100+
break;
101+
102+
default:
103+
throw new RuntimeException(sprintf(
104+
'Invalid encryption type "%s"',
105+
$encryptionData['type']
106+
));
107+
}
108+
109+
return new DataPlaneConfig(
110+
$dataPlaneId,
111+
$kubernetesConfig,
112+
$encryptionConfig,
113+
);
102114
}
103115
}

0 commit comments

Comments
 (0)