Fork me on GitHub
#babashka
<
2023-06-20
>
didibus00:06:09

When I use pods from bb.edn, I'm guessing I can't run the script with Clojure anymore?

Bob B01:06:56

I'm not 100%, but pretty confident that it's possible, but the pod would need to be loaded with pods/load-pod (this could potentially go into a reader conditional maybe if double-loading would cause a problem)

lispyclouds06:06:58

The pods lib is meant for both the JVM and bb: https://github.com/babashka/pods It needs to be included as a dep when running there and pods need to be https://github.com/babashka/pods#usage and cannot be done declaratively like in bb.edn. Adding onto what @U013JFLRFS8 said, you can always load the pod as code and not via bb.edn to make it work on both platforms.

borkdude07:06:08

Using pods in bb.edn was kind-of-a mistake, it only works for local projects, not as library code. Just wrap your pod in a library using load-pod for bb-only which you can use via deps.edn and bb.edn. Examples here: • https://github.com/babashka/instaparse-bbhttps://github.com/clj-kondo/clj-kondo-bb

👍 2
borkdude07:06:33

Unless the pod isn't exposing a Clojure library, then just use the pods library on the JVM as well

licht1stein10:06:32

How do I capture output of this command with babashka? openssl s_client -starttls imap -connect 127.0.0.1:1143 -showcerts When I try (p/shell "openssl s_client -starttls imap -connect 127.0.0.1:1143 -showcerts") it just hangs, cause the program itself doesn’t exit. If I use commands that produce the output in bash with automatic exit, like echo | openssl s_client -starttls imap -connect 127.0.0.1:1143 -showcerts there is no output.

borkdude10:06:35

You want to capture the output as a stream, while it's running?

licht1stein10:06:11

I want it to print and die 🙂

borkdude10:06:19

but why is the program hanging?

licht1stein10:06:36

it’s not hanging, it has some sort of interactive mode I guess

borkdude10:06:52

you can try {:in ""} as an argument, so stdin is an empty string

borkdude10:06:09

as the first argument to p/shell

licht1stein10:06:55

Thanks, that helped! (shell {:in "" :out :string} "openssl s_client -starttls imap -connect 127.0.0.1:1143 -showcerts")

licht1stein10:06:13

Wow that was fast!

2
licht1stein10:06:15

I get the output as an exception though, I guess it’s printing to the error buffer

licht1stein10:06:32

which is fine, I still get it, but maybe there’s a way to get the err?

licht1stein10:06:14

No, my bad, I get it ok

borkdude10:06:34

:err :string is also an option. to not throw, you can use :continue true

licht1stein10:06:07

It was the last manual step in my mac setup. Now the entire system from scratch is configured using babashka, including importing gpg keys, pass vaults, certificates, all dotfiles, installation of all required apps etc 🙂

licht1stein10:06:34

And it’s more or less idempotent. I can rerun it as many times as I want, and it will bring the system to the state I want it in, but only if something is missing.

2
licht1stein10:06:53

thank you, you made it possible 🙂

❤️ 2
nitin02:06:48

Wow, is it available on public repo? or minimal snippet?

mmer14:06:18

Hi hopefully an easy one to answer - how can I make the babashka/http handle insecure https endpoints. In clj-http there is an :insecure? true option.

mmer14:06:50

Sorry Borkdude, I am not sure I can decode that: This is what I am sending:

(http/post (str "https://" (:cpd-route config) "/secure-url")
                                  {
                                   :body (json/generate-string {:username (:username config)
                                                          :api_key (:user-api-key config)})
                                   :content-type :json
                                   :accept :json
                                   :as :json
                                   :insecure true})

mmer14:06:08

And I get :

javax.net.ssl.SSLHandshakeException: unable to find valid certification path to requested target core c:\Users\MartinRoberts\Box\Personal\projects\SiteplannerData\core.clj:2:22

borkdude14:06:11

you need to create a client with the insecure option

borkdude14:06:47

(http/client (assoc http/default-client-opts :ssl-context {:insecure true}))

borkdude14:06:00

and then (http/get ... {:client client})

mmer12:06:48

Hi, glad the conference went well. When trying to reproduce using the issue in JVM I am now getting an error that random-uuid is not declared. I have looked in the source and can't trace where it is.

borkdude12:06:46

this is because you're using a tool old version of clojure, probably

mmer12:06:03

OK I will update

mmer12:06:14

Sadly I have it all set up for JVM, but dns is now failing. It seems to work with the clj-http.

borkdude12:06:14

Do you have a repro?

mmer12:06:22

repro? Do you mean - that I have the code somewhere you can view?

borkdude12:06:46

a piece of code which demonstrates the problem so it can be debugged

borkdude12:06:19

it doesn't have to be the code you are using in full, preferably the smallest piece of code which shows the problem

mmer12:06:28

(ns ogsetup.core
  (:require 
   [babashka.http-client :as http]
   [cheshire.core :as json]))

(def client (http/client (assoc http/default-client-opts :ssl-context {:insecure true})))




(def config (json/parse-string (slurp "config.json") true))


(defn get-token []
  (let [resp  (:body (http/post (:url config)
                                {:client client
                                 :body (json/generate-string {:username (:username config)
                                                              :api_key (:user-api-key config)})
                                 :content-type :json
                                 :accept :json
                                 :as :json}))]
    (:token resp)))

(get-token)

mmer12:06:45

The url is an "https".

borkdude12:06:11

Can you also provide the url?

mmer12:06:31

Sorry it is internal to my business.

mmer12:06:07

I am getting the same error in both jvm and bb versions

mmer12:06:03

Evaluating file: core.clj
; javax.net.ssl.SSLHandshakeException: No subject alternative DNS name matching `url` found. ogsetup.core 
; core.clj:22:22
; Evaluation of file core.clj failed: class javax.net.ssl.SSLHandshakeException

borkdude12:06:46

I need a url to reproduce the problem

mmer12:06:01

OK, lets leave it there. @U04V15CAJ thank you so much for all your work and support.

borkdude13:06:05

Why leave it here?

mmer13:06:41

Because I can't share the url.

borkdude13:06:46

But perhaps the problem will also occur with another url? Or is it specific to this url?

mmer13:06:59

I realised I could say something about the url - it was an endpoint on a k8s cluster.

mmer13:06:41

Is there anyway to use clj-http instead.

borkdude14:06:33

no, but you can try httpkit, clj-http-lite, hato or raw java.net.http

mmer14:06:11

OK I will give that a try. using lein uberjar is just a nightmare!

mmer09:07:14

Hi here is the snippet that is failing with the url, it is an endpoint in a k8s cluster. Do I need to add more options to the client?

(def client (http/client (assoc http/default-client-opts :ssl-context {:insecure true})))

(defn get-token
  [] (tap-> "Get Token for user: admin")
              (let [url (str "https://<cluster>/icp4d-api/v1/authorize")
                    json-body (json/generate-string {:username (:username "admin")
                                                     :api_key (:user-api-key "<replace with api key>")})
                    resp  (json/parse-string (:body (http/post url
                                                                 {:client client
                                                                  :body json-body
                                                                  :content-type :json
                                                                  :accept :json
                                                                  :as :json
                                                                  :throw-entire-message? true})) true)]
                (:token resp)))

(get-token)

borkdude09:07:47

:throw-entire-message? isn't an option supported by babashka.http-client, neither is :as :json , also not :content-type :json

borkdude09:07:29

you need to add those headers yourself:

{:client ... :body :headers {:content-type "application/json" :accept "application/json"}}

borkdude09:07:37

and then parse the JSON body string yourself

mmer09:07:44

OK - cut and paste from clj-http-lite

borkdude09:07:26

I don't know kubernetes. Is there anybody who can make a reproduction out of this problem? Perhaps @rahul080327?

mmer10:07:26

Getting the same error with - hope this is what you meant from above

(http/post url
    {:client client
     :body json-body
     :headers {:content-type "application/json" :accept "application/json"}})

mmer10:07:01

It does seem strange that it works with clj-http-lite with no problems.

borkdude10:07:12

What error are you seeing exactly

mmer10:07:44

; http://javax.net.ssl.SSLHandshakeException: No subject alternative DNS name matching http://cpd-lifecycle-manager.apps.nonage.cp.fyre.ibm.com found. http-test c:\Users\MartinRoberts\Documents\projects\http-client-exp\http-test.clj:6:53

borkdude10:07:18

Can you maybe set up a Docker image or so that I can run locally? I’ve never used k8s before but if you can provide an environment that I can easily run locally I would be able to look into it more

mmer10:07:04

Let me think about that. Thanks for be willing.

lispyclouds10:07:23

Are you able to curl that endpoint? That error seems to be a host name mismatch from what the certificate is providing

lispyclouds10:07:29

The cert the server is producing isn’t meant for it. That’s mostly when this error happens

mmer10:07:28

We are using a self signed cert that may be generic across all our test platforms.

mmer10:07:59

I would have though that setting the client to insecure would get round that?

lispyclouds10:07:09

Does curl -k <the url> work? I’m on limited machine access now, can try more later

lispyclouds10:07:40

The error doesn’t seem to be about a signature mismatch but the host name itself seems to be different

borkdude10:07:50

I'm able to repro with a self-signed certificate + python https server

curl -k 
works but bb http-client doesn't

mmer10:07:17

Is that a bug then?

mmer10:07:50

What I mean am I doing something wrong? Like a missing option?

borkdude10:07:00

I don't know yet

lispyclouds10:07:24

Looks like it could be a bug in bb http-client. Just for completeness, could you try curl -k with your url @U4C3ZU6KX ?

mmer10:07:12

@rahul080327 it reached the endpoint ok.

borkdude10:07:14

I can get it to work by doing this:

(require '[babashka.http-client :as http])

(System/setProperty "jdk.internal.httpclient.disableHostnameVerification" "true")

(def client (http/client (assoc http/default-client-opts :ssl-context {:insecure true})))

(defn get-token
  []
  (let [url (str "")]
    (prn (http/post url
                   {:client client}))))

(get-token)

borkdude10:07:33

Note: (System/setProperty "jdk.internal.httpclient.disableHostnameVerification" "true") Probably not advisable for production

2
mmer10:07:05

Thats great thanks.

mmer10:07:18

I am only working on test machines.

lispyclouds10:07:24

Like I was thinking, this isn’t about the cert signature

borkdude10:07:14

You can also configure :keystore and :truststore

mmer11:07:39

I am guessing that the following error when using the http-kit client is for the same reason:

[{:type java.lang.IllegalArgumentException
   :message "host is null: https//server/icp4d-api/v1/authorize"
   :at [org.httpkit.client.HttpClient exec "HttpClient.java" 291]}]

borkdude11:07:10

it might be because you forgot a : in the url

mmer11:07:00

I keep ending up blocked. With this bb.edn file I thought your fix above would work. But I get the same DNS error.

{ :paths ["."]
  :deps {}
 :tasks {:requires ([httptest :as test]
                    [babashka.http-client :as http])
         :init (do
                 (def client (http/client (assoc http/default-client-opts :ssl-context {:insecure true}))))
         get-token (do (System/setProperty "jdk.internal.httpclient.disableHostnameVerification" "true")
                       (test/get-token))}
}
Unfortunately, I feel blocked as clj-http-lite works but not for multipart. I have tried http-kit but I get the following error: java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.lang.String which the case of an open issue: https://github.com/http-kit/http-kit/issues/343 and the obvious route of using the http-client is proving problematic.

borkdude11:07:31

I’ll check back tonight, I’m traveling

mmer11:07:47

Thank you - you have been so patient.

mmer14:07:58

BTW is there a reason the clj-http-lite does not support multipart forms?

grav14:07:30

Maybe https://badssl.com/ can help as a repro? It has various hostnames with bad ssl certificates.

👍 4
chucklehead17:07:44

In the CSR for your self-signed certs, are you only specifying a subject or do you also have a DNS subjectAlternativeName with the same host name?

borkdude19:07:17

I noticed that (System/setProperty "jdk.internal.httpclient.disableHostnameVerification" "true") doesn't have the same effect in bb (when natively compiled) as in the JVM. I tried investigating but can't find the issue right now. I'll file a bb issue for this and will resume later

borkdude19:07:42

https://github.com/babashka/babashka/issues/1587 If anyone else wants to dig into it before I can, please do

borkdude19:07:18

About multipart in clj-http-lite: feel free to port whatever bb http-client has to clj-http-lite, the code is open source. cc @UE21H2HHD

borkdude19:07:37

@U4C3ZU6KX have you tried httpkit though?

borkdude19:07:09

I will get to the bottom of this once I'm back from my trip, next week or so

lispyclouds19:07:17

@U4C3ZU6KX re: > Unfortunately, I feel blocked as clj-http-lite works but not for multipart. I have tried http-kit but I get the following > error: java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.lang.String are you sending a headers with as a map with keyword keys and could that be causing this? httpkit doesnt take keywords as keys iirc, needs strings.

lispyclouds19:07:03

user=> @(http/get "" {:headers {:foo "bar"}})
java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.lang.String [at <repl>:6:2]
user=> @(http/get "" {:headers {"foo" "bar"}})
{:opts {:headers {"foo" "bar"}, :method :get, :url ""}, :body "{\n  \"args\": {}, \n  \"headers\": {\n    \"Accept-Encoding\": \"gzip, deflate\", \n    \"Content-Length\": \"0\", \n    \"Foo\": \"bar\", \n    \"Host\": \"\", \n    \"User-Agent\": \"http-kit/2.0\", \n    \"X-Amzn-Trace-Id\": \"Root=1-64a47937-56c777d27a560b462c23e37a\"\n  }, \n  \"origin\": \"188.214.11.255\", \n  \"url\": \"\"\n}\n", :headers {:access-control-allow-credentials "true", :access-control-allow-origin "*", :connection "keep-alive", :content-length "323", :content-type "application/json", :date "Tue, 04 Jul 2023 19:55:35 GMT", :server "gunicorn/19.9.0"}, :status 200}

chucklehead20:07:26

I think replacing the insecure-tm implementation with

(proxy [X509ExtendedTrustManager] []
(checkClientTrusted [& _])
(checkServerTrusted [& _])) 
would solve it

chucklehead20:07:19

nevermind, see you're already onto that solution in the github issue

chucklehead20:07:08

I also confirmed that setting an appropriate subjectAltName on the self-signed cert makes the problem go away using the existing TrustManager, if regenerating/deploying certs is an option for @U4C3ZU6KX e.g. this cert from the github issue with localhost specified only in the subject causes errors:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 3650 -nodes -subj "/C=XX/ST=StateName/L=CityName/O=CompanyName/OU=CompanySectionName/CN=localhost"
but after adding a SAN it works fine connecting as localhost or by IP:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 3650 -nodes -subj "/C=XX/ST=StateName/L=CityName/O=CompanyName/OU=CompanySectionName/CN=localhost" -addext "subjectAltName = DNS:localhost, IP:127.0.0.1"

👍 2
mmer08:07:34

@U015879P2F8 Thanks for the suggestion, unfortunately I am not in control of the certificates, I am just using a standard installation we have. What is strange is that both clj-http-lite and http-kit do not show this behaviour.

lread15:07:57

> BTW is there a reason the clj-http-lite does not support multipart forms? @U4C3ZU6KX, it's due to the -lite aspect of clj-http-lite, it's not a full-featured HTTP client by design, but does the trick for some use cases.

chucklehead15:07:30

On mobile so can’t seem to link directly to line number, but for clj-http-lite it looks like it also overrides the HostnameVerifier in addition to the SSLContext

mmer15:07:31

Make sense.

borkdude15:07:22

@UE21H2HHD clj-http-lite could have this, was my point, it can be done in pure Clojure like in bb http client, but makes sense to skip

lread15:07:09

Right... gotcha. If have no real preference or strong opinions, but maybe nice to keep a lite library light?

lread15:07:50

<@U015879P2F8> ya, I'm at desktop and can link easily, <https://github.com/clj-commons/clj-http-lite/blob/5d5f836e70dc0e5946d2b0a66b5292e8df22b12e/src/clj_http/lite/core.clj#L45-L65|here's the clj-http-lite code that is >_<https://github.com/clj-commons/clj-http-lite/blob/5d5f836e70dc0e5946d2b0a66b5292e8df22b12e/src/clj_http/lite/core.clj#L45-L65|very>_<https://github.com/clj-commons/clj-http-lite/blob/5d5f836e70dc0e5946d2b0a66b5292e8df22b12e/src/clj_http/lite/core.clj#L45-L65| trusting>.

borkdude19:07:15

ok, I fixed the issue by using http://javax.net.ssl.X509ExtendedTrustManager - bb http-client should now work as is for your use case @U4C3ZU6KX but you will need the bb version from master. You can download it using bash <(curl ) --dev-build --dir /tmp This will only work when the master build is finished (should take 10 minutes from now or so)

borkdude19:07:58

should be there now

borkdude20:07:25

I’m curious if it does work for you now

mmer20:07:05

I will try first thing tomorrow

mmer09:07:05

That fixed the issue - many, many thanks

🎉 2
mmer14:06:24

Why would I get this No subject alternative DNS name matching when I can ping the name of the end point, but in the script it fails? Sorry for asking primitive questions.

borkdude14:06:06

Can you try this from JVM Clojure to see if it works differently from babashka?

mmer14:06:17

I have been using calva and leinegen and it seems to work.

mmer15:06:36

Putting the ipaddress directly in yields: No subject alternative names matching IP address

borkdude15:06:47

with the same babashka.http library right?

mmer15:06:36

Sorry no with clj-http. I will try with the babashka library

borkdude15:06:03

also make sure you're using the latest bb version

borkdude09:07:26

I don't know kubernetes. Is there anybody who can make a reproduction out of this problem? Perhaps @rahul080327?