yaroslaff / showcert

Simple OpenSSL for humans: all you need for X.509 TLS certificates (and nothing more).
MIT License
74 stars 5 forks source link

missing dependency on cryptography? #4

Open FelixSchwarz opened 3 months ago

FelixSchwarz commented 3 months ago

The code uses the cryptography module quite a bit but it is not listed as a dependency in setup.cfg. Did I overlook something?

yaroslaff commented 3 months ago

showcert uses pyproject.toml for packaging. cryptography installed as dependency for other package (pyopenssl). But since showcert uses cryptography directly, I added it as direct dependency. Also, pinned versions for all requirements. New version of showcert (0.2.4) uses pinned requirements:

    'cryptography==43.0.0',
    'pyopenssl==24.2.1',
    'pem==23.1.0',
    'certifi==2024.7.4'

Let me know if you need any help :-)

FelixSchwarz commented 3 months ago

Thank you for adding the dependency.

I have to say that pinning of exact versions is a bit inconvenient unless you run showcert in a separate environment.

For example in Fedora you will be able to install showcert just by running dnf install showcert. However that uses whatever versions Fedora ships (usually the latest ones). I can of course patch the code to handle that situation but it is an extra step that causes some extra effort. At the same time as a Linux packager I am relying on upstream maintainers like you to tell me which versions are absolutely required (as there are too many packages out there for me to understand in detail).

In my opinion version pinning should only be used if you know exactly where the software is being deployed (e.g. inside a single company) and even there you should be really careful (for example what happens if another team wants to use the library in a different setting?).

I prefer only specifying the "hard" dependency versions, for example because you need a certain API and that is only present in Version X. Or maybe Version Y removed some mechanism your software still needs. In particular these versions are not necessary what is "tested" or "supported" (if I can help it -> when coding just for fun instead of being tied to contracts and SLAs).

My "best practice" for in-house software with exact version pinning looks like this: In development I just say "crytography > 42". When I do a release the GitHub workflow (Azure pipeline, ...) pins the versions to an exact number, does a git commit + tag, builds the wheel (with exact dependencies burned in) and reverts the version restrictions back to the pre-release state.

Anyway, way too long post, the gist is: Could you maybe reconsider your version restrictions?

yaroslaff commented 3 months ago

Yes, usually I install it via pipx, so it runs in virtual environment, but I'd be happy if showcert will be easy to install in Fedora.

I do not use Fedora, so have a question - if you do "dnf install showcert" it installs python package globally, similarly to "pip3 install showcert" would do?

Are any package versions preferred for Fedora? e.g. maybe cryptography/pyopenssl/pem/certify ver A.B.C is installed by default so I can use it as minimal version requirement? if yes, which ones? I can test showcert with this particular versions and require version higher or equal for showcert. (so it will be compatible).

I could leave dependency without any version specification at all but I'm almost sure it will not work with ancient versions of dependencies, so maybe better way is to have >= / > requirement starting from some popular version? Or I can use current version, just change == to >= ?

FelixSchwarz commented 3 months ago

I do not use Fedora, so have a question - if you do "dnf install showcert" it installs python package globally, similarly to "pip3 install showcert" would do?

Yes. The executables are available in /usr/bin after installation.

Are any package versions preferred for Fedora? e.g. maybe cryptography/pyopenssl/pem/certify ver A.B.C is installed by default so I can use it as minimal version requirement?

Well, the installed versions will be different for each supported version:

In addition there is Fedora EPEL ("Red Hat Enterprise Linux") and I would like to add "showcert" at least to the current version (EPEL 9 with Python 3.9).

The Fedora Python packagers will try to ensure that a core set of packages (e.g. cryptography, requests, babel, Cython, ...) are compatible with each other and the system versions (e.g. openssl, Python). The remaining Fedora packagers will take care of lesser used packages. One advantage upstream maintainers get for free is that we test packages with new Python versions really early. I think the first "test rebuild" for Python 3.13 was in January this year.

Usually in Fedora we keep versions of important packages stable for a given release. For example Fedora 40 ships cryptography 41 and only the next version of Fedora will ship cryptography 42. (Some packages are upgrading in a "rolling release" manner like the Linux kernel.)

You can check the versions for different releases yourself:

Other distributions have other policies and schedules. So the ideal solution for me is just to specify a minimum version if you really need a specific API. If you bump this version requirement every time you start using a new API, this gives a lot of value to "git blame" because as a packager I can also look through these changes and determine why a certain version was required (sometimes I implement a custom workaround if I really need to make the software work with an older version).

That being said, using >= or ~= is much more convenient for me than exact pinning.

While this might sound pretty "Linux specific" I found that "only specify minimum versions" also helped me in a professional context. Many times teams need to use closed-source vendor tools and all kinds of internal software. Having to each and every small utility in its own docker container/environment is really annoying and causes a lot of effort.

On the other hand I understand that there might be an uncomfortable feeling if there are no version restrictions at all. My personal rule of thumb is to check how many times old requirements caused bugs in my environment/how many support requests I got which were resolved by just upgrading the dependencies.

FelixSchwarz commented 3 months ago

Oh, btw: Let me express my gratitude for coming up with showcert. This tool was really, really helpful for me, especially when deploying mail server certificates.

FelixSchwarz commented 3 months ago

One more comment about tests: As a packager having some automated tests are really helpful, provided they can run offline (network is shut down when building Linux packages for security reasons). We try to run test suites on every build and ideally this detects potential incompatibilities with new versions of Python, cryptography, ... even before a single user gets the new packages.

yaroslaff commented 3 months ago

I published showcert 0.2.5

  1. dependencies now unpinned and uses >= syntax, using oldest version supported by Fedora (tested, it works)
  2. I split tests to two files test_local.py and test_remote.py, you can run pytest tests/test_local.py to run only local test (without network).

Let me know if this works for you or if you need any fixes.