14. září 2018

Nová verze blogu


Tato verze blogu (běžící na platformě Blogger) je archivována. Nové články je možno sledovat na doméně sw-samuraj.cz, kam byly rovněž zmigrovány všechny minulé články.

6. září 2018

GopherCon UK 2018, den 2

Nevím, jestli někdo odhalil smysl nadpisů v minulé části (jednoduché 4-dílné řešení můžete psát do komentářů, plus jedno bonusové i v tomto textu), kdy jsme se v článku podívali na první den londýnské Golang konferencce GopherCon UK, která se konala ve dnech 1.-3. srpna.

Po středečních workshopech, kterých jsem se neúčastnil, proběhly dva dny přednášek. Už jsem zmiňoval, že čvrteční přednášky nebyly až tolik Golang-technické (a žádná z nich nebyla advanced) a z tohoto pohledu byl páteční den přínosnější i zajímavější.

🔑 Growing a Community of Gophers

Úvodní keynote Cassandry Salisbury (@Cassandraoid) jsem neviděl - ať už to bylo proto, že jsem se rozhodnul snídat déle, či jít z hotelu na konferenci cca 50 minut pěšky (Londýn je obrovský), anebo proto, že mě téma moc nezajímalo. Jak už jsem psal, téma budování komunity na konferenci (aspoň mezi speakery) silně rezonovalo.

Záznam přednášky

London Eye

👍 From source code to Kubernetes, a Continuous Deployment tale

Z přenášky Alexandra Gonzáleze (@agonzalezro) si toho moc nepamatuju - jen to, že měl pekné live-demo, ve kterém ukazoval:
  1. Jednoduché Hello, world! s využitím gorilla/mux.
  2. Push do GitHub repozitory.
  3. Webhook + push na (public) Jenkins.
  4. Deployment do Kubernetes clusteru.
Nic světoborného, takhle si představuju Continuous Deployment. Samozřejmě, chyběly tam testy atd. a čekal bych nějaké modernější Pipelines, než obstarožní Jenkins, ale jinak pěkná a svižná přednáška.

Záznam přednášky

👍 Goroutines: the dark side of the runtime

Konečně přednáška, která přesahovala mé Golang technické znalosti! Roberto Clapis (@empijei) se ponořil do záludností goroutines. Zkuste si tipnout, jaký bude výstup tohoto programu:


Že to bude deset desítek asi nikdo z vás netipoval, co? 🤔

To podstatné z Robertovy přednášky:
  • Go má jak goroutines, tak closures - nemíchat! 
  • Runtime is not preemptive - goroutine is done when it says it's done. 
  • Garbage collection (stop the world) - goroutines are asked to yield execution. Čekání na goroutines může blokovat GC -> freeze all the cores.
  • Goroutine cannot be stopped. Měly by explicitně vracet return a přijímat context (s cancel funkcí), nebo done channel.
  • Check for cancellation wherever possible. Pokud knihovna/funkce cancellation neumožňuje, dodejte svoji vlastní via closure.
 A pro zvědavce, jak by měl předešlý kód správně vypadat, aby dával očekávaný výstup (ďábel 😈 je skrytý v detailu).


Pro vysvětlení se podívejte buď na přednášku, nebo si přečtěte Effective Go.

Záznam přednášky

St Paul Cathedral a The City

👍 Understanding Go's Memory Allocator

André Carvalho (@andresantostc) doručil druhou z nejtechničtějších přednášek - vysvětlení, jak funguje Go Memory Allocator:
  • Založený na TCMalloc (Thread-Caching Malloc).
  • Navíc přidává tiny allocations (k původním small, medium a large alokacím).
  • Go (očividně) nemá malloc, ani free.
  • Pragma //go:noinline prevents inlining.
  • Kompilátor se snaží držet většinu proměnných na stacku (levnější) a jenom ty, které uniknou (escape) dává na heap
  • Volání funkce mallocgc() vkládá kompilátor.
  • GC Sweeping:
    1. Scan all objects.
    2. Mark objects that are live.
    3. Sweep objects that are not alive.
  • Šikovná funkce ReadMemStats() - runtime statistiky memory allokátoru.

Záznam přednášky

👍 Building Resilient Data Pipelines in Go

Přednáška Granta Griffithse (@griffithsgrant) byla primárně o případu užití Go - vytvoření data pipelines, které přesouvají data z IoT do zákaznických aplikací. Pipelines, které přesouvají data z Apache Kafka nodů do Apache Cassandra nodů, měli původně napsané v Javě, ale kvůli provozním nákladům je začali přepisovat do Golang. Pro porovnání:
  • 30 Kafka nodes -> 144 Java pipelines nodes -> 150 Cassandra nodes = 900.000 writes/sec.
  • 4 Kafka nodes -> 32 Go pipelines -> 9 Cassandra nodes = 450.000 writes/sec.
Po náběhu na stejnou úroveň nodů jako u Java řešení očekávají dvojnásobné množství zápisů do Cassandry.

Design Go data pipelines vypadá následovně:
  • Go micro-services
  • Go channels
    • Message channel - čte data z Kafky
    • Notification channel - rebalance notifikace
    • Error channel - chyby v Offset Managementu
    • OS Signals channel - naslouchání signálům OS pro graceful shutdown
  • Message transformation
  • Deployované na K8s cluster
Zajímavé bylo také Reliability Testing, něco vy stylu:
  1. Pošli 50 zpráv,
  2. "Za-pauzuj" Docker po 10 zprávách,
  3. "Od-pauzuj" Docker po 30 zprávách.
Celkově, velmi zajímavá přednáška o real-world, large-scale use casu, jakých na koferenci moc nebylo (což mi chybělo).

Záznam přednášky

Golden Hind

👍 How do you structure your Go apps?

Od prezentace Kat Zien (@kasiazien) jsem nečekal žádné zjevení, ale ve výsledku to byla příjemná přednáška a i něco nového jsem se v závěru přiučil. Jak strukturovat Go projekt je vousatá otázka. Přednáška shrnula různé layouty a krátce vypíchla jejich charakteristiky. Tedy:
  • Flat structure - všechno je v main packagi, vhodné pro malé projekty. Z pohledu na soubory je většinou nejasná business doména.
  • Group by function - klasika, která většinou vede k něčemu, jako je MVC.
  • Group by module - seskupení podle business domény. Vede k repetitivnosti (user.User, user.AddUser() atd.) a není intuitivní (kam přidat novou funkci?).
  • Group by context - vhodné pro komplikovanější aplikace:
Takže, jako vždycky - No Silver Bullet, strukturu svého Golang projektu si budete muset vyřešit sami. 😉

Záznam přednášky

🔑 Athens - The Center of Knowledge

Brian Ketelsen (@bketelsen), mající závěrečnou keynote, přinesl asi nejzajímavější téma celé akce. Obecně, problém verzování a dependency managementu Golang packagů mi na konferenci hodně chybělo - je to nejsilnější a nejbolavější téma posledního půlroku, který jsem s Go strávil. Občas se sice někdo zeptal, kdo používá vgo a kdo používá dep, ale žádná přednáška se tomu nevěnovala.

Brian představil zbrusu nový projekt - Athens, který zastřešuje několik aktivit. Mimo jiné poskytuje:
  • Caching proxy server, který může běžet za firewallem.
  • Distributed trust, potvrzující autenticitu balíčků.
  • Decentralized verification, nezávisející na jednom centrálním poskytovateli (a.k.a. evil corporation).
Co to všechno nabízí (resp. bude poskytovat)?
  • Repeatable builds (i pokud je GitHub/GitLab/Bitbucket nedostupný).
  • Module validation, využívající hash v go.sum souboru (nyní součást Go modules).
  • Module signing, pomocí sítě distribuovanýcn "notářství" (notaries).
  • Discoverability = Notaries + Publishers (collect certificates from Notaries).
Hlavním heslem je: Decentralized, Federated, Independent. Bude hodně zajímavé tenhle projekt sledovat!

Záznam přednášky

Tower Bridge

Gopher - to be, or not to be?

Celkově hodnotím konferenci pozitivně. Co bych vypíchnul, byla profesionalita, která byla všudypřítomná. Nevím, jestli je v Česku něco podobně srovnatelného. Samozřejmě, nesmím zapomenout na dobré jídlo a catering.

Orientaci na komunitu jsem opakovaně zmiňoval. Což je pozitivní - Go je velice otevřená platforma a byť je to jazyk, který se blíží první dekádě, je zatím relativně mladý a řekl bych, že - minimálně v oblasti cloudu (a cloudové infrastruktury) - ještě stále nabírá momentum (které do Česka zatím ještě moc nedorazilo).

Co mi na konferenci chybělo? Advanced přednášky - pokud má konference 3 streamy, jsou dvě pokročilé prezentace za dva dny málo. Taky mi chybělo víc use case použití, real-world scénářů, kdy Go je dobrá/správná/excelentní volba.

Musím ocenit, že na konferenci bylo relativně hodně holek - na jednu stranu je to trochu překvapující (Go je docela low-level jazyk), na druhou stranu, na konferenci bylo znát, že nastupující/etablovanou generací jsou Milleniálové, což možná jde ruku v ruce.

Takže, za mne palec nahoru 👍 a snad se jednou dočkáme Golang konference i v Česku. 🤞

The Loneliness of the Long Distance Runner

Konference je jedna věc, co dělat ve zbývajícím volném čase je jiná záležitost. Londýn samozřejmě nabízí mnoho lákadel, od volného vstupu do mnoha muzeí a galerií, přes kvantum pamětihodností, až po obrážení tradičních pubů a rozmanitých restaurací s národními jídly.

Byť jsem některé z těchto možností také využil, hlavně jsem si užil Londýn běžecky - sice to není úplně intuitivní volba, ale když to člověk zkusí, zjistí, že tak pokryje docela velký akční rádius, včetně bonusových překvapení. Můžu doporučit. Doprovodné fotografie (vyjma 3 konferenčních) jsou pořízeny právě z těchto běžecko-průzkumných výprav.

Mind Map

GopherCon UK 2018, den 2.

Související články


31. srpna 2018

GopherCon UK 2018

Should I Stay or Should I Go

Poté, co jsem měl poslední dva roky utrum s technicko-pracovním vzděláváním, se na mě usmálo štěstí a zásluhou nového zaměstnavatele jsem vyrazil na svoji první zahraniční konferenci.

Nových věcí v nové práci je (a bylo) dost a tak jsem měl poměrně široký výběr (technických) domén, ale nejvíc mě to táhlo ke Golangu - i když jsem k němu přišel jak slepý k houslím, tak jsem si ho velmi rychle oblíbil. A tak, když se v mém Twitter feedu mihnul @GopherConUK, bylo rozhodnuto - vyrazím do Anglie!

London Calling

Konference se konala ve dnech 1.-3. srpna v Londýně a ne jen tak ledaskde, ale přímo v The City, v prostorách bývalého pivovaru z 18. století, The Brewery. Luxusní místo pro konferenci.

První den byly workshopy (kterých jsem se neúčastnil) a pak dva dny klasických přednášek (to je gró, proč na konference chodím). No a samozřejmě, sociální události (kterým se, jakožto introvert, striktně vyhýbám).

The Brewery, konference venue

Thursday's Child

Celkově, čvrteční přednášky mi přišly slabší, než ty páteční. Možná je to i záměr organizátorů?

🔑 You Might Be a Go Contributor Already and Not Know It

Úvodní keynote Aditya Mukerjeeho (@chimeracoder) se točila kolem různých způsobů kontribuce - jako gopher (fanoušek Golangu) můžete:
 Obecně, budování a participace na Golang komunitě bylo téma, které se rekurentně na konferenci vracelo.

Záznam přednášky

👍 Three Billy GOats Gruff - a developer's tale from VMs to serverless

Občas mají přednášky obskurní názvy, ovšem tahle byla dobrá. Michael Hausenblas (@mhausenblas) prezentoval přechod z jednoduchého monolitu (majícího 2 goroutines), přes rozpad stejné funkcionality do kontejnerovaných micro-servis (běžících na Kubernetes) a skončil u serverless funkcí (implementovaných jako AWS Lambdas).

Michael pracuje v Red Hatu (a tudíž OpenShift), takže nepřekvapí, že jeho doménou byly hlavně kontejnery (v Lambdách měl dokonce jeden anti-pattern), ale jeho prezentace pěkně a jednoduše ukázala, jak by taková transition mohla vypadat.

Záznam přednášky

Canary Wharf

😐 Broadcasting Channels: Writing a timeout-aware abstraction to enable asynchronous fanout in Go

Sean Kelly (@StabbyCutyou) má hodně rád svého psa - jeho slidy se jím jenom hemžily. Nicméně celkem vtipné to bylo. Sean si jen tak pro radost (a studium) naimplementoval broadcasting pomocí channels.

V podstatě bylo vyznění jeho přednášky víc o Enterprise Integration Patterns (ačkoliv je nikde explicitně nezmínil), než o Go (kterého stejně moc neukázal). I když si původně myslel, že to bude jednoduché, tak se postupně dopracoval k věcem jako Error Queue Channel, re-tries, time-outs atd. Prostě to, co je v EIP už dávno vyřešené.

Záznam přednášky

👍 Orchestration of microservices

Bernd Rücker (@berndruecker) je spolu-zakladatel workflow enginu Camunda. Ani v jeho případě nebyla přednáška moc o Go, jako spíš o BPMN, workflow enginech a problémech distribuovaných architektur. Pokud do toho posledního něco málo děláte, asi by vás v jeho prezentaci nic moc nepřekvapilo, ale přednáška byla vtipná a svižná.

Dva, tři nejzajímavější body zahrnovaly:
  • Strategie pro Fallacies of distributed computing (ignore | re-throw error | retry | stateful retry)
  • Konzistence - těžký problém všech distribuovaných architketur. Tady mě pobavila hláška "Grownups don't use distributed transactions". 😁 Lepší je použít kompenzace (Saga pattern).
  • Orchestrace a Choreografie - choreografie zatemňuje viditelnost procesu, tj. je obtížnější a víc náchylná k (designovým) chybám.
Záznam přednášky

Cutty Sark

👎 Component and integration tests for micro-services

Jednoznačně nejslabší přednáška celé konference - Dmitry Matyukhin měl prvně dlouhé intro pro začátečníky o základech testování a pak se podělil o to, jak napsali nějaké služby v Go, ale testovali je... v Ruby!?! Takže místo Golangu jsme koukali, jak se dělá BDD v Cucumber 😩 Já jsem teda valil oči a přemýšlel, jestli si chlapec nespletl konferenci. 🤦

Záznam přednášky

👍 Documenting Go Code with Beautiful Tests

Přednáška Pawła Słomky (@pawel_slomka) byla jedna z nejtechničtějších a taky nejvtipnějších toho dne: hodně jsem se zasmál jeho vtipu o Schrödinger's TDD - is it TDD alive, or dead? 😹

Ohledně testování v Go zmiňoval:
Paweł byl jediný, s kým jsem si na konferenci pokecal - jednak jsem chtěl něco dovysvětlit ohledně těch check functions a jednak jsme probrali běhání maratonů. 🏃

Záznam přednášky

Canary Wharf, pohled od Royal Observatory, Greenwich

🔑 Code, Content, & Crafting Your Voice

Závěrečná keynote Amy Chen (@TheAmyCode) byla velmi... milleniálská. Jak formou, tak obsahem. Doporučuju, pokud chcete budovat svůj personal brand. Zejména formou YouTube kanálů a všech těch moderních sociálních sítí, bez kterých Generace Y nedokáže žít. Možná, že Amy je dobrá kóderka... ale já to zjišťovat nebudu.

Nicméně, abych to úplně nezahodil, jeden dobrý bod tam byl - pokud chcete být jakkoli virtuálně přítomni ve veřejném prostoru, tak prvotní by mělo být si definovat identitu - jak se chcete prezentovat, jak chcete, aby vás vaše audience vnímala. Aneb "Followers follow your identity."

Záznam přednášky

Západ slunce za The City (bedlivým okem můžete rozeznat The Shard a The Gherkin)

Friday I'm in Love

Na přednášky ze (zajímavějšího) druhého dne GohperConu se podíváme v příštím článku: GopherCon UK 2018, den 2. Plus nějaké celkové shrnutí konference.

Mind Map

GopherCon UK 2018, den 1.

Související články


30. června 2018

Správa proprietárních závislostí v Golang

Se změnou zaměstnání přišly nové výzvy - prototypujeme teď nový produkt a jako primární technologie byl zvolen Golang. Myslím si, že vzhledem k povaze produktu (smečka mikro-servis) a cílové infrastruktuře (IaaS) je to dobrá volba.

Golang není zas až tak nový jazyk (je tady s námi nějakých 9 let), a ačkoliv se v něm příjemně píše, má vývoj v Golangu určitá úskalí a výzvy - to buď v případě, že vám úplně nevyhovuje, jak v Googlu vymysleli vývojový proces, anebo pokud očekáváte vlastnosti běžné na některé zralejší platformě.

Jak já, tak celý tým máme silné Java zázemí a je tedy možné, že náš přístup ke Golang infrastruktuře není úplně adekvátní. Nicméně poslední tři měsíce jsem se tématu verzování, závislostí, reprodukovatelnosti a automatizaci Go buildů intenzivně věnoval a řekl bych, že to soudruzi z U.S.A "nedotáhli úplně dokonce".

Požadavky

Pro náš projekt jsme měli, řekl bych, celkem běžné nároky:
  1. Privátní Git repository za firemní proxy. Kvůli legálním záležitostem a firemním politikám nemůžeme dát projektový kód na GitHub.
  2. Samostatná projektová repozitory. OK, chápu, že v Googlu milují monorepo, ale většina z nás v Googlu nepracuje...
  3. Reprodukovatelný build. To je samozřejmost, k tomu asi není co dodat.
  4. Spolehlivá správa závislostí a jejich verzí. V Javě, nebo na Linuxu je to no-brainer - stačí mít package manager a repozitory, ne?
  5. Plně automatizované. Zase by se řeklo samozřejmost, ale pořád a pořád potkávám lidi, kteří smolí (klidně i produkční) buildy ručně.

Problémy

Pokud budete chtít výše zmíněné požadavky naimplementovat v Golangu, narazíte na problém: out-of-the-box to nejde vůbec a pokud nebudete ochotni část nároků oželet, čeká vás world-class hackování. (Teda ne, že bych byl takovej hustej hacker... spíš jsme narazili na hluché místo.)

Esenciální potíž je, že celý Golang ekosystém je navržený jako jedno velké open-source monorepo (a.k.a. GitHub). Pokud nechcete/nemůžete mít svůj kód na GitHubu, máte problém. Protože:
  • Golang nemá jednotný/dominantní nástroj na automatizaci. Většina projektů na GitHubu builduje makem. make je fajn na kompilaci, ale dělat v něm komplexnější automatizaci je masochismus.
  • Golang nemá dořešený verzování dependencí. Člověk by řekl, že po těch letech to už bude nějak usazený, ale stačí nahlédnout do oficiální wiki stránky, nazvané lapidárně Package Management Tools a zjistit, že pro správu dependencí a verzí existuje nějakejch 20-30 nástrojů. Naštěstí se od loňského léta masivně prosazuje nástroj dep a velmi slibně to vypadá s oficiálním návrhem vgo, který by se snad měl cca na podzim dostat do Go verze 1.11.
  • Oficiální Golang nástroje neumí pracovat se závislostmi, které nejsou ve veřejných repozitářích (GitHub, Bitbucket, GitLab). Jediný podporovaný způsob je nastavit na repozitory HTML meta tag go-import. Což většinou(?) nemáte pod kontrolou.

GOPATH odbočka

Malé vysvětlení pro čtenáře, kteří nejsou Gophers (fanoušci Golangu). Proč jsou výše zmíněné problémy reálnými problémy? Všechny Golang nástroje předpokládají, že vaše zdrojáky jsou soustředeny pod tzv. GOPATH - což je fakticky lokální monorepo.

Protože v Golangu se všechno linkuje a kompiluje staticky, je potřeba mít všechny zdrojové kódy na jednom místě, neexistují binární závislosti. Pro stažení externích závislostí (v Go nazývaných package import) slouží nástroj go get, který de facto naklonuje Git repository dané závislosti do adresářové struktury pod GOPATH.

Pokud bychom pominuli verzování a reprodukovatelnost a soustředili se jenom na kompilaci, máme tady dva základní konflikty:
  • go get neumí klonovat z non-public repozitářů.
  • Pokud nemáte váš projekt pod GOPATH, budete muset s GOPATH nějak manipulovat, aby Go nástroje vůbec fungovaly.


Řešení

Protože jsem husto-krutej drsňák, před kterým bledne jak Phil Marlowe, tak Dirty Harry, tak jsem se nezaleknul, zatnul zuby a všechny problémy vyřešil. Svým způsobem...

Pravdou je, že řešení, ke kterému jsme prozatím doiterovali, byl průzkum bojem - tj. paralelně řešit business požadavky (proč vlastně ten prototyp děláme) a zároveň vyřešit automatizaci buildů (nebo minimálně aspoň kompilaci Golang projektů).

Když začnu s výše popsanými požadavky od konce - pro automatizaci jsme zvolili Gradle. Původně jsme počítali s nějakým polyglot řešením (něco v Javě, něco v Golang), ale nakonec jsme skončili s čistě Golang moduly.

Ironií je, že v celém řešení víceméně žádná Java není (výjimkou jsou Gradle pluginy). Každopádně, Gradle se výborně osvědčil - buildujeme v něm Go, RPM balíčky, Docker image, stahujeme a re-packagujeme binárky z internetu, pouštíme integrační testy, deployujeme do repozitářů a do cloudu atd.

To všechno je hezké, jak ale v Gradlu skompilovat Golang zdrojáky? Samozřejmě, vezmu nějaký hotový plugin. Bohužel, výše naznačené problémy s verzováním Golang závislostí způsobily, že nám žádný plugin úplně nevyhovoval.

A tak jsem si napsal svůj plugin. Řekl jsem si, že základní nástroje v Go fungují dobře a tak je jenom zorchestruju. Takže můj plugin není nic jiného než: wrapper + orchestrátor + lifecycle. Plugin řeší následující věci:
  1. Manipulace s GOPATH, aby fungovaly nástroje, které očekávají zdrojáky v... GOPATH.
  2. Stažení externích závislostí z public repozitářů (pomocí nástroje dep).
  3. Stažení externích závislostí z non-public repozitářů (pomocí Git klonování).
  4. Spuštění testů.
  5. Kompilace binárky.

O správu verzí public závislostí se stará nástroj dep. O správu verzí non-public závislostí se stará plugin (task proprietaryVendors). V případě, že non-public závislosti mají tranzitivní závislosti na public závislostech, je to kombinace obojího. Technický popis je trochu komplexnější, takže zájemce odkazuji do dokumentace: How to handle proprietary vendors; nicméně použití by mělo být (v rámci možností) jednoduché.

Sekvenční diagram build life-cyclu godep pluginu


Problem solved?

Takže... problém vyřešen? Nový Gradle plugin splňuje všechny v úvodu uvedené požadavky a za ty tři měsíce má za sebou stovky úspěšných buildů (build se v GitLab Pipelině pouští pro každý git push). Tudíž zatím ano, funguje to k naší spokojenosti.

Otázkou ale je, jak dlouho to vydrží - verzování závislostí je žhavé téma jak Golang komunity, tak core vývojářů Go. Všichni s očekáváním vzhlížejí ke zmíněnému vgo a tak za půl roku možná bude všechno jinak a nějaký Gradle plugin už nebude potřeba.

Ale nijak se tím netrápím - pár takových Gradle pluginů už jsem napsal: v daný moment vyřešily mou situaci, avšak časem přestaly být potřeba. A to se mi líbí - nástroje, které jsou dostatečně flexibilní a zároveň mají hezký a moderní design. A dobře se v nich dělá. A to jak Golang, tak Gradle splňují.

Externí odkazy


Mind Map


30. května 2018

Cesta samuraje, rok sedmý

Je květen a blog SoftWare Samuraj má narozeniny. Něž sfouknu pomyslné svíčky, trochu si zavzpomínám, co se od minulé oslavy událo.

Asi to nebude veselý článek - dlouho jsem se na něj mentálně chystal a stejně si nejsem úplně jistý, jak to dopadne. Emoce jsou někdy silnější, než rozum.

Co bylo

Mám za sebou těžký rok. A byť, z hlediska blogování, to byl rok velice úspěšný, tak co mi v hlavě utkvívá, jsou ty negativní věci.

Doba temna

Je to rok a měsíc, co jsem v minulé práci oznámil, že odcházím. A začaly se dít věci. Nebylo to rozhodnutí z čistého nebe - už měsíce a měsíce to k tomu spělo a ačkoliv jsem o tom otevřeně referoval svému bývalému šefovi (říkejme mu BŠ) na pravidelných 1:1 a vysílal jasné varovné signály, tak BŠ s chápavým úsměvem sledoval, jak klasám pod hladinu řeky Styx.

Je to takový ten klasický příběh: Šéfové nejvíc přetěžují svoje nejlepší pracovníky. A tak, když jsem pozvolna vyhodnotil situaci, že k žádné změně nedojde, udělal jsem dvě věci:
  1. Aktivně jsem se vyvázal ze svých povinností, tedy hlavně budování týmu a technical recruitmentu a taky technical leadingu pod-staffovaného, špatně obsazeného a špatně řízeného projektu.
  2. S konečnou platností řekl, že končím.

Odezva na sebe nedala dlouho čekat - BŠ mi obratem zrušil 1:1 a zavedl rádiové ticho:
  • Po devět měsíců se mnou nekomunikoval,
  • pracovně, společensky a lidsky mě ignoroval (ačkoli jsem pořád byl manažer týmu a ohledně projektu jsem měl největší zákaznickou, businessovou i technickou znalost),
  • řešil věci za mými zády
  • a když si myslel, že se nikdo nedívá, tak se mi zbaběle a nemorálně mstil.

Ale co už. I když jsem přemýšlel, že bych z toho vytěžil článek, který pracovně nazývám "O špatných šéfech" (BŠ by se umístil na stříbrné pozici), nevím, jestli se mi chce v takových sračkách rýpat. Některé běsy je lepší nechat spát.

Jak jsem psal, mé rozhodnutí zrálo dlouho a ve výsledku nebylo emocionální - neběžel jsem na HR třísknout výpovědí. Jenom jsem tváří v tvář oznámil, že budu končit a začal si hledat novou práci.

Během onoho "zrání" jsem si uvědomil, že potřebuji zásadnější změnu, než jen zaměstnání. Chci změnu více aspektů své práce: technologie, domény, role atd. A zároveň, některé své vysoce seniorní skilly, buď dočasně, nebo trvale opustit. A tak, když jsem se ocitnul na pracovním trhu, trvalo to dlouho, než jsem si něco vybral (a byl vybrán). Své zkušenosti jsem popsal v článku Smutná zpráva o stavu IT trhu. Bylo to většinou tristní a doufám, že minimálně dalších pět let to nebudu muset absolvovat.

Kromě těhle negativních věcí musím vyzvednout aspoň jednu pozitivní - našel jsem si na projektu (po odevzdání svých zodpovědností) svoji niku a mohl se tak po měsíce věnovat svojí oblíbené činnosti: prototypování. Vzniklo z toho několik článků (i když jsem jich původně plánoval víc), z nichž nejvíc si cením miniseriálu o SAMLu.

Nadešel poslední den v mé práci a... BŠ se se mnou ani nerozloučil. Ačkoliv si se mnou naplánoval schůzku (na nejposlednější možnou minutu), nakonec na mě neměl čas... měl totiž telefon 🤣, jistě důležitý. No, aspoň byl v té ne-komunikaci konzistentní. 🙉

Doba světla

Po 9 měsících temna (vidíte tu symboliku? 😁) jsem nastoupil do nové práce a... všude bylo plno světla, tráva zelenější, obloha modřejší, vzduch krásně voněl. No, každopádně jsem poslední tři měsíce velmi spokojený:
  • Mám fajn šéfa (i když, to jsem o BŠ před pár roky říkal taky 😲).
  • Jsem v týmu inspirativních lidí, od kterých se mám hodně co učit.
  • Přesedlal jsem z Javy na Golang.
  • Přesedlal jsem korporátních 3-vrstvých aplikací na cloud a big data.
  • Nedělám projektově, ale produktově.
  • Hlavním runtime prostředím pro mne (momentálně) není aplikační server, ale Docker.
  • Z Continuous Integration jsem se přesunul na Continuous Delivery, konkrétně GitLab Pipelines. Jenkins je pro mne dnes stejný vtip, jako Maven.
  • Sedím u okna s výhledem na fontánu a mám to autobusem 10 minut do práce.
  • Letos jsem za 3 měsíce naběhal tolik, co loni za celej rok. 🏃

Má to i své stinné stránky - už si cestou do práce tolik nepočtu. 📖

Co bude?

I když moje křišťálová koule leccos naznačuje, je ošidné dělat předpovědi. Zejména, pokud jde o budoucnost (ha, ha, ha). O čem bych tak mohl psát, naznačuje předešlá sekce - vždycky jsem psal o tématech, která se týkala mé práce. Kromě těch nových témat, mi ale zbývá ještě pár oblastí z minulosti. Možná o nich napíšu, možná ne. Dejte vědět v komentářích, co by vás zajímalo.


Související články


17. března 2018

Maximální počet otevřených souborů v Ubuntu

Operační systémy a někdy i přímo jazyky, či jejich runtimy mají omezený maximální počet otevřených souborů. Z bezpečnostních a performance důvodů. Občas se vám stane, že na tento limit narazíte a potřebujete ho upravit. Jak to pořešit na Ubuntu?

Začal jsem teď na stávajícím Java projektu a první, co jsem zkusil - zbuildovat ho. Bylo tam plno testů (a mraky logování z testů) a běželo to dlouho. Život je plný překvapení: Vyskočila na mne výjimka, co jsem zatím ještě neviděl:
java.io.FileNotFoundException: /path/to/file (Too many open files)

Java používá pro maximální počet otevřených souborů limit operačního systému. Pro nastavení (nejen) tohoto limitu slouží soubor /etc/security/limits.conf. Limity se nastavují per uživatel/skupina a nastavují se dva: soft a hard. Přiznám se, úplně nechápu, jak (pro soubory) funguje soft limit - z dokumentace jsem to úplně nepochopil. Nicméně nás bude (pro Javu) stejně zajímat pouze hard limit, který procesu řekne: Hasta la vista, baby!

Jaký limit otevřených souborů máte momenálně k dispozici, zjistíte příkazy:
  • ulimit -Sn (soft limit maxima otevřených souborů)
  • ulimit -Hn (hard limit maxima otevřených souborů)

Výpis soft a hard limitu max. počtu otevřených souborů

Příklad nastavení:


Tak. A mohli bysme mít hotovo - budete to fungovat... pokud se přihlašujete z terminálu. Typický use case by byl třeba nastavení limitů pro webový server. Pokud vás to ale trápí jako vývojáře na lokálním prostředí, tak budete muset použit příkaz su, aby se změna v terminálu projevila. Problém je, že v grafickém prostředí se soubor limits.conf ignoruje

Výpis limitů po změně uživatele

Aby limit pro počet otevřených souborů vzalo v potaz i GUI, je potřeba ještě poeditovat soubor /etc/systemd/system.conf (a v některých případech i soubor /etc/systemd/user.conf):


Pak už stačí jen systém restartovat a máme hotovo. (Možná to jde i bez restartu pomocí nějaké systemctl magie, ale na to jsem nepřišel.)

22. února 2018

Jak se staví tým


Tenhle článek jsem chtěl napsat už několik let. Pořád jsem to odkládal s tím, že časem ještě získám víc zkušeností a tak to bude mít větší, komplexnější váhu. Že pořád na to bude jednou dost času. Ale tak to v životě nechodí... jednou přijde čas a uvědomíte si, že věci, která vás kdysi extrémně přitahovaly, vám najednou nic neříkají. A že pokud to neuděláte teď, tak už to neuděláte nikdy.

Přesně takovým obdobím teď procházím. Přičinil jsem se o zlom ve své kariéře a tak po 8 letech, kdy jsem dělal team leadera a souběžných 6 letech, kdy jsem se intenzivně věnoval technickému rekruitmentu, tyto dvě oblasti (dobrovolně) opouštím. A tak je tenhle článek jakýmsi rozloučením a předáním štafety.

Na začátku by měla být vize

Když dostanete možnost postavit nový tým, nebo třeba významně doplnit ten stávající, měli byste mít nějakou vizi, jak ten tým bude vypadat. Proč vize? Protože budování týmu nekončí přijímacím pohovorem. Nekončí ani po zkušební době, či úplném zapracování. Ono totiž nekončí nikdy - je to cesta, která je svým vlastním cílem. A proto potřebujete úběžník, ke kterému budete po celou dobu existence týmu směřovat.

Termín z perspektivy jsem si nevybral náhodou:
  • Vize i úběžník jsou virtuální entity, kterých v realitě nejde dosáhnout.
  • Vize i úběžník jsou "lehce pohyblivé cíle" - záleží na perspektivě, úhlu pohledu, času a pozorovateli.
  • O skutečném vývoji/postupu vypovídá historie - to když se ohlédnete zpět a uvidíte, jakou cestu jste urazili.
  • Existují nástroje, které vám ve složitem terénu pomůžou udržet směr.
Smutnou pravdou je, že většina teamleaderů a manažerů - pokud už si dali tu práci a takovou týmovou vizi si definovali - vám nebude schopna tuto vizi popsat. Samozřejmě, takový ty soft-skill/HR/people-management keci vám řekne každý. Ale to jsou jen newspeak keci.

Jestli mě Kanban něčemu naučil, tak "make policies explicit". Pro vizi to platí taky. Nemusíte ji s nikým sdílet. Ale sepište si to. Vyslovte to nahlas. Není to žádná magie, ale funguje to zázračně. Jinak budete po léta bloudit v pustinách. Vy i celý tým.

Přijímací pohovor

O (technických) přijímacích pohovorech jsem tady na blogu psal po léta. Ačkoliv to jsou, nijak překvapivě, ty nejčtenější články, jejich vliv byl minimální. Když jsem se po 5 letech vrátil na pracovní trh, byla to velmi tristní zkušenost.

Tak jako jsem v minulé sekci zdůrazňoval důležitost vize, pro pohovory platí to samé - nepokažte si to hned na začátku. Může vám v tom pomoci pár pravidel:
  • Buďte konzistentní. Všichni lidi v týmu by měli projít stejným procesem. (Ale udělejte výjimku, když to dává smysl.)
  • Udělejte technické kolo co nejbližší skutečné práci, kterou děláte. Tohle většině českých firem ještě nedošlo. Jste SW inženýři, dělejte věci racionálně a nedržte se bludných mýtů.
  • Nedělejte síto příliš úzké a husté. Nemáte ani představu, jak je život rozmanitý. Pravda, čím budete starší, tím méně věcí vás bude překvapovat. Ale stejně vždycky přijde něco, co jste nečekali (pokud jste před tím nezavřeli oči). Výjimkou z tohoto pravidla je, pokud jste si ve vizi definovali, že chcete postavit tým ze samých klonů tzv. ideálního kandidáta (mmch. to chce většina pražských firem).
  • Směřujte k vizi. Ptejte se: bude tenhle kandidát za 1/2 roku, za rok sedět do naší (týmové) vize?
 Neexistuje ideální pohovor. Pokud to s pohovorem myslíte vážně a neberete kohokoli z ulice, stojí za to se inspirovat u zkušených (článků je plný internet), něco seriózního si o tom přečíst a pracovat na tom a pohovor zlepšovat. Za sebe doporučuji třeba Esther Derby, Johanna Rothman, Gerald Weinberg, Andy Lester, či Michael Lopp (Rands in Repose).

Já jsem svůj způsob pohovorování vybrušoval pět let. Je to proces, který odpovídá mé vizi, takže pro někoho může být nevhodný. Některé věci jsou dokonce nepřenosné.

Pokud nevíte kde začít, zkuste 2-a-půl kolové schéma (obsah už si doplníte sami):
  • Phone screen. Krátký a jednoduchý technický filtr - má smysl se vidět tváří v tvář a strávit spolu víc času? (Pro inspiraci, jak jsem to dělal já.)
  • Technické kolo. Viz výše. A opět můžete nakouknout ke mně do kuchyně.
  • Netechnické kolo. Podívejte se na kandidáta i jinak, než přes technologie - není to robot. Pokud si později nebudete sedět, bude to spíš kvůli osobním, netechnickým kvalitám. Ale i tady platí "nedělejte síto příliš husté".

Neúprosná pohovorová statistika

Postavit dobrý tým je těžká makačka. Je to plnohodnotný (IT) projekt. Věc, kterou si členové vašeho týmu nejspíš nikdy neuvědomí (a spousta dalších lidí okolo), je, kolik je za tím práce, dát dohromady 5 až 10 lidí.

Po léta si vedu pohovorovou statistiku. Tady je jeden konkrétní, řekl bych průměrný rok:
  • Phone screen: celkově 46 pohovorů, z toho 33 postoupilo do dalšího kola (úspěšnost 72 %).
  • Technické interview: celkově 29 pohovorů, z toho 20 postoupilo do dalšího kola (úspěšnost 69 %).
  • Personální intervew: pro toto kolo nemám data (v grafu níže extrapoluji).
  • Do týmu nastoupilo 6 lidí. Trvalo to rok.
 
Statistika pohovorů


Ke statistice pár poznámek:
  • To že se lidi dostali na phone screen, znamená, že už byli minimálně profiltrovaný přes CV, buď interním HR, nebo agenturou. Tzn. že většinou už absolvovali headhunterský telefon. A samozřejmě prošli přes moje CV review.
  • Reálně do dalšího kola nastoupí méně kandidátů, než kolik jich bylo úspěšných (z různých důvodů nepokračují dál).
  • Interview byla během roku konzistentně rozvrstvena. Zhruba to znamená udělat za měsíc 4 phone screeny a 2-3 technická interview. A jednou za dva měsíce zapracovat nového člověka.
  • Počítejte, že ze všech lidí, kteří vám projdou pohovory, vám do týmu nastoupí cca 10 % z nich. I míň.
  • Povšimněte si poměrně vysoké úspěšnosti kandidátů v jednotlivých kolech. Domnívám se, že je to dáno tím, že jsem měl celý proces pod kontrolou a zůčastnil jsem se všech pohovorů (vyjma personálních interview). Pokud vám dělají interview různí lidé a nekonzistentně, bude neúspěšnost vyšší.

Zapracování

Fajn. Člověk vám nastoupil a dostal počítač a stravenky. Zpravidla bude nadšený a iniciativní. Neprošvihněte to! Samozřejmě, musí se naučit všechny ty procesy nástroje, projekty a produkty. Zaručeně tím ztráví celou zkušební dobu a velmi pravděpodobně celý úvodní semestr. Pokud je vaše doména složitá, může zapracování trvat i dva roky (true story).

Tohle období ubíhá tak nějak samo od sebe, samospádem. Možná to bude dost překotné. Ale nepodceňte to - je to první čas, kdy budete daného člověka opravdu poznávat. Jak pracuje, jak žije, jak se chová, jak na něj reagují ostatní (členové týmu)?

Je to jedinečné období, kdy můžete zasadit semínko kultury a pomáhat mu zakořenit a růst. Pomůžou vám v tom nástroje jako 1:1 a ochota naslouchat a řešit problémy.

Týmová kultura

Jakmile máte v týmu prvního člověka, je týmová kultura to nejdůležitější, o co byste měli jako team leadeři pečovat. Je otázka, jaká je konstelace a kolik na to budete mít reálně času. Ale pokud má tým zdravě funovat v následujících letech a překoná různé (personální, pracovní a další) krize, bude to díky živoucí kultuře. Pokud týmová kultura churaví, nebo dokonce umře (taky jsem to zažil), bude to jen o tom, jak přinést domů pytel peněz na kus žvance.

Každá kultura funguje na tom, že se lidé potkávají. Čím širší komunikační kanál, tím lepší (zdravější). Nejlépe osobně, když to nejde tak aspoň video, až pak telefon a úplně na konci instant messaging. Pokud si píšete už jen emailem, tak už vlastně nekomunikujete.

Mějte pravidelné týmové schůzky. Potkávejte se nad problémy, u jídla a (v rozumné míře) mimo práci.

Každá kultura, která se rozvíjí, má nějaké (samo)korektivní mechanizmy, historii a způsob zpracování zpětné vazby. V případě SW inženýrství máme skvělý a ozkoušený nástroj: týmové retrospektivy. Retrospektivy nemusí být jen o projektech a iteracích. Můžou mít zaměření i na tým a jeho kulturu.

Retrospektiva: team radar

Mít dobrou týmovou kulturu není nic zas až tak těžkého - chce to jen pár rutinních a pravidelných úkonů. Jako když pečujete o zahrádku. Když to zandedbáte, začne vám zvolna zarůstat plevelem. V určitý moment se může stát, že se vám zahrádka vylidní. Přeju, ať se to nestane.

Související články


29. ledna 2018

Spring Security, SAML & ADFS: Implementace

Posledně jsme se vyřádili na konfiguraci, tak teď už jen zbývá to nabouchat v tom Springu, ne? Dobrá zpráva je, že pokud budete následovat Reference Documentation, bude vám Spring SAML a ADFS fungovat out-of-the-box.

Špatná zpráva je, že pokud budete chtít použít Java configuration, nemáte se moc kde inspirovat. Pokud vím, tak k dnešnímu dni jsou k dispozici jen dva příklady:
Dalším benefitem mého příspěvku a ukázkového projektu je, že používají aktuální verzi Spring Frameworku a Spring Security, tedy verzi 5 (v tomhle asi budu chviličku unikátní). Třešničkou na dortu je pak buildování pomocí Gradle (protože kdo by ještě chtěl v dnešní době používat Maven, že jo? ;-)

Závislosti

Pro zdar operace budeme potřebovat následující závislosti:

Drobná Gradle poznámka: Protože používám současnou verzi Gradlu, používám konfiguraci implementation. Pro starší verze Gradle (2.14.1-) použijte původní (nyní deprecated) konfiguraci compile.

Spring SAML Configuration

Ať už se použije XML, nebo Java konfigurace, bude to v každém případě velmi dlouhý soubor. Velmi. I když nebudu počítat téměř 40 řádek importů, i tak zabere ta nejzákladnější konfigurace zhruba 5 obrazovek. Víc se mi to ořezat nepodařilo.

Ale nebojte se, nebudu vás oblažovat každým detailem. Jen vypíchnu to zajímavé, vynechám co jsem zmiňoval v minulém díle o konfiguraci a pro zbytek konfigurace vás odkážu do svého repozitáře, kde si to můžete vychutnat celé: SecurityConfiguration.java.

Nastavení HttpSecurity

Nebudu příliš zabíhat do podrobností, jak funguje samotné Spring Security (prostě chrání pomocí filtrů určité URL/zdroje) a podívám se na jedno konkrétní nastavení:

Uvedené nastavení definuje:
  • Vypnuté CSRF. U SAMLu nedává CSRF moc smysl - SAML requesty jsou podepsané privátním klíčem daného SP, jehož veřejný klíč je zaregistrován na použitém IdP.
  • Přídání dvou filtrů: jeden pro SAML metadata (metadataGeneratorFilter), druhý řeší samotný SAML mechanismus (samlFilter).
  • Definice URL, které vyžadují autentikaci (/user). 
  • Podstrčení SAML entry pointu namísto přihlašovacího formuláře (loginPage("/saml/login")).
  • Přesměrování na root kontext aplikace po úspěšném odhlášení (logoutSuccessUrl("/")).

SAML filtry

Základem jak Spring Security, tak Spring Security SAMLu jsou filtry - odchytí HTTP(S) komunikaci a transparentně aplikují zabezpečení aplikace. V případě SAMLu je těch filtrů celá smečka, ale v zásadě řeší jen tři věci: přihlášení (SSO), odhlášení (SLO) a metadata. Čtvrtým mušketýrem může být ještě IdP discovery, ale tu v našem případě nemáme.


Key manager

Všechny SAML zprávy, jež si IdP a SP vyměňují jsou podepsané privátním klíčem dané strany. Doporučuji mít pro SAML podpisový klíč separátní key store (nemíchat ho třeba s key storem, který potřebuje aplikační server pro HTTPS).

V naší ukázkové aplikaci je SAML key store na classpath - v jakémkoli jiném, než lokálním vývojovém prostředí, key store samozřejmě externalizujeme (nepřibalujeme do WARu) a hesla kryptujeme.


Podepisování SHA-256

V minulém díle jsem zmiňoval, že Spring SAML defaultně používá při podepisování algoritmus SHA-1, kdežto ADFS očekává SHA-256. Jedna strana se musí přizpůsobit. Doporučuji upravit aplikaci - použít SHA-256 není nic těžkého.

Výběr podpisového algoritmu se provádí při inicializaci SAMLu pomocí třídy SAMLBootstrap, která bohužel není konfigurovatelná. Pomůžeme si tak, že od třídy podědíme a potřebný algoritmus podstrčíme:

V konfiguraci pak třídu instancujeme následujícím způsobem. Mimochodem, povšimněte si, že beana je instancovaná jako static. To proto, aby inicializace proběhal velmi záhy při vytváření kontextu.


That's All Folks!

Tím se náš 3-dílný mini seriál o Spring Security, SAMLu a ADFS uzavírá. Samozřejmě, že bych mohl napsat ještě mnoho odstavců a nasdílet spoustu dalších gistů. Ale už by to bylo jen nošení housek do krámu.

Lepší bude, pokud si teď stáhnete ukázkový projekt sw-samuraj/blog-spring-security, trochu se povrtáte ve zdrojácích a na závěr v něm vyměníte soubor FederationMetadata.xml a zkusíte ho rozchodit vůči vašemu ADFS. Při troše štěstí by to mělo fungovat na první dobrou :-)

Jako bonus pro odvážné - pokud se opravdu pustíte do těch zdrojových kódů - můžete v historii projektu najít další Spring Security ukázky (je to celkem rozumně otagovaný):
  • Výměna CSRF tokenu mezi Springem a Wicketem (tag local-ldap).
  • Multiple HttpSecurity - v jedné aplikaci: autentikace uživatele přes formulář a mutual-autentication REST služeb přes certifikát (tag form-login).
  • Autentikace vůči lokálnímu (embedovanému) LDAPu (tag local-ldap).
  • Autentikace vůči Active Directory (tag remote-ad).

Související články


17. ledna 2018

Spring Security, SAML & ADFS: Konfigurace

Minule jsme se podívali - z obecnějšího pohledu - jak SAML funguje pro autentikaci aplikace. Kromě toho, že byste měli znovu zkouknout ty pěkné barevné diagramy, zobrazující SSO (Single Sign-On) a SLO (Single Logout), by se vám mohl hodit SAML a ADFS slovníček - od teď už očekávám, že termíny máte našprtané ;-)

Tenhle článek se bude zaměřovat na konfiguraci potřebnou pro to, aby nám SAML autentikace fungovala. V realitě pak tato konfigurace půjde nejčastěji ruku v ruce s implementací, protože abyste získali SP (Service Provider) metadata, budete potřebovat ho mít už funkční (pokud nejste SAML-Superman, který to zvládne nabouchat ručně, nebo externím nástrojem).

Registrace metadat

Aby nám SAML fungoval, musíme nejdřív vzájemně zaregistrovat jednotlivé IdP (Identity Providery) a SP (Service Providery). Jak jsme si říkali v minlém díle, vztah IdP - SP může být M:N, nicméně pro zbytek článku (a i v tom následujícím) budeme uvažovat jenom vztah 1:1, tedy náš SP (aplikace) se autentikuje vůči jednomu IdP.

Registrace metadat se může provést dvojím způsobem - buď můžeme poskytnou URL, na kterém si IdP/SP metadata sám stáhne při svém startu, nebo (asi častější) metadata poskytneme jako statický soubor. Zde budeme pracovat s druhým případem.

Registrace (ADFS) Federation metadat

Registrace Federation Metadat je jednoduchá - stáhneme XML soubor z daného URL a protože pro implementaci SP používáme Spring Security SAML, poskytneme ho jako resource pro MetadataProvider.

Metadata na ADFS serveru najdeme na následujícím URL:

Federation Metadata je dlouhý, ošklivý XML soubor. Způsob, jak ho poskytnout naší aplikaci je trojí:
  • dát ho na classpath a načíst třídou ClasspathResource
  • dát ho na file systém a načíst třídou FilesystemResource
  • načíst ho přímo z ADFS třídou HttpResource

Pokud např. soubor FederationMetadata.xml umístíme do adresáře src/main/resource/metadata, můžeme ho načíst následujícím způsobem:


Pokud potřebujete trochu víc (Spring) kontextu, může se podívat do kompletní Spring SAML konfigurace:

Registrace (Spring) SAML metadat

Registraci SAML metadat na ADFS si rozdělíme do dvou kroků:
  • Získání metadat z aplikace.
  • Registraci metadat na ADFS.

Generování SAML metadat (z aplikace)

Tady přichází ke slovu, co jsem předesílal - abyste byli schopný si vygenerovat SAML metadata, budete potřebovat mít Spring SAML aspoň částečně naimplementovaný. O generování metadat se stará Springovský filtr MetadataGeneratorFilter.

Generování metadat out-of-the-box funguje dobře (a s ADFS ho rozchodíte). Pokud chcete, nebo musíte metadata upravit, tohle je to správné místo. Například specifické (SP) Entity ID se dá nastavit tímto způsobem:


Filter pak necháme naslouchat na určitém URL endpointu, kde nám bude metadata poslušně generovat:


Situace je samozřejmě trochu složitější, takže pokud jste netrpělivý, nebo vám chybí potřebné Spring beany, nahlídněte do zmiňované SecurityConfiguration.java.

Ještě než si metadata vygenerujete a stáhnete z daného URL, jedno důležité upozornění! Při nesplnění následujících podmínek vám SAML před ADFS nebude fungovat.
  • Na URL musíte přistoupit přes HTTPS (a mít tedy odpovídajícím způsobem nakonfigurovaný aplikační server/servlet kontejner).
  • Na URL musíte přistoupit přes hostname nebo IP adresu, které jsou z IdP (ADFS) viditelné. (Takže ne https://localhost.)

Registrace metadat na ADFS

Teď se magicky přenesema na ADFS server (typicky přes Remote Desktop), kam si zkopírujeme vygeneraovaný SAML metadata soubor. Spring ho defaultně nazývá spring_saml_metadata.xml, nicméně na jméně nezáleží.

V AD FS Management konzoli nás bude zajímat jediná věc - položka Relying Party Trust, kde metadata našeho SP zaregistrujeme, resp. naimportujeme.

AD FS Management konzole

Import metadat se provádí pomocí wizardu (jak jinak ve Windows). Je to jednoduché a přímočaré: zadáme import ze souboru a pak už se jen doklikáme nakonec:

Import SP metadat ze souboru

V závěrečném shrnutí je dobré si zkontrolovat, že v sekci Endpoints jsou splněny dvě výše uvedené podmínky (HTTPS a hostname/IP adresa):

Kontrolní shrnutí SP endpointů

ADFS defaultně očekává, že hash algoritmus použitý při podepisování SAML zpráv bude SHA-256. Bohužel, Spring SAML posílá out-of-the-box SHA-1. Máte tedy dvě možnosti:
  • Upravit Spring SAML, aby používal SHA-256 (jak to ohackovat vám prozradím příště),
  • nebo říct ADFS, aby očekávalo SHA-1.

Nastavení Secure hash algorithm najdete po rozkliknutí Properties na záložce Advanced (je potřeba to udělat dodatečně - při importu metadat je tato volba nefunkční):

Nastavení Secure hash algorithm

Pokud si to na obou stranách nesladíte, budete na straně Springu dostávat nic neříkající výjimku:
2018-01-17 12:15:01 DEBUG org.springframework.security.saml.SAMLProcessingFilter - Authentication request failed: org.springframework.security.authentication.AuthenticationServiceException: Error validating SAML message
org.springframework.security.authentication.AuthenticationServiceException: Error validating SAML message
        at org.springframework.security.saml.SAMLAuthenticationProvider.authenticate(SAMLAuthenticationProvider.java:100) ~[spring-security-saml2-core-1.0.3.RELEASE.jar:1.0.3.RELEASE]
        at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174) ~[spring-security-core-5.0.0.RELEASE.jar:5.0.0.RELEASE]
Caused by: org.opensaml.common.SAMLException: Response has invalid status code urn:oasis:names:tc:SAML:2.0:status:Responder, status message is null
        at org.springframework.security.saml.websso.WebSSOProfileConsumerImpl.processAuthenticationResponse(WebSSOProfileConsumerImpl.java:113) ~[spring-security-saml2-core-1.0.3.RELEASE.jar:1.0.3.RELEASE]
        at org.springframework.security.saml.SAMLAuthenticationProvider.authenticate(SAMLAuthenticationProvider.java:87) ~[spring-security-saml2-core-1.0.3.RELEASE.jar:1.0.3.RELEASE]

A na straně ADFS nápomocnější:
Microsoft.IdentityServer.Protocols.Saml.SamlProtocolSignatureAlgorithmMismatchException:
    MSIS7093: The message is not signed with expected signature algorithm.
    Message is signed with signature algorithm http://www.w3.org/2000/09/xmldsig#rsa-sha1.
    Expected signature algorithm http://www.w3.org/2001/04/xmldsig-more#rsa-sha256.
Takže, prozatím SHA-1. "Dvě stě padesát šestka" bude příště ;-)

Claim Rules

Poslední věc, kterou zbývá nastavit je mapování claims na assertions. Na naší nově vytvořené Relying Party Trust dáme Edit Claim Rules... a přidáme následující pravidlo, které nám z Active Directory vytáhne Name ID a doménové skupiny daného uživatele:

Editace Claim Rules

To be continued...

Tak a máme hotovo! Teda konfiguraci. Ovšem, jak už jsem naznačoval, v tento moment už stejně většinou máte hotovou i zbývající implementaci, takže pokud jsme nic neopomněli, mělo by nám fungovat jak SSO, tak SLO, přesně podlě těch krásných diagramů z minulého dílu.

V příštím, závěrečném díle, se podíváme, jak nabastlit zbytek Springovských věcí - můžete se těšit na Java konfiguraci (což je zatím vzácnost, protože Reference Documentation stále jede na XML) a samozřejmě pofrčíme na aktuálním Spring 5 (Cože?!? Vy jedete ještě na čtyřce?! No, nekecej 8-)