I am running into an issue after upgrading a custom cordapp from M13 to V1. I have a small test suite which launches nodes using the node driver, and after upgrading to version 1 I get an issue which seems to be caused by the cordadevcakeys.jks file being null (see the error stack below). To upgrade I simply changed the build gradle release version and gradle plugins version from 0.13.0 to 1.0.0 - I am not sure if there is a step I am missing here that could potentially cause this error? I have also pulled the latests version 1 Corda project locally - although I was under the impression that this step isnt needed.
[ERROR] 12:45:26,017 [main] (Driver.kt:396) driver.DriverDSL.genericDriver -
Driver shutting down because of exception
java.lang.ExceptionInInitializerError: null
at net.corda.testing.driver.DriverDSL.start(Driver.kt:796) ~[corda-node-driver-1.0.0.jar:?]
at net.corda.testing.driver.Driver.genericDriver(Driver.kt:393) [corda-node-driver-1.0.0.jar:?]
at net.corda.testing.driver.Driver.driver(Driver.kt:317) [corda-node-driver-1.0.0.jar:?]
at net.corda.testing.driver.Driver.driver$default(Driver.kt:314) [corda-node-driver-1.0.0.jar:?]
at src.DeploymentTestKt.main(DeploymentTest.kt:29) [main/:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_131]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_131]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_131]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_131]
at com.intellij.rt.execution.CommandLineWrapper.main(CommandLineWrapper.java:65) [idea_rt.jar:?]
Caused by: java.lang.IllegalStateException: ClassLoader.getSystemRes…ates/cordadevcakeys.jks") must not be null
at net.corda.testing.TestConstants$DEV_CA$2.invoke(TestConstants.kt:72) ~[corda-test-utils-1.0.0.jar:?]
at net.corda.testing.TestConstants$DEV_CA$2.invoke(TestConstants.kt) ~[corda-test-utils-1.0.0.jar:?]
at kotlin.SynchronizedLazyImpl.getValue(Lazy.kt:130) ~[kotlin-stdlib-1.1.4.jar:1.1.4]
at net.corda.testing.TestConstants.getDEV_CA(TestConstants.kt) ~[corda-test-utils-1.0.0.jar:?]
at net.corda.testing.CoreTestUtils.getTestPartyAndCertificate$default(CoreTestUtils.kt:145) ~[corda-test-utils-1.0.0.jar:?]
at net.corda.testing.CoreTestUtils.getBOC_IDENTITY(CoreTestUtils.kt:75) ~[corda-test-utils-1.0.0.jar:?]
at net.corda.testing.CoreTestUtils.getBOC(CoreTestUtils.kt:76) ~[corda-test-utils-1.0.0.jar:?]
at net.corda.testing.CoreTestUtils.<clinit>(CoreTestUtils.kt:77) ~[corda-test-utils-1.0.0.jar:?]
... 10 more
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.CommandLineWrapper.main(CommandLineWrapper.java:65)
Caused by: java.lang.NoClassDefFoundError: Could not initialize class net.corda.testing.CoreTestUtils
at net.corda.testing.driver.ShutdownManager.shutdown(Driver.kt:505)
at net.corda.testing.driver.DriverDSL.shutdown(Driver.kt:627)
at net.corda.testing.driver.Driver.genericDriver(Driver.kt:399)
at net.corda.testing.driver.Driver.driver(Driver.kt:317)
at net.corda.testing.driver.Driver.driver$default(Driver.kt:314)
at src.DeploymentTestKt.main(DeploymentTest.kt:29)
... 5 more
Exception in thread "Thread-1" java.lang.NoClassDefFoundError: Could not initialize class net.corda.testing.CoreTestUtils
at net.corda.testing.driver.ShutdownManager.shutdown(Driver.kt:505)
at net.corda.testing.driver.DriverDSL.shutdown(Driver.kt:627)
at net.corda.testing.driver.Driver$genericDriver$shutdownHook$1.invoke(Driver.kt:391)
at net.corda.testing.driver.Driver$genericDriver$shutdownHook$1.invoke(Driver.kt)
at net.corda.nodeapi.internal.ShutdownHookKt$addShutdownHook$hook$1.run(ShutdownHook.kt:15)
at java.lang.Thread.run(Thread.java:748)
I can post the code I am using to launch the driver if need be, but by having a look at the cordapp-example it seems my method for starting the driver and nodes is correct, and it was working on M13.
*Edit, added in my gradle build and node driver code
apply plugin: 'java'
apply plugin: 'kotlin'
apply plugin: 'idea'
apply plugin: 'net.corda.plugins.publish-utils'
apply plugin: 'net.corda.plugins.cordformation'
apply plugin: 'maven-publish'
apply plugin: 'application'
apply plugin: 'net.corda.plugins.quasar-utils'
repositories {
mavenLocal()
jcenter()
mavenCentral()
maven { url 'https://dl.bintray.com/kotlin/exposed' }
maven { url 'https://jitpack.io' }
}
sourceSets {
main {
resources {
srcDir "../config/dev"
}
}
test {
resources {
srcDir "../config/test"
}
}
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version"
compileOnly "co.paralleluniverse:capsule:1.0.1"
compile 'net.sourceforge.plantuml:plantuml:8039'
testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
testCompile "junit:junit:$junit_version"
//Corda integration dependencies
cordaCompile "net.corda:corda-core:$corda_release_version"
cordaCompile "net.corda:corda-finance:$corda_release_version"
cordaCompile "net.corda:corda-jackson:$corda_release_version"
cordaCompile "net.corda:corda-jfx:$corda_release_version"
cordaCompile "net.corda:corda-rpc:$corda_release_version"
cordaCompile "net.corda:corda-node-api:$corda_release_version"
cordaCompile "net.corda:corda-webserver-impl:$corda_release_version"
cordaCompile "net.corda:corda-test-utils:$corda_release_version"
testCompile "net.corda:corda-test-utils:$corda_release_version"
cordaRuntime "net.corda:corda:$corda_release_version"
cordaRuntime "net.corda:corda-webserver:$corda_release_version"
cordaCompile "net.corda:corda-node-driver:$corda_release_version"
//testCompile "net.corda:corda-node-driver:$corda_release_version"
cordapp "net.corda:corda-finance:$corda_release_version"
// cordaCompile "net.corda:corda-core:$corda_release_version"
// cordaCompile "net.corda:corda-finance:$corda_release_version"
// cordaCompile "net.corda:corda-jackson:$corda_release_version"
// cordaCompile "net.corda:corda-rpc:$corda_release_version"
// cordaCompile "net.corda:corda-node-api:$corda_release_version"
// cordaCompile "net.corda:corda-webserver-impl:$corda_release_version"
// cordaRuntime "net.corda:corda:$corda_release_version"
// cordaRuntime "net.corda:corda-webserver:$corda_release_version"
// testCompile "net.corda:corda-test-utils:$corda_release_version"
// cordaCompile "net.corda:corda-node-driver:$corda_release_version"
// testCompile "net.corda:corda-node-driver:$corda_release_version"
}
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions {
languageVersion = "1.1"
apiVersion = "1.1"
jvmTarget = "1.8"
javaParameters = true // Useful for reflection.
}
}
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
directory "./build/nodes"
networkMap "CN=Controller,O=R3,OU=corda,L=London,C=UK"
node {
name "CN=Controller,O=R3,OU=corda,L=London,C=UK"
advertisedServices = ["corda.notary.validating"]
p2pPort 10002
rpcPort 10003
cordapps = ["secLendModel"]
}
node {
name "CN=NodeA,O=NodeA,L=London,C=UK"
advertisedServices = []
p2pPort 10005
rpcPort 10006
webPort 10007
cordapps = ["secLendModel"]
rpcUsers = [[ user: "user1", "password": "test", "permissions": []]]
}
node {
name "CN=NodeB,O=NodeB,L=New York,C=US"
advertisedServices = []
p2pPort 10008
rpcPort 10009
webPort 10010
cordapps = ["secLendModel"]
rpcUsers = [[ user: "user1", "password": "test", "permissions": []]]
}
node {
name "CN=NodeC,O=NodeC,L=Paris,C=FR"
advertisedServices = []
p2pPort 10011
rpcPort 10012
webPort 10013
cordapps = ["secLendModel"]
rpcUsers = [[ user: "user1", "password": "test", "permissions": []]]
}
}
// TODO: Make into gradle plugin without any references to Jython
task installJythonDeps(dependsOn: ['build']) {
project.copy {
from project.configurations.runtime
into "build/jythonDeps"
}
}
installJythonDeps.shouldRunAfter build
idea {
module {
downloadJavadoc = true // defaults to false
downloadSources = true
}
}
publishing {
publications {
jarAndSources(MavenPublication) {
from components.java
artifactId 'secLendModel'
artifact sourceJar
artifact javadocJar
}
}
}
task runTemplateClientRPC(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'com.template.client.TemplateClientRPCKt'
args 'localhost:10006'
}
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions {
jvmTarget = "1.8"
}
}
and this is my node driver code
fun runSimulation() {
driver(portAllocation = PortAllocation.Incremental(20000), isDebug = false, startNodesInProcess = true, extraCordappPackagesToScan = listOf("com.secLendModel")) {
//Normal Users
val arnoldParams = NodeParameters(providedName = ARNOLD, rpcUsers = arrayListOf(stdUser))
val barryParams = NodeParameters(providedName = BARRY, rpcUsers = arrayListOf(stdUser))
val colinParams = NodeParameters(providedName = COLIN, rpcUsers = arrayListOf(stdUser))
val arnold = startNode(defaultParameters = arnoldParams)
val barry = startNode(defaultParameters = barryParams)
val colin = startNode(defaultParameters = colinParams)
//Special Users (i.e asset issuers and oracles)
val notaryParams = NodeParameters(providedName = NOTARY, advertisedServices = setOf(ServiceInfo(ValidatingNotaryService.type)))
val notary = startNode(defaultParameters = notaryParams)
//Stock issuer AND stock price oracle
val exchangeParams = NodeParameters(providedName = EXCHANGE, rpcUsers = arrayListOf(specialUser),
advertisedServices = MARKET.plus(ServiceInfo(PriceType.type)))
val exchange = startNode(defaultParameters = exchangeParams)
//Cash issuer
val centralbankParams = NodeParameters(providedName = CENTRALBANK, rpcUsers = arrayListOf(specialUser),
advertisedServices = CURRENCIES)
val centralBank = startNode(defaultParameters = centralbankParams)
// val oracle = startNode(ORACLE, advertisedServices = setOf(ServiceInfo(PriceType.type)))
notaryNode = notary.get()
arnoldNode = arnold.get()
barryNode = barry.get()
colinNode = colin.get()
exchangeNode = exchange.get()
centralNode = centralBank.get()
// oracleNode = oracle.get()
startWebserver(arnoldNode)
setUpNodes()
simulateTransactions()
waitForAllNodesToFinish()
}
You need to close IntelliJ and clear out your gradle cache (under ~/.gradle on Mac).
Related
I am migrating from Kong 2.8.0 to 3.0.0.
I have a few custom plugins which are giving me trouble while migrating.
Once i start migration I am getting this error:
[error] 1#0: init_by_lua error: /usr/local/share/lua/5.1/kong/init.lua:560: error loading plugin schemas: on plugin 'file-log-extended': [postgres] 2 schema violations (fields: expected an array; name: field required for entity check)
stack traceback:
[C]: in function 'assert'
/usr/local/share/lua/5.1/kong/init.lua:560: in function 'init'
init_by_lua:3: in main chunk
So, the problem to me seems related to the schema.lua :
local typedefs = require "kong.db.schema.typedefs"
local pl_utils = require "pl.utils"
return {
fields = {
path = { required = true, type = "string"},
log_bodies = { type = "boolean", default = true }
}
}
What I've done is changing the schema to:
...
return {
fields = {{
config = {
type = "record",
fields = {
path = { required = true, type = "string"},
log_bodies = { type = "boolean", default = true }
}
}
}}
}
But now when I start Kong I get the following error:
[error] 1#0: init_by_lua error: /usr/local/share/lua/5.1/kong/init.lua:543: error
loading plugin schemas: on plugin 'file-log-extended': failed converting legacy schema for file-log-extended: unknown legacy field attribute: "config"
stack traceback:
[C]: in function 'assert'
/usr/local/share/lua/5.1/kong/init.lua:543: in function 'init'
init_by_lua:3: in main chunk
Can someone help me understand why I can't migrate properly this plugin?
Thanks
Actually the format was incorrect.
This version is accepted.
return {
name="file-log-extended",
fields = {
{
-- this plugin will only be applied to Services or Routes
consumer = typedefs.no_consumer
},
{
config = {
type = "record",
fields = {
-- Describe your plugin's configuration's schema here.
{
path = {
required = true,
type = "string"
}
},
{
log_bodies = {
type = "boolean",
default = true
}
}
}
}
}
}
}
I can't get TLS to work. The CertficateRequest gets created, the Order too and also the Challenge. However, the Challenge is stuck in pending.
Name: test-tls-secret-8qshd-3608253913-1269058669
Namespace: test
Labels: <none>
Annotations: <none>
API Version: acme.cert-manager.io/v1
Kind: Challenge
Metadata:
Creation Timestamp: 2022-07-19T08:17:04Z
Finalizers:
finalizer.acme.cert-manager.io
Generation: 1
Managed Fields:
API Version: acme.cert-manager.io/v1
Fields Type: FieldsV1
fieldsV1:
f:metadata:
f:finalizers:
.:
v:"finalizer.acme.cert-manager.io":
Manager: cert-manager-challenges
Operation: Update
Time: 2022-07-19T08:17:04Z
API Version: acme.cert-manager.io/v1
Fields Type: FieldsV1
fieldsV1:
f:metadata:
f:ownerReferences:
.:
k:{"uid":"06029d3f-d1ce-45db-a267-796ff9b82a67"}:
f:spec:
.:
f:authorizationURL:
f:dnsName:
f:issuerRef:
.:
f:group:
f:kind:
f:name:
f:key:
f:solver:
.:
f:dns01:
.:
f:azureDNS:
.:
f:environment:
f:hostedZoneName:
f:resourceGroupName:
f:subscriptionID:
f:token:
f:type:
f:url:
f:wildcard:
Manager: cert-manager-orders
Operation: Update
Time: 2022-07-19T08:17:04Z
API Version: acme.cert-manager.io/v1
Fields Type: FieldsV1
fieldsV1:
f:status:
.:
f:presented:
f:processing:
f:reason:
f:state:
Manager: cert-manager-challenges
Operation: Update
Subresource: status
Time: 2022-07-19T08:25:38Z
Owner References:
API Version: acme.cert-manager.io/v1
Block Owner Deletion: true
Controller: true
Kind: Order
Name: test-tls-secret-8qshd-3608253913
UID: 06029d3f-d1ce-45db-a267-796ff9b82a67
Resource Version: 4528159
UID: 9594ed48-72c6-4403-8356-4991950fe9bb
Spec:
Authorization URL: https://acme-v02.api.letsencrypt.org/acme/authz-v3/131873811576
Dns Name: test.internal.<company_id>.com
Issuer Ref:
Group: cert-manager.io
Kind: ClusterIssuer
Name: letsencrypt
Key: xrnhZETWbkGTE7CA0A3CQd6a48d4JG4HKDiCXPpxTWM
Solver:
dns01:
Azure DNS:
Environment: AzurePublicCloud
Hosted Zone Name: internal.<company_id>.com
Resource Group Name: tool-cluster-rg
Subscription ID: <subscription_id>
Token: jXCR2UorNanlHqZd8T7Ifjbx6PuGfLBwnzWzBnDvCyc
Type: DNS-01
URL: https://acme-v02.api.letsencrypt.org/acme/chall-v3/131873811576/vCGdog
Wildcard: false
Status:
Presented: false
Processing: true
Reason: azure.BearerAuthorizer#WithAuthorization: Failed to refresh the Token for request to https://management.azure.com/subscriptions/<subscription_id>/resourceGroups/tool-cluster-rg/providers/Microsoft.Network/dnsZones/internal.<company_id>.com/TXT/_acme-challenge.test?api-version=2017-10-01: StatusCode=404 -- Original Error: adal: Refresh request failed. Status Code = '404'. Response body: getting assigned identities for pod cert-manager/cert-manager-5bb7949947-qlg5j in CREATED state failed after 16 attempts, retry duration [5]s, error: <nil>. Check MIC pod logs for identity assignment errors
Endpoint http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fmanagement.core.windows.net%2F
State: pending
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Started 59m cert-manager-challenges Challenge scheduled for processing
Warning PresentError 11s (x7 over 51m) cert-manager-challenges Error presenting challenge: azure.BearerAuthorizer#WithAuthorization: Failed to refresh the Token for request to https://management.azure.com/subscriptions/<subscription_id>/resourceGroups/tool-cluster-rg/providers/Microsoft.Network/dnsZones/internal.<company_id>.com/TXT/_acme-challenge.test?api-version=2017-10-01: StatusCode=404 -- Original Error: adal: Refresh request failed. Status Code = '404'. Response body: getting assigned identities for pod cert-manager/cert-manager-5bb7949947-qlg5j in CREATED state failed after 16 attempts, retry duration [5]s, error: <nil>. Check MIC pod logs for identity assignment errors
Endpoint http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fmanagement.core.windows.net%2F
It says to check the MIC pod logs, however, there are no errors logged:
I0719 08:16:52.271516 1 mic.go:587] pod test/test-deployment-b5dcc75f4-5gdtj has no assigned node yet. it will be ignored
I0719 08:16:52.284362 1 mic.go:608] No AzureIdentityBinding found for pod test/test-deployment-b5dcc75f4-5gdtj that matches selector: certman-label. it will be ignored
I0719 08:16:53.735678 1 mic.go:648] certman-identity identity not found when using test/certman-id-binding binding
I0719 08:16:53.737027 1 mic.go:1040] processing node aks-default-10282586-vmss, add [1], del [0], update [0]
I0719 08:16:53.737061 1 crd.go:514] creating assigned id test/test-deployment-b5dcc75f4-5gdtj-test-certman-identity
I0719 08:16:53.844892 1 cloudprovider.go:210] updating user-assigned identities on aks-default-10282586-vmss, assign [1], unassign [0]
I0719 08:17:04.545556 1 crd.go:777] updating AzureAssignedIdentity test/test-deployment-b5dcc75f4-5gdtj-test-certman-identity status to Assigned
I0719 08:17:04.564464 1 mic.go:525] work done: true. Found 1 pods, 1 ids, 1 bindings
I0719 08:17:04.564477 1 mic.go:526] total work cycles: 392, out of which work was done in: 320
I0719 08:17:04.564492 1 stats.go:183] ** stats collected **
I0719 08:17:04.564497 1 stats.go:162] Pod listing: 20.95µs
I0719 08:17:04.564504 1 stats.go:162] AzureIdentity listing: 2.357µs
I0719 08:17:04.564508 1 stats.go:162] AzureIdentityBinding listing: 3.211µs
I0719 08:17:04.564512 1 stats.go:162] AzureAssignedIdentity listing: 431ns
I0719 08:17:04.564516 1 stats.go:162] System: 71.101µs
I0719 08:17:04.564520 1 stats.go:162] CacheSync: 4.482µs
I0719 08:17:04.564523 1 stats.go:162] Cloud provider GET: 83.123547ms
I0719 08:17:04.564527 1 stats.go:162] Cloud provider PATCH: 10.700611864s
I0719 08:17:04.564531 1 stats.go:162] AzureAssignedIdentity creation: 24.654916ms
I0719 08:17:04.564535 1 stats.go:162] AzureAssignedIdentity update: 0s
I0719 08:17:04.564538 1 stats.go:162] AzureAssignedIdentity deletion: 0s
I0719 08:17:04.564542 1 stats.go:170] Number of cloud provider PATCH: 1
I0719 08:17:04.564546 1 stats.go:170] Number of cloud provider GET: 1
I0719 08:17:04.564549 1 stats.go:170] Number of AzureAssignedIdentities created in this sync cycle: 1
I0719 08:17:04.564554 1 stats.go:170] Number of AzureAssignedIdentities updated in this sync cycle: 0
I0719 08:17:04.564557 1 stats.go:170] Number of AzureAssignedIdentities deleted in this sync cycle: 0
I0719 08:17:04.564561 1 stats.go:162] Find AzureAssignedIdentities to create: 0s
I0719 08:17:04.564564 1 stats.go:162] Find AzureAssignedIdentities to delete: 0s
I0719 08:17:04.564568 1 stats.go:162] Total time to assign or update AzureAssignedIdentities: 10.827425179s
I0719 08:17:04.564573 1 stats.go:162] Total: 10.82763016s
I0719 08:17:04.564577 1 stats.go:212] *********************
I0719 08:19:34.077484 1 mic.go:1466] reconciling identity assignment for [/subscriptions/<subscription_id>/resourceGroups/tool-cluster-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cert-manager-dns01] on node aks-default-10282586-vmss
I0719 08:22:34.161195 1 mic.go:1466] reconciling identity assignment for [/subscriptions/<subscription_id>/resourceGroups/tool-cluster-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cert-manager-dns01] on node aks-default-10282586-vmss
The "reconciling identity" output gets repeated afterwards. Up to this point, I was able to handle my way through error messages, but now I have no idea how to proceed. Anyone got any lead what I'm missing?
Following my terraform code for the infrastructure.
terraform {
cloud {
organization = "<company_id>"
workspaces {
name = "tool-cluster"
}
}
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">= 3.6.0, < 4.0.0"
}
}
}
provider "azurerm" {
features {}
}
data "azurerm_client_config" "default" {}
variable "id" {
type = string
description = "Company wide unique terraform identifier"
default = "tool-cluster"
}
resource "azurerm_resource_group" "default" {
name = "${var.id}-rg"
location = "westeurope"
}
resource "azurerm_kubernetes_cluster" "default" {
name = "${var.id}-aks"
location = azurerm_resource_group.default.location
resource_group_name = azurerm_resource_group.default.name
dns_prefix = var.id
default_node_pool {
name = "default"
node_count = 1
vm_size = "Standard_D4_v5"
}
identity {
type = "SystemAssigned"
}
role_based_access_control_enabled = true
http_application_routing_enabled = true
}
resource "azurerm_dns_zone" "internal" {
name = "internal.<company_id>.com"
resource_group_name = azurerm_resource_group.default.name
}
resource "azurerm_user_assigned_identity" "dns_identity" {
name = "cert-manager-dns01"
resource_group_name = azurerm_resource_group.default.name
location = azurerm_resource_group.default.location
}
resource "azurerm_role_assignment" "dns_contributor" {
scope = azurerm_dns_zone.internal.id
role_definition_name = "DNS Zone Contributor"
principal_id = azurerm_user_assigned_identity.dns_identity.principal_id
}
I've added the roles "Managed Identity Operator" and "Virtual Machine Contributor" in the scope of the generated resourcegroup of the cluster (MC_tool-cluster-rg_tool-cluster-aks_westeurope) and "Managed Identity Operator" to the resource group of the cluster itself (tool-cluster-rg) to the kubelet_identity.
Code for the cert-manager:
terraform {
cloud {
organization = "<company_id>"
workspaces {
name = "cert-manager"
}
}
required_providers {
kubernetes = {
source = "hashicorp/kubernetes"
version = ">= 2.12.0, < 3.0.0"
}
helm = {
source = "hashicorp/helm"
version = ">= 2.6.0, < 3.0.0"
}
azurerm = {
source = "hashicorp/azurerm"
version = ">= 3.6.0, < 4.0.0"
}
}
}
data "terraform_remote_state" "tool-cluster" {
backend = "remote"
config = {
organization = "<company_id>"
workspaces = {
name = "tool-cluster"
}
}
}
provider "azurerm" {
features {}
}
provider "kubernetes" {
host = data.terraform_remote_state.tool-cluster.outputs.host
client_certificate = base64decode(data.terraform_remote_state.tool-cluster.outputs.client_certificate)
client_key = base64decode(data.terraform_remote_state.tool-cluster.outputs.client_key)
cluster_ca_certificate = base64decode(data.terraform_remote_state.tool-cluster.outputs.cluster_ca_certificate)
}
provider "helm" {
kubernetes {
host = data.terraform_remote_state.tool-cluster.outputs.host
client_certificate = base64decode(data.terraform_remote_state.tool-cluster.outputs.client_certificate)
client_key = base64decode(data.terraform_remote_state.tool-cluster.outputs.client_key)
cluster_ca_certificate = base64decode(data.terraform_remote_state.tool-cluster.outputs.cluster_ca_certificate)
}
}
locals {
app-name = "cert-manager"
}
resource "kubernetes_namespace" "cert_manager" {
metadata {
name = local.app-name
}
}
resource "helm_release" "cert_manager" {
name = local.app-name
repository = "https://charts.jetstack.io"
chart = "cert-manager"
version = "v1.8.2"
namespace = kubernetes_namespace.cert_manager.metadata.0.name
set {
name = "installCRDs"
value = "true"
}
}
resource "helm_release" "aad_pod_identity" {
name = "aad-pod-identity"
repository = "https://raw.githubusercontent.com/Azure/aad-pod-identity/master/charts"
chart = "aad-pod-identity"
version = "v4.1.10"
namespace = kubernetes_namespace.cert_manager.metadata.0.name
}
resource "azurerm_user_assigned_identity" "default" {
name = local.app-name
resource_group_name = data.terraform_remote_state.tool-cluster.outputs.resource_name
location = data.terraform_remote_state.tool-cluster.outputs.resource_location
}
resource "azurerm_role_assignment" "default" {
scope = data.terraform_remote_state.tool-cluster.outputs.dns_zone_id
role_definition_name = "DNS Zone Contributor"
principal_id = azurerm_user_assigned_identity.default.principal_id
}
output "namespace" {
value = kubernetes_namespace.cert_manager.metadata.0.name
sensitive = false
}
and the code for my issuer:
terraform {
cloud {
organization = "<company_id>"
workspaces {
name = "cert-issuer"
}
}
required_providers {
kubernetes = {
source = "hashicorp/kubernetes"
version = ">= 2.12.0, < 3.0.0"
}
helm = {
source = "hashicorp/helm"
version = ">= 2.6.0, < 3.0.0"
}
azurerm = {
source = "hashicorp/azurerm"
version = ">= 3.6.0, < 4.0.0"
}
}
}
data "terraform_remote_state" "tool-cluster" {
backend = "remote"
config = {
organization = "<company_id>"
workspaces = {
name = "tool-cluster"
}
}
}
data "terraform_remote_state" "cert-manager" {
backend = "remote"
config = {
organization = "<company_id>"
workspaces = {
name = "cert-manager"
}
}
}
provider "azurerm" {
features {}
}
provider "kubernetes" {
host = data.terraform_remote_state.tool-cluster.outputs.host
client_certificate = base64decode(data.terraform_remote_state.tool-cluster.outputs.client_certificate)
client_key = base64decode(data.terraform_remote_state.tool-cluster.outputs.client_key)
cluster_ca_certificate = base64decode(data.terraform_remote_state.tool-cluster.outputs.cluster_ca_certificate)
}
provider "helm" {
kubernetes {
host = data.terraform_remote_state.tool-cluster.outputs.host
client_certificate = base64decode(data.terraform_remote_state.tool-cluster.outputs.client_certificate)
client_key = base64decode(data.terraform_remote_state.tool-cluster.outputs.client_key)
cluster_ca_certificate = base64decode(data.terraform_remote_state.tool-cluster.outputs.cluster_ca_certificate)
}
}
locals {
app-name = "cert-manager"
}
data "azurerm_subscription" "current" {}
resource "kubernetes_manifest" "cluster_issuer" {
manifest = yamldecode(templatefile(
"${path.module}/cluster-issuer.tpl.yaml",
{
"name" = "letsencrypt"
"subscription_id" = data.azurerm_subscription.current.subscription_id
"resource_group_name" = data.terraform_remote_state.tool-cluster.outputs.resource_name
"dns_zone_name" = data.terraform_remote_state.tool-cluster.outputs.dns_zone_name
}
))
}
Also, the yaml:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: ${name}
spec:
acme:
email: support#<company_id>.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: ${name}
solvers:
- dns01:
azureDNS:
resourceGroupName: ${resource_group_name}
subscriptionID: ${subscription_id}
hostedZoneName: ${dns_zone_name}
environment: AzurePublicCloud
Finally, my sample app:
terraform {
cloud {
organization = "<company_id>"
workspaces {
name = "test-web-app"
}
}
required_providers {
kubernetes = {
source = "hashicorp/kubernetes"
version = ">= 2.12.0, < 3.0.0"
}
azurerm = {
source = "hashicorp/azurerm"
version = ">= 3.6.0, < 4.0.0"
}
azuread = {
source = "hashicorp/azuread"
version = ">= 2.26.0, < 3.0.0"
}
}
}
data "terraform_remote_state" "tool-cluster" {
backend = "remote"
config = {
organization = "<company_id>"
workspaces = {
name = "tool-cluster"
}
}
}
provider "azuread" {}
provider "azurerm" {
features {}
}
provider "kubernetes" {
host = data.terraform_remote_state.tool-cluster.outputs.host
client_certificate = base64decode(data.terraform_remote_state.tool-cluster.outputs.client_certificate)
client_key = base64decode(data.terraform_remote_state.tool-cluster.outputs.client_key)
cluster_ca_certificate = base64decode(data.terraform_remote_state.tool-cluster.outputs.cluster_ca_certificate)
}
locals {
app-name = "test"
host = "test.${data.terraform_remote_state.tool-cluster.outputs.cluster_domain_name}"
}
resource "azurerm_dns_cname_record" "default" {
name = local.app-name
zone_name = data.terraform_remote_state.tool-cluster.outputs.dns_zone_name
resource_group_name = data.terraform_remote_state.tool-cluster.outputs.resource_name
ttl = 300
record = local.host
}
resource "azuread_application" "default" {
display_name = local.app-name
}
resource "kubernetes_namespace" "default" {
metadata {
name = local.app-name
}
}
resource "kubernetes_secret" "auth" {
metadata {
name = "basic-auth"
namespace = kubernetes_namespace.default.metadata.0.name
}
data = {
"auth" = file("./auth")
}
}
resource "kubernetes_deployment" "default" {
metadata {
name = "${local.app-name}-deployment"
namespace = kubernetes_namespace.default.metadata.0.name
labels = {
app = local.app-name
}
}
spec {
replicas = 1
selector {
match_labels = {
app = local.app-name
}
}
template {
metadata {
labels = {
app = local.app-name
aadpodidbinding = "certman-label"
}
}
spec {
container {
image = "crccheck/hello-world:latest"
name = local.app-name
port {
container_port = 8000
host_port = 8000
}
}
}
}
}
}
resource "kubernetes_service" "default" {
metadata {
name = "${local.app-name}-svc"
namespace = kubernetes_namespace.default.metadata.0.name
}
spec {
selector = {
app = kubernetes_deployment.default.metadata.0.labels.app
}
port {
port = 8000
target_port = 8000
}
}
}
resource "kubernetes_ingress_v1" "default" {
metadata {
name = "${local.app-name}-ing"
namespace = kubernetes_namespace.default.metadata.0.name
annotations = {
"kubernetes.io/ingress.class" = "addon-http-application-routing"
"cert-manager.io/cluster-issuer" = "letsencrypt"
# basic-auth
"nginx.ingress.kubernetes.io/auth-type" = "basic"
"nginx.ingress.kubernetes.io/auth-secret" = "basic-auth"
"nginx.ingress.kubernetes.io/auth-realm" = "Authentication Required - foo"
}
}
spec {
rule {
host = local.host
http {
path {
path = "/"
backend {
service {
name = kubernetes_service.default.metadata.0.name
port {
number = 8000
}
}
}
}
}
}
rule {
host = trimsuffix(azurerm_dns_cname_record.default.fqdn, ".")
http {
path {
path = "/"
backend {
service {
name = kubernetes_service.default.metadata.0.name
port {
number = 8000
}
}
}
}
}
}
tls {
hosts = [ trimsuffix(azurerm_dns_cname_record.default.fqdn, ".") ]
secret_name = "${local.app-name}-tls-secret"
}
}
}
resource "kubernetes_manifest" "azure_identity" {
manifest = yamldecode(templatefile(
"${path.module}/azure_identity.tpl.yaml",
{
"namespace" = kubernetes_namespace.default.metadata.0.name
"resource_id" = data.terraform_remote_state.tool-cluster.outputs.identity_resource_id
"client_id" = data.terraform_remote_state.tool-cluster.outputs.identity_client_id
}
))
}
resource "kubernetes_manifest" "azure_identity_binding" {
manifest = yamldecode(templatefile(
"${path.module}/azure_identity_binding.tpl.yaml",
{
"namespace" = kubernetes_namespace.default.metadata.0.name
"resource_id" = data.terraform_remote_state.tool-cluster.outputs.identity_resource_id
"client_id" = data.terraform_remote_state.tool-cluster.outputs.identity_client_id
}
))
}
The two identity yaml:
apiVersion: "aadpodidentity.k8s.io/v1"
kind: AzureIdentity
metadata:
annotations:
# recommended to use namespaced identites https://azure.github.io/aad-pod-identity/docs/configure/match_pods_in_namespace/
aadpodidentity.k8s.io/Behavior: namespaced
name: certman-identity
namespace: ${namespace} # change to your preferred namespace
spec:
type: 0 # MSI
resourceID: ${resource_id} # Resource Id From Previous step
clientID: ${client_id} # Client Id from previous step
and
apiVersion: "aadpodidentity.k8s.io/v1"
kind: AzureIdentityBinding
metadata:
name: certman-id-binding
namespace: ${namespace} # change to your preferred namespace
spec:
azureIdentity: certman-identity
selector: certman-label # This is the label that needs to be set on cert-manager pods
edit: reformatted
I was not able to solve it with http application routing, so I installed my own ingress and instead of aad-pod-identity I installed ExternalDNS with Service Principal. The terraform code for that:
locals {
app-name = "external-dns"
}
resource "azuread_application" "dns" {
display_name = "dns-service_principal"
}
resource "azuread_application_password" "dns" {
application_object_id = azuread_application.dns.object_id
}
resource "azuread_service_principal" "dns" {
application_id = azuread_application.dns.application_id
description = "Service Principal to write DNS changes for ${data.terraform_remote_state.tool-cluster.outputs.dns_zone_name}"
}
resource "azurerm_role_assignment" "dns_zone_contributor" {
scope = data.terraform_remote_state.tool-cluster.outputs.dns_zone_id
role_definition_name = "DNS Zone Contributor"
principal_id = azuread_service_principal.dns.id
}
resource "azurerm_role_assignment" "rg_reader" {
scope = data.terraform_remote_state.tool-cluster.outputs.dns_zone_id
role_definition_name = "Reader"
principal_id = azuread_service_principal.dns.id
}
resource "kubernetes_secret" "external_dns_secret" {
metadata {
name = "azure-config-file"
}
data = { "azure.json" = jsonencode({
tenantId = data.azurerm_subscription.default.tenant_id
subscriptionId = data.azurerm_subscription.default.subscription_id
resourceGroup = data.terraform_remote_state.tool-cluster.outputs.resource_name
aadClientId = azuread_application.dns.application_id
aadClientSecret = azuread_application_password.dns.value
})
}
}
resource "kubernetes_service_account" "dns" {
metadata {
name = local.app-name
}
}
resource "kubernetes_cluster_role" "dns" {
metadata {
name = local.app-name
}
rule {
api_groups = [ "" ]
resources = [ "services","endpoints","pods", "nodes" ]
verbs = [ "get","watch","list" ]
}
rule {
api_groups = [ "extensions","networking.k8s.io" ]
resources = [ "ingresses" ]
verbs = [ "get","watch","list" ]
}
}
resource "kubernetes_cluster_role_binding" "dns" {
metadata {
name = "${local.app-name}-viewer"
}
role_ref {
api_group = "rbac.authorization.k8s.io"
kind = "ClusterRole"
name = kubernetes_cluster_role.dns.metadata.0.name
}
subject {
kind = "ServiceAccount"
name = kubernetes_service_account.dns.metadata.0.name
}
}
resource "kubernetes_deployment" "dns" {
metadata {
name = local.app-name
}
spec {
strategy {
type = "Recreate"
}
selector {
match_labels = {
"app" = local.app-name
}
}
template {
metadata {
labels = {
"app" = local.app-name
}
}
spec {
service_account_name = kubernetes_service_account.dns.metadata.0.name
container {
name = local.app-name
image = "bitnami/external-dns:0.12.1"
args = [ "--source=service", "--source=ingress", "--provider=azure", "--txt-prefix=externaldns-" ]
volume_mount {
name = kubernetes_secret.external_dns_secret.metadata.0.name
mount_path = "/etc/kubernetes"
read_only = true
}
}
volume {
name = kubernetes_secret.external_dns_secret.metadata.0.name
secret {
secret_name = kubernetes_secret.external_dns_secret.metadata.0.name
}
}
}
}
}
}
I'm trying to play with Kotlin Multiplatform and can't get it compiled for an iOS project.
My build.gradle.kt file:
plugins {
kotlin("multiplatform")
// kotlin("native.cocoapods") //version "1.5.10"
id("co.touchlab.native.cocoapods")
id("kotlinx-serialization")
}
kotlin {
// ios()
// Revert to just ios() when gradle plugin can properly resolve it
val onPhone = System.getenv("SDK_NAME")?.startsWith("iphoneos") ?: false
if (onPhone) {
iosArm64("ios")
} else {
iosX64("ios")
}
version = "1.1"
sourceSets { ... }
cocoapodsext {
summary = "Common library for the KaMP starter kit"
homepage = "https://github.com/touchlab/KaMPKit"
// isStatic = false
framework {
isStatic = false
transitiveExport = true
}
}
}
I have tried to use both co.touchlab.native.cocoapods and native.cocoapods plugins and I always get the same error for any way I choose.
The error:
> Task :kotlin-api-client:compileKotlinIosX64 UP-TO-DATE
> Task :shared:generateIosMainKaMPKitDbInterface UP-TO-DATE
> Task :shared:compileKotlinIos UP-TO-DATE
> Task :shared:linkDebugFrameworkIos FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':shared:linkDebugFrameworkIos'.
> 'void org.jetbrains.kotlin.konan.target.Distribution.<init>(java.lang.String, boolean, java.lang.String, java.util.Map, int, kotlin.jvm.internal.DefaultConstructorMarker)'
What could be wrong? Any ideas at least where to look at?
I'am using nomad on GCE and I cannot pull docker images from the public registry.
I can do a pull form the command line with docker pull gerlacdt/helloapp:v0.1.0
But when trying to run a nomad job with a public registry image, I have this error:
Failed to find docker auth for repo "gerlacdt/helloapp": docker-credential-gcr
Relevant files :
The /root/.docker/config.json file:
{
"auths": {
"https://index.docker.io/v1/": {}
},
"credHelpers": {
"asia.gcr.io": "gcr",
"eu.gcr.io": "gcr",
"gcr.io": "gcr",
"staging-k8s.gcr.io": "gcr",
"us.gcr.io": "gcr"
}
}
The nomad client config:
datacenter = "europe-west1-c"
name = "consul-clients-092s"
region = "europe-west1"
bind_addr = "0.0.0.0"
advertise {
http = "172.27.3.132"
rpc = "172.27.3.132"
serf = "172.27.3.132"
}
client {
enabled = true
options = {
"docker.auth.config" = "/root/.docker/config.json"
"docker.auth.helper" = "gcr"
}
}
consul {
address = "127.0.0.1:8500"
}
The job file:
job "helloapp" {
datacenters = ["europe-west1-b", "europe-west1-c", "europe-west1-d"]
constraint {
attribute = "${attr.kernel.name}"
value = "linux"
}
# Configure the job to do rolling updates
update {
stagger = "10s"
max_parallel = 1
}
group "hello" {
count = 1
restart {
attempts = 2
interval = "1m"
delay = "10s"
mode = "fail"
}
# Define a task to run
task "hello" {
driver = "docker"
config {
image = "gerlacdt/helloapp:v0.1.0"
port_map {
http = 8080
}
}
service {
name = "${TASKGROUP}-service"
tags = [
# "traefik.tags=public",
"traefik.frontend.rule=Host:bla.zapto.org",
"traefik.frontend.entryPoints=http",
"traefik.tags=exposed"
]
port = "http"
check {
name = "alive"
type = "http"
interval = "10s"
timeout = "3s"
path = "/health"
}
}
resources {
cpu = 500 # 500 MHz
memory = 128 # 128MB
network {
mbits = 1
port "http" {
}
}
}
logs {
max_files = 10
max_file_size = 15
}
kill_timeout = "10s"
}
}
}
The complete error message from nomad client logs:
failed to initialize task "hello" for alloc "c845bdb9-500a-dc40-0f17-2b79fe4866f1": Failed to find docker auth for repo "gerlacdt/helloapp": docker-credential-gcr with input "gerlacdt/helloapp" failed with stderr:
When try to create AntBuidler object in groovy file I am getting below exception
java.lang.NoClassDefFoundError: org/apache/tools/ant/BuildException
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2493)
at java.lang.Class.getDeclaredConstructors(Class.java:1901)
.....
at at features.step_definitions.RewardEventsGeneration.GetEventXML(RewardEventsGeneration.groovy:40)
at ✽.Then updateLoyaltyInfo event should be generated
I have added relevant jar to my lib folder and then placed below code under the build.gradle
repositories {
mavenCentral()
flatDir {
dirs 'lib'
}
}
My code as below
def GetEventXML (userId, eventTypeIn)
{
def Host = "10.77.69.14"
def UserName = "system"
def Password = "password"
def Path = "/temp"
def eventTypeToLookFor = "eventType=\"$eventTypeIn\""
def resultAsString = "" as String
def commandToRun = "grep -lH $userId $Path/*.xml | xargs grep -l '$eventTypeToLookFor' | cut -d: -f1"
def antEventCheck = new AntBuilder(); ********** Error line ******************
antEventCheck.sshexec( trust:'true',
host:Host,
username:UserName,
password:Password,
command:commandToRun,
verbose:'true',
timeout:'10000',
failonerror:'false',
outputproperty:'eventCheckResult');
resultAsString = antEventCheck.properties.eventCheckResult.toString()
return resultAsString
}
build.gradle
dependencies {
ext.groovyVersion = "2.0.4"
ext.cucumberJvmVersion = "1.1.5"
ext.httpclientVersion = "4.2.1"
cucumberRuntime files("${jar.archivePath}")
compile ('com.jcraft:jsch:0.1.49')
compile('com.github.groovy-wslite:groovy-wslite:0.8.0')
groovy("org.codehaus.groovy:groovy-all:${groovyVersion}")
compile("org.apache.httpcomponents:httpmime:4.1.2")
compile("org.codehaus.groovy.modules.http-builder:http-builder:0.5.2") {
exclude group: "org.codehaus.groovy", module: "groovy"
}
compile("net.sf.json-lib:json-lib:2.4:jdk15")
compile("javax.mail:mail:1.4.5")
compile("org.apache.httpcomponents:httpclient:${httpclientVersion}")
compile("org.codehaus.geb:geb-core:0.7.2") {
exclude group: "org.codehaus.geb", module: "geb-implicit-assertions"
}
drivers.each { driver ->
testCompile "org.seleniumhq.selenium:selenium-$driver-driver:$version.selenium"
}
compile("org.seleniumhq.selenium:selenium-support:2.25.0")
compile("log4j:log4j:1.2.17")
testCompile("junit:junit:4.10")
testCompile("info.cukes:cucumber-groovy:${cucumberJvmVersion}")
testCompile("info.cukes:cucumber-junit:${cucumberJvmVersion}")
}
Appreciate your comments
Following works perfectly
As specified by Peter's answer adding flatDir is not gonna be enough. Need to add same to the dependencies as well
repositories {
mavenCentral()
flatDir {
dirs 'lib'
}
}
dependencies {
compile("ant:ant:1.7.0")
}
Thanks Peter