Posted on

Another step on the road.

I got the A1-A3 and A2 drone license.
(and I’m not stopping there…)
Got around to doing the second part, going for the A2, and if you are thinking of getting your drone training and license, take a look here:
https://www.dronelicense.eu/

Very good and effective training material, allowing you to work at your own pace, and most importantly,
get there, and get properly licensed across EU.

  • It’s formal,
  • It’s real,
  • It’s official.
  • It’s valid across all of EU.
    (please note that you will need to register as a pilot in at least one EU country, and some require individual national registrations)

Ok, ok… so what are the rules?!

You can effectively sum it up as:

  • A1: fly over people but not over assemblies of people
  • A2: fly close to people
  • A3: fly far from people (heavyweight drones are limiting this)

This is a EASA (European Aviation Safety Agency) summary of drone classes and rules. 

EASA information:
https://www.easa.europa.eu/en/domains/drones-air-mobility/operating-drone/open-category-low-risk-civil-drones

Posted on

Contractor vs Employee?

Consultants/Contractors vs Employee – A side by side comparison

Which one? Or both?
A seemingly never-ending and long-standing dilemma for many decision-makers and businesses is whether to use employees or consultants/contractors (hereafter, contractors).

When choosing between contractors and employees, it’s a common perception that contractors are for short-term and employees are for long-term commitments, and contractors are very expensive, but this does not generally hold true as of today.

In either case, one needs to consider real factors like flexibility, cost-effectiveness, and specialized expertise. Contractors offer targeted skills ideal for equally short-term specific projects without long-term commitments, or general long-term commitments and continuity, if properly managed by the provider, while employees has the ability to bring continuity and deeper integration into your organization’s culture. It is all down to what your priorities and goals are.

Shifting preferences. 
Also, in today’s world, the sentiment of many highly skilled and professional workers have shifted a lot as of recent years, with them becoming contractors rather than employeers, and being a contractor have become a new common form of employment, offering a greater flexibility as seen to the business side of things, and one that can equally come to become a longer term part of the business with an equal level of commitment, if done right.

The longevity of commitment claim is especially at stake here, as it is today common for employees to change jobs in the range of every two to four years, sometimes more often, negating the long-term engagement claim, and price-wise, there is not much of a realistic difference between the two anymore. 

The net result of this, speaks in favor of the contractor, not just purely from the business perspective.

Side by side:
Take a look at these two quick summaries, side-by-side examples on comparable levels: 

Contractor/Consultant
Contractor: 550/day over 44 weeks.

No additional costs of:

  • Paid holidays
  • Sick leave
  • Employer NI
  • Pension match
  • Bonuses
  • Training

Benefits (their selling points)

  • Flexibility
  • Preserved continuity by well-managed service provision
  • Pre-defined documented skills and knowledge
  • Little to no onboarding costs/time.
  • Only paid for days working
  • Break clauses based on work
    or project requirements.
Employee
Permanent employee: 75K salary over 44 weeks.

Additional costs to consider:

  • Employers NI  ~10%-15% (7,500 – 11,250)
  • Pension match  ~5% (750)
  • Bonus ~10% on average (7,500)
  • Recruitment fee ~15-20% (11,250 – 15,000)
  • Statutory 20 days PTO (or more)
  • Statutory sickness leave (up to ~15 days)

Other types of common costs (benefits) include (estimates per year):

  • Private Medical/Dental Insurance,
    €500 – €3,000
  • Voucher Schemes, €500-€2,500
  • Employee Wellbeing Programs,
    €100 – €1,000+.
  • Away Days, Parties, and Events,
    €50 – €500+ per-event. (3/y)
  • Equipment and Tech Costs, €500 – €2,000

Office space average cost across EU p/a and employee: €7500 (range: 3.9-15k/y)
This includes rent, maintenance, supplies. 

Total: 550/day for 44 weeks – €121K  Total Year 1: €121 – €148K (€134.5k)
Total Year 2+: €108 – €135k (€121.5k)

Today, and so far in this comparison, it is pretty much like-for-like, cost-wise, but with added benefits for both parties, but it does not stop there. 

The contractor, in greater self-governance, albeit at somewhat greater risks and contractual committments, and for the business, it’s a more well-defined commitment with a known entity and lesser set of risks in cases of non-performance and similar issues. 

The hidden costs:
Additionally, there are likely considerable company overheads in HR, Legal, and compliance due to the costs required to maintain employee records, manage disputes management, conduct reviews, provide training, and many other functions. These are commonly not required for contractors, due to their contractual self-governance.

It doesn’t stop there,  as for the staff, the business usually has other overheads not covered in the above, such as parking, office space, heating, energy, office supplies and additional factors that needs to be added to the costs of the employee, which for the contractor is mainly or wholly covered by themselves at their own expense. The cost of this has been summarized above as a range, and is based on 15sqm/employee and year, as an average across EU, for both cowork and outright rented spaces. 

As for the longevity and company culture, the relatively small cost of including contractors to company events, parties, etc, will be greatly outweighed by the benefits, and still be a tax-deductible, as it is  now supplier entertainment. One just needs to be careful about the anti-bribery regulations. 

As you can see, after the first year, contractors and employees are on par or cheaper, without the loss of productivity or protection for your business, and in the end, with all things considered, it is a win-win situation for both parties, business and contractor, offering the greater flexibility.

Summary: 
If you take all of the hidden business overheads as listed above into account, you will likely soon see that the contractor is actually the cheaper option overall, with the same or greater business benefits.
The primary question now comes down to:

  • Are you willing to have consultants and allow them to work remotely? 
  • Are you willing to trust the people you hired to work for you, to do their job? 

If the answer is yes, then, you have just widened your recruitment basis and access to qualified staff. 

Posted on

CICD – passwords and settings to config?

… and keeping them out of the code in GIT? 

Let’s say you have a larger config file with a pile of items that you want to fill in while deploying, but don’t want to keep in git, such as settings or credentials?

At the same time, you want to test things while developing, without having to set up credentials etc all the time, copying files in and out, or quickly configure things for deploying / testing against different targets..

This obviously does not take away from the use of live secret management,
such as aws secrets manager and others, but is suitable for more “static” solutions,
or fundamental configurations required for base setups.

For the local shell, add the following to your .bashrc or similar:
alias 1passlogin="eval \$(op signin)"

Pre-requisites; 

Steps: 

  • Create a new vault in the 1Password, like “CICD”
  • Create the item, and name it as you please, no spaces in the name, like.. “app-config”.
  • In the item, say a secure note called ‘general-creds’ , create a field and name it “json”. 
  • In this json field, store the json as an array of key/value sets, like this: 
    {
       "cred": [
            { "key_1": "value 1" }, 
            { "key_2": "value 2" }, 
            .... and so on. 
       }
    }
  • and this shellscript; 
    #!/usr/bin/env bash
    ROOT="$(dirname "$(realpath "$0")")"
    
    # Check if the required arguments are provided
    if [ "$#" -ne 2 ]; then
       echo "Usage: $0 <1pass vault/item> <template_file>"
       exit 1
    fi
    
    # Read the JSON file and template file
    path="$1"
    template_file="$2"
    
    # Get the credentials from the 1Password
    op read "op://${path}/json" > 1p-credfile.json
    
    # Validate that the JSON file exists
    if [ ! -f "1p-credfile.json" ]; then
        echo "Error: JSON file '1p-credfile.json' does not exist."
        exit 1
    fi
    
    # Validate that the template file exists
    if [ ! -f "$template_file" ]; then
        echo "Error: Template file '$template_file' does not exist."
        exit 1
    fi
    
    # Read the JSON content and template content from the files
    json="$(cat "1p-credfile.json")"
    template="$(cat "$ROOT/$template_file")"
    
    # Use jq to traverse the JSON array and replace placeholders
    result=$(echo "$json" | jq -r --arg template "$template" '
       reduce .cred[] as $item ($template; 
       reduce ($item | to_entries[]) as $kv (.;
         gsub("\\[\\[" + $kv.key + "\\]\\]"; $kv.value))
       )
     ')
    
    # Output the replaced string
    echo "$result"
    
    # Clean up after ourselves. 
    if [ -e 1p-credfile.json ] ; then rm -f 1p-credfile.json ; fi
  • .. and a config template file (or other file), like this, inserting the key names in double hard brackets, such as [[keyname]]
    {
       "configValue1": "[[key_1]]",
       "configValue2": "[[key_2]]"
    }

Putting it all to work… 

In your Makefile or similar, use the script as: 

./MapCreds-onepass.sh “<vault>/<item>” “<source_file>”  > “<target_file>”

Example: 

./MapCreds-onepass.sh CICD/app-config config-template.json > config.json

and the output – config.json, would become ;

{
   "configValue1": "value 1",
   "configValue2": "value 2"
}

… just don’t forget to mark the resulting “config.json” as an exluded file in git!
(and obviously, this would work on other text files as well,  including source code for replacing values / settings having the source in 1pass.)

Njoy!

Posted on

Application rewrites?

Legacy applications…

… the regular pain in everyone’s back.

Do you have a legacy application application that needs updating or even a rewrite?

The failure of application rewrites often involves a combination of factors, and among these are the following common culprits and factors, being the primary reasons for the failure – not the language it is written in, or the conversion from one language to another or that language not being able to do the work of the other language.

Any turing complete language could do the job, literally, even such a hellish language as brainf*ck..

This shows that the language in itself, is not the problem, and it more often than not comes down to being a case of – what is the right tool to do the job?

I prefer working with Go, as it is a modern language that works equally well on almost any platform, and it is fast to develop and get working results in.
It also has the benefit of being close enough to many other languages, that devs of those, can understand it without any issues.

Also, Go, does typically not really have the inherent issue that many other languages like Python, Java or C++ suffers from with the “legacy library hell”, as it has a modern take on this, with efficient ways of keeping up to date through various mechanisms.

So what IS the big issues then?

Let’s say we start with a classic “problem child” of yesteryears – COBOL, symbolizing the language landscape of more “mature” languages, and using this as an example, as the very same core issues can be applied to pretty much any language.

It really doesn’t matter what the language is, but the underlying problems are commonly the same for all legacy applications.
Lets look at a few key points. 

1. Lack of Documentation and Knowledge

  • Legacy systems like COBOL often lack detailed, up-to-date documentation. Over time, original developers may leave, and institutional knowledge is lost.
    This often enough comes from the claim that code is the documentation in itself. This has never been true, nor will ever be true.
    The the code is merely the implementation of the specification and what you did, and never the documentation itself, this specifically as the code itself never describes the original intent of what you set out to do. I will accept documentation to be in the code on the condition that, the comment proceeding the code block explains your Intent and what you plan to achieve, returns etc before you actually write the code. This helps maintainability, as now you can check against this common if it actually does what you said it will do.
  • Business rules, logic, and workflows are often “baked into the code” without external references, making it hard to replicate functionality correctly.
  • Another common example in many Legacy applications is the use of “Magic values”, poorly or undocumented numbers that has specific meanings, But is commonly used throughout the code and will changing such a value can have catastrophic effects. Especially where you do not expect it.

2. Underestimating System Complexity

  • These systems have grown organically over decades, often integrating with other systems and processes in undocumented or implicit ways, sometimes using protocols that no longer exists or is poorly documented by themselves, and this is specifically the often the case in the use of proprietary protocols, and even more so when custom hardware is involved, never mind the eternal curse of undocumented storage formats, and especially binary such.
  • Dependencies are not always well understood, leading to gaps in the new implementation.

3. Scope Creep and Poor Requirements Gathering

  • Stakeholders might not fully articulate all requirements or fail to prioritize them.
  • The rewrite team might inadvertently “over-simplify” or “over-engineer” the replacement, causing mismatches with actual needs.
  • While there may have been initial documentation, often new additions and rewrites will rarely or never capture the changes in documentation, as many developers still thinks “code is the documentation”.
    I have never, even until today, seen documentation being a priority to any greater extent in any commercial Products, with the exception of mission critical systems such as aerospace, oil industry, nuclear, and to some degree medical or similar, and even thenThis is often not by any other means then force of regulation. From what I have seen over my years, so far, anything in the financial industry, looks more like a joke, than anything else.

4. Mismatch Between New and Existing Systems

  • COBOL systems often interact with old, niche hardware and protocols that are difficult to replicate or interface with modern platforms.
    See my previous point.
  • Rewrites might inadvertently introduce performance bottlenecks or fail to handle edge cases that the legacy system managed, and again this is often down to poorly understood original requirements and specifications that may not even original requirements and specifications that may not even be available anymore, together with the fact that many developers simply will not together with the fact that many developers simply will not sit down and read such documentation to actually understand what the code does originally.
    On a commercial side, there is rarely time allocated for any of this anyway, and you end up paying for it over and over again often to costs exceeding what it would have taken to allocate the time initially, doing it as right as you can, from start

5. Cultural and Organizational Resistance

  • Organizations often resist change, especially when it involves mission-critical systems.
  • Lack of buy-in from stakeholders or fear of disrupting operations hampers the process.

6. Testing Challenges

  • Legacy systems often run for years without interruption, with real-time updates and transactions.
    This concept often introduces the fact that you actually have no clear understanding of what’s actually and really running in the machine, especially when hot patches has been applied.
    While it can be simple enough for small systems, with bigger systems the complexity often grows exponentially.
  • Rewriting introduces risks, and testing environments struggle to replicate the production workload, leading to missed issues.

7. Skill Gaps

  • Teams tasked with rewriting may lack knowledge of legacy systems and their quirks.
  • Similarly, COBOL developers might not be part of the rewrite team, leading to a disconnect between old and new paradigms, including lack of knowledge transfer and especially so for the original intent and meaning of certain things.

8. Cost and Time Overruns

  • Rewrites frequently underestimate the effort required, both in terms of budget and time.
    This is often down to poor pre-analysis and understanding of the complexity of the task.
    A rewrite is almost always more complex than writing a new application from start, because of all the hidden complexities.
  • Incremental delays add up, and as costs mount, projects are abandoned or deemed infeasible.

9. Failure to Preserve Legacy Business Logic

  • Legacy systems encode decades of evolving business logic.
  • Translating this logic accurately to new systems without introducing errors is extremely challenging.
  • As a consultant on such matters, I often come to the point where the recommendation will be to simply start over, writing the functionality from a clean start, based on the existing perception of, and the requirements for the business logic.
    For such projects documentation (specification, documentation, and intent comments in the code) is always a high priority for future maintainability.

Key Point: Lack Of Documentation Amplifies All Other Problems

When documentation is lacking, every other issue is compounded:

  • Reverse engineering logic consumes enormous time and resources, and the risk some missing quirks, hidden behaviors etc becomes increasingly large as the by the complexity in size of the application.
  • Testing becomes harder because edge cases are unknown.
  • Training new developers is significantly more difficult.

Solution Approaches?

  • Incremental Modernization:
    Instead of a full rewrite, gradually modernize and refactor specific components.
    Where possible, break out the individual piece and serve it in a new setting.
    One issue at a time.
  • Automated Code Analysis:
    Use tools to extract business logic and system dependencies.
    This is one of the things where AI tools can actually make sense, to capture very complex logic behaviors, putting them into simpler words and shortened versions, that’s easier to understand, Giving the developer a head-start understanding of what they are looking at.
  • Collaborative Teams:
    Combine legacy system experts with modern tech specialists.
    Not leaving the “legacy teams” behind. They can be absolute key to your success of the rewrite!
  • Prioritize Documentation:
    All documentation should focus on practical maintainability. 

    Document as much as possible before starting the rewrite and throughout the process.
    The documentation and specification is, in the end the benchmark and test specification, to which you measure “are we there yet”?
    Do we have the correct and expected behavior?
    Also, for the documentation, don’t overdo it.
    There is a very valuable balance between detail and general overview.
    The specificiations should be the absolute, non-negotiable requirements.
    The maintenance documentation, should be practical how-to’s with necessary examples and details.
    The protocols and data items should be explained in detail, as this is the basis of all logic.
    The data flows should be made clear between the components.NB!!
    The code is the explicit implementation – NOT documentation.
    I am sorry, but if you claim that the code IS the documentation, you are wrong, for the very reason that anyone can read what you did, but not what you intended to do, and because of this, you should always write “intent documentation” as a block before the actual code, and before you write the actual code. This way, you or anyone else have a fightng chance of correcting mistakes made.
    This intent documentation often happens to be the same as the specification, and now, it becomes relatively easy to compare the intent to implementation, to see where the bug is.

Why Modern Languages Like Go?

  • Go offers significant advantages for rewriting legacy systems:
    • Simplicity: A minimalistic design reduces complexity, making it easier for teams to adopt.
    • Concurrency: Built-in support for concurrency enables efficient handling of modern workloads.
    • Performance: Go’s compiled nature ensures high performance, rivaling C/C++ in many scenarios.
    • Deployment: Go’s single-binary model simplifies deployment processes, especially in cloud-native environments.

Conclusion

Rewriting an application is a significant undertaking, but with careful preparation, stakeholder alignment, and the use of modern tools and languages, it can transform outdated systems into robust, efficient platforms. By addressing risks head-on and employing best practices, organizations can successfully modernize their applications while minimizing disruption and maximizing value.

Do you have legacy applications that needs reworked, modernized or documented?
.. all while using modern tools, technologies, and keeping future maintainability and support in mind?

Let’s talk.

Posted on

New flights!

It’s a quick, rough and dirty edit of some footage after the improved settings of the camera.
Please forgive the movements as I am still bugging about, getting to know the drone… It’s a journey…

Next one up will be likely be goggle flight, unless I get some noice views getting in the way before that… =D

The weather for the next few days promises high winds and rain, so, if i don’t fly and post,
you know why – I won’t do unsafe flights…

We do all our flights in line with regulations.

Safety, and doing it right, first…