Repository: microsoft/garnet
File: libs/host/Configuration/Redis/RedisOptions.cs (C#)

Code before:
namespace Garnet
{
    /// <summary>
    /// This class contains all redis.conf settings that have a matching configurable setting in Garnet's Options class.
    /// In order to add a new redis.conf setting:
    /// 1. Verify that the matching Garnet setting is defined in Options.cs
    /// 2. If a custom type is necessary (e.g. enum), use existing or create a new one under RedisTypes.cs 
    /// 3. Add a new property and decorate it with an RedisOptionAttribute, pointing it to the matching Options property name.
    /// 4. If a type conversion is needed to convert between the Redis option and the Garnet option,
    ///    use existing type converters or add a new one under TypeConverters.cs
    /// 5. If a more complex transformer is needed to transform the Redis option and the Garnet option,
    ///    use existing type converters or add a new one under GarnetCustomTransformers.cs, and add its type to the RedisOptionAttribute
    /// </summary>
    internal class RedisOptions
    {
        private const string BindWarning = "Only first IP address specified in bind option is used. All other addresses are ignored.";
        private const string TlsPortWarning = "tls-port option is used only to determine if TLS is enabled. The port value is otherwise ignored.";
        private const string TlsCertFileWarning = @"When using tls-cert-file make sure to first convert your certificate format to .pfx. 
Specify your passphrase in the tls-key-file-pass option (or via the cert-password command line argument), if applicable. 
Specify your subject name via the cert-subject-name command line argument, if applicable.";

        [RedisOption("bind", nameof(Options.Address), BindWarning, typeof(ArrayToFirstItemTransformer<string>))]
        public Option<string[]> Bind { get; set; }

        [RedisOption("enable-debug-command", nameof(Options.EnableDebugCommand))]
        public Option<string> EnableDebugCommand { get; set; }

        [RedisOption("port", nameof(Options.Port))]
        public Option<int> Port { get; set; }

        [RedisOption("maxmemory", nameof(Options.MemorySize))]
        public Option<string> MaxMemory { get; set; }

        [RedisOption("logfile", nameof(Options.FileLogger))]
        public Option<string> LogFile { get; set; }

        [RedisOption("dir", nameof(Options.CheckpointDir))]
        public Option<string> Dir { get; set; }

        [RedisOption("cluster-enabled", nameof(Options.EnableCluster))]
        public Option<RedisBoolean> ClusterEnabled { get; set; }

        [RedisOption("requirepass", nameof(Options.Password))]
        public Option<string> RequirePass { get; set; }

        [RedisOption("aclfile", nameof(Options.AclFile))]
        public Option<string> AclFile { get; set; }

        [RedisOption("cluster-node-timeout", nameof(Options.ClusterTimeout))]
        public Option<int> ClusterNodeTimeout { get; set; }


Review comment (security):
This should be of a new enum type that gets translated to the Garnet enum (`ConnectionProtectionOption`), see `RedisTlsAuthClients` and `RedisTlsClientsTypeConverter` for reference.

Code after:
namespace Garnet
{
    /// <summary>
    /// This class contains all redis.conf settings that have a matching configurable setting in Garnet's Options class.
    /// In order to add a new redis.conf setting:
    /// 1. Verify that the matching Garnet setting is defined in Options.cs
    /// 2. If a custom type is necessary (e.g. enum), use existing or create a new one under RedisTypes.cs 
    /// 3. Add a new property and decorate it with an RedisOptionAttribute, pointing it to the matching Options property name.
    /// 4. If a type conversion is needed to convert between the Redis option and the Garnet option,
    ///    use existing type converters or add a new one under TypeConverters.cs
    /// 5. If a more complex transformer is needed to transform the Redis option and the Garnet option,
    ///    use existing type converters or add a new one under GarnetCustomTransformers.cs, and add its type to the RedisOptionAttribute
    /// </summary>
    internal class RedisOptions
    {
        private const string BindWarning = "Only first IP address specified in bind option is used. All other addresses are ignored.";
        private const string TlsPortWarning = "tls-port option is used only to determine if TLS is enabled. The port value is otherwise ignored.";
        private const string TlsCertFileWarning = @"When using tls-cert-file make sure to first convert your certificate format to .pfx. 
Specify your passphrase in the tls-key-file-pass option (or via the cert-password command line argument), if applicable. 
Specify your subject name via the cert-subject-name command line argument, if applicable.";

        [RedisOption("bind", nameof(Options.Address), BindWarning, typeof(ArrayToFirstItemTransformer<string>))]
        public Option<string[]> Bind { get; set; }

        [RedisOption("enable-debug-command", nameof(Options.EnableDebugCommand))]
        public Option<RedisConnectionProtectionOption> EnableDebugCommand { get; set; }

        [RedisOption("port", nameof(Options.Port))]
        public Option<int> Port { get; set; }

        [RedisOption("maxmemory", nameof(Options.MemorySize))]
        public Option<string> MaxMemory { get; set; }

        [RedisOption("logfile", nameof(Options.FileLogger))]
        public Option<string> LogFile { get; set; }

        [RedisOption("dir", nameof(Options.CheckpointDir))]
        public Option<string> Dir { get; set; }

        [RedisOption("cluster-enabled", nameof(Options.EnableCluster))]
        public Option<RedisBoolean> ClusterEnabled { get; set; }

        [RedisOption("requirepass", nameof(Options.Password))]
        public Option<string> RequirePass { get; set; }

        [RedisOption("aclfile", nameof(Options.AclFile))]
        public Option<string> AclFile { get; set; }

        [RedisOption("cluster-node-timeout", nameof(Options.ClusterTimeout))]
        public Option<int> ClusterNodeTimeout { get; set; }